mirror of https://github.com/llvm/circt.git
[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:
parent
ee01f0817b
commit
623e7ed584
|
@ -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 ®ion, 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.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue