10#include "mlir/IR/BuiltinOps.h"
11#include "mlir/IR/Operation.h"
12#include "mlir/IR/Threading.h"
13#include "mlir/Pass/Pass.h"
14#include "llvm/ADT/SmallVector.h"
17#define GEN_PASS_DEF_STRIPDEBUGINFOWITHPRED
18#include "circt/Transforms/Passes.h.inc"
22template <
typename OpOrBlockArgument>
24 if (op->getLoc() != newLoc)
29struct StripDebugInfoWithPred
30 :
public circt::impl::StripDebugInfoWithPredBase<StripDebugInfoWithPred> {
31 StripDebugInfoWithPred(
const std::function<
bool(mlir::Location)> &pred)
33 void runOnOperation()
override;
36 mlir::Location getStrippedLoc(Location loc) {
39 return UnknownLoc::get(loc.getContext());
41 if (
auto fusedLoc = dyn_cast<FusedLoc>(loc)) {
42 SmallVector<mlir::Location> newLocations;
43 newLocations.reserve(fusedLoc.getLocations().size());
44 for (
auto loc : fusedLoc.getLocations())
45 newLocations.push_back(getStrippedLoc(loc));
49 return FusedLoc::get(newLocations, fusedLoc.getMetadata(), &getContext());
56 void updateLocArray(Operation *op, StringRef attributeName) {
57 SmallVector<Attribute> newLocs;
58 if (
auto resLocs = op->getAttrOfType<ArrayAttr>(attributeName)) {
60 for (
auto loc : resLocs.getAsRange<LocationAttr>()) {
61 auto newLoc = getStrippedLoc(loc);
62 changed |= newLoc != loc;
63 newLocs.push_back(newLoc);
66 op->setAttr(attributeName, ArrayAttr::get(&getContext(), newLocs));
71 std::function<bool(mlir::Location)> pred;
75void StripDebugInfoWithPred::runOnOperation() {
78 if (!pred && !dropSuffix.empty()) {
79 pred = [&](mlir::Location loc) {
80 if (
auto fileLoc = dyn_cast<FileLineColLoc>(loc))
81 return fileLoc.getFilename().getValue().ends_with(dropSuffix);
87 getOperation().emitWarning()
88 <<
"predicate is uninitialized. No debug information is stripped.";
92 auto stripLocsOnOp = [
this](Operation *op) {
94 updateLocArray(op,
"arg_locs");
95 updateLocArray(op,
"result_locs");
96 updateLocArray(op,
"port_locs");
103 SmallVector<Operation *> topLevelOpsToWalk;
104 for (
auto &op : getOperation().getOps()) {
106 if (op.getNumRegions() != 0) {
107 topLevelOpsToWalk.push_back(&op);
115 parallelForEach(&getContext(), topLevelOpsToWalk, [&](Operation *toplevelOp) {
116 toplevelOp->walk([&](Operation *op) {
119 for (Region ®ion : op->getRegions())
120 for (
Block &block : region.getBlocks())
121 for (BlockArgument &arg : block.getArguments())
130 const std::function<
bool(mlir::Location)> &pred) {
131 return std::make_unique<StripDebugInfoWithPred>(pred);
static void updateLocIfChanged(OpOrBlockArgument *op, Location newLoc)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
std::unique_ptr< mlir::Pass > createStripDebugInfoWithPredPass(const std::function< bool(mlir::Location)> &pred)
Creates a pass to strip debug information from a function.