16 #include "llvm/Support/Debug.h"
18 #define DEBUG_TYPE "llhd-sig2reg"
22 #define GEN_PASS_DEF_SIG2REG
23 #include "circt/Dialect/LLHD/Transforms/Passes.h.inc"
28 using namespace circt;
31 struct Sig2RegPass :
public circt::llhd::impl::Sig2RegBase<Sig2RegPass> {
32 void runOnOperation()
override;
36 static LogicalResult
promote(llhd::SignalOp sigOp) {
37 SmallVector<llhd::PrbOp> probes;
39 for (
auto *user : sigOp.getResult().getUsers()) {
40 if (user->getBlock() != sigOp->getBlock()) {
42 { llvm::dbgs() <<
"Promotion failed: user in other block\n"; });
46 if (
auto prbOp = dyn_cast<llhd::PrbOp>(user)) {
47 probes.push_back(prbOp);
51 if (
auto drvOp = dyn_cast<llhd::DrvOp>(user)) {
53 LLVM_DEBUG({ llvm::dbgs() <<
"Promotion failed: multiple drivers\n"; });
57 if (drvOp.getEnable()) {
59 { llvm::dbgs() <<
"Promotion failed: conditional driver\n"; });
68 llvm::dbgs() <<
"Promotion failed: user that is not a probe or drive: "
76 auto timeOp = driveOp.getTime().getDefiningOp<llhd::ConstantTimeOp>();
80 OpBuilder builder(driveOp);
81 if (timeOp.getValue().getTime() == 0 && timeOp.getValue().getDelta() == 0)
82 replacement = driveOp.getValue();
84 replacement = builder.create<llhd::DelayOp>(
85 driveOp.getLoc(), driveOp.getValue(), timeOp.getValue());
87 replacement = sigOp.getInit();
90 for (
auto prb : probes) {
91 prb.getResult().replaceAllUsesWith(replacement);
101 void Sig2RegPass::runOnOperation() {
105 llvm::make_early_inc_range(moduleOp.getOps<llhd::SignalOp>())) {
107 { llvm::dbgs() <<
"\nAttempting to promote " << sigOp <<
"\n"; });
111 LLVM_DEBUG({ llvm::dbgs() <<
"Successfully promoted!\n"; });
static LogicalResult promote(llhd::SignalOp sigOp)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.