CIRCT  18.0.0git
StripDebugInfoWithPred.cpp
Go to the documentation of this file.
1 //===- StripDebugInfoWithPred.cpp - Strip debug information selectively ---===//
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 #include "PassDetail.h"
11 #include "mlir/IR/BuiltinOps.h"
12 #include "mlir/IR/Operation.h"
13 #include "mlir/IR/Threading.h"
14 #include "mlir/Pass/Pass.h"
15 #include "llvm/ADT/SmallVector.h"
16 
17 using namespace mlir;
18 
19 template <typename OpOrBlockArgument>
20 static void updateLocIfChanged(OpOrBlockArgument *op, Location newLoc) {
21  if (op->getLoc() != newLoc)
22  op->setLoc(newLoc);
23 }
24 
25 namespace {
26 struct StripDebugInfoWithPred
27  : public circt::StripDebugInfoWithPredBase<StripDebugInfoWithPred> {
28  StripDebugInfoWithPred(const std::function<bool(mlir::Location)> &pred)
29  : pred(pred) {}
30  void runOnOperation() override;
31 
32  // Return stripped location for the given `loc`.
33  mlir::Location getStrippedLoc(Location loc) {
34  // If `pred` return true, strip the location.
35  if (pred(loc))
36  return UnknownLoc::get(loc.getContext());
37 
38  if (auto fusedLoc = loc.dyn_cast<FusedLoc>()) {
39  SmallVector<mlir::Location> newLocations;
40  newLocations.reserve(fusedLoc.getLocations().size());
41  for (auto loc : fusedLoc.getLocations())
42  newLocations.push_back(getStrippedLoc(loc));
43  return FusedLoc::get(&getContext(), newLocations, fusedLoc.getMetadata());
44  }
45 
46  // TODO: Handle other loc type.
47  return loc;
48  }
49 
50  void updateLocArray(Operation *op, StringRef attributeName) {
51  SmallVector<Attribute> newLocs;
52  if (auto resLocs = op->getAttrOfType<ArrayAttr>(attributeName)) {
53  bool changed = false;
54  for (auto loc : resLocs.getAsRange<LocationAttr>()) {
55  auto newLoc = getStrippedLoc(loc);
56  changed |= newLoc != loc;
57  newLocs.push_back(newLoc);
58  }
59  if (changed)
60  op->setAttr(attributeName, ArrayAttr::get(&getContext(), newLocs));
61  }
62  }
63 
64 private:
65  std::function<bool(mlir::Location)> pred;
66 };
67 } // namespace
68 
69 void StripDebugInfoWithPred::runOnOperation() {
70  // If pred is null and dropSuffix is non-empty, initialize the predicate to
71  // strip file info with that suffix.
72  if (!pred && !dropSuffix.empty()) {
73  pred = [&](mlir::Location loc) {
74  if (auto fileLoc = loc.dyn_cast<FileLineColLoc>())
75  return fileLoc.getFilename().getValue().endswith(dropSuffix);
76  return false;
77  };
78  }
79 
80  if (!pred) {
81  getOperation().emitWarning()
82  << "predicate is uninitialized. No debug information is stripped.";
83  return;
84  }
85 
86  parallelForEach(
87  &getContext(), getOperation().getOps(), [&](Operation &toplevelOp) {
88  toplevelOp.walk([&](Operation *op) {
89  updateLocIfChanged(op, getStrippedLoc(op->getLoc()));
90  updateLocArray(op, "argLocs");
91  updateLocArray(op, "resultLocs");
92  updateLocArray(op, "portLocs");
93  // Strip block arguments debug info.
94  for (Region &region : op->getRegions())
95  for (Block &block : region.getBlocks())
96  for (BlockArgument &arg : block.getArguments())
97  updateLocIfChanged(&arg, getStrippedLoc(arg.getLoc()));
98  });
99  });
100 }
101 
102 namespace circt {
103 /// Creates a pass to strip debug information from a function.
104 std::unique_ptr<Pass> createStripDebugInfoWithPredPass(
105  const std::function<bool(mlir::Location)> &pred) {
106  return std::make_unique<StripDebugInfoWithPred>(pred);
107 }
108 } // namespace circt
static void updateLocIfChanged(OpOrBlockArgument *op, Location newLoc)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:53
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
std::unique_ptr< mlir::Pass > createStripDebugInfoWithPredPass(const std::function< bool(mlir::Location)> &pred)
Creates a pass to strip debug information from a function.