CIRCT  20.0.0git
LayerMerge.cpp
Go to the documentation of this file.
1 //===- LayerMerge.cpp - Merge layer blocks together -----------------------===//
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 // This pass merges layer blocks in a module which reference the same layer
10 // definition.
11 //
12 //===----------------------------------------------------------------------===//
13 
16 #include "mlir/IR/Iterators.h"
17 #include "mlir/IR/PatternMatch.h"
18 #include "mlir/Pass/Pass.h"
19 #include "llvm/Support/Debug.h"
20 
21 #define DEBUG_TYPE "firrtl-layer-merge"
22 
23 namespace circt {
24 namespace firrtl {
25 #define GEN_PASS_DEF_LAYERMERGE
26 #include "circt/Dialect/FIRRTL/Passes.h.inc"
27 } // namespace firrtl
28 } // namespace circt
29 
30 using namespace circt;
31 using namespace firrtl;
32 
33 namespace {
34 /// A pass that merges layer blocks referencing the same layer definition.
35 struct LayerMerge : public circt::firrtl::impl::LayerMergeBase<LayerMerge> {
36  void runOnOperation() override;
37 };
38 } // namespace
39 
40 void LayerMerge::runOnOperation() {
41  LLVM_DEBUG(
42  llvm::dbgs() << "==----- Running LayerMerge "
43  "--------------------------------------------------===\n"
44  << "Module: '" << getOperation().getName() << "'\n";);
45 
46  // Track the last layer block in a module associated with a specific layer.
47  llvm::DenseMap<SymbolRefAttr, LayerBlockOp> lastBlockMap;
48 
49  // Recursively visit LayerBlockOps in reverse order. Merge all earlier layer
50  // blocks into the last layer blocks of the same layer definition.
51  //
52  // The recursive walk will cause nested layer blocks to also be merged.
53  auto moduleOp = getOperation();
54  mlir::IRRewriter rewriter(moduleOp.getContext());
55  moduleOp.walk<mlir::WalkOrder::PostOrder, mlir::ReverseIterator>(
56  [&](LayerBlockOp thisBlock) {
57  auto layer = thisBlock.getLayerName();
58  // If we haven't seen this block before, then it is the last block.
59  auto [item, inserted] = lastBlockMap.try_emplace(layer, thisBlock);
60  if (inserted)
61  return WalkResult::advance();
62 
63  auto &lastBlock = item->getSecond();
64  rewriter.inlineBlockBefore(thisBlock.getBody(), lastBlock.getBody(),
65  lastBlock.getBody()->begin());
66  thisBlock->erase();
67  numMerged++;
68  return WalkResult::advance();
69  });
70 }
71 
72 std::unique_ptr<mlir::Pass> circt::firrtl::createLayerMergePass() {
73  return std::make_unique<LayerMerge>();
74 }
std::unique_ptr< mlir::Pass > createLayerMergePass()
Definition: LayerMerge.cpp:72
StringAttr getName(ArrayAttr names, size_t idx)
Return the name at the specified index of the ArrayAttr or null if it cannot be determined.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21