CIRCT 22.0.0git
Loading...
Searching...
No Matches
KanagawaEliminateRedundantOps.cpp
Go to the documentation of this file.
1//===- KanagawaEliminateRedundantOps.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
13
14#include "mlir/Pass/Pass.h"
15
16#include "llvm/ADT/TypeSwitch.h"
17#include "llvm/Support/Debug.h"
18
19#define DEBUG_TYPE "kanagawa-eliminate-redundant-ops"
20
21namespace circt {
22namespace kanagawa {
23#define GEN_PASS_DEF_KANAGAWAELIMINATEREDUNDANTOPS
24#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc"
25} // namespace kanagawa
26} // namespace circt
27
28using namespace circt;
29using namespace kanagawa;
30
31// Helper function to eliminate redundant GetPortOps in a container
32static void eliminateRedundantGetPortOps(ContainerOp containerOp) {
33 // Structure to track accesses to each port of each instance
34 struct PortAccesses {
35 GetPortOp getAsInput;
36 GetPortOp getAsOutput;
37 };
38
39 llvm::DenseMap</*instance*/ Value,
40 /*portName*/ llvm::DenseMap<StringAttr, PortAccesses>>
41 instancePortAccessMap;
42
43 // Collect all GetPortOps and identify redundant ones
44 llvm::SmallVector<GetPortOp> redundantOps;
45
46 for (auto getPortOp : containerOp.getOps<GetPortOp>()) {
47 PortAccesses &portAccesses =
48 instancePortAccessMap[getPortOp.getInstance()]
49 [getPortOp.getPortSymbolAttr().getAttr()];
50
51 if (getPortOp.getDirection() == Direction::Input) {
52 if (portAccesses.getAsInput) {
53 // Found redundant input GetPortOp - mark the current one for removal
54 // and replace its uses with the existing one
55 getPortOp.replaceAllUsesWith(portAccesses.getAsInput.getResult());
56 redundantOps.push_back(getPortOp);
57 } else {
58 portAccesses.getAsInput = getPortOp;
59 }
60 } else {
61 if (portAccesses.getAsOutput) {
62 // Found redundant output GetPortOp - mark the current one for removal
63 // and replace its uses with the existing one
64 getPortOp.replaceAllUsesWith(portAccesses.getAsOutput.getResult());
65 redundantOps.push_back(getPortOp);
66 } else {
67 portAccesses.getAsOutput = getPortOp;
68 }
69 }
70 }
71
72 // Remove all redundant GetPortOps
73 for (auto redundantOp : redundantOps)
74 redundantOp.erase();
75}
76
77// Helper function to eliminate redundant PortReadOps in a container
78static void eliminateRedundantPortReadOps(ContainerOp containerOp) {
79 // Map to track the first PortReadOp for each port being read from
80 llvm::DenseMap<Value, PortReadOp> portFirstReadMap;
81 llvm::SmallVector<PortReadOp> redundantOps;
82
83 for (auto portReadOp : containerOp.getOps<PortReadOp>()) {
84 Value portBeingRead =
85 portReadOp.getPort(); // The port operand being read from
86
87 if (auto existingRead = portFirstReadMap.lookup(portBeingRead)) {
88 // Found redundant PortReadOp - mark the current one for removal
89 // and replace its uses with the existing one
90 portReadOp.replaceAllUsesWith(existingRead.getResult());
91 redundantOps.push_back(portReadOp);
92 } else {
93 portFirstReadMap[portBeingRead] = portReadOp;
94 }
95 }
96
97 // Remove all redundant PortReadOps
98 for (auto redundantOp : redundantOps)
99 redundantOp.erase();
100}
101
102namespace {
103
104struct EliminateRedundantOpsPass
105 : public circt::kanagawa::impl::KanagawaEliminateRedundantOpsBase<
106 EliminateRedundantOpsPass> {
107 void runOnOperation() override {
108 ContainerOp containerOp = getOperation();
109 eliminateRedundantGetPortOps(containerOp);
111 }
112};
113
114} // anonymous namespace
115
117 return std::make_unique<EliminateRedundantOpsPass>();
118}
static void eliminateRedundantPortReadOps(ContainerOp containerOp)
static void eliminateRedundantGetPortOps(ContainerOp containerOp)
std::unique_ptr< mlir::Pass > createEliminateRedundantOpsPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.