19 #define GEN_PASS_DEF_SYMBOLDCE
20 #include "mlir/Transforms/Passes.h.inc"
26 struct SymbolDCE :
public impl::SymbolDCEBase<SymbolDCE> {
27 void runOnOperation()
override;
32 LogicalResult computeLiveness(
Operation *symbolTableOp,
34 bool symbolTableIsHidden,
39 void SymbolDCE::runOnOperation() {
40 Operation *symbolTableOp = getOperation();
45 <<
" was scheduled to run under SymbolDCE, but does not define a "
47 return signalPassFailure();
52 bool symbolTableIsHidden =
true;
53 SymbolOpInterface symbol = dyn_cast<SymbolOpInterface>(symbolTableOp);
55 symbolTableIsHidden = symbol.isPrivate();
60 if (failed(computeLiveness(symbolTableOp, symbolTable, symbolTableIsHidden,
62 return signalPassFailure();
69 for (
auto &block : nestedSymbolTable->
getRegion(0)) {
70 for (Operation &op : llvm::make_early_inc_range(block)) {
71 if (isa<SymbolOpInterface>(&op) && !liveSymbols.count(&op)) {
83 LogicalResult SymbolDCE::computeLiveness(
Operation *symbolTableOp,
85 bool symbolTableIsHidden,
92 for (
auto &block : symbolTableOp->
getRegion(0)) {
95 SymbolOpInterface symbol = dyn_cast<SymbolOpInterface>(&op);
97 worklist.push_back(&op);
100 bool isDiscardable = (symbolTableIsHidden || symbol.isPrivate()) &&
101 symbol.canDiscardOnUseEmpty();
102 if (!isDiscardable && liveSymbols.insert(&op).second)
103 worklist.push_back(&op);
109 while (!worklist.empty()) {
116 SymbolOpInterface symbol = dyn_cast<SymbolOpInterface>(op);
117 bool symIsHidden = symbolTableIsHidden || !symbol || symbol.isPrivate();
118 if (failed(computeLiveness(op, symbolTable, symIsHidden, liveSymbols)))
123 std::optional<SymbolTable::UseRange> uses = SymbolTable::getSymbolUses(op);
126 <<
"operation contains potentially unknown symbol table, "
127 "meaning that we can't reliable compute symbol uses";
133 resolvedSymbols.clear();
135 op->
getParentOp(), use.getSymbolRef(), resolvedSymbols)))
140 for (
Operation *resolvedSymbol : resolvedSymbols)
141 if (liveSymbols.insert(resolvedSymbol).second)
142 worklist.push_back(resolvedSymbol);
150 return std::make_unique<SymbolDCE>();
A trait used to provide symbol table functionalities to a region operation.
Operation is the basic unit of execution within MLIR.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
This class represents a collection of SymbolTables.
Operation * lookupSymbolIn(Operation *symbolTableOp, StringAttr symbol)
Look up a symbol with the specified name within the specified symbol table operation,...
This class represents a specific symbol use.
Include the generated interface declarations.
std::unique_ptr< Pass > createSymbolDCEPass()
Creates a pass which delete symbol operations that are unreachable.