[hir] Add MutableRange to Identifier
Sathya Gunasekaran committed
Nov 4, 2022 at 16:39 UTC
c75a1fe6bb8aa3c8376a536445b3ac48f1f6914a
4 files changed
+39
-4
compiler/forget/src/HIR/HIR.ts
+12
@@ -240,12 +240,24 @@ export type Primitive = {
240
loc: SourceLocation;
241
};
242
243
+/*
244
+ * Range in which an identifier is mutable. Start and End refer to Instruction.id.
245
+ * TODO(gsn): Type Instruction.id better and use it here.
246
+ *
247
+ * Start is exclusive, End is inclusive (ie, the value is mutable at that instruction).
248
+ */
249
+export type MutableRange = {
250
+ start: number;
251
+ end: number;
252
+};
253
+
254
/**
255
* Represents a user-defined variable (has a name) or a temporary variable (no name).
256
*/
257
export type Identifier = {
258
id: IdentifierId; // unique value to distinguish different instances of the same name in different scopes
259
name: string | null; // null for temporaries. name is primarily used for debugging.
260
+ mutableRange: MutableRange;
261
};
262
263
/**
compiler/forget/src/HIR/HIRBuilder.ts
+2
-1
@@ -116,6 +116,7 @@ export default class HIRBuilder {
116
return {
117
id,
118
name: null,
119
+ mutableRange: { start: 0, end: 0 },
120
};
121
}
122
@@ -123,7 +124,7 @@ export default class HIRBuilder {
124
let identifier = this.#bindings.get(node);
125
if (identifier == null) {
126
const id = this.nextIdentifierId;
126
- identifier = { id, name: node.name };
127
+ identifier = { id, name: node.name, mutableRange: { start: 0, end: 0 } };
128
this.#bindings.set(node, identifier);
129
}
130
return identifier;
compiler/forget/src/HIR/PrintHIR.ts
+12
-1
@@ -14,6 +14,7 @@ import {
14
InstructionKind,
15
InstructionValue,
16
LValue,
17
+ MutableRange,
18
Phi,
19
Place,
20
SourceLocation,
@@ -96,6 +97,7 @@ export function printInstruction(instr: Instruction): string {
97
function printPhi(phi: Phi): string {
98
const items = [];
99
items.push(printIdentifier(phi.id));
100
+ items.push(printMutableRange(phi.id.mutableRange));
101
items.push(": phi(");
102
const phis = [];
103
for (const [block, id] of phi.operands) {
@@ -239,8 +241,17 @@ function printInstructionValue(instrValue: InstructionValue): string {
241
return value;
242
}
243
244
+function isMutable(range: MutableRange): boolean {
245
+ return range.end > range.start;
246
+}
247
+
248
+function printMutableRange(range: MutableRange): string {
249
+ return isMutable(range) ? `[${range.start}:${range.end}]` : "";
250
+}
251
+
252
export function printLValue(lval: LValue): string {
243
- const place = printPlace(lval.place);
253
+ let place = printPlace(lval.place);
254
+ place += printMutableRange(lval.place.identifier.mutableRange);
255
switch (lval.kind) {
256
case InstructionKind.Let: {
257
return `Let ${place}`;
compiler/forget/src/HIR/SSAify.ts
+13
-2
@@ -44,9 +44,20 @@ class SSABuilder {
44
return this.#states.get(this.#current)!;
45
}
46
47
+ makeId(oldId: Identifier): Identifier {
48
+ return {
49
+ id: this.nextIdentifierId,
50
+ name: oldId.name,
51
+ mutableRange: {
52
+ start: 0,
53
+ end: 0,
54
+ },
55
+ };
56
+ }
57
+
58
definePlace(oldPlace: Place): Place {
59
const oldId = oldPlace.identifier;
49
- const newId = { ...oldId, id: this.nextIdentifierId };
60
+ const newId = this.makeId(oldId);
61
this.state().defs.set(oldId, newId);
62
return {
63
...oldPlace,
@@ -103,7 +114,7 @@ class SSABuilder {
114
// Adding a phi may loop back to our block if there is a loop in the CFG. We
115
// update our defs before adding the phi to terminate the recursion rather than
116
// looping infinitely.
106
- const newId = { ...oldId, id: this.nextIdentifierId };
117
+ const newId = this.makeId(oldId);
118
state.defs.set(oldId, newId);
119
120
const predDefs: Map<BasicBlock, Identifier> = new Map();