[λ] Use Effect.Capture for mutating deps

Leverage Effect.Capture to differentiate between mutating and non mutating deps.
This commit is contained in:
Sathya Gunasekaran
2023-02-07 16:59:36 +00:00
parent 85c92bcfbe
commit 3df1ae66c0
6 changed files with 24 additions and 29 deletions
-1
View File
@@ -1364,7 +1364,6 @@ function lowerExpression(
name,
loweredFunc,
dependencies: captured.refs,
mutatedDeps: [],
expr: expr.node,
loc: exprLoc,
};
-3
View File
@@ -470,9 +470,6 @@ export type FunctionExpression = {
kind: "FunctionExpression";
name: string | null;
dependencies: Array<Place>;
// TODO(gsn): Remove this mutatedDeps array and use dependencies as single
// source of truth.
mutatedDeps: Array<Place>;
loweredFunc: HIRFunction;
expr: t.ArrowFunctionExpression | t.FunctionExpression;
};
@@ -5,6 +5,7 @@ import {
Identifier,
mergeConsecutiveBlocks,
Place,
Effect,
} from "../HIR";
import { constantPropagation } from "../Optimization";
import { eliminateRedundantPhi, enterSSA } from "../SSA";
@@ -85,7 +86,6 @@ function infer(
.filter((m) => m !== null) as string[]
);
const mutatedDeps: Place[] = [];
for (const dep of value.dependencies) {
let name: string | null = null;
@@ -97,7 +97,7 @@ function infer(
}
if (name !== null && mutations.has(name)) {
mutatedDeps.push(dep);
dep.effect = Effect.Capture;
}
}
@@ -114,11 +114,10 @@ function infer(
);
if (mutations.has(place.identifier.name)) {
mutatedDeps.push(place);
place.effect = Effect.Capture;
value.dependencies.push(place);
}
}
value.mutatedDeps = mutatedDeps;
}
function isMutated(id: Identifier) {
@@ -28,7 +28,8 @@ export function inferAliasForStores(
case "ArrayExpression":
case "ObjectExpression":
case "ComputedStore":
case "PropertyStore": {
case "PropertyStore":
case "FunctionExpression": {
for (const operand of eachInstructionValueOperand(value)) {
if (
operand.effect === Effect.Capture ||
@@ -39,11 +40,6 @@ export function inferAliasForStores(
}
break;
}
case "FunctionExpression": {
for (const dep of value.mutatedDeps) {
maybeAlias(aliases, lvalue.place, dep, instr.id);
}
}
}
}
}
@@ -572,12 +572,6 @@ function inferBlock(env: Environment, block: BasicBlock) {
lvalueEffect = Effect.Store;
break;
}
case "FunctionExpression": {
valueKind = ValueKind.Mutable;
effectKind = Effect.Read;
lvalueEffect = Effect.Store;
break;
}
case "UnaryExpression": {
valueKind = ValueKind.Immutable;
effectKind = Effect.Read;
@@ -615,6 +609,18 @@ function inferBlock(env: Environment, block: BasicBlock) {
valueKind = ValueKind.Immutable;
break;
}
case "FunctionExpression": {
for (const operand of eachInstructionOperand(instr)) {
env.reference(
operand,
operand.effect === Effect.Unknown ? Effect.Read : operand.effect
);
}
env.initialize(instrValue, ValueKind.Mutable);
env.define(instr.lvalue.place, instrValue);
instr.lvalue.place.effect = Effect.Store;
continue;
}
case "PropertyCall": {
if (!env.isDefined(instrValue.receiver)) {
// TODO @josephsavona: improve handling of globals
@@ -19,20 +19,18 @@ function component(a) {
```javascript
function component(a) {
const $ = React.unstable_useMemoCache();
const c_0 = $[0] !== a;
let y;
if (c_0) {
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
y = function () {
m(x);
};
const x = { a: a };
m(x);
$[0] = a;
$[1] = y;
$[0] = y;
} else {
y = $[1];
y = $[0];
}
const x = { a: a };
m(x);
return y;
}