Fix EliminateRedundantPhi for cascading eliminated phis

This was the actual bug. When EliminateRedundantPhis eliminates a phi, it has to 
rewrite downstream usages of the phi id to the single operand id. We were 
correctly doing that in all but one place. When we iterate _downstream phis_, we 
were looking up the operands against the rewrite table, but not updating the phi 
operands themselves to the rewritten value. 

This fixes the bug, and incidentally fixes a test that has been broken for a 
while and nagging at me.
This commit is contained in:
Joe Savona
2023-03-08 21:10:07 -08:00
parent 1fb0aed668
commit 7813cfa52c
4 changed files with 27 additions and 17 deletions
@@ -57,12 +57,19 @@ export function eliminateRedundantPhi(fn: HIRFunction) {
// Find any redundant phis
phis: for (const phi of block.phis) {
// Remap phis in case operands are from eliminated phis
phi.operands = new Map(
Array.from(phi.operands).map(([block, id]) => [
block,
rewrites.get(id) ?? id,
])
);
// Find if the phi can be eliminated
let same: Identifier | null = null;
for (const [_, operand] of phi.operands) {
const ident = rewrites.get(operand) ?? operand;
if (
(same !== null && ident.id === same.id) ||
ident.id === phi.id.id
(same !== null && operand.id === same.id) ||
operand.id === phi.id.id
) {
// This operand is the same as the phi or is the same as the
// previous non-phi operands
@@ -73,7 +80,7 @@ export function eliminateRedundantPhi(fn: HIRFunction) {
continue phis;
} else {
// First non-phi operand
same = ident;
same = operand;
}
}
invariant(same !== null, "Expected phis to be non-empty");
@@ -21,20 +21,23 @@ function foo(props) {
```javascript
function foo(props) {
const $ = React.unstable_useMemoCache(1);
const $ = React.unstable_useMemoCache(2);
const c_0 = $[0] !== props;
let y;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
if (c_0) {
y = 0;
$[0] = y;
for (
let x = 0;
x > props.min && x < props.max;
x = x + (props.cond ? props.increment : 2), x
) {
x = x * 2;
y = y + x;
}
$[0] = props;
$[1] = y;
} else {
y = $[0];
}
for (
let x = 0;
x > props.min && x < props.max;
x = x + (props.cond ? props.increment : 2), x
) {
x = x * 2;
y = $[1];
}
return y;
}
@@ -25,6 +25,7 @@ function Component(props) {
```javascript
function Component(props) {
const $ = React.unstable_useMemoCache(4);
let x = 0;
const c_0 = $[0] !== props;
let values;
if (c_0) {
@@ -40,12 +41,11 @@ function Component(props) {
}
const y = t0;
values.push(y);
let x$0 = x;
if (props.c) {
x = 1;
}
values.push(x$0);
values.push(x);
if (props.d) {
x = 2;
}