Memoize based on inferred return type, not signature

This commit is contained in:
Joe Savona
2023-05-22 09:20:16 -07:00
parent 4ce22ebcfe
commit d456e4a78c
3 changed files with 22 additions and 58 deletions
@@ -10,7 +10,6 @@ import {
HIRFunction,
Identifier,
Instruction,
InstructionValue,
makeInstructionId,
makeScopeId,
Place,
@@ -21,7 +20,6 @@ import {
eachInstructionOperand,
eachPatternOperand,
} from "../HIR/visitors";
import { getFunctionCallSignature } from "../Inference/InferReferenceEffects";
import DisjointSet from "../Utils/DisjointSet";
import { assertExhaustive } from "../Utils/utils";
@@ -105,7 +103,7 @@ export function inferReactiveScopeVariables(fn: HIRFunction): void {
for (const instr of block.instructions) {
const operands: Array<Identifier> = [];
const range = instr.lvalue.identifier.mutableRange;
if (range.end > range.start + 1 || mayAllocate(fn.env, instr.value)) {
if (range.end > range.start + 1 || mayAllocate(fn.env, instr)) {
operands.push(instr.lvalue!.identifier);
}
if (
@@ -219,7 +217,8 @@ function isMutable({ id }: Instruction, place: Place): boolean {
return id >= range.start && id < range.end;
}
function mayAllocate(env: Environment, value: InstructionValue): boolean {
function mayAllocate(env: Environment, instruction: Instruction): boolean {
const { value } = instruction;
switch (value.kind) {
case "Destructure": {
return doesPatternContainSpreadElement(value.lvalue.pattern);
@@ -247,27 +246,10 @@ function mayAllocate(env: Environment, value: InstructionValue): boolean {
case "Debugger": {
return false;
}
case "CallExpression": {
if (env.enableFunctionCallSignatureOptimizations) {
const signature = getFunctionCallSignature(
env,
value.callee.identifier.type
);
if (signature !== null) {
return signature.returnType.kind !== "Primitive";
}
}
return true;
}
case "CallExpression":
case "MethodCall": {
if (env.enableFunctionCallSignatureOptimizations) {
const signature = getFunctionCallSignature(
env,
value.receiver.identifier.type
);
if (signature !== null) {
return signature.returnType.kind !== "Primitive";
}
return instruction.lvalue.identifier.type.kind !== "Primitive";
}
return true;
}
@@ -24,7 +24,7 @@ function Component(props) {
import { unstable_useMemoCache as useMemoCache } from "react"; // Check that we correctly resolve type and effect lookups on the javascript
// global object.
function Component(props) {
const $ = useMemoCache(7);
const $ = useMemoCache(4);
const c_0 = $[0] !== props.b;
let t0;
if (c_0) {
@@ -35,32 +35,21 @@ function Component(props) {
t0 = $[1];
}
const neverAliasedOrMutated = t0;
const c_2 = $[2] !== props.a;
const c_3 = $[3] !== neverAliasedOrMutated;
let t1;
if (c_2 || c_3) {
t1 = Math.max(props.a, neverAliasedOrMutated);
$[2] = props.a;
$[3] = neverAliasedOrMutated;
$[4] = t1;
} else {
t1 = $[4];
}
const primitiveVal1 = t1;
const primitiveVal1 = Math.max(props.a, neverAliasedOrMutated);
const primitiveVal3 = globaThis.globalThis.NaN;
foo(primitiveVal1, Infinity, primitiveVal3);
const c_5 = $[5] !== primitiveVal1;
let t2;
if (c_5) {
t2 = { primitiveVal1, primitiveVal2: Infinity, primitiveVal3 };
$[5] = primitiveVal1;
$[6] = t2;
const c_2 = $[2] !== primitiveVal1;
let t1;
if (c_2) {
t1 = { primitiveVal1, primitiveVal2: Infinity, primitiveVal3 };
$[2] = primitiveVal1;
$[3] = t1;
} else {
t2 = $[6];
t1 = $[3];
}
return t2;
return t1;
}
```
@@ -24,33 +24,26 @@ function component() {
```javascript
import { unstable_useMemoCache as useMemoCache } from "react";
function component() {
const $ = useMemoCache(3);
const $ = useMemoCache(2);
const p = makePrimitive();
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = makePrimitive();
t0 = {};
$[0] = t0;
} else {
t0 = $[0];
}
const p = t0;
let t1;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
t1 = {};
$[1] = t1;
} else {
t1 = $[1];
}
const o = t1;
const o = t0;
let x;
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
x = {};
x.t = p;
x.t = o;
$[2] = x;
$[1] = x;
} else {
x = $[2];
x = $[1];
}
const y = x.t;
return y;