[aliasing] Introduce Effect.Capture

Effect.Capture is very similar to Effect.Read, but the only difference is that 
this reference is stored somewhere via a Effect.Store. 

Previously, any operand associated with a Effect.Store in the same instruction 
would get aliased -- so there was no need to explicitly differentiate between a 
"normal read" and "read that gets stored". 

This difference is now explicit with FunctionExpression where every dependency 
is "read" but only a few are "captured" for store (and mutation). In a follow up 
PR, the mutating deps will have an Effect.Capture to differentiate from the 
other non mutating deps (Effect.Read).
This commit is contained in:
Sathya Gunasekaran
2023-02-07 16:59:35 +00:00
parent 4e07b8a869
commit 85c92bcfbe
4 changed files with 18 additions and 6 deletions
+2
View File
@@ -546,6 +546,8 @@ export enum Effect {
Freeze = "freeze",
// This reference reads the value
Read = "read",
// This reference reads and stores the value
Capture = "capture",
// This reference may write to (mutate) the value
Mutate = "mutate",
// This reference may alias to (mutate) the value
@@ -30,7 +30,12 @@ export function inferAliasForStores(
case "ComputedStore":
case "PropertyStore": {
for (const operand of eachInstructionValueOperand(value)) {
maybeAlias(aliases, lvalue.place, operand, instr.id);
if (
operand.effect === Effect.Capture ||
operand.effect === Effect.Store
) {
maybeAlias(aliases, lvalue.place, operand, instr.id);
}
}
break;
}
@@ -77,6 +77,7 @@ function inferPlace(
)}!`
);
}
case Effect.Capture:
case Effect.Read:
case Effect.Freeze:
return;
@@ -303,6 +303,10 @@ class Environment {
effect = Effect.Store;
break;
}
case Effect.Capture: {
effect = Effect.Capture;
break;
}
case Effect.Read: {
effect = Effect.Read;
break;
@@ -542,7 +546,7 @@ function inferBlock(env: Environment, block: BasicBlock) {
}
case "ArrayExpression": {
valueKind = ValueKind.Mutable;
effectKind = Effect.Read;
effectKind = Effect.Capture;
lvalueEffect = Effect.Store;
break;
}
@@ -564,7 +568,7 @@ function inferBlock(env: Environment, block: BasicBlock) {
case "ObjectExpression": {
valueKind = ValueKind.Mutable;
// Object construction captures but does not modify the key/property values
effectKind = Effect.Read;
effectKind = Effect.Capture;
lvalueEffect = Effect.Store;
break;
}
@@ -658,7 +662,7 @@ function inferBlock(env: Environment, block: BasicBlock) {
const effect = isObjectType(instrValue.object.identifier)
? Effect.Store
: Effect.Mutate;
env.reference(instrValue.value, Effect.Read);
env.reference(instrValue.value, Effect.Capture);
env.reference(instrValue.object, effect);
const lvalue = instr.lvalue;
@@ -688,8 +692,8 @@ function inferBlock(env: Environment, block: BasicBlock) {
const effect = isObjectType(instrValue.object.identifier)
? Effect.Store
: Effect.Mutate;
env.reference(instrValue.value, Effect.Read);
env.reference(instrValue.property, Effect.Read);
env.reference(instrValue.value, Effect.Capture);
env.reference(instrValue.property, Effect.Capture);
env.reference(instrValue.object, effect);
const lvalue = instr.lvalue;