CIRCT 20.0.0git
Loading...
Searching...
No Matches
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
23namespace circt {
24namespace firrtl {
25#define GEN_PASS_DEF_LAYERMERGE
26#include "circt/Dialect/FIRRTL/Passes.h.inc"
27} // namespace firrtl
28} // namespace circt
29
30using namespace circt;
31using namespace firrtl;
32
33namespace {
34/// A pass that merges layer blocks referencing the same layer definition.
35struct LayerMerge : public circt::firrtl::impl::LayerMergeBase<LayerMerge> {
36 void runOnOperation() override;
37};
38} // namespace
39
40void 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
72std::unique_ptr<mlir::Pass> circt::firrtl::createLayerMergePass() {
73 return std::make_unique<LayerMerge>();
74}
std::unique_ptr< mlir::Pass > createLayerMergePass()
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.