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;
36 struct TestDebugAnalysisPass
37 :
public PassWrapper<TestDebugAnalysisPass, OperationPass<mlir::ModuleOp>> {
38 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDebugAnalysisPass)
40 void runOnOperation()
override;
41 StringRef getArgument()
const override {
return "test-debug-analysis"; }
42 StringRef getDescription()
const override {
43 return "Perform debug analysis and emit results as attributes";
48 void TestDebugAnalysisPass::runOnOperation() {
49 auto *context = &getContext();
50 auto &analysis = getAnalysis<DebugAnalysis>();
51 for (
auto *op : analysis.debugOps) {
61 struct TestDependenceAnalysisPass
62 :
public PassWrapper<TestDependenceAnalysisPass,
63 OperationPass<func::FuncOp>> {
64 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDependenceAnalysisPass)
66 void runOnOperation()
override;
67 StringRef getArgument()
const override {
return "test-dependence-analysis"; }
68 StringRef getDescription()
const override {
69 return "Perform dependence analysis and emit results as attributes";
74 void TestDependenceAnalysisPass::runOnOperation() {
75 MLIRContext *context = &getContext();
79 getOperation().walk([&](Operation *op) {
80 if (!isa<AffineReadOpInterface, AffineWriteOpInterface>(op))
83 SmallVector<Attribute> deps;
85 for (
auto dep : analysis.getDependences(op)) {
86 if (dep.dependenceType != DependenceResult::HasDependence)
89 SmallVector<Attribute> comps;
90 for (auto comp : dep.dependenceComponents) {
91 SmallVector<Attribute> vector;
93 IntegerAttr::get(IntegerType::get(context, 64), *comp.lb));
95 IntegerAttr::get(IntegerType::get(context, 64), *comp.ub));
96 comps.push_back(ArrayAttr::get(context, vector));
103 op->setAttr(
"dependences", dependences);
112 struct TestSchedulingAnalysisPass
113 :
public PassWrapper<TestSchedulingAnalysisPass,
114 OperationPass<func::FuncOp>> {
115 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestSchedulingAnalysisPass)
117 void runOnOperation()
override;
118 StringRef getArgument()
const override {
return "test-scheduling-analysis"; }
119 StringRef getDescription()
const override {
120 return "Perform scheduling analysis and emit results as attributes";
125 void TestSchedulingAnalysisPass::runOnOperation() {
126 MLIRContext *context = &getContext();
130 getOperation().walk([&](AffineForOp forOp) {
131 if (isa<AffineForOp>(forOp.getBody()->front()))
134 forOp.getBody()->walk([&](Operation *op) {
135 for (auto dep : problem.getDependences(op)) {
136 assert(!dep.isInvalid());
137 if (dep.isAuxiliary())
138 op->setAttr(
"dependence", UnitAttr::get(context));
149 struct InferTopModulePass
150 :
public PassWrapper<InferTopModulePass, OperationPass<mlir::ModuleOp>> {
151 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(InferTopModulePass)
153 void runOnOperation()
override;
154 StringRef getArgument()
const override {
return "test-infer-top-level"; }
155 StringRef getDescription()
const override {
156 return "Perform top level module inference and emit results as attributes "
157 "on the enclosing module.";
162 void InferTopModulePass::runOnOperation() {
170 llvm::SmallVector<Attribute, 4> attrs;
171 for (
auto *node : *res)
172 attrs.push_back(node->getModule().getModuleNameAttr());
174 analysis.
getParent()->setAttr(
"test.top",
185 registerPass([]() -> std::unique_ptr<Pass> {
186 return std::make_unique<TestDependenceAnalysisPass>();
188 registerPass([]() -> std::unique_ptr<Pass> {
189 return std::make_unique<TestSchedulingAnalysisPass>();
191 registerPass([]() -> std::unique_ptr<Pass> {
192 return std::make_unique<TestDebugAnalysisPass>();
194 registerPass([]() -> std::unique_ptr<Pass> {
195 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()
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
CyclicSchedulingAnalysis constructs a CyclicProblem for each AffineForOp by performing a memory depen...
CyclicProblem & getProblem(affine::AffineForOp forOp)
MemoryDependenceAnalysis traverses any AffineForOps in the FuncOp body and checks for affine memory a...