@samitouri / QOS-React-2 / commits / 9da7ad557d

[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.

Sathya Gunasekaran committed Dec 5, 2022 at 22:27 UTC 9da7ad557d6ffe36db06e7bea82f21cbcedaa5d3
1 file changed +29 -14
compiler/forget/src/HIR/BuildAliasSets.ts
+29 -14
@@ -32,6 +32,11 @@ class AbstractState {
32 return value;
33 }
34
35 + if (alias.memberPath.length > 1) {
36 + // TODO(gsn): Correctly handle nested member paths when reading values
37 + return { kind: "Object", values: new Map() };
38 + }
39 +
40 // Complex alias:
41 // read(alias.memberPath);
42 let object = this.#values.get(alias.identifier);
@@ -83,22 +88,28 @@ class AbstractState {
88 return value;
89 }
90
86 - // Simple lvalue:
87 - // lvalue = alias;
88 - // lvalue = alias.memberPath;
91 alias(lvalue: LValue, alias: Place) {
90 - if (alias.memberPath !== null && alias.memberPath.length > 1) {
91 - // TODO(gsn): Handle nested member paths
92 + // TODO(gsn): Handle aliasing for complex lvalue
93 + if (lvalue.place.memberPath !== null) {
94 return;
95 }
96
95 - const value = this.read(alias);
96 - this.#values.set(lvalue.place.identifier, value);
97 + // Simple lvalue:
98 + // lvalue = alias;
99 + // lvalue = alias.memberPath;
100 + this.aliases.union([lvalue.place.identifier, alias.identifier]);
101 + }
102
98 - // No need to alias Primitives.
99 - if (value.kind !== "Primitive") {
100 - this.aliases.union([lvalue.place.identifier, alias.identifier]);
103 + store(lvalue: LValue, value: AbstractValue) {
104 + // TODO(gsn): Handle stores for complex lvalue
105 + if (lvalue.place.memberPath !== null) {
106 + return;
107 }
108 +
109 + // Simple lvalue:
110 + // lvalue = alias;
111 + // lvalue = alias.memberPath;
112 + this.#values.set(lvalue.place.identifier, value);
113 }
114
115 buildAliasSets(): Array<Set<Identifier>> {
@@ -137,9 +148,11 @@ export function buildAliasSets(func: HIRFunction): Array<Set<Identifier>> {
148 function inferInstr(instr: Instruction, state: AbstractState) {
149 const { lvalue, value: instrValue } = instr;
150 let alias: Place | null = null;
151 + let value: AbstractValue | null = null;
152 switch (instrValue.kind) {
153 case "Identifier": {
154 alias = instrValue;
155 + value = state.read(alias);
156 break;
157 }
158 default:
@@ -147,8 +160,8 @@ function inferInstr(instr: Instruction, state: AbstractState) {
160 }
161
162 invariant(
150 - alias !== null,
151 - `expected ${printInstructionValue(instrValue)} to have an alias`
163 + value !== null,
164 + `expected ${printInstructionValue(instrValue)} to be an alias or value`
165 );
166
167 // TODO(gsn): handle this.
@@ -156,8 +169,10 @@ function inferInstr(instr: Instruction, state: AbstractState) {
169 return;
170 }
171
159 - // simple aliasing
160 - if (lvalue.place.memberPath === null) {
172 + // No need to alias Primitives.
173 + if (alias !== null && value.kind !== "Primitive") {
174 state.alias(lvalue, alias);
175 }
176 +
177 + state.store(lvalue, value);
178 }