@samitouri / QOS-React-2 / commits / e7f4eae619

Reset canonicalId mutable range if not mutated after creation

Lauren Tan committed Feb 8, 2023 at 10:26 UTC e7f4eae619cd38c829c62f5a6f869b50f7789c70
15 files changed +158 -277
compiler/forget/src/HIR/PrintHIR.ts
+1 -1
@@ -114,7 +114,7 @@ export function printInstruction(instr: ReactiveInstruction): string {
114 function printPhi(phi: Phi): string {
115 const items = [];
116 items.push(printIdentifier(phi.id));
117 - // items.push(printMutableRange(phi.id));
117 + items.push(printMutableRange(phi.id));
118 items.push(printType(phi.type));
119 items.push(": phi(");
120 const phis = [];
compiler/forget/src/SSA/LeaveSSA.ts
+8 -9
@@ -174,15 +174,8 @@ export function leaveSSA(fn: HIRFunction) {
174 }
175
176 // all versions of the variable need to be remapped to the canonical id
177 - // also extend the mutable range of the canonical id based on the min/max
178 - // of the ranges of its operands
179 - let start = canonicalId.mutableRange.start as number;
180 - let end = canonicalId.mutableRange.end as number;
177 for (const [, operand] of phi.operands) {
182 - start = Math.min(start, operand.mutableRange.start);
183 - end = Math.max(end, operand.mutableRange.end);
178 reassignments.set(operand, canonicalId);
185 -
179 if (operand.mutableRange.start < terminal.id) {
180 invariant(
181 initOperand === null,
@@ -191,8 +184,6 @@ export function leaveSSA(fn: HIRFunction) {
184 initOperand = operand;
185 }
186 }
194 - canonicalId.mutableRange.start = makeInstructionId(start);
195 - canonicalId.mutableRange.end = makeInstructionId(end);
187
188 // If there are no instructions in the block then there's just a terminal
189 // node, which has no mutation, so that should be false.
@@ -203,6 +194,14 @@ export function leaveSSA(fn: HIRFunction) {
194 phi.id.mutableRange.end >
195 (phiBlock.instructions.at(0)?.id ?? phiBlock.terminal.id);
196
197 + // If a phi is never mutated after creation, reset its mutable range to be itself
198 + if (!isPhiMutatedAfterCreation) {
199 + canonicalId.mutableRange.start = phiBlock.terminal.id;
200 + canonicalId.mutableRange.end = makeInstructionId(
201 + phiBlock.terminal.id + 1
202 + );
203 + }
204 +
205 // If this phi id is the canonical id we need to generate a let binding for it
206 // (otherwise, it means this phi merges into some other phi which already generated
207 // a binding
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md
+11 -21
@@ -29,29 +29,19 @@ function Component(props) {
29 const $ = React.unstable_useMemoCache();
30 const cond = props.cond;
31 const x = props.x;
32 - const c_0 = $[0] !== cond;
33 - const c_1 = $[1] !== x;
34 - let a;
35 - if (c_0 || c_1) {
36 - a = undefined;
37 - if (cond) {
38 - const a$0 = x;
39 - a = a$0;
32 + let a = undefined;
33 + if (cond) {
34 + const a$0 = x;
35 + a = a$0;
36 + } else {
37 + let a$1;
38 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
39 + a$1 = [];
40 + $[0] = a$1;
41 } else {
41 - let a$1;
42 - if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
43 - a$1 = [];
44 - $[3] = a$1;
45 - } else {
46 - a$1 = $[3];
47 - }
48 - a = a$1;
42 + a$1 = $[0];
43 }
50 - $[0] = cond;
51 - $[1] = x;
52 - $[2] = a;
53 - } else {
54 - a = $[2];
44 + a = a$1;
45 }
46
47 useFreeze(a);
compiler/forget/src/__tests__/fixtures/hir/infer-phi-primitive.expect.md
+6 -15
@@ -20,22 +20,13 @@ function foo(a, b) {
20
21 ```javascript
22 function foo(a, b) {
23 - const $ = React.unstable_useMemoCache();
24 - const c_0 = $[0] !== a;
25 - let x;
26 - if (c_0) {
27 - x = undefined;
28 - if (a) {
29 - const x$0 = 1;
30 - x = x$0;
31 - } else {
32 - const x$1 = 2;
33 - x = x$1;
34 - }
35 - $[0] = a;
36 - $[1] = x;
23 + let x = undefined;
24 + if (a) {
25 + const x$0 = 1;
26 + x = x$0;
27 } else {
38 - x = $[1];
28 + const x$1 = 2;
29 + x = x$1;
30 }
31
32 const y = x;
compiler/forget/src/__tests__/fixtures/hir/obj-literal-cached-in-if-else.expect.md
+20 -30
@@ -20,39 +20,29 @@ function foo(a, b, c, d) {
20 ```javascript
21 function foo(a, b, c, d) {
22 const $ = React.unstable_useMemoCache();
23 - const c_0 = $[0] !== b;
24 - const c_1 = $[1] !== c;
25 - let x;
26 - if (c_0 || c_1) {
27 - x = undefined;
28 - if (someVal) {
29 - const c_3 = $[3] !== b;
30 - let x$0;
31 - if (c_3) {
32 - x$0 = { b: b };
33 - $[3] = b;
34 - $[4] = x$0;
35 - } else {
36 - x$0 = $[4];
37 - }
38 - x = x$0;
23 + let x = undefined;
24 + if (someVal) {
25 + const c_0 = $[0] !== b;
26 + let x$0;
27 + if (c_0) {
28 + x$0 = { b: b };
29 + $[0] = b;
30 + $[1] = x$0;
31 } else {
40 - const c_5 = $[5] !== c;
41 - let x$1;
42 - if (c_5) {
43 - x$1 = { c: c };
44 - $[5] = c;
45 - $[6] = x$1;
46 - } else {
47 - x$1 = $[6];
48 - }
49 - x = x$1;
32 + x$0 = $[1];
33 }
51 - $[0] = b;
52 - $[1] = c;
53 - $[2] = x;
34 + x = x$0;
35 } else {
55 - x = $[2];
36 + const c_2 = $[2] !== c;
37 + let x$1;
38 + if (c_2) {
39 + x$1 = { c: c };
40 + $[2] = c;
41 + $[3] = x$1;
42 + } else {
43 + x$1 = $[3];
44 + }
45 + x = x$1;
46 }
47 return x;
48 }
compiler/forget/src/__tests__/fixtures/hir/primitive-alias-mutate.expect.md
+6 -15
@@ -20,22 +20,13 @@ function component(a) {
20
21 ```javascript
22 function component(a) {
23 - const $ = React.unstable_useMemoCache();
24 - const c_0 = $[0] !== a;
25 - let x;
26 - if (c_0) {
27 - x = undefined;
28 - if (a) {
29 - const x$0 = "bar";
30 - x = x$0;
31 - } else {
32 - const x$1 = "baz";
33 - x = x$1;
34 - }
35 - $[0] = a;
36 - $[1] = x;
23 + let x = undefined;
24 + if (a) {
25 + const x$0 = "bar";
26 + x = x$0;
27 } else {
38 - x = $[1];
28 + const x$1 = "baz";
29 + x = x$1;
30 }
31
32 const y = x;
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+14 -24
@@ -35,37 +35,27 @@ function Component(props) {
35 x = $[1];
36 }
37 const y = x;
38 - const c_2 = $[2] !== props.p1;
39 - let x$0;
40 - if (c_2) {
41 - x$0 = x;
42 - if (props.p1) {
43 - let x$1;
44 - if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
45 - x$1 = [];
46 - $[4] = x$1;
47 - } else {
48 - x$1 = $[4];
49 - }
50 - x$0 = x$1;
38 + let x$0 = x;
39 + if (props.p1) {
40 + let x$1;
41 + if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
42 + x$1 = [];
43 + $[2] = x$1;
44 + } else {
45 + x$1 = $[2];
46 }
52 - $[2] = props.p1;
53 - $[3] = x$0;
54 - } else {
55 - x$0 = $[3];
47 + x$0 = x$1;
48 }
49
50 y.push(props.p2);
59 - const c_5 = $[5] !== x$0;
60 - const c_6 = $[6] !== y;
51 + const c_3 = $[3] !== y;
52 let t0;
62 - if (c_5 || c_6) {
53 + if (c_3) {
54 t0 = <Component x={x$0} y={y}></Component>;
64 - $[5] = x$0;
65 - $[6] = y;
66 - $[7] = t0;
55 + $[3] = y;
56 + $[4] = t0;
57 } else {
68 - t0 = $[7];
58 + t0 = $[4];
59 }
60 return t0;
61 }
compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md
+31 -43
@@ -56,61 +56,49 @@ function foo(a, b, c) {
56 } else {
57 y = $[3];
58 }
59 - const c_4 = $[4] !== b;
60 - const c_5 = $[5] !== c;
61 - let x$0;
62 - if (c_4 || c_5) {
63 - x$0 = undefined;
64 - bb3: switch (b) {
65 - case 0: {
66 - const c_7 = $[7] !== b;
67 - let x$1;
68 - if (c_7) {
69 - x$1 = [];
70 - x$1.push(b);
71 - $[7] = b;
72 - $[8] = x$1;
73 - } else {
74 - x$1 = $[8];
75 - }
76 - x$0 = x$1;
77 - break bb3;
59 + let x$0 = undefined;
60 + bb3: switch (b) {
61 + case 0: {
62 + const c_4 = $[4] !== b;
63 + let x$1;
64 + if (c_4) {
65 + x$1 = [];
66 + x$1.push(b);
67 + $[4] = b;
68 + $[5] = x$1;
69 + } else {
70 + x$1 = $[5];
71 }
79 - default: {
80 - const c_9 = $[9] !== c;
81 - let x$2;
82 - if (c_9) {
83 - x$2 = [];
84 - x$2.push(c);
85 - $[9] = c;
86 - $[10] = x$2;
87 - } else {
88 - x$2 = $[10];
89 - }
90 - x$0 = x$2;
72 + x$0 = x$1;
73 + break bb3;
74 + }
75 + default: {
76 + const c_6 = $[6] !== c;
77 + let x$2;
78 + if (c_6) {
79 + x$2 = [];
80 + x$2.push(c);
81 + $[6] = c;
82 + $[7] = x$2;
83 + } else {
84 + x$2 = $[7];
85 }
86 + x$0 = x$2;
87 }
93 - $[4] = b;
94 - $[5] = c;
95 - $[6] = x$0;
96 - } else {
97 - x$0 = $[6];
88 }
99 - const c_11 = $[11] !== y;
100 - const c_12 = $[12] !== x$0;
89 + const c_8 = $[8] !== y;
90 let t0;
102 - if (c_11 || c_12) {
91 + if (c_8) {
92 t0 = (
93 <div>
94 {y}
95 {x$0}
96 </div>
97 );
109 - $[11] = y;
110 - $[12] = x$0;
111 - $[13] = t0;
98 + $[8] = y;
99 + $[9] = t0;
100 } else {
113 - t0 = $[13];
101 + t0 = $[9];
102 }
103 return t0;
104 }
compiler/forget/src/__tests__/fixtures/hir/ssa-leave-case.expect.md
+6 -11
@@ -27,11 +27,10 @@ function Component(props) {
27 const c_0 = $[0] !== props.p0;
28 const c_1 = $[1] !== props.p1;
29 let x;
30 - let y$0;
30 if (c_0 || c_1) {
31 x = [];
32 const y = undefined;
34 - y$0 = y;
33 + let y$0 = y;
34 if (props.p0) {
35 x.push(props.p1);
36 const y$1 = x;
@@ -40,26 +39,22 @@ function Component(props) {
39 $[0] = props.p0;
40 $[1] = props.p1;
41 $[2] = x;
43 - $[3] = y$0;
42 } else {
43 x = $[2];
46 - y$0 = $[3];
44 }
48 - const c_4 = $[4] !== x;
49 - const c_5 = $[5] !== y$0;
45 + const c_3 = $[3] !== x;
46 let t0;
51 - if (c_4 || c_5) {
47 + if (c_3) {
48 t0 = (
49 <Component>
50 {x}
51 {y$0}
52 </Component>
53 );
58 - $[4] = x;
59 - $[5] = y$0;
60 - $[6] = t0;
54 + $[3] = x;
55 + $[4] = t0;
56 } else {
62 - t0 = $[6];
57 + t0 = $[4];
58 }
59 return t0;
60 }
compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-phi.expect.md
+4 -13
@@ -19,21 +19,12 @@ function foo(a, b, c) {
19
20 ```javascript
21 function foo(a, b, c) {
22 - const $ = React.unstable_useMemoCache();
22 const x = a;
23 if (b) {
25 - const c_0 = $[0] !== c;
26 - let x$0;
27 - if (c_0) {
28 - x$0 = x;
29 - if (c) {
30 - const x$1 = c;
31 - x$0 = x$1;
32 - }
33 - $[0] = c;
34 - $[1] = x$0;
35 - } else {
36 - x$0 = $[1];
24 + let x$0 = x;
25 + if (c) {
26 + const x$1 = c;
27 + x$0 = x$1;
28 }
29 return x$0;
30 }
compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-reassignment.expect.md
+8 -23
@@ -20,31 +20,16 @@ function foo(a, b, c, d, e) {
20
21 ```javascript
22 function foo(a, b, c, d, e) {
23 - const $ = React.unstable_useMemoCache();
23 const x = null;
25 - const c_0 = $[0] !== a;
26 - const c_1 = $[1] !== b;
27 - const c_2 = $[2] !== c;
28 - const c_3 = $[3] !== d;
29 - let x$0;
30 - if (c_0 || c_1 || c_2 || c_3) {
31 - x$0 = x;
32 - if (a) {
33 - const x$1 = b;
34 - x$0 = x$1;
35 - } else {
36 - if (c) {
37 - const x$2 = d;
38 - x$0 = x$2;
39 - }
40 - }
41 - $[0] = a;
42 - $[1] = b;
43 - $[2] = c;
44 - $[3] = d;
45 - $[4] = x$0;
24 + let x$0 = x;
25 + if (a) {
26 + const x$1 = b;
27 + x$0 = x$1;
28 } else {
47 - x$0 = $[4];
29 + if (c) {
30 + const x$2 = d;
31 + x$0 = x$2;
32 + }
33 }
34 return x$0;
35 }
compiler/forget/src/__tests__/fixtures/hir/ssa-renaming.expect.md
+12 -22
@@ -30,29 +30,19 @@ function foo(props) {
30 } else {
31 x = $[1];
32 }
33 - const c_2 = $[2] !== props.cond;
34 - const c_3 = $[3] !== props.foo;
35 - let x$0;
36 - if (c_2 || c_3) {
37 - x$0 = x;
38 - if (props.cond) {
39 - const c_5 = $[5] !== props.foo;
40 - let x$1;
41 - if (c_5) {
42 - x$1 = [];
43 - x$1.push(props.foo);
44 - $[5] = props.foo;
45 - $[6] = x$1;
46 - } else {
47 - x$1 = $[6];
48 - }
49 - x$0 = x$1;
33 + let x$0 = x;
34 + if (props.cond) {
35 + const c_2 = $[2] !== props.foo;
36 + let x$1;
37 + if (c_2) {
38 + x$1 = [];
39 + x$1.push(props.foo);
40 + $[2] = props.foo;
41 + $[3] = x$1;
42 + } else {
43 + x$1 = $[3];
44 }
51 - $[2] = props.cond;
52 - $[3] = props.foo;
53 - $[4] = x$0;
54 - } else {
55 - x$0 = $[4];
45 + x$0 = x$1;
46 }
47 return x$0;
48 }
compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md
+6 -15
@@ -23,23 +23,14 @@ function Foo(cond) {
23 function log() {}
24
25 function Foo(cond) {
26 - const $ = React.unstable_useMemoCache();
26 const str = "";
28 - const c_0 = $[0] !== cond;
29 - let str$0;
30 - if (c_0) {
31 - str$0 = str;
32 - if (cond) {
33 - const str_0 = "other test";
34 - log(str_0);
35 - } else {
36 - const str$1 = "fallthrough test";
37 - str$0 = str$1;
38 - }
39 - $[0] = cond;
40 - $[1] = str$0;
27 + let str$0 = str;
28 + if (cond) {
29 + const str_0 = "other test";
30 + log(str_0);
31 } else {
42 - str$0 = $[1];
32 + const str$1 = "fallthrough test";
33 + str$0 = str$1;
34 }
35
36 log(str$0);
compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md
+14 -19
@@ -36,11 +36,10 @@ function Component(props) {
36 const c_0 = $[0] !== props.p0;
37 const c_1 = $[1] !== props.p2;
38 let x;
39 - let y$0;
39 if (c_0 || c_1) {
40 x = [];
41 const y = undefined;
43 - y$0 = y;
42 + let y$0 = y;
43 bb1: switch (props.p0) {
44 case 1: {
45 break bb1;
@@ -48,11 +47,11 @@ function Component(props) {
47 case true: {
48 x.push(props.p2);
49 let y$1;
51 - if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
50 + if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
51 y$1 = [];
53 - $[4] = y$1;
52 + $[3] = y$1;
53 } else {
55 - y$1 = $[4];
54 + y$1 = $[3];
55 }
56 y$0 = y$1;
57 break bb1;
@@ -68,31 +67,27 @@ function Component(props) {
67 $[0] = props.p0;
68 $[1] = props.p2;
69 $[2] = x;
71 - $[3] = y$0;
70 } else {
71 x = $[2];
74 - y$0 = $[3];
72 }
76 - const c_5 = $[5] !== x;
73 + const c_4 = $[4] !== x;
74 let child;
78 - if (c_5) {
75 + if (c_4) {
76 child = <Component data={x}></Component>;
80 - $[5] = x;
81 - $[6] = child;
77 + $[4] = x;
78 + $[5] = child;
79 } else {
83 - child = $[6];
80 + child = $[5];
81 }
82 y$0.push(props.p4);
86 - const c_7 = $[7] !== y$0;
87 - const c_8 = $[8] !== child;
83 + const c_6 = $[6] !== child;
84 let t0;
89 - if (c_7 || c_8) {
85 + if (c_6) {
86 t0 = <Component data={y$0}>{child}</Component>;
91 - $[7] = y$0;
92 - $[8] = child;
93 - $[9] = t0;
87 + $[6] = child;
88 + $[7] = t0;
89 } else {
95 - t0 = $[9];
90 + t0 = $[7];
91 }
92 return t0;
93 }
compiler/forget/src/__tests__/fixtures/hir/switch.expect.md
+11 -16
@@ -32,11 +32,10 @@ function Component(props) {
32 const c_1 = $[1] !== props.p2;
33 const c_2 = $[2] !== props.p3;
34 let x;
35 - let y$0;
35 if (c_0 || c_1 || c_2) {
36 x = [];
37 const y = undefined;
39 - y$0 = y;
38 + let y$0 = y;
39 switch (props.p0) {
40 case true: {
41 x.push(props.p2);
@@ -51,31 +50,27 @@ function Component(props) {
50 $[1] = props.p2;
51 $[2] = props.p3;
52 $[3] = x;
54 - $[4] = y$0;
53 } else {
54 x = $[3];
57 - y$0 = $[4];
55 }
59 - const c_5 = $[5] !== x;
56 + const c_4 = $[4] !== x;
57 let child;
61 - if (c_5) {
58 + if (c_4) {
59 child = <Component data={x}></Component>;
63 - $[5] = x;
64 - $[6] = child;
60 + $[4] = x;
61 + $[5] = child;
62 } else {
66 - child = $[6];
63 + child = $[5];
64 }
65 y$0.push(props.p4);
69 - const c_7 = $[7] !== y$0;
70 - const c_8 = $[8] !== child;
66 + const c_6 = $[6] !== child;
67 let t0;
72 - if (c_7 || c_8) {
68 + if (c_6) {
69 t0 = <Component data={y$0}>{child}</Component>;
74 - $[7] = y$0;
75 - $[8] = child;
76 - $[9] = t0;
70 + $[6] = child;
71 + $[7] = t0;
72 } else {
78 - t0 = $[9];
73 + t0 = $[7];
74 }
75 return t0;
76 }