CIRCT  20.0.0git
MSFTLowerInstances.cpp
Go to the documentation of this file.
1 //===- MSFTLowerInstances.cpp - Instace lowering pass -----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "PassDetails.h"
11 #include "circt/Dialect/HW/HWOps.h"
18 
19 #include "mlir/IR/BuiltinOps.h"
20 #include "mlir/IR/PatternMatch.h"
21 #include "mlir/Pass/Pass.h"
22 #include "mlir/Pass/PassRegistry.h"
23 #include "mlir/Transforms/DialectConversion.h"
24 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
25 
26 namespace circt {
27 namespace msft {
28 #define GEN_PASS_DEF_LOWERINSTANCES
29 #include "circt/Dialect/MSFT/MSFTPasses.h.inc"
30 } // namespace msft
31 } // namespace circt
32 
33 using namespace circt;
34 using namespace msft;
35 
36 //===----------------------------------------------------------------------===//
37 // Lower dynamic instances to global refs.
38 //===----------------------------------------------------------------------===//
39 
40 namespace {
41 struct LowerInstancesPass
42  : public circt::msft::impl::LowerInstancesBase<LowerInstancesPass> {
43  void runOnOperation() override;
44 
45  LogicalResult lower(DynamicInstanceOp inst, InstanceHierarchyOp hier,
46  OpBuilder &b);
47 
48  // Cache the top-level symbols. Insert the new ones we're creating for new
49  // HierPathOps.
50  SymbolCache topSyms;
51 };
52 } // anonymous namespace
53 
54 LogicalResult LowerInstancesPass::lower(DynamicInstanceOp inst,
56  OpBuilder &b) {
57 
58  hw::HierPathOp ref = nullptr;
59 
60  // If 'inst' doesn't contain any ops which use a hierpath op, don't create
61  // one.
62  if (llvm::any_of(inst.getOps(), [](Operation &op) {
63  return isa<DynInstDataOpInterface>(op);
64  })) {
65 
66  // Come up with a unique symbol name.
67  auto refSym = StringAttr::get(&getContext(), "instref");
68  auto origRefSym = refSym;
69  unsigned ctr = 0;
70  while (topSyms.getDefinition(refSym))
71  refSym = StringAttr::get(&getContext(),
72  origRefSym.getValue() + "_" + Twine(++ctr));
73 
74  // Create a hierpath to replace us.
75  ArrayAttr hierPath = inst.getPath();
76  ref = b.create<hw::HierPathOp>(inst.getLoc(), refSym, hierPath);
77 
78  // Add the new symbol to the symbol cache.
79  topSyms.addDefinition(refSym, ref);
80  }
81 
82  // Relocate all my children.
83  OpBuilder hierBlock(&hier.getBody().front().front());
84  for (Operation &op : llvm::make_early_inc_range(inst.getOps())) {
85  // Child instances should have been lowered already.
86  assert(!isa<DynamicInstanceOp>(op));
87  op.remove();
88  hierBlock.insert(&op);
89 
90  // Assign a ref for ops which need it.
91  if (auto specOp = dyn_cast<UnaryDynInstDataOpInterface>(op)) {
92  assert(ref);
93  specOp.setPathOp(ref);
94  }
95  }
96 
97  inst.erase();
98  return success();
99 }
100 void LowerInstancesPass::runOnOperation() {
101  auto top = getOperation();
102  auto *ctxt = &getContext();
103 
104  // Populate the top level symbol cache.
105  topSyms.addDefinitions(top);
106 
107  size_t numFailed = 0;
108  OpBuilder builder(ctxt);
109 
110  // Find all of the InstanceHierarchyOps.
111  for (Operation &op : llvm::make_early_inc_range(top.getOps())) {
112  auto instHierOp = dyn_cast<InstanceHierarchyOp>(op);
113  if (!instHierOp)
114  continue;
115  builder.setInsertionPoint(&op);
116  // Walk the child dynamic instances in _post-order_ so we lower and delete
117  // the children first.
118  instHierOp->walk<mlir::WalkOrder::PostOrder>([&](DynamicInstanceOp inst) {
119  if (failed(lower(inst, instHierOp, builder)))
120  ++numFailed;
121  });
122  }
123  if (numFailed)
124  signalPassFailure();
125 }
126 
127 namespace circt {
128 namespace msft {
129 std::unique_ptr<Pass> createLowerInstancesPass() {
130  return std::make_unique<LowerInstancesPass>();
131 }
132 } // namespace msft
133 } // namespace circt
assert(baseType &&"element must be base type")
Default symbol cache implementation; stores associations between names (StringAttr's) to mlir::Operat...
Definition: SymCache.h:85
def create(name_ref)
Definition: msft.py:43
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:55
std::unique_ptr< mlir::Pass > createLowerInstancesPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Definition: msft.py:1