Skip to content

Commit 0d8ac6d

Browse files
committed
[Synth]LowerWordsToBits: Improve scalability with bit-sensitive constprop
Previously, GreedyPatternRewriter was naively used to bit-blast multi-bit values but it didn't scale well due to worklist iteration and unnecessary IR creation which occasionally ended up with constant values. Hence the pass was often not scalable for large designs. This commit fixes the issue by applying constant propagation during the bit-blast process and replaces GreedyPatternRewriter with a manual one-shot walk with recursion. Key improvements: - Rename Driver class to BitBlaster for better clarity - Complete rewrite from pattern-based approach to sophisticated algorithm - Implement known bits analysis for efficient constant propagation - Add comprehensive statistics collection and performance metrics - Enhance bit extraction logic with intelligent caching mechanisms - Support full range of operations: AIG, MIG, and combinatorial ops - Improve error handling with combinational cycle detection - Preserve debugging information with name hint propagation The new implementation provides significant scalability improvements through bit-sensitive constant propagation, enabling more efficient synthesis of large multi-bit operations by avoiding unnecessary computations on constant bits.
1 parent d3e792b commit 0d8ac6d

File tree

7 files changed

+476
-95
lines changed

7 files changed

+476
-95
lines changed

include/circt/Dialect/Synth/SynthOps.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ struct AndInverterVariadicOpConversion
3838
mlir::PatternRewriter &rewriter) const override;
3939
};
4040

41+
LogicalResult topologicallyGraphRegionBlocks(
42+
mlir::Operation *op,
43+
llvm::function_ref<bool(mlir::Value, mlir::Operation *)> isOperandReady);
4144
} // namespace synth
4245
} // namespace circt
4346

include/circt/Dialect/Synth/Transforms/SynthPasses.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ def LowerVariadic : Pass<"synth-lower-variadic", "hw::HWModuleOp"> {
8484
def LowerWordToBits : Pass<"synth-lower-word-to-bits", "hw::HWModuleOp"> {
8585
let summary = "Lower multi-bit AndInverter to single-bit ones";
8686
let dependentDialects = ["comb::CombDialect"];
87+
let statistics = [
88+
Statistic<"numLoweredBits", "num-lowered-bits",
89+
"Number of total bits lowered including constant">,
90+
Statistic<"numLoweredConstants", "num-lowered-constants",
91+
"Number of total constant bits lowered">,
92+
Statistic<"numLoweredOps", "num-lowered-ops",
93+
"Number of total operations lowered">,
94+
];
8795
}
8896

8997
def PrintLongestPathAnalysis

lib/Dialect/Synth/SynthOps.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
#include "circt/Dialect/HW/HWOps.h"
1111
#include "circt/Support/CustomDirectiveImpl.h"
1212
#include "circt/Support/Naming.h"
13+
#include "mlir/Analysis/TopologicalSortUtils.h"
1314
#include "mlir/IR/BuiltinAttributes.h"
1415
#include "mlir/IR/Matchers.h"
1516
#include "mlir/IR/OpDefinition.h"
1617
#include "mlir/IR/PatternMatch.h"
1718
#include "llvm/ADT/APInt.h"
1819
#include "llvm/Support/Casting.h"
20+
#include "llvm/Support/LogicalResult.h"
1921

2022
using namespace mlir;
2123
using namespace circt;
@@ -301,3 +303,25 @@ LogicalResult circt::synth::AndInverterVariadicOpConversion::matchAndRewrite(
301303
op, op.getOperands(), op.getInverted(), rewriter));
302304
return success();
303305
}
306+
307+
LogicalResult circt::synth::topologicallyGraphRegionBlocks(
308+
mlir::Operation *op,
309+
llvm::function_ref<bool(mlir::Value, mlir::Operation *)> isOperandReady) {
310+
// Sort the operations topologically
311+
auto walkResult = op->walk([&](Region *region) {
312+
auto regionKindOp =
313+
dyn_cast<mlir::RegionKindInterface>(region->getParentOp());
314+
if (!regionKindOp ||
315+
regionKindOp.hasSSADominance(region->getRegionNumber()))
316+
return WalkResult::advance();
317+
318+
// Graph region.
319+
for (auto &block : *region) {
320+
if (!mlir::sortTopologically(&block, isOperandReady))
321+
return WalkResult::interrupt();
322+
}
323+
return WalkResult::advance();
324+
});
325+
326+
return success(!walkResult.wasInterrupted());
327+
}

lib/Dialect/Synth/Transforms/CutRewriter.cpp

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -122,30 +122,15 @@ static bool compareDelayAndArea(OptimizationStrategy strategy, double newArea,
122122
LogicalResult
123123
circt::synth::topologicallySortLogicNetwork(mlir::Operation *topOp) {
124124

125-
// Sort the operations topologically
126-
auto walkResult = topOp->walk([&](Region *region) {
127-
auto regionKindOp =
128-
dyn_cast<mlir::RegionKindInterface>(region->getParentOp());
129-
if (!regionKindOp ||
130-
regionKindOp.hasSSADominance(region->getRegionNumber()))
131-
return WalkResult::advance();
132-
133-
auto isOperationReady = [&](Value value, Operation *op) -> bool {
134-
// Topologically sort simulatable ops and purely
135-
// dataflow ops. Other operations can be scheduled.
136-
return !(isSupportedLogicOp(op) ||
137-
isa<comb::ExtractOp, comb::ReplicateOp, comb::ConcatOp>(op));
138-
};
139-
140-
// Graph region.
141-
for (auto &block : *region) {
142-
if (!mlir::sortTopologically(&block, isOperationReady))
143-
return WalkResult::interrupt();
144-
}
145-
return WalkResult::advance();
146-
});
125+
auto isOperationReady = [](Value value, Operation *op) -> bool {
126+
// Topologically sort simulatable ops and purely
127+
// dataflow ops. Other operations can be scheduled.
128+
return !(isSupportedLogicOp(op) ||
129+
isa<comb::ExtractOp, comb::ReplicateOp, comb::ConcatOp>(op));
130+
};
147131

148-
if (walkResult.wasInterrupted())
132+
auto result = topologicallyGraphRegionBlocks(topOp, isOperationReady);
133+
if (failed(result))
149134
return mlir::emitError(topOp->getLoc(),
150135
"failed to sort operations topologically");
151136
return success();

0 commit comments

Comments
 (0)