1
import invariant from "invariant";
2
import DisjointSet from "./DisjointSet";
3
-import { HIRFunction, Identifier, Instruction, Place, LValue } from "./HIR";
3
+import { HIRFunction, Identifier, Instruction, LValue, Place } from "./HIR";
4
import { printInstructionValue } from "./PrintHIR";
5
6
type AbstractValue = AbstractObject | AbstractPrimitive;
14
};
15
16
export type AliasSet = Set<Identifier>;
17
+
18
+export function buildAliasSets(
19
+ aliases: DisjointSet<Identifier>
20
+): Array<AliasSet> {
21
+ const aliasIds: Map<Identifier, number> = new Map();
22
+ const aliasSets: Map<number, Set<Identifier>> = new Map();
23
+
24
+ aliases.forEach((identifier, groupIdentifier) => {
25
+ let aliasId = aliasIds.get(groupIdentifier);
26
+ if (aliasId == null) {
27
+ aliasId = aliasIds.size;
28
+ aliasIds.set(groupIdentifier, aliasId);
29
+ }
30
+
31
+ let aliasSet = aliasSets.get(aliasId);
32
+ if (aliasSet === undefined) {
33
+ aliasSet = new Set();
34
+ aliasSets.set(aliasId, aliasSet);
35
+ }
36
+ aliasSet.add(identifier);
37
+ });
38
+
39
+ return [...aliasSets.values()];
40
+}
41
+
42
class AbstractState {
43
aliases = new DisjointSet<Identifier>();
44
// NOTE(gsn): Should this be a part of AbstractObject? No, because this has
157
}
158
159
memberAlias.add(alias.identifier);
135
- this.aliases.union([lvalue.place.identifier, alias.identifier]);
160
return;
161
}
162
177
// lvalue = alias.memberPath;
178
this.#values.set(lvalue.place.identifier, value);
179
}
156
-
157
- buildAliasSets(): Array<Set<Identifier>> {
158
- const aliasIds: Map<Identifier, number> = new Map();
159
- const aliasSets: Map<number, Set<Identifier>> = new Map();
160
-
161
- this.aliases.forEach((identifier, groupIdentifier) => {
162
- let aliasId = aliasIds.get(groupIdentifier);
163
- if (aliasId == null) {
164
- aliasId = aliasIds.size;
165
- aliasIds.set(groupIdentifier, aliasId);
166
- }
167
-
168
- let aliasSet = aliasSets.get(aliasId);
169
- if (aliasSet === undefined) {
170
- aliasSet = new Set();
171
- aliasSets.set(aliasId, aliasSet);
172
- }
173
- aliasSet.add(identifier);
174
- });
175
-
176
- return [...aliasSets.values()];
177
- }
180
}
181
180
-export function buildAliasSets(func: HIRFunction): Array<AliasSet> {
182
+export function inferAliases(func: HIRFunction): DisjointSet<Identifier> {
183
const state = new AbstractState();
184
for (const [_, block] of func.body.blocks) {
185
for (const instr of block.instructions) {
186
inferInstr(instr, state);
187
}
188
}
187
- return state.buildAliasSets();
189
+
190
+ return state.aliases;
191
}
192
193
function inferInstr(instr: Instruction, state: AbstractState) {