CIRCT  20.0.0git
DebugAnalysis.cpp
Go to the documentation of this file.
1 //===- DebugAnalysis.cpp --------------------------------------------------===//
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 
12 #include "circt/Dialect/HW/HWOps.h"
13 #include "llvm/ADT/SetVector.h"
14 #include "llvm/Support/Debug.h"
15 
16 using namespace circt;
17 using namespace debug;
18 using namespace mlir;
19 
20 namespace {
21 struct DebugAnalysisBuilder {
22  DebugAnalysisBuilder(Operation *rootOp) : rootOp(rootOp) {}
23  void run();
24  void addDebugOp(Operation *op);
25  void addDebugValue(Value value);
26  void addDebugOperand(OpOperand *operand);
27  void maybeDebugOp(Operation *op);
28 
29  Operation *rootOp;
30  SetVector<Operation *> worklist;
31 
32  DenseSet<Operation *> debugOps;
33  DenseSet<Value> debugValues;
34  DenseSet<OpOperand *> debugOperands;
35 };
36 } // namespace
37 
39  // Find all debug ops nested under the root op and mark them as debug-only
40  // to kickstart the analysis.
41  rootOp->walk([&](Operation *op) {
42  if (isa<debug::DebugDialect>(op->getDialect())) {
43  addDebugOp(op);
44  return;
45  }
46  for (auto &region : op->getRegions())
47  for (auto &block : region)
48  for (auto arg : block.getArguments())
49  if (isa<debug::DebugDialect>(arg.getType().getDialect()))
50  addDebugValue(arg);
51  for (auto result : op->getResults())
52  if (isa<debug::DebugDialect>(result.getType().getDialect()))
53  addDebugValue(result);
54  });
55 
56  // Visit operations and check if all their operands or all their uses are
57  // marked as debug-only. If they are, mark the op itself as debug-only.
58  while (!worklist.empty()) {
59  auto *op = worklist.pop_back_val();
60  if (debugOps.contains(op))
61  continue;
62 
63  // Do not propagate through stateful elements. This should probably be
64  // configurable, since certain forms of debug info extraction would be able
65  // to pull entire state machines out of the design. For now this just
66  // represents the common denominator across all debug infos.
67  if (!isa<hw::HWDialect, comb::CombDialect>(op->getDialect()))
68  continue;
69  if (op->hasAttr("name"))
70  continue;
71 
72  if (op->getNumResults() > 0) {
73  auto allUsesDebug = llvm::all_of(op->getUses(), [&](auto &use) {
74  return debugOperands.contains(&use);
75  });
76  if (allUsesDebug) {
77  addDebugOp(op);
78  continue;
79  }
80  }
81 
82  if (op->getNumOperands() > 0) {
83  auto allOperandsDebug =
84  llvm::all_of(op->getOperands(), [&](auto operand) {
85  return debugValues.contains(operand);
86  });
87  if (allOperandsDebug) {
88  addDebugOp(op);
89  continue;
90  }
91  }
92  }
93 }
94 
95 void DebugAnalysisBuilder::addDebugOp(Operation *op) {
96  if (debugOps.insert(op).second) {
97  for (auto &operand : op->getOpOperands())
98  addDebugOperand(&operand);
99  for (auto result : op->getResults())
100  addDebugValue(result);
101  }
102 }
103 
104 void DebugAnalysisBuilder::addDebugValue(Value value) {
105  if (debugValues.insert(value).second) {
106  for (auto *user : value.getUsers())
107  maybeDebugOp(user);
108  }
109 }
110 
111 void DebugAnalysisBuilder::addDebugOperand(OpOperand *operand) {
112  if (debugOperands.insert(operand).second)
113  maybeDebugOp(operand->get().getDefiningOp());
114 }
115 
116 void DebugAnalysisBuilder::maybeDebugOp(Operation *op) {
117  if (!op || debugOps.contains(op))
118  return;
119  worklist.insert(op);
120 }
121 
123  DebugAnalysisBuilder builder(op);
124  builder.run();
125  debugOps = std::move(builder.debugOps);
126  debugValues = std::move(builder.debugValues);
127  debugOperands = std::move(builder.debugOperands);
128 }
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Definition: debug.py:1
int run(Type[Generator] generator=CppGenerator, cmdline_args=sys.argv)
Definition: codegen.py:121
DebugAnalysis(Operation *op)