CIRCT 20.0.0git
Loading...
Searching...
No Matches
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
13#include "llvm/ADT/SetVector.h"
14#include "llvm/Support/Debug.h"
15
16using namespace circt;
17using namespace debug;
18using namespace mlir;
19
20namespace {
21struct 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
38void DebugAnalysisBuilder::run() {
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
95void 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
104void DebugAnalysisBuilder::addDebugValue(Value value) {
105 if (debugValues.insert(value).second) {
106 for (auto *user : value.getUsers())
107 maybeDebugOp(user);
108 }
109}
110
111void DebugAnalysisBuilder::addDebugOperand(OpOperand *operand) {
112 if (debugOperands.insert(operand).second)
113 maybeDebugOp(operand->get().getDefiningOp());
114}
115
116void 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 debug.py:1
int run(Type[Generator] generator=CppGenerator, cmdline_args=sys.argv)
Definition codegen.py:121
DebugAnalysis(Operation *op)
DenseSet< OpOperand * > debugOperands
DenseSet< Operation * > debugOps
DenseSet< Value > debugValues