[SSP] Add pass to print instances as DOT graphs. (#4363)

This commit is contained in:
Julian Oppermann 2022-11-29 12:27:29 +13:00 committed by GitHub
parent 0f47c4f5ba
commit fa61059d0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 207 additions and 2 deletions

View File

@ -48,6 +48,10 @@ This document describes the available CIRCT passes and their contracts.
[include "SeqPasses.md"]
## SSP Dialect Passes
[include "SSPPasses.md"]
## SV Dialect Passes
[include "SVPasses.md"]

View File

@ -7,3 +7,9 @@ mlir_tablegen(SSPAttributes.h.inc -gen-attrdef-decls)
mlir_tablegen(SSPAttributes.cpp.inc -gen-attrdef-defs)
add_public_tablegen_target(CIRCTSSPAttributesIncGen)
add_dependencies(circt-headers CIRCTSSPAttributesIncGen)
set(LLVM_TARGET_DEFINITIONS SSPPasses.td)
mlir_tablegen(SSPPasses.h.inc -gen-pass-decls)
add_public_tablegen_target(CIRCTSSPTransformsIncGen)
add_circt_doc(SSPPasses SSPPasses -gen-pass-doc)

View File

@ -0,0 +1,31 @@
//===- SSPPasses.h - SSP pass entry points ----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This header file defines prototypes that expose pass constructors.
//
//===----------------------------------------------------------------------===//
#ifndef CIRCT_DIALECT_SSP_SSPPASSES_H
#define CIRCT_DIALECT_SSP_SSPPASSES_H
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassRegistry.h"
#include <memory>
namespace circt {
namespace ssp {
std::unique_ptr<mlir::Pass> createPrintInstancePass();
#define GEN_PASS_REGISTRATION
#include "circt/Dialect/SSP/SSPPasses.h.inc"
} // namespace ssp
} // namespace circt
#endif // CIRCT_DIALECT_SSP_SSPPASSES_H

View File

@ -0,0 +1,23 @@
//===- SSPPasses.td - SSP pass definition file -------------*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the passes that work on the SSP dialect.
//
//===----------------------------------------------------------------------===//
#ifndef CIRCT_DIALECT_SSP_SSPPASSES_TD
#define CIRCT_DIALECT_SSP_SSPPASSES_TD
include "mlir/Pass/PassBase.td"
def PrintInstance : Pass<"ssp-print-instance", "mlir::ModuleOp"> {
let summary = "Prints all SSP instances as DOT graphs.";
let constructor = "circt::ssp::createPrintInstancePass()";
}
#endif // CIRCT_DIALECT_SSP_SSPPASSES_TD

View File

@ -25,6 +25,7 @@
#include "circt/Dialect/LLHD/Transforms/Passes.h"
#include "circt/Dialect/MSFT/MSFTPasses.h"
#include "circt/Dialect/Pipeline/PipelinePasses.h"
#include "circt/Dialect/SSP/SSPPasses.h"
#include "circt/Dialect/SV/SVPasses.h"
#include "circt/Dialect/Seq/SeqPasses.h"
#include "circt/Dialect/SystemC/SystemCPasses.h"
@ -51,6 +52,7 @@ inline void registerAllPasses() {
handshake::registerPasses();
hw::registerPasses();
pipeline::registerPasses();
ssp::registerPasses();
systemc::registerPasses();
}

View File

@ -15,6 +15,8 @@
#include "circt/Scheduling/Problems.h"
#include "llvm/Support/raw_ostream.h"
#include <functional>
namespace circt {
@ -50,6 +52,9 @@ LogicalResult computeStartTimesInCycle(ChainingProblem &prob);
/// Export \p prob as a DOT graph into \p fileName.
void dumpAsDOT(Problem &prob, StringRef fileName);
/// Print \p prob as a DOT graph onto \p stream.
void dumpAsDOT(Problem &prob, raw_ostream &stream);
} // namespace scheduling
} // namespace circt

View File

@ -34,3 +34,5 @@ add_circt_dialect_library(CIRCTSSP
LINK_LIBS PUBLIC
${SSP_LinkLibs}
)
add_subdirectory(Transforms)

View File

@ -0,0 +1,13 @@
add_circt_dialect_library(CIRCTSSPTransforms
PrintInstance.cpp
DEPENDS
CIRCTSSPTransformsIncGen
LINK_LIBS PUBLIC
CIRCTScheduling
CIRCTSSP
MLIRIR
MLIRPass
MLIRTransformUtils
)

View File

