@samitouri / QOS-React / commits / d456e4a78c

Memoize based on inferred return type, not signature

Joe Savona committed May 22, 2023 at 09:20 UTC d456e4a78ccf1cf607a46e802c67eb1442657300
3 files changed +22 -58
compiler/forget/src/ReactiveScopes/InferReactiveScopeVariables.ts
+5 -23
@@ -10,7 +10,6 @@ import {
10 HIRFunction,
11 Identifier,
12 Instruction,
13 - InstructionValue,
13 makeInstructionId,
14 makeScopeId,
15 Place,
@@ -21,7 +20,6 @@ import {
20 eachInstructionOperand,
21 eachPatternOperand,
22 } from "../HIR/visitors";
24 -import { getFunctionCallSignature } from "../Inference/InferReferenceEffects";
23 import DisjointSet from "../Utils/DisjointSet";
24 import { assertExhaustive } from "../Utils/utils";
25
@@ -105,7 +103,7 @@ export function inferReactiveScopeVariables(fn: HIRFunction): void {
103 for (const instr of block.instructions) {
104 const operands: Array<Identifier> = [];
105 const range = instr.lvalue.identifier.mutableRange;
108 - if (range.end > range.start + 1 || mayAllocate(fn.env, instr.value)) {
106 + if (range.end > range.start + 1 || mayAllocate(fn.env, instr)) {
107 operands.push(instr.lvalue!.identifier);
108 }
109 if (
@@ -219,7 +217,8 @@ function isMutable({ id }: Instruction, place: Place): boolean {
217 return id >= range.start && id < range.end;
218 }
219
222 -function mayAllocate(env: Environment, value: InstructionValue): boolean {
220 +function mayAllocate(env: Environment, instruction: Instruction): boolean {
221 + const { value } = instruction;
222 switch (value.kind) {
223 case "Destructure": {
224 return doesPatternContainSpreadElement(value.lvalue.pattern);
@@ -247,27 +246,10 @@ function mayAllocate(env: Environment, value: InstructionValue): boolean {
246 case "Debugger": {
247 return false;
248 }
250 - case "CallExpression": {
251 - if (env.enableFunctionCallSignatureOptimizations) {
252 - const signature = getFunctionCallSignature(
253 - env,
254 - value.callee.identifier.type
255 - );
256 - if (signature !== null) {
257 - return signature.returnType.kind !== "Primitive";
258 - }
259 - }
260 - return true;
261 - }
249 + case "CallExpression":
250 case "MethodCall": {
251 if (env.enableFunctionCallSignatureOptimizations) {
264 - const signature = getFunctionCallSignature(
265 - env,
266 - value.receiver.identifier.type
267 - );
268 - if (signature !== null) {
269 - return signature.returnType.kind !== "Primitive";
270 - }
252 + return instruction.lvalue.identifier.type.kind !== "Primitive";
253 }
254 return true;
255 }
compiler/forget/src/__tests__/fixtures/compiler/infer-global-object.expect.md
+10 -21
@@ -24,7 +24,7 @@ function Component(props) {
24 import { unstable_useMemoCache as useMemoCache } from "react"; // Check that we correctly resolve type and effect lookups on the javascript
25 // global object.
26 function Component(props) {
27 - const $ = useMemoCache(7);
27 + const $ = useMemoCache(4);
28 const c_0 = $[0] !== props.b;
29 let t0;
30 if (c_0) {
@@ -35,32 +35,21 @@ function Component(props) {
35 t0 = $[1];
36 }
37 const neverAliasedOrMutated = t0;
38 - const c_2 = $[2] !== props.a;
39 - const c_3 = $[3] !== neverAliasedOrMutated;
40 - let t1;
41 - if (c_2 || c_3) {
42 - t1 = Math.max(props.a, neverAliasedOrMutated);
43 - $[2] = props.a;
44 - $[3] = neverAliasedOrMutated;
45 - $[4] = t1;
46 - } else {
47 - t1 = $[4];
48 - }
49 - const primitiveVal1 = t1;
38 + const primitiveVal1 = Math.max(props.a, neverAliasedOrMutated);
39
40 const primitiveVal3 = globaThis.globalThis.NaN;
41
42 foo(primitiveVal1, Infinity, primitiveVal3);
54 - const c_5 = $[5] !== primitiveVal1;
55 - let t2;
56 - if (c_5) {
57 - t2 = { primitiveVal1, primitiveVal2: Infinity, primitiveVal3 };
58 - $[5] = primitiveVal1;
59 - $[6] = t2;
43 + const c_2 = $[2] !== primitiveVal1;
44 + let t1;
45 + if (c_2) {
46 + t1 = { primitiveVal1, primitiveVal2: Infinity, primitiveVal3 };
47 + $[2] = primitiveVal1;
48 + $[3] = t1;
49 } else {
61 - t2 = $[6];
50 + t1 = $[3];
51 }
63 - return t2;
52 + return t1;
53 }
54
55 ```
compiler/forget/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md
+7 -14
@@ -24,33 +24,26 @@ function component() {
24 ```javascript
25 import { unstable_useMemoCache as useMemoCache } from "react";
26 function component() {
27 - const $ = useMemoCache(3);
27 + const $ = useMemoCache(2);
28 + const p = makePrimitive();
29 let t0;
30 if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
30 - t0 = makePrimitive();
31 + t0 = {};
32 $[0] = t0;
33 } else {
34 t0 = $[0];
35 }
35 - const p = t0;
36 - let t1;
37 - if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
38 - t1 = {};
39 - $[1] = t1;
40 - } else {
41 - t1 = $[1];
42 - }
43 - const o = t1;
36 + const o = t0;
37 let x;
45 - if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
38 + if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
39 x = {};
40
41 x.t = p;
42
43 x.t = o;
51 - $[2] = x;
44 + $[1] = x;
45 } else {
53 - x = $[2];
46 + x = $[1];
47 }
48 const y = x.t;
49 return y;