This pass deletes all symbols that are found to be unreachable. This is done by computing the set of operations that are known to be live, propagating that liveness to other symbols, and then deleting all symbols that are not within this live set.
Unit tests: pass. 62198 tests passed, 0 failed and 815 were skipped.
We do need our own pass in MLIR for a couple of reasons:
- There are many targets of MLIR that don't directly lower to LLVM(e.g. some non programming language front-ends).
- Symbols are used at many different abstraction levels, and having the ability to DCE at each is important and powerful.
Note that even if these abstractions do eventually lower to LLVM, sometimes the 'symbol' does not have a direct representation in LLVM. For example, a Dialect in MLIR may have a 'global variable' like operation that is eventually transformed into a buffer when compiling for a specific device. In situations like those, the resultant code wouldn't contain a global in the traditional sense.
- MLIR supports nested references. A "module" isn't constrained to be a module like in the LLVM sense. Modules(and module like operations) can be arbitrarily nested within each other.
I've looked a bit at GlobalDCE, but at this time I'm not sure how much sharing we can do. This pass is meant to be generic, i.e. agnostic to the specific design choices of a given dialect, and the LLVM definition of globals/linkage/visibility does not generalize across all of the different users.
Did you have any specific ideas in mind for how/what things could be shared?