@ -0,0 +1,36 @@
//===- PassDetails.h - SSP pass class details --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Contains the stuff shared between the different SSP passes.
//
//===----------------------------------------------------------------------===//
// clang-tidy seems to expect the absolute path in the
// header guard on some systems, so just disable it.
// NOLINTNEXTLINE(llvm-header-guard)
#ifndef DIALECT_SSP_TRANSFORMS_PASSDETAILS_H
#define DIALECT_SSP_TRANSFORMS_PASSDETAILS_H
#include "circt/Dialect/SSP/SSPAttributes.h"
#include "circt/Dialect/SSP/SSPOps.h"
#include "circt/Dialect/SSP/SSPPasses.h"
#include "circt/Dialect/SSP/Utilities.h"
#include "circt/Scheduling/Problems.h"
#include "mlir/IR/BuiltinOps.h"
namespace circt {
namespace ssp {
#define GEN_PASS_CLASSES
#include "circt/Dialect/SSP/SSPPasses.h.inc"
} // namespace ssp
} // namespace circt
#endif // DIALECT_SSP_TRANSFORMS_PASSDETAILS_H

View File

@ -0,0 +1,60 @@
//===- PrintInstance.cpp - Print instance pass ------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implements the PrintInstance (as a DOT graph) pass.
//
//===----------------------------------------------------------------------===//
#include "PassDetails.h"
#include "circt/Scheduling/Utilities.h"
using namespace circt;
using namespace scheduling;
using namespace ssp;
namespace {
struct PrintInstancePass : public PrintInstanceBase<PrintInstancePass> {
explicit PrintInstancePass(raw_ostream &os) : os(os) {}
void runOnOperation() override;
raw_ostream &os;
};
} // end anonymous namespace
template <typename ProblemT>
static void printInstance(InstanceOp instOp, raw_ostream &os) {
auto prob = loadProblem<ProblemT>(instOp);
dumpAsDOT(prob, os);
}
void PrintInstancePass::runOnOperation() {
auto moduleOp = getOperation();
for (auto instOp : moduleOp.getOps<InstanceOp>()) {
StringRef probName = instOp.getProblemName();
if (probName.equals("Problem"))
printInstance<Problem>(instOp, os);
else if (probName.equals("CyclicProblem"))
printInstance<CyclicProblem>(instOp, os);
else if (probName.equals("ChainingProblem"))
printInstance<ChainingProblem>(instOp, os);
else if (probName.equals("SharedOperatorsProblem"))
printInstance<SharedOperatorsProblem>(instOp, os);
else if (probName.equals("ModuloProblem"))
printInstance<ModuloProblem>(instOp, os);
else {
auto instName = instOp.getSymName().value_or("unnamed");
llvm::errs() << "ssp-print-instance: Unknown problem class '" << probName
<< "' in instance '" << instName << "'\n";
return signalPassFailure();
}
}
}
std::unique_ptr<mlir::Pass> circt::ssp::createPrintInstancePass() {
return std::make_unique<PrintInstancePass>(llvm::errs());
}

View File

@ -55,7 +55,12 @@ LogicalResult scheduling::handleOperationsInTopologicalOrder(Problem &prob,
void scheduling::dumpAsDOT(Problem &prob, StringRef fileName) {
std::error_code ec;
llvm::raw_fd_ostream out(fileName, ec);
mlir::raw_indented_ostream os(out);
scheduling::dumpAsDOT(prob, out);
out.close();
}
void scheduling::dumpAsDOT(Problem &prob, raw_ostream &stream) {
mlir::raw_indented_ostream os(stream);
os << "digraph G {\n";
os.indent();
@ -154,5 +159,4 @@ void scheduling::dumpAsDOT(Problem &prob, StringRef fileName) {
os.unindent();
os << "}\n";
out.close();
}

View File

@ -0,0 +1,18 @@
// RUN: circt-opt -ssp-print-instance %s 2>&1 | FileCheck %s
// CHECK: digraph G {
ssp.instance @Foo of "Problem" {
library {
operator_type @Bar [latency<1>]
}
graph {
// CHECK: op0 -> op1
// CHECK: op0 -> op2
// CHECK: op1 -> op3
// CHECK: op2 -> op3
%0 = operation<@Bar>()
%1 = operation<@Bar>(%0)
%2 = operation<@Bar>(%0)
operation<@Bar>(%1, %2)
}
}

View File

@ -49,6 +49,7 @@ target_link_libraries(circt-opt
CIRCTSeq
CIRCTSeqTransforms
CIRCTSSP
CIRCTSSPTransforms
CIRCTStandardToHandshake
CIRCTPipelineOps
CIRCTPipelineToHW