Skip to content

Commit 87d10b7

Browse files
committed
Revert "[FIRRTL] FoldRegMems: insert new ops into same block as memory (#7868)"
This reverts commit b342d31. This commit can introduce use-before-def in some situations related to the pipeline generation. While this entire folder looks very sketchy, I'm opting to leave in the original folder as this was done due to downstream user complaints of single-element memories showing up. Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
1 parent b342d31 commit 87d10b7

File tree

2 files changed

+25
-128
lines changed

2 files changed

+25
-128
lines changed

lib/Dialect/FIRRTL/FIRRTLFolds.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,7 +2870,7 @@ struct FoldRegMems : public mlir::RewritePattern {
28702870
if (hasDontTouch(mem) || info.depth != 1)
28712871
return failure();
28722872

2873-
auto *block = mem->getBlock();
2873+
auto memModule = mem->getParentOfType<FModuleOp>();
28742874

28752875
// Find the clock of the register-to-be, all write ports should share it.
28762876
Value clock;
@@ -2926,17 +2926,11 @@ struct FoldRegMems : public mlir::RewritePattern {
29262926
}
29272927

29282928
// Create a new register to store the data.
2929-
auto clockWire = rewriter.create<WireOp>(mem.getLoc(), clock.getType());
29302929
auto ty = mem.getDataType();
2931-
auto reg = rewriter
2932-
.create<RegOp>(mem.getLoc(), ty, clockWire.getResult(),
2933-
mem.getName())
2930+
rewriter.setInsertionPointAfterValue(clock);
2931+
auto reg = rewriter.create<RegOp>(mem.getLoc(), ty, clock, mem.getName())
29342932
.getResult();
29352933

2936-
rewriter.setInsertionPointToEnd(block);
2937-
rewriter.create<MatchingConnectOp>(mem.getLoc(), clockWire.getResult(),
2938-
clock);
2939-
29402934
// Helper to insert a given number of pipeline stages through registers.
29412935
auto pipeline = [&](Value value, Value clock, const Twine &name,
29422936
unsigned latency) {
@@ -2970,7 +2964,7 @@ struct FoldRegMems : public mlir::RewritePattern {
29702964
auto portPipeline = [&, port = port](StringRef field, unsigned stages) {
29712965
Value value = getPortFieldValue(port, field);
29722966
assert(value);
2973-
rewriter.setInsertionPointAfterValue(reg);
2967+
rewriter.setInsertionPointAfterValue(value);
29742968
return pipeline(value, portClock, name + "_" + field, stages);
29752969
};
29762970

@@ -3004,7 +2998,7 @@ struct FoldRegMems : public mlir::RewritePattern {
30042998

30052999
Value en = getPortFieldValue(port, "en");
30063000
Value wmode = getPortFieldValue(port, "wmode");
3007-
rewriter.setInsertionPointToEnd(block);
3001+
rewriter.setInsertionPointToEnd(memModule.getBodyBlock());
30083002

30093003
auto wen = rewriter.create<AndPrimOp>(port.getLoc(), en, wmode);
30103004
auto wenPipelined =
@@ -3016,7 +3010,7 @@ struct FoldRegMems : public mlir::RewritePattern {
30163010
}
30173011

30183012
// Regardless of `writeUnderWrite`, always implement PortOrder.
3019-
rewriter.setInsertionPointToEnd(block);
3013+
rewriter.setInsertionPointToEnd(memModule.getBodyBlock());
30203014
Value next = reg;
30213015
for (auto &[data, en, mask] : writes) {
30223016
Value masked;

test/Dialect/FIRRTL/simplify-mems.mlir

Lines changed: 19 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -408,21 +408,10 @@ firrtl.circuit "OneAddressNoMask" {
408408
in %in_rwen: !firrtl.uint<1>,
409409
out %result_read: !firrtl.uint<32>,
410410
out %result_rw: !firrtl.uint<32>) {
411-
%c1_ui1 = firrtl.constant 1 : !firrtl.uint<1>
412-
%Memory_read, %Memory_rw, %Memory_write = firrtl.mem Undefined
413-
{
414-
depth = 1 : i64,
415-
name = "Memory",
416-
portNames = ["read", "rw", "write"],
417-
readLatency = 2 : i32,
418-
writeLatency = 4 : i32
419-
} :
420-
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<32>>,
421-
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>,
422-
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<32>, mask: uint<1>>
423411

424-
// CHECK: %Memory = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<32>
425-
412+
// Pipeline the inputs.
413+
// TODO: It would be good to de-duplicate these either in the pass or in a canonicalizer.
414+
426415
// CHECK: %Memory_write_en_0 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<1>
427416
// CHECK: firrtl.matchingconnect %Memory_write_en_0, %in_wen : !firrtl.uint<1>
428417
// CHECK: %Memory_write_en_1 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<1>
@@ -444,6 +433,22 @@ firrtl.circuit "OneAddressNoMask" {
444433
// CHECK: %Memory_rw_wdata_2 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<32>
445434
// CHECK: firrtl.matchingconnect %Memory_rw_wdata_2, %Memory_rw_wdata_1 : !firrtl.uint<32>
446435

436+
%c1_ui1 = firrtl.constant 1 : !firrtl.uint<1>
437+
438+
%Memory_read, %Memory_rw, %Memory_write = firrtl.mem Undefined
439+
{
440+
depth = 1 : i64,
441+
name = "Memory",
442+
portNames = ["read", "rw", "write"],
443+
readLatency = 2 : i32,
444+
writeLatency = 4 : i32
445+
} :
446+
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<32>>,
447+
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>,
448+
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<32>, mask: uint<1>>
449+
450+
// CHECK: %Memory = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<32>
451+
447452
// CHECK: firrtl.matchingconnect %result_read, %Memory : !firrtl.uint<32>
448453
%read_addr = firrtl.subfield %Memory_read[addr] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<32>>
449454
firrtl.connect %read_addr, %addr : !firrtl.uint<1>, !firrtl.uint<1>
@@ -492,105 +497,3 @@ firrtl.circuit "OneAddressNoMask" {
492497
firrtl.connect %write_mask, %c1_ui1 : !firrtl.uint<1>, !firrtl.uint<1>
493498
}
494499
}
495-
496-
// -----
497-
498-
// This test ensures that the FoldRegMems canonicalization correctly
499-
// folds memories under layerblocks.
500-
firrtl.circuit "Rewrite1ElementMemoryToRegisterUnderLayerblock" {
501-
firrtl.layer @A bind {}
502-
503-
firrtl.module public @Rewrite1ElementMemoryToRegisterUnderLayerblock(
504-
in %clock: !firrtl.clock,
505-
in %addr: !firrtl.uint<1>,
506-
in %in_data: !firrtl.uint<32>,
507-
in %wmode_rw: !firrtl.uint<1>,
508-
in %in_wen: !firrtl.uint<1>,
509-
in %in_rwen: !firrtl.uint<1>) {
510-
511-
%c1_ui1 = firrtl.constant 1 : !firrtl.uint<1>
512-
513-
// CHECK firrtl.layerblock @A
514-
firrtl.layerblock @A {
515-
// CHECK: %result_read = firrtl.wire : !firrtl.uint<32>
516-
// CHECK: %result_rw = firrtl.wire : !firrtl.uint<32>
517-
%result_read = firrtl.wire : !firrtl.uint<32>
518-
%result_rw = firrtl.wire : !firrtl.uint<32>
519-
520-
%Memory_read, %Memory_rw, %Memory_write = firrtl.mem Undefined
521-
{
522-
depth = 1 : i64,
523-
name = "Memory",
524-
portNames = ["read", "rw", "write"],
525-
readLatency = 2 : i32,
526-
writeLatency = 2 : i32
527-
} :
528-
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<32>>,
529-
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>,
530-
!firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<32>, mask: uint<1>>
531-
532-
// CHECK: %Memory = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<32>
533-
// CHECK: %Memory_write_mask_0 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<1>
534-
// CHECK: firrtl.matchingconnect %Memory_write_mask_0, %c1_ui1 : !firrtl.uint<1>
535-
536-
// CHECK: %Memory_write_en_0 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<1>
537-
// CHECK: firrtl.matchingconnect %Memory_write_en_0, %in_wen : !firrtl.uint<1>
538-
539-
// CHECK: %Memory_write_data_0 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<32>
540-
// CHECK: firrtl.matchingconnect %Memory_write_data_0, %in_data : !firrtl.uint<32>
541-
542-
// CHECK: %Memory_rw_wmask_0 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<1>
543-
// CHECK: firrtl.matchingconnect %Memory_rw_wmask_0, %c1_ui1 : !firrtl.uint<1>
544-
545-
// CHECK: %Memory_rw_wdata_0 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<32>
546-
// CHECK: firrtl.matchingconnect %Memory_rw_wdata_0, %in_data : !firrtl.uint<32>
547-
548-
// CHECK: firrtl.matchingconnect %result_read, %Memory : !firrtl.uint<32>
549-
// CHECK: firrtl.matchingconnect %result_rw, %Memory : !firrtl.uint<32>
550-
551-
// CHECK: %0 = firrtl.and %in_rwen, %wmode_rw : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
552-
// CHECK: %Memory_rw_wen_0 = firrtl.reg %clock : !firrtl.clock, !firrtl.uint<1>
553-
// CHECK: firrtl.matchingconnect %Memory_rw_wen_0, %0 : !firrtl.uint<1>
554-
// CHECK: %1 = firrtl.and %Memory_rw_wen_0, %Memory_rw_wmask_0 : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
555-
// CHECK: %2 = firrtl.mux(%1, %Memory_rw_wdata_0, %Memory) : (!firrtl.uint<1>, !firrtl.uint<32>, !firrtl.uint<32>) -> !firrtl.uint<32>
556-
// CHECK: %3 = firrtl.and %Memory_write_en_0, %Memory_write_mask_0 : (!firrtl.uint<1>, !firrtl.uint<1>) -> !firrtl.uint<1>
557-
// CHECK: %4 = firrtl.mux(%3, %Memory_write_data_0, %2) : (!firrtl.uint<1>, !firrtl.uint<32>, !firrtl.uint<32>) -> !firrtl.uint<32>
558-
// CHECK: firrtl.matchingconnect %Memory, %4 : !firrtl.uint<32>
559-
560-
%read_addr = firrtl.subfield %Memory_read[addr] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<32>>
561-
firrtl.connect %read_addr, %addr : !firrtl.uint<1>, !firrtl.uint<1>
562-
%read_en = firrtl.subfield %Memory_read[en] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<32>>
563-
firrtl.connect %read_en, %c1_ui1 : !firrtl.uint<1>, !firrtl.uint<1>
564-
%read_clk = firrtl.subfield %Memory_read[clk] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<32>>
565-
firrtl.connect %read_clk, %clock : !firrtl.clock, !firrtl.clock
566-
%read_data = firrtl.subfield %Memory_read[data] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data flip: uint<32>>
567-
firrtl.connect %result_read, %read_data : !firrtl.uint<32>, !firrtl.uint<32>
568-
569-
%rw_addr = firrtl.subfield %Memory_rw[addr] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>
570-
firrtl.connect %rw_addr, %addr : !firrtl.uint<1>, !firrtl.uint<1>
571-
%rw_en = firrtl.subfield %Memory_rw[en] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>
572-
firrtl.connect %rw_en, %in_rwen : !firrtl.uint<1>, !firrtl.uint<1>
573-
%rw_clk = firrtl.subfield %Memory_rw[clk] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>
574-
firrtl.connect %rw_clk, %clock : !firrtl.clock, !firrtl.clock
575-
%rw_rdata = firrtl.subfield %Memory_rw[rdata] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>
576-
firrtl.connect %result_rw, %rw_rdata : !firrtl.uint<32>, !firrtl.uint<32>
577-
%rw_wmode = firrtl.subfield %Memory_rw[wmode] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>
578-
firrtl.connect %rw_wmode, %wmode_rw : !firrtl.uint<1>, !firrtl.uint<1>
579-
%rw_wdata = firrtl.subfield %Memory_rw[wdata] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>
580-
firrtl.connect %rw_wdata, %in_data : !firrtl.uint<32>, !firrtl.uint<32>
581-
%rw_wmask = firrtl.subfield %Memory_rw[wmask] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, rdata flip: uint<32>, wmode: uint<1>, wdata: uint<32>, wmask: uint<1>>
582-
firrtl.connect %rw_wmask, %c1_ui1 : !firrtl.uint<1>, !firrtl.uint<1>
583-
584-
%write_addr = firrtl.subfield %Memory_write[addr] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<32>, mask: uint<1>>
585-
firrtl.connect %write_addr, %addr : !firrtl.uint<1>, !firrtl.uint<1>
586-
%write_en = firrtl.subfield %Memory_write[en] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<32>, mask: uint<1>>
587-
firrtl.connect %write_en, %in_wen : !firrtl.uint<1>, !firrtl.uint<1>
588-
%write_clk = firrtl.subfield %Memory_write[clk] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<32>, mask: uint<1>>
589-
firrtl.connect %write_clk, %clock : !firrtl.clock, !firrtl.clock
590-
%write_data = firrtl.subfield %Memory_write[data] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<32>, mask: uint<1>>
591-
firrtl.connect %write_data, %in_data : !firrtl.uint<32>, !firrtl.uint<32>
592-
%write_mask = firrtl.subfield %Memory_write[mask] : !firrtl.bundle<addr: uint<1>, en: uint<1>, clk: clock, data: uint<32>, mask: uint<1>>
593-
firrtl.connect %write_mask, %c1_ui1 : !firrtl.uint<1>, !firrtl.uint<1>
594-
}
595-
}
596-
}

0 commit comments

Comments
 (0)