mirror of https://github.com/llvm/circt.git
[Arc] Don't sink ops with nested writes in MergeIfs (#8584)
This commit is contained in:
parent
b6b1ced097
commit
f4995a322c
|
@ -133,13 +133,19 @@ void MergeIfsPass::sinkOps(Block &rootBlock) {
|
||||||
// Assign an order to this op.
|
// Assign an order to this op.
|
||||||
auto order = OpOrder{opOrder.size() + 1, 0};
|
auto order = OpOrder{opOrder.size() + 1, 0};
|
||||||
opOrder[&op] = order;
|
opOrder[&op] = order;
|
||||||
|
// Track whether the op is, or contains, any writes (and thus can't
|
||||||
|
// generally be moved into a block)
|
||||||
|
bool opContainsWrites = false;
|
||||||
|
|
||||||
// Analyze the side effects in the op.
|
// Analyze the side effects in the op.
|
||||||
op.walk([&](Operation *subOp) {
|
op.walk([&](Operation *subOp) {
|
||||||
if (auto ptr = getPointerWrittenByOp(subOp))
|
if (auto ptr = getPointerWrittenByOp(subOp)) {
|
||||||
nextWrite[ptr] = &op;
|
nextWrite[ptr] = &op;
|
||||||
else if (!isa<StateReadOp, MemoryReadOp>(subOp) && hasSideEffects(subOp))
|
opContainsWrites = true;
|
||||||
|
} else if (!isa<StateReadOp, MemoryReadOp>(subOp) &&
|
||||||
|
hasSideEffects(subOp)) {
|
||||||
nextSideEffect = &op;
|
nextSideEffect = &op;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Determine how much the op can be moved.
|
// Determine how much the op can be moved.
|
||||||
|
@ -151,7 +157,7 @@ void MergeIfsPass::sinkOps(Block &rootBlock) {
|
||||||
// Don't move across general side-effecting ops.
|
// Don't move across general side-effecting ops.
|
||||||
if (nextSideEffect)
|
if (nextSideEffect)
|
||||||
moveLimit.maximize({nextSideEffect, opOrder.lookup(nextSideEffect)});
|
moveLimit.maximize({nextSideEffect, opOrder.lookup(nextSideEffect)});
|
||||||
} else if (isa<StateWriteOp, MemoryWriteOp>(&op) || nextSideEffect == &op) {
|
} else if (opContainsWrites || nextSideEffect == &op) {
|
||||||
// Don't move writes or side-effecting ops.
|
// Don't move writes or side-effecting ops.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,3 +281,28 @@ func.func @MergeNestedIfs(%arg0: i42, %arg1: i1, %arg2: i1) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that ops containing a write aren't sunk
|
||||||
|
// CHECK-LABEL: func.func @DontNestWrites
|
||||||
|
func.func @DontNestWrites(%arg0: !arc.state<i1>, %arg1: i1, %arg2: i1) {
|
||||||
|
// We just want to check that the first if hasn't been moved into the second
|
||||||
|
// CHECK-NEXT: {{%.+}} = scf.if %arg1 -> (i1) {
|
||||||
|
// CHECK: } else {
|
||||||
|
// CHECK: }
|
||||||
|
// CHECK-NEXT: scf.if %arg2 {
|
||||||
|
// CHECK: }
|
||||||
|
// CHECK-NEXT: return
|
||||||
|
|
||||||
|
%1 = scf.if %arg1 -> (i1) {
|
||||||
|
%0 = hw.constant true
|
||||||
|
arc.state_write %arg0 = %0 : <i1>
|
||||||
|
scf.yield %0 : i1
|
||||||
|
} else {
|
||||||
|
%0 = hw.constant false
|
||||||
|
scf.yield %0 : i1
|
||||||
|
}
|
||||||
|
scf.if %arg2 {
|
||||||
|
%0 = comb.or %1, %1 : i1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue