mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Update on "[compiler] Infer phi types, extend mutable ranges to account for Store effects"
Redo of an earlier (pre-OSS) PR to infer types of phi nodes. There are a few pieces to this: 1. Update InferTypes to infer the type of `phi.id.type`, not the unused `phi.type`. 2. Update the algorithm to verify that all the phi types are actually equal, not just have the same kind. 3. Handle circular types by removing the cycle. However, that reveals another issue: InferMutableRanges currently infers the results of `Store` effects _after_ its fixpoint loop. That was fine when a Store could never occur on a phi (since they wouldn't have a type to get a function signature from). Now though, we can have Store effects occur on phis, and we need to ensure that this correctly updates the mutable range of the phi operands - recursively. See new test that fails without the fixpoint loop. [ghstack-poisoned]
This commit is contained in:
@@ -50,11 +50,10 @@ export function inferMutableRanges(ir: HIRFunction): void {
|
||||
// Re-infer mutable ranges for all values
|
||||
inferMutableLifetimes(ir, true);
|
||||
|
||||
// Re-infer mutable ranges for aliases
|
||||
// Re-infer mutable ranges for aliases, but *not* for stores
|
||||
prevAliases = aliases.canonicalize();
|
||||
while (true) {
|
||||
inferMutableRangesForAlias(ir, aliases);
|
||||
inferAliasForStores(ir, aliases);
|
||||
inferAliasForPhis(ir, aliases);
|
||||
const nextAliases = aliases.canonicalize();
|
||||
if (areEqualMaps(prevAliases, nextAliases)) {
|
||||
|
||||
+9
-2
@@ -23,7 +23,7 @@ import { c as _c } from "react/compiler-runtime"; // arrayInstance.push should h
|
||||
// - read on all args (rest parameter)
|
||||
// - mutate on receiver
|
||||
function Component(props) {
|
||||
const $ = _c(7);
|
||||
const $ = _c(8);
|
||||
let t0;
|
||||
if ($[0] !== props.x) {
|
||||
t0 = foo(props.x);
|
||||
@@ -45,7 +45,14 @@ function Component(props) {
|
||||
let arr;
|
||||
if ($[4] !== x || $[5] !== y) {
|
||||
arr = [];
|
||||
arr.push({});
|
||||
let t2;
|
||||
if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = {};
|
||||
$[7] = t2;
|
||||
} else {
|
||||
t2 = $[7];
|
||||
}
|
||||
arr.push(t2);
|
||||
arr.push(x, y);
|
||||
$[4] = x;
|
||||
$[5] = y;
|
||||
|
||||
+11
-4
@@ -40,7 +40,7 @@ import { c as _c } from "react/compiler-runtime";
|
||||
import { identity } from "shared-runtime";
|
||||
|
||||
function useFoo(t0) {
|
||||
const $ = _c(7);
|
||||
const $ = _c(9);
|
||||
const { input, cond, hasAB } = t0;
|
||||
let x;
|
||||
let t1;
|
||||
@@ -53,9 +53,6 @@ function useFoo(t0) {
|
||||
t1 = null;
|
||||
break bb0;
|
||||
}
|
||||
|
||||
x.push(identity(input.a.b));
|
||||
} else {
|
||||
let t2;
|
||||
if ($[5] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
@@ -65,6 +62,16 @@ function useFoo(t0) {
|
||||
t2 = $[6];
|
||||
}
|
||||
x.push(t2);
|
||||
} else {
|
||||
let t2;
|
||||
if ($[7] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
$[7] = input.a.b;
|
||||
$[8] = t2;
|
||||
} else {
|
||||
t2 = $[8];
|
||||
}
|
||||
x.push(t2);
|
||||
}
|
||||
}
|
||||
$[0] = cond;
|
||||
|
||||
+23
-8
@@ -41,7 +41,7 @@ import { c as _c } from "react/compiler-runtime";
|
||||
import { identity } from "shared-runtime";
|
||||
|
||||
function useFoo(t0) {
|
||||
const $ = _c(7);
|
||||
const $ = _c(11);
|
||||
const { input, cond, hasAB } = t0;
|
||||
let x;
|
||||
let t1;
|
||||
@@ -54,18 +54,33 @@ function useFoo(t0) {
|
||||
t1 = null;
|
||||
break bb0;
|
||||
} else {
|
||||
x.push(identity(input.a.b));
|
||||
let t2;
|
||||
if ($[5] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
$[5] = input.a.b;
|
||||
$[6] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
}
|
||||
x.push(t2);
|
||||
}
|
||||
|
||||
x.push(identity(input.a.b));
|
||||
let t2;
|
||||
if ($[7] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
$[7] = input.a.b;
|
||||
$[8] = t2;
|
||||
} else {
|
||||
t2 = $[8];
|
||||
}
|
||||
x.push(t2);
|
||||
} else {
|
||||
let t2;
|
||||
if ($[5] !== input.a.b) {
|
||||
if ($[9] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
$[5] = input.a.b;
|
||||
$[6] = t2;
|
||||
$[9] = input.a.b;
|
||||
$[10] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
t2 = $[10];
|
||||
}
|
||||
x.push(t2);
|
||||
}
|
||||
|
||||
+14
-6
@@ -31,7 +31,7 @@ import { c as _c } from "react/compiler-runtime";
|
||||
import { identity } from "shared-runtime";
|
||||
|
||||
function useFoo(t0) {
|
||||
const $ = _c(7);
|
||||
const $ = _c(9);
|
||||
const { input, hasAB, returnNull } = t0;
|
||||
let x;
|
||||
let t1;
|
||||
@@ -40,19 +40,27 @@ function useFoo(t0) {
|
||||
bb0: {
|
||||
x = [];
|
||||
if (!hasAB) {
|
||||
x.push(identity(input.a));
|
||||
let t2;
|
||||
if ($[5] !== input.a) {
|
||||
t2 = identity(input.a);
|
||||
$[5] = input.a;
|
||||
$[6] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
}
|
||||
x.push(t2);
|
||||
if (!returnNull) {
|
||||
t1 = null;
|
||||
break bb0;
|
||||
}
|
||||
} else {
|
||||
let t2;
|
||||
if ($[5] !== input.a.b) {
|
||||
if ($[7] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
$[5] = input.a.b;
|
||||
$[6] = t2;
|
||||
$[7] = input.a.b;
|
||||
$[8] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
t2 = $[8];
|
||||
}
|
||||
x.push(t2);
|
||||
}
|
||||
|
||||
+23
-7
@@ -41,7 +41,7 @@ import { c as _c } from "react/compiler-runtime";
|
||||
import { identity } from "shared-runtime";
|
||||
|
||||
function useFoo(t0) {
|
||||
const $ = _c(7);
|
||||
const $ = _c(11);
|
||||
const { input, cond2, cond1 } = t0;
|
||||
let x;
|
||||
let t1;
|
||||
@@ -51,20 +51,36 @@ function useFoo(t0) {
|
||||
x = [];
|
||||
if (cond1) {
|
||||
if (!cond2) {
|
||||
x.push(identity(input.a.b));
|
||||
let t2;
|
||||
if ($[5] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
$[5] = input.a.b;
|
||||
$[6] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
}
|
||||
x.push(t2);
|
||||
t1 = null;
|
||||
break bb0;
|
||||
} else {
|
||||
x.push(identity(input.a.b));
|
||||
let t2;
|
||||
if ($[7] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
$[7] = input.a.b;
|
||||
$[8] = t2;
|
||||
} else {
|
||||
t2 = $[8];
|
||||
}
|
||||
x.push(t2);
|
||||
}
|
||||
} else {
|
||||
let t2;
|
||||
if ($[5] !== input.a.b) {
|
||||
if ($[9] !== input.a.b) {
|
||||
t2 = identity(input.a.b);
|
||||
$[5] = input.a.b;
|
||||
$[6] = t2;
|
||||
$[9] = input.a.b;
|
||||
$[10] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
t2 = $[10];
|
||||
}
|
||||
x.push(t2);
|
||||
}
|
||||
|
||||
+23
-8
@@ -32,7 +32,7 @@ import { c as _c } from "react/compiler-runtime";
|
||||
import { identity } from "shared-runtime";
|
||||
|
||||
function useFoo(t0) {
|
||||
const $ = _c(7);
|
||||
const $ = _c(11);
|
||||
const { input, inputHasAB, inputHasABC } = t0;
|
||||
let x;
|
||||
let t1;
|
||||
@@ -41,21 +41,36 @@ function useFoo(t0) {
|
||||
bb0: {
|
||||
x = [];
|
||||
if (!inputHasABC) {
|
||||
x.push(identity(input.a));
|
||||
let t2;
|
||||
if ($[5] !== input.a) {
|
||||
t2 = identity(input.a);
|
||||
$[5] = input.a;
|
||||
$[6] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
}
|
||||
x.push(t2);
|
||||
if (!inputHasAB) {
|
||||
t1 = null;
|
||||
break bb0;
|
||||
}
|
||||
|
||||
x.push(identity(input.a.b));
|
||||
let t3;
|
||||
if ($[7] !== input.a.b) {
|
||||
t3 = identity(input.a.b);
|
||||
$[7] = input.a.b;
|
||||
$[8] = t3;
|
||||
} else {
|
||||
t3 = $[8];
|
||||
}
|
||||
x.push(t3);
|
||||
} else {
|
||||
let t2;
|
||||
if ($[5] !== input.a.b.c) {
|
||||
if ($[9] !== input.a.b.c) {
|
||||
t2 = identity(input.a.b.c);
|
||||
$[5] = input.a.b.c;
|
||||
$[6] = t2;
|
||||
$[9] = input.a.b.c;
|
||||
$[10] = t2;
|
||||
} else {
|
||||
t2 = $[6];
|
||||
t2 = $[10];
|
||||
}
|
||||
x.push(t2);
|
||||
}
|
||||
|
||||
+11
-4
@@ -27,14 +27,11 @@ export const FIXTURE_ENTRYPOINT = {
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
function foo(a) {
|
||||
const $ = _c(3);
|
||||
const $ = _c(4);
|
||||
let x;
|
||||
if ($[0] !== a) {
|
||||
x = {};
|
||||
if (a) {
|
||||
const y = {};
|
||||
x.y = y;
|
||||
} else {
|
||||
let t0;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = {};
|
||||
@@ -42,6 +39,16 @@ function foo(a) {
|
||||
} else {
|
||||
t0 = $[2];
|
||||
}
|
||||
const y = t0;
|
||||
x.y = y;
|
||||
} else {
|
||||
let t0;
|
||||
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = {};
|
||||
$[3] = t0;
|
||||
} else {
|
||||
t0 = $[3];
|
||||
}
|
||||
const z = t0;
|
||||
x.z = z;
|
||||
}
|
||||
|
||||
+9
-2
@@ -28,12 +28,19 @@ import { c as _c } from "react/compiler-runtime";
|
||||
const { shallowCopy, throwErrorWithMessage } = require("shared-runtime");
|
||||
|
||||
function Component(props) {
|
||||
const $ = _c(2);
|
||||
const $ = _c(3);
|
||||
let x;
|
||||
if ($[0] !== props.a) {
|
||||
x = [];
|
||||
try {
|
||||
x.push(throwErrorWithMessage("oops"));
|
||||
let t0;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = throwErrorWithMessage("oops");
|
||||
$[2] = t0;
|
||||
} else {
|
||||
t0 = $[2];
|
||||
}
|
||||
x.push(t0);
|
||||
} catch {
|
||||
x.push(shallowCopy({ a: props.a }));
|
||||
}
|
||||
|
||||
+17
-3
@@ -29,14 +29,28 @@ import { c as _c } from "react/compiler-runtime";
|
||||
const { throwErrorWithMessage, shallowCopy } = require("shared-runtime");
|
||||
|
||||
function Component(props) {
|
||||
const $ = _c(2);
|
||||
const $ = _c(4);
|
||||
let x;
|
||||
if ($[0] !== props.value) {
|
||||
x = [];
|
||||
try {
|
||||
x.push(throwErrorWithMessage("oops"));
|
||||
let t0;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = throwErrorWithMessage("oops");
|
||||
$[2] = t0;
|
||||
} else {
|
||||
t0 = $[2];
|
||||
}
|
||||
x.push(t0);
|
||||
} catch {
|
||||
x.push(shallowCopy({}));
|
||||
let t0;
|
||||
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t0 = shallowCopy({});
|
||||
$[3] = t0;
|
||||
} else {
|
||||
t0 = $[3];
|
||||
}
|
||||
x.push(t0);
|
||||
}
|
||||
|
||||
x.push(props.value);
|
||||
|
||||
Reference in New Issue
Block a user