CIRCT 23.0.0git
Loading...
Searching...
No Matches
MaterializeDebugVariables.cpp
Go to the documentation of this file.
1//===- MaterializeDebugVariables.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 "circt/Support/LLVM.h"
15#include "mlir/Pass/Pass.h"
16#include "llvm/ADT/Twine.h"
17
18using namespace mlir;
19using namespace circt;
20using namespace hw;
21
22namespace circt {
23#define GEN_PASS_DEF_MATERIALIZEDEBUGVARIABLES
24#include "circt/Tools/circt-bmc/Passes.h.inc"
25} // namespace circt
26
27namespace {
28struct MaterializeDebugVariablesPass
29 : public circt::impl::MaterializeDebugVariablesBase<
30 MaterializeDebugVariablesPass> {
31 using MaterializeDebugVariablesBase::MaterializeDebugVariablesBase;
32
33 void runOnOperation() override {
34 for (auto module : getOperation().getOps<HWModuleOp>())
35 materializeDebugVariables(module);
36 }
37
38private:
39 static void materializeDebugVariables(HWModuleOp module) {
40 auto *body = module.getBodyBlock();
41 DenseSet<Value> trackedValues;
42 for (auto varOp : body->getOps<debug::VariableOp>())
43 trackedValues.insert(varOp.getValue());
44
45 OpBuilder builder = OpBuilder::atBlockBegin(body);
46 for (auto &port : module.getPortList()) {
47 if (port.isOutput())
48 continue;
49 if (isa<seq::ClockType>(port.type))
50 continue;
51 if (!port.name || port.name.getValue().empty())
52 continue;
53
54 auto value = body->getArgument(port.argNum);
55 if (!trackedValues.insert(value).second)
56 continue;
57 debug::VariableOp::create(builder, value.getLoc(), port.name, value,
58 /*scope=*/Value{});
59 }
60
61 auto materializeRegAnchor = [&](auto regOp, StringRef regName) {
62 auto regResult = regOp.getResult();
63 if (!trackedValues.insert(regResult).second)
64 return;
65 auto regNameAttr = builder.getStringAttr(regName);
66 OpBuilder regBuilder(regOp);
67 regBuilder.setInsertionPointAfter(regOp);
68 debug::VariableOp::create(regBuilder, regResult.getLoc(), regNameAttr,
69 regResult, /*scope=*/Value{});
70 };
71
72 unsigned regIndex = 0;
73 for (auto regOp : body->getOps<seq::CompRegOp>()) {
74 if (regOp.getName() && !regOp.getName()->empty())
75 materializeRegAnchor(regOp, regOp.getName().value());
76 else
77 materializeRegAnchor(regOp, ("reg_" + Twine(regIndex)).str());
78 ++regIndex;
79 }
80
81 for (auto regOp : body->getOps<seq::FirRegOp>()) {
82 if (!regOp.getName().empty())
83 materializeRegAnchor(regOp, regOp.getName());
84 else
85 materializeRegAnchor(regOp, ("reg_" + Twine(regIndex)).str());
86 ++regIndex;
87 }
88 }
89};
90} // namespace
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition hw.py:1