18 #include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h"
19 #include "mlir/Dialect/Affine/IR/AffineOps.h"
20 #include "mlir/Dialect/Func/IR/FuncOps.h"
21 #include "mlir/IR/BuiltinOps.h"
22 #include "mlir/IR/Value.h"
23 #include "mlir/Pass/Pass.h"
24 #include "llvm/Support/Debug.h"
28 using namespace circt;
37 struct TestDebugAnalysisPass
38 :
public PassWrapper<TestDebugAnalysisPass, OperationPass<mlir::ModuleOp>> {
39 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDebugAnalysisPass)
41 void runOnOperation()
override;
42 StringRef getArgument()
const override {
return "test-debug-analysis"; }
43 StringRef getDescription()
const override {
44 return "Perform debug analysis and emit results as attributes";
49 void TestDebugAnalysisPass::runOnOperation() {
50 auto *context = &getContext();
51 auto &analysis = getAnalysis<DebugAnalysis>();
52 for (
auto *op : analysis.debugOps) {
62 struct TestDependenceAnalysisPass
63 :
public PassWrapper<TestDependenceAnalysisPass,
64 OperationPass<func::FuncOp>> {
65 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDependenceAnalysisPass)
67 void runOnOperation()
override;
68 StringRef getArgument()
const override {
return "test-dependence-analysis"; }
69 StringRef getDescription()
const override {
70 return "Perform dependence analysis and emit results as attributes";
75 void TestDependenceAnalysisPass::runOnOperation() {
76 MLIRContext *context = &getContext();
80 getOperation().walk([&](Operation *op) {
81 if (!isa<AffineReadOpInterface, AffineWriteOpInterface>(op))
84 SmallVector<Attribute> deps;
86 for (
auto dep : analysis.getDependences(op)) {
87 if (dep.dependenceType != DependenceResult::HasDependence)
90 SmallVector<Attribute> comps;
91 for (auto comp : dep.dependenceComponents) {
92 SmallVector<Attribute> vector;
94 IntegerAttr::get(IntegerType::get(context, 64), *comp.lb));
96 IntegerAttr::get(IntegerType::get(context, 64), *comp.ub));
97 comps.push_back(ArrayAttr::get(context, vector));
104 op->setAttr(
"dependences", dependences);
113 struct TestSchedulingAnalysisPass
114 :
public PassWrapper<TestSchedulingAnalysisPass,
115 OperationPass<func::FuncOp>> {
116 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestSchedulingAnalysisPass)
118 void runOnOperation()
override;
119 StringRef getArgument()
const override {
return "test-scheduling-analysis"; }
120 StringRef getDescription()
const override {
121 return "Perform scheduling analysis and emit results as attributes";
126 void TestSchedulingAnalysisPass::runOnOperation() {
127 MLIRContext *context = &getContext();
131 getOperation().walk([&](AffineForOp forOp) {
132 if (isa<AffineForOp>(forOp.getBody()->front()))
135 forOp.getBody()->walk([&](Operation *op) {
136 for (auto dep : problem.getDependences(op)) {
137 assert(!dep.isInvalid());
138 if (dep.isAuxiliary())
139 op->setAttr(
"dependence", UnitAttr::get(context));
150 struct InferTopModulePass
151 :
public PassWrapper<InferTopModulePass, OperationPass<mlir::ModuleOp>> {
152 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(InferTopModulePass)
154 void runOnOperation()
override;
155 StringRef getArgument()
const override {
return "test-infer-top-level"; }
156 StringRef getDescription()
const override {
157 return "Perform top level module inference and emit results as attributes "
158 "on the enclosing module.";
163 void InferTopModulePass::runOnOperation() {
171 llvm::SmallVector<Attribute, 4> attrs;
172 for (
auto *node : *res)
173 attrs.push_back(node->getModule().getModuleNameAttr());
175 analysis.
getParent()->setAttr(
"test.top",
186 registerPass([]() -> std::unique_ptr<Pass> {
187 return std::make_unique<TestDependenceAnalysisPass>();
189 registerPass([]() -> std::unique_ptr<Pass> {
190 return std::make_unique<TestSchedulingAnalysisPass>();
192 registerPass([]() -> std::unique_ptr<Pass> {
193 return std::make_unique<TestDebugAnalysisPass>();
195 registerPass([]() -> std::unique_ptr<Pass> {
196 return std::make_unique<InferTopModulePass>();
HW-specific instance graph with a virtual entry node linking to all publicly visible modules.
FailureOr< llvm::ArrayRef< InstanceGraphNode * > > getInferredTopLevelNodes()
Get the nodes corresponding to the inferred top-level modules of a circuit.
Operation * getParent()
Return the parent under which all nodes are nested.
This class models a cyclic scheduling problem.
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
void registerAnalysisTestPasses()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
CyclicSchedulingAnalysis constructs a CyclicProblem for each AffineForOp by performing a memory depen...
scheduling::CyclicProblem & getProblem(mlir::affine::AffineForOp forOp)
MemoryDependenceAnalysis traverses any AffineForOps in the FuncOp body and checks for affine memory a...