[hir] Introduce AbstractState.store

Currently AbstractState.alias performs three operations: - Reading a value - 
Storing the value - Updating aliasing (in the DisjointSet) 

This commit makes AbstractState.alias only responsible for updating the alias 
information. The rest of the operations are split into separate functions.
This commit is contained in:
Sathya Gunasekaran
2022-12-05 22:27:00 +00:00
parent 1c6e39a1d6
commit 9da7ad557d
+29 -14
View File
@@ -32,6 +32,11 @@ class AbstractState {
return value;
}
if (alias.memberPath.length > 1) {
// TODO(gsn): Correctly handle nested member paths when reading values
return { kind: "Object", values: new Map() };
}
// Complex alias:
// read(alias.memberPath);
let object = this.#values.get(alias.identifier);
@@ -83,22 +88,28 @@ class AbstractState {
return value;
}
// Simple lvalue:
// lvalue = alias;
// lvalue = alias.memberPath;
alias(lvalue: LValue, alias: Place) {
if (alias.memberPath !== null && alias.memberPath.length > 1) {
// TODO(gsn): Handle nested member paths
// TODO(gsn): Handle aliasing for complex lvalue
if (lvalue.place.memberPath !== null) {
return;
}
const value = this.read(alias);
this.#values.set(lvalue.place.identifier, value);
// Simple lvalue:
// lvalue = alias;
// lvalue = alias.memberPath;
this.aliases.union([lvalue.place.identifier, alias.identifier]);
}
// No need to alias Primitives.
if (value.kind !== "Primitive") {
this.aliases.union([lvalue.place.identifier, alias.identifier]);
store(lvalue: LValue, value: AbstractValue) {
// TODO(gsn): Handle stores for complex lvalue
if (lvalue.place.memberPath !== null) {
return;
}
// Simple lvalue:
// lvalue = alias;
// lvalue = alias.memberPath;
this.#values.set(lvalue.place.identifier, value);
}
buildAliasSets(): Array<Set<Identifier>> {
@@ -137,9 +148,11 @@ export function buildAliasSets(func: HIRFunction): Array<Set<Identifier>> {
function inferInstr(instr: Instruction, state: AbstractState) {
const { lvalue, value: instrValue } = instr;
let alias: Place | null = null;
let value: AbstractValue | null = null;
switch (instrValue.kind) {
case "Identifier": {
alias = instrValue;
value = state.read(alias);
break;
}
default:
@@ -147,8 +160,8 @@ function inferInstr(instr: Instruction, state: AbstractState) {
}
invariant(
alias !== null,
`expected ${printInstructionValue(instrValue)} to have an alias`
value !== null,
`expected ${printInstructionValue(instrValue)} to be an alias or value`
);
// TODO(gsn): handle this.
@@ -156,8 +169,10 @@ function inferInstr(instr: Instruction, state: AbstractState) {
return;
}
// simple aliasing
if (lvalue.place.memberPath === null) {
// No need to alias Primitives.
if (alias !== null && value.kind !== "Primitive") {
state.alias(lvalue, alias);
}
state.store(lvalue, value);
}