[RTLCleanup] Merge consequtive procedural if's with the same condition.

This also fixes ifdef merging to only merge ifdefs with the same condition :-)
This commit is contained in:
Chris Lattner 2021-02-21 11:23:06 -08:00
parent ee01f0817b
commit 623e7ed584
2 changed files with 65 additions and 13 deletions

View File

@ -14,7 +14,6 @@
#include "SVPassDetail.h"
#include "circt/Dialect/SV/SVOps.h"
#include "circt/Dialect/SV/SVPasses.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
using namespace circt;
@ -200,24 +199,42 @@ void RTLCleanupPass::runOnProceduralRegion(Region &region, bool shallow) {
if (auto ifdef = dyn_cast<sv::IfDefProceduralOp>(op)) {
if (auto prevIfDef =
dyn_cast_or_null<sv::IfDefProceduralOp>(lastSideEffectingOp)) {
// We know that there are no side effective operations between the two,
// so merge the first one into this one.
mergeOperationsIntoFrom(ifdef, prevIfDef);
anythingChanged = true;
prevIfDef->erase();
if (ifdef.cond() == prevIfDef.cond()) {
// We know that there are no side effective operations between the
// two, so merge the first one into this one.
mergeOperationsIntoFrom(ifdef, prevIfDef);
anythingChanged = true;
prevIfDef->erase();
// Reprocess the merged body because this may have uncovered other
// simplifications.
runOnProceduralRegion(ifdef->getRegion(0), /*shallow=*/true);
runOnProceduralRegion(ifdef->getRegion(1), /*shallow=*/true);
// Reprocess the merged body because this may have uncovered other
// simplifications.
runOnProceduralRegion(ifdef->getRegion(0), /*shallow=*/true);
runOnProceduralRegion(ifdef->getRegion(1), /*shallow=*/true);
}
}
}
// Merge 'if' operations with the same condition.
if (auto ifop = dyn_cast<sv::IfOp>(op)) {
if (auto prevIf = dyn_cast_or_null<sv::IfOp>(lastSideEffectingOp)) {
if (ifop.cond() == prevIf.cond()) {
// We know that there are no side effective operations between the
// two, so merge the first one into this one.
mergeOperationsIntoFrom(ifop, prevIf);
anythingChanged = true;
prevIf->erase();
// Reprocess the merged body because this may have uncovered other
// simplifications.
runOnProceduralRegion(ifop->getRegion(0), /*shallow=*/true);
runOnProceduralRegion(ifop->getRegion(1), /*shallow=*/true);
}
}
}
// Keep track of the last side effecting operation we've seen.
if (!mlir::MemoryEffectOpInterface::hasNoEffect(&op))
lastSideEffectingOp = &op;
// TODO: Merge procedural if's.
}
}

View File

@ -141,7 +141,6 @@ rtl.module @ifdef_merge(%arg0: i1) {
rtl.output
}
// CHECK-LABEL: rtl.module @ifdef_proc_merge(%arg0: i1) {
// CHECK-NEXT: sv.alwaysff(posedge %arg0) {
// CHECK-NEXT: %true = comb.constant(true) : i1
@ -150,6 +149,9 @@ rtl.module @ifdef_merge(%arg0: i1) {
// CHECK-NEXT: sv.fwrite "A1"
// CHECK-NEXT: sv.fwrite "%x"(%0) : i1
// CHECK-NEXT: }
// CHECK-NEXT: sv.ifdef.procedural "BAR" {
// CHECK-NEXT: sv.fwrite "B1"
// CHECK-NEXT: }
// CHECK-NEXT: }
rtl.module @ifdef_proc_merge(%arg0: i1) {
sv.alwaysff(posedge %arg0) {
@ -161,6 +163,39 @@ rtl.module @ifdef_proc_merge(%arg0: i1) {
sv.ifdef.procedural "FOO" {
sv.fwrite "%x"(%0) : i1
}
sv.ifdef.procedural "BAR" {
sv.fwrite "B1"
}
}
rtl.output
}
// CHECK-LABEL: rtl.module @if_merge(%arg0: i1, %arg1: i1) {
// CHECK-NEXT: sv.alwaysff(posedge %arg0) {
// CHECK-NEXT: %true = comb.constant(true) : i1
// CHECK-NEXT: %0 = comb.xor %arg1, %true : i1
// CHECK-NEXT: sv.if %arg1 {
// CHECK-NEXT: sv.fwrite "A1"
// CHECK-NEXT: sv.fwrite "%x"(%0) : i1
// CHECK-NEXT: }
// CHECK-NEXT: sv.if %0 {
// CHECK-NEXT: sv.fwrite "B1"
// CHECK-NEXT: }
// CHECK-NEXT: }
rtl.module @if_merge(%arg0: i1, %arg1: i1) {
sv.alwaysff(posedge %arg0) {
sv.if %arg1 {
sv.fwrite "A1"
}
%true = comb.constant(true) : i1
%0 = comb.xor %arg1, %true : i1
sv.if %arg1 {
sv.fwrite "%x"(%0) : i1
}
sv.if %0 {
sv.fwrite "B1"
}
}
rtl.output
}