Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UnusedOpPruner.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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#ifndef CIRCT_SUPPORT_UNUSEDOPPRUNER_H
10#define CIRCT_SUPPORT_UNUSEDOPPRUNER_H
11
12#include "circt/Support/LLVM.h"
13#include "mlir/IR/Operation.h"
14#include "mlir/Interfaces/ControlFlowInterfaces.h"
15#include "mlir/Interfaces/SideEffectInterfaces.h"
16
17namespace circt {
18
19/// Utility that tracks operations that have potentially become unused and
20/// allows them to be cleaned up at a later point. Useful to make passes clean
21/// up dead code.
23 /// Mark an op the be erased later if it is unused at that point.
24 void eraseLaterIfUnused(Operation *op) {
25 assert(op);
26 opsToEraseIfUnused.insert(op);
27 }
28
29 /// Mark the defining op of a value to be erased later if the op is unused at
30 /// that point.
31 void eraseLaterIfUnused(Value value) {
32 if (!value)
33 return;
34 if (auto *defOp = value.getDefiningOp())
35 eraseLaterIfUnused(defOp);
36 else
37 blockArgsToEraseIfUnused.insert(cast<BlockArgument>(value));
38 }
39
40 /// Mark the defining ops of a range of values to be erased later if the ops
41 /// are unused at that point.
42 void eraseLaterIfUnused(ValueRange values) {
43 for (auto value : values)
44 eraseLaterIfUnused(value);
45 }
46
47 /// Erase an operation immediately, and remove it from the set of ops to be
48 /// removed later. The op is erase regardless of whether it has any side
49 /// effects or not.
50 void eraseNow(Operation *op) {
51 eraseLaterIfUnused(op->getOperands());
52 opsToEraseIfUnused.erase(op);
53 op->erase();
54 }
55
56 // Erase tracked operations that are side-effect free and have become unused.
57 void eraseNow() {
58 using mlir::BranchOpInterface;
59 while (!opsToEraseIfUnused.empty() || !blockArgsToEraseIfUnused.empty()) {
60 while (!opsToEraseIfUnused.empty()) {
61 auto it = opsToEraseIfUnused.begin();
62 auto *op = *it;
63 opsToEraseIfUnused.erase(it);
64 if (!isOpTriviallyDead(op))
65 continue;
66 eraseLaterIfUnused(op->getOperands());
67 op->erase();
68 }
69 while (!blockArgsToEraseIfUnused.empty()) {
70 auto it = blockArgsToEraseIfUnused.begin();
71 auto arg = *it;
73 if (!arg.use_empty())
74 continue;
75 if (!llvm::all_of(arg.getOwner()->getUses(), [](auto &blockOperand) {
76 return isa<BranchOpInterface>(blockOperand.getOwner());
77 }))
78 continue;
79 unsigned argIdx = arg.getArgNumber();
80 for (auto &blockOperand : arg.getOwner()->getUses()) {
81 auto branchOp = cast<BranchOpInterface>(blockOperand.getOwner());
82 auto operands =
83 branchOp.getSuccessorOperands(blockOperand.getOperandNumber());
84 eraseLaterIfUnused(operands[argIdx]);
85 operands.erase(argIdx);
86 }
87 arg.getOwner()->eraseArgument(argIdx);
88 }
89 }
90 }
91
92private:
93 /// The set of operations that may have become unused.
94 llvm::SmallDenseSet<Operation *> opsToEraseIfUnused;
95 /// The set of block arguments that may have become unused.
96 llvm::SmallDenseSet<BlockArgument> blockArgsToEraseIfUnused;
97};
98
99} // namespace circt
100
101#endif // CIRCT_SUPPORT_UNUSEDOPPRUNER_H
assert(baseType &&"element must be base type")
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Utility that tracks operations that have potentially become unused and allows them to be cleaned up a...
llvm::SmallDenseSet< BlockArgument > blockArgsToEraseIfUnused
The set of block arguments that may have become unused.
void eraseLaterIfUnused(Value value)
Mark the defining op of a value to be erased later if the op is unused at that point.
llvm::SmallDenseSet< Operation * > opsToEraseIfUnused
The set of operations that may have become unused.
void eraseLaterIfUnused(Operation *op)
Mark an op the be erased later if it is unused at that point.
void eraseLaterIfUnused(ValueRange values)
Mark the defining ops of a range of values to be erased later if the ops are unused at that point.
void eraseNow(Operation *op)
Erase an operation immediately, and remove it from the set of ops to be removed later.