mirror of https://github.com/llvm/circt.git
[SSP] Add pass to print instances as DOT graphs. (#4363)
This commit is contained in:
parent
0f47c4f5ba
commit
fa61059d0a
|
@ -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"]
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -34,3 +34,5 @@ add_circt_dialect_library(CIRCTSSP
|
|||
LINK_LIBS PUBLIC
|
||||
${SSP_LinkLibs}
|
||||
)
|
||||
|
||||
add_subdirectory(Transforms)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
add_circt_dialect_library(CIRCTSSPTransforms
|
||||
PrintInstance.cpp
|
||||
|
||||
DEPENDS
|
||||
CIRCTSSPTransformsIncGen
|
||||
|
||||
LINK_LIBS PUBLIC
|
||||
CIRCTScheduling
|
||||
CIRCTSSP
|
||||
MLIRIR
|
||||
MLIRPass
|
||||
MLIRTransformUtils
|
||||
)
|
|
@ -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
|
|
@ -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());
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -49,6 +49,7 @@ target_link_libraries(circt-opt
|
|||
CIRCTSeq
|
||||
CIRCTSeqTransforms
|
||||
CIRCTSSP
|
||||
CIRCTSSPTransforms
|
||||
CIRCTStandardToHandshake
|
||||
CIRCTPipelineOps
|
||||
CIRCTPipelineToHW
|
||||
|
|
Loading…
Reference in New Issue