CIRCT 20.0.0git
Loading...
Searching...
No Matches
Sig2RegPass.cpp
Go to the documentation of this file.
1//===- Sig2RegPass.cpp - Implement the Sig2Reg Pass -----------------------===//
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// Implement Pass to promote LLHD signals to SSA values.
10//
11//===----------------------------------------------------------------------===//
12
16#include "llvm/Support/Debug.h"
17
18#define DEBUG_TYPE "llhd-sig2reg"
19
20namespace circt {
21namespace llhd {
22#define GEN_PASS_DEF_SIG2REG
23#include "circt/Dialect/LLHD/Transforms/Passes.h.inc"
24} // namespace llhd
25} // namespace circt
26
27using namespace mlir;
28using namespace circt;
29
30namespace {
31struct Sig2RegPass : public circt::llhd::impl::Sig2RegBase<Sig2RegPass> {
32 void runOnOperation() override;
33};
34} // namespace
35
36static LogicalResult promote(llhd::SignalOp sigOp) {
37 SmallVector<llhd::PrbOp> probes;
38 llhd::DrvOp driveOp;
39 for (auto *user : sigOp.getResult().getUsers()) {
40 if (user->getBlock() != sigOp->getBlock()) {
41 LLVM_DEBUG(
42 { llvm::dbgs() << "Promotion failed: user in other block\n"; });
43 return failure();
44 }
45
46 if (auto prbOp = dyn_cast<llhd::PrbOp>(user)) {
47 probes.push_back(prbOp);
48 continue;
49 }
50
51 if (auto drvOp = dyn_cast<llhd::DrvOp>(user)) {
52 if (driveOp) {
53 LLVM_DEBUG({ llvm::dbgs() << "Promotion failed: multiple drivers\n"; });
54 return failure();
55 }
56
57 if (drvOp.getEnable()) {
58 LLVM_DEBUG(
59 { llvm::dbgs() << "Promotion failed: conditional driver\n"; });
60 return failure();
61 }
62
63 driveOp = drvOp;
64 continue;
65 }
66
67 LLVM_DEBUG({
68 llvm::dbgs() << "Promotion failed: user that is not a probe or drive: "
69 << *user << "\n";
70 });
71 return failure();
72 }
73
74 Value replacement;
75 if (driveOp) {
76 auto timeOp = driveOp.getTime().getDefiningOp<llhd::ConstantTimeOp>();
77 if (!timeOp)
78 return failure();
79
80 OpBuilder builder(driveOp);
81 if (timeOp.getValue().getTime() == 0 && timeOp.getValue().getDelta() == 0)
82 replacement = driveOp.getValue();
83 else
84 replacement = builder.create<llhd::DelayOp>(
85 driveOp.getLoc(), driveOp.getValue(), timeOp.getValue());
86 } else {
87 replacement = sigOp.getInit();
88 }
89
90 for (auto prb : probes) {
91 prb.getResult().replaceAllUsesWith(replacement);
92 prb.erase();
93 }
94
95 if (driveOp)
96 driveOp.erase();
97
98 return success();
99}
100
101void Sig2RegPass::runOnOperation() {
102 hw::HWModuleOp moduleOp = getOperation();
103
104 for (auto sigOp :
105 llvm::make_early_inc_range(moduleOp.getOps<llhd::SignalOp>())) {
106 LLVM_DEBUG(
107 { llvm::dbgs() << "\nAttempting to promote " << sigOp << "\n"; });
108 if (failed(promote(sigOp)))
109 continue;
110
111 LLVM_DEBUG({ llvm::dbgs() << "Successfully promoted!\n"; });
112 sigOp.erase();
113 }
114}
static LogicalResult promote(llhd::SignalOp sigOp)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.