Skip to content

Commit 0fba073

Browse files
author
Joe Savona
committed
[compiler] Cleanup for @enablePreserveExistingMemoizationGuarantees
I tried turning on `@enablePreserveExistingMemoizationGuarantees` by default and cleaned up a couple small things: * We emit freeze calls for StartMemoize deps but these had ValueReason.Other so the message wasn't great. We now treat these like other hook arguments. * PruneNonEscapingScopes was being too aggressive in this mode and memoizing even loads of globals. Switching to MemoizationLevel.Conditional ensures we build a graph that connects through to primitive-returning function calls, but doesn't unnecessarily force memoization otherwise.
1 parent 735e9ac commit 0fba073

File tree

8 files changed

+138
-23
lines changed

8 files changed

+138
-23
lines changed

compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2089,7 +2089,7 @@ function computeSignatureForInstruction(
20892089
effects.push({
20902090
kind: 'Freeze',
20912091
value: operand,
2092-
reason: ValueReason.Other,
2092+
reason: ValueReason.HookCaptured,
20932093
});
20942094
}
20952095
}

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonEscapingScopes.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,7 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor<
546546
* memoization. Note: we may still prune primitive-producing scopes if
547547
* they don't ultimately escape at all.
548548
*/
549-
const level = MemoizationLevel.Memoized;
549+
const level = MemoizationLevel.Conditional;
550550
return {
551551
lvalues: lvalue !== null ? [{place: lvalue, level}] : [],
552552
rvalues: [...eachReactiveValueOperand(value)],
@@ -701,9 +701,7 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor<
701701
}
702702
case 'ComputedLoad':
703703
case 'PropertyLoad': {
704-
const level = options.forceMemoizePrimitives
705-
? MemoizationLevel.Memoized
706-
: MemoizationLevel.Conditional;
704+
const level = MemoizationLevel.Conditional;
707705
return {
708706
// Indirection for the inner value, memoized if the value is
709707
lvalues: lvalue !== null ? [{place: lvalue, level}] : [],

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/meta-isms/repro-cx-namespace-nesting.expect.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
## Input
33

44
```javascript
5+
// @compilationMode:"infer"
56
import {makeArray} from 'shared-runtime';
67

78
function Component() {
@@ -30,7 +31,7 @@ export const FIXTURE_ENTRYPOINT = {
3031
## Code
3132

3233
```javascript
33-
import { c as _c } from "react/compiler-runtime";
34+
import { c as _c } from "react/compiler-runtime"; // @compilationMode:"infer"
3435
import { makeArray } from "shared-runtime";
3536

3637
function Component() {

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/meta-isms/repro-cx-namespace-nesting.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// @compilationMode:"infer"
12
import {makeArray} from 'shared-runtime';
23

34
function Component() {
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @enablePreserveExistingMemoizationGuarantees
6+
import {fbt} from 'fbt';
7+
8+
function Component() {
9+
const buttonLabel = () => {
10+
if (!someCondition) {
11+
return <fbt desc="My label">{'Purchase as a gift'}</fbt>;
12+
} else if (
13+
!iconOnly &&
14+
showPrice &&
15+
item?.current_gift_offer?.price?.formatted != null
16+
) {
17+
return (
18+
<fbt desc="Gift button's label">
19+
{'Gift | '}
20+
<fbt:param name="price">
21+
{item?.current_gift_offer?.price?.formatted}
22+
</fbt:param>
23+
</fbt>
24+
);
25+
} else if (!iconOnly && !showPrice) {
26+
return <fbt desc="Gift button's label">{'Gift'}</fbt>;
27+
}
28+
};
29+
30+
return (
31+
<View>
32+
<Button text={buttonLabel()} />
33+
</View>
34+
);
35+
}
36+
37+
```
38+
39+
## Code
40+
41+
```javascript
42+
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees
43+
import { fbt } from "fbt";
44+
45+
function Component() {
46+
const $ = _c(1);
47+
const buttonLabel = _temp;
48+
let t0;
49+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
50+
t0 = (
51+
<View>
52+
<Button text={buttonLabel()} />
53+
</View>
54+
);
55+
$[0] = t0;
56+
} else {
57+
t0 = $[0];
58+
}
59+
return t0;
60+
}
61+
function _temp() {
62+
if (!someCondition) {
63+
return fbt._("Purchase as a gift", null, { hk: "1gHj4g" });
64+
} else {
65+
if (
66+
!iconOnly &&
67+
showPrice &&
68+
item?.current_gift_offer?.price?.formatted != null
69+
) {
70+
return fbt._(
71+
"Gift | {price}",
72+
[fbt._param("price", item?.current_gift_offer?.price?.formatted)],
73+
{ hk: "3GTnGE" },
74+
);
75+
} else {
76+
if (!iconOnly && !showPrice) {
77+
return fbt._("Gift", null, { hk: "3fqfrk" });
78+
}
79+
}
80+
}
81+
}
82+
83+
```
84+
85+
### Eval output
86+
(kind: exception) Fixture not implemented
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// @enablePreserveExistingMemoizationGuarantees
2+
import {fbt} from 'fbt';
3+
4+
function Component() {
5+
const buttonLabel = () => {
6+
if (!someCondition) {
7+
return <fbt desc="My label">{'Purchase as a gift'}</fbt>;
8+
} else if (
9+
!iconOnly &&
10+
showPrice &&
11+
item?.current_gift_offer?.price?.formatted != null
12+
) {
13+
return (
14+
<fbt desc="Gift button's label">
15+
{'Gift | '}
16+
<fbt:param name="price">
17+
{item?.current_gift_offer?.price?.formatted}
18+
</fbt:param>
19+
</fbt>
20+
);
21+
} else if (!iconOnly && !showPrice) {
22+
return <fbt desc="Gift button's label">{'Gift'}</fbt>;
23+
}
24+
};
25+
26+
return (
27+
<View>
28+
<Button text={buttonLabel()} />
29+
</View>
30+
);
31+
}

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/primitive-reassigned-loop-force-scopes-enabled.expect.md

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Input
33

44
```javascript
5-
// @enableForest
5+
// @enablePreserveExistingMemoizationGuarantees
66
function Component({base, start, increment, test}) {
77
let value = base;
88
for (let i = start; i < test; i += increment) {
@@ -27,25 +27,23 @@ export const FIXTURE_ENTRYPOINT = {
2727
## Code
2828

2929
```javascript
30-
import { c as _c } from "react/compiler-runtime"; // @enableForest
30+
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees
3131
function Component(t0) {
32-
const $ = _c(5);
32+
const $ = _c(2);
3333
const { base, start, increment, test } = t0;
34-
let value;
35-
if ($[0] !== base || $[1] !== increment || $[2] !== start || $[3] !== test) {
36-
value = base;
37-
for (let i = start; i < test; i = i + increment, i) {
38-
value = value + i;
39-
}
40-
$[0] = base;
41-
$[1] = increment;
42-
$[2] = start;
43-
$[3] = test;
44-
$[4] = value;
34+
let value = base;
35+
for (let i = start; i < test; i = i + increment, i) {
36+
value = value + i;
37+
}
38+
let t1;
39+
if ($[0] !== value) {
40+
t1 = <div>{value}</div>;
41+
$[0] = value;
42+
$[1] = t1;
4543
} else {
46-
value = $[4];
44+
t1 = $[1];
4745
}
48-
return <div>{value}</div>;
46+
return t1;
4947
}
5048

5149
export const FIXTURE_ENTRYPOINT = {

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/primitive-reassigned-loop-force-scopes-enabled.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// @enableForest
1+
// @enablePreserveExistingMemoizationGuarantees
22
function Component({base, start, increment, test}) {
33
let value = base;
44
for (let i = start; i < test; i += increment) {

0 commit comments

Comments
 (0)