CIRCT 22.0.0git
Loading...
Searching...
No Matches
MergeTaps.cpp
Go to the documentation of this file.
1//===- MergeTaps.cpp ------------------------------------------------------===//
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
12
13#include "mlir/IR/Threading.h"
14#include "mlir/Pass/Pass.h"
15
16namespace circt {
17namespace arc {
18#define GEN_PASS_DEF_MERGETAPS
19#include "circt/Dialect/Arc/ArcPasses.h.inc"
20} // namespace arc
21} // namespace circt
22
23using namespace circt;
24using namespace arc;
25using namespace hw;
26
27namespace {
28struct MergeTapsPass : public arc::impl::MergeTapsBase<MergeTapsPass> {
29 using MergeTapsBase::MergeTapsBase;
30
31 void mergeTaps();
32
33 void runOnOperation() override { mergeTaps(); }
34};
35} // namespace
36
37void MergeTapsPass::mergeTaps() {
38 // Collect Tap ops with the same SSA operand and merge them
39 // into a single TapOp. Erases TapOps while traversing the
40 // module body, but will never erase the op currently visited.
41 for (auto tapOp : getOperation().getBodyBlock()->getOps<arc::TapOp>()) {
42 SmallVector<TapOp> aliasTaps;
43 for (auto user : tapOp.getOperand().getUsers()) {
44 if (user == tapOp)
45 continue;
46 if (auto otherTap = dyn_cast<arc::TapOp>(user)) {
47 // Don't combine taps across blocks
48 if (tapOp->getBlock() == otherTap->getBlock())
49 aliasTaps.push_back(otherTap);
50 }
51 }
52 if (aliasTaps.empty())
53 continue;
54 // Collect the names and erase all other taps
55 SmallVector<Attribute> names;
56 aliasTaps.push_back(tapOp);
57 for (auto mergeTap : aliasTaps) {
58 for (auto nameAttr : mergeTap.getNames())
59 names.push_back(nameAttr);
60 if (mergeTap != tapOp)
61 mergeTap.erase();
62 }
63 // Sort the names and remove duplicates
64 llvm::sort(names, [](Attribute a, Attribute b) {
65 return cast<StringAttr>(a).getValue() < cast<StringAttr>(b).getValue();
66 });
67 names.erase(llvm::unique(names), names.end());
68 tapOp.setNamesAttr(ArrayAttr::get(tapOp.getContext(), names));
69 }
70}
static Block * getBodyBlock(FModuleLike mod)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition hw.py:1