HIRVisitor - change labels to block ids
HIRTreeVisitor previously passed a string label (for certain blocks). This changes to pass the raw BlockId, and have codegen convert that to a string. I'm not sure if we'll need this but it would be helpful for eg visiting the IR and emitting a new IR, while mapping block ids forward. Even if we don't need that it makes sense for Codegen to decide how to convert a block id into a label (which has to obey the rules of an identifier, not the visitor's concern).
Joe Savona committed
Nov 30, 2022 at 10:24 UTC
509aa9f0e504ead3133a5f7c75e2be5becbb69ab
5 files changed
+38
-18
compiler/forget/src/HIR/Codegen.ts
+18
-5
@@ -9,6 +9,7 @@ import * as t from "@babel/types";
9
import { assertExhaustive } from "../Common/utils";
10
import { invariant } from "../CompilerError";
11
import {
12
+ BlockId,
13
GeneratedSource,
14
HIRFunction,
15
Identifier,
@@ -168,14 +169,16 @@ class CodegenVisitor
169
switch (terminal.kind) {
170
case "break": {
171
if (terminal.label) {
171
- return t.breakStatement(t.identifier(terminal.label));
172
+ return t.breakStatement(t.identifier(codegenLabel(terminal.label)));
173
} else {
174
return t.breakStatement();
175
}
176
}
177
case "continue": {
178
if (terminal.label) {
178
- return t.continueStatement(t.identifier(terminal.label));
179
+ return t.continueStatement(
180
+ t.identifier(codegenLabel(terminal.label))
181
+ );
182
} else {
183
return t.continueStatement();
184
}
@@ -223,13 +226,19 @@ class CodegenVisitor
226
appendBlock(
227
block: t.Statement[],
228
item: t.Statement,
226
- label?: string | undefined
229
+ blockId?: BlockId | undefined
230
): void {
231
if (item.type === "EmptyStatement") {
232
return;
233
}
231
- if (label !== undefined) {
232
- block.push(createLabelledStatement(item.loc, t.identifier(label), item));
234
+ if (blockId !== undefined) {
235
+ block.push(
236
+ createLabelledStatement(
237
+ item.loc,
238
+ t.identifier(codegenLabel(blockId)),
239
+ item
240
+ )
241
+ );
242
} else {
243
block.push(item);
244
}
@@ -240,6 +249,10 @@ class CodegenVisitor
249
}
250
}
251
252
+function codegenLabel(id: BlockId): string {
253
+ return `bb${id}`;
254
+}
255
+
256
function codegenInstructionValue(
257
temp: Temporaries,
258
instrValue: InstructionValue
compiler/forget/src/HIR/HIRTreeVisitor.ts
+8
-8
@@ -138,7 +138,7 @@ class Driver<TBlock, TValue, TItem, TCase> {
138
consequent: consequent ?? this.emptyBlock(),
139
alternate: alternate,
140
}),
141
- `bb${fallthroughId}` //
141
+ fallthroughId
142
);
143
this.visitBlock(this.cx.ir.blocks.get(fallthroughId)!, blockValue);
144
} else {
@@ -217,7 +217,7 @@ class Driver<TBlock, TValue, TItem, TCase> {
217
test,
218
cases,
219
}),
220
- `bb${fallthroughId}`
220
+ fallthroughId
221
);
222
this.visitBlock(this.cx.ir.blocks.get(fallthroughId)!, blockValue);
223
} else {
@@ -290,7 +290,7 @@ class Driver<TBlock, TValue, TItem, TCase> {
290
test: testValue,
291
loop: loopBody,
292
}),
293
- `bb${fallthroughId}`
293
+ fallthroughId
294
);
295
this.visitBlock(this.cx.ir.blocks.get(fallthroughId)!, blockValue);
296
} else {
@@ -359,7 +359,7 @@ class Driver<TBlock, TValue, TItem, TCase> {
359
case "labeled": {
360
return this.visitor.visitTerminal({
361
kind: "break",
362
- label: `bb${target.block}`,
362
+ label: target.block,
363
});
364
}
365
}
@@ -375,7 +375,7 @@ class Driver<TBlock, TValue, TItem, TCase> {
375
case "labeled": {
376
return this.visitor.visitTerminal({
377
kind: "continue",
378
- label: `bb${target.block}`,
378
+ label: target.block,
379
});
380
}
381
case "unlabeled": {
@@ -687,7 +687,7 @@ export interface Visitor<TBlock, TValue, TItem, TCase> {
687
* Appends an item onto the given block, with an optional label. The label
688
* indicates that a break/continue will proceed to code *after* the given item.
689
*/
690
- appendBlock(block: TBlock, item: TItem, label?: string): void;
690
+ appendBlock(block: TBlock, item: TItem, label?: BlockId): void;
691
692
/**
693
* Converts the visitor's block representation into the representation of a
@@ -713,5 +713,5 @@ export type BlockTerminal<TBlock, TValue, TItem, TCase> =
713
test: TValue;
714
loop: TItem;
715
}
716
- | { kind: "break"; label: string | null }
717
- | { kind: "continue"; label: string | null };
716
+ | { kind: "break"; label: BlockId | null }
717
+ | { kind: "continue"; label: BlockId | null };
compiler/forget/src/HIR/InferReactiveScopeDependencies.ts
+2
-1
@@ -7,6 +7,7 @@
7
8
import { assertExhaustive, retainWhere } from "../Common/utils";
9
import {
10
+ BlockId,
11
HIRFunction,
12
Identifier,
13
Instruction,
@@ -190,6 +191,6 @@ class ScopeDependenciesVisitor
191
enterBlock(): void {}
192
visitImplicitTerminal(): void | null {}
193
visitCase(test: InstructionValue, block: void): void {}
193
- appendBlock(block: void, item: void, label?: string | undefined): void {}
194
+ appendBlock(block: void, item: void, label?: BlockId | undefined): void {}
195
leaveBlock(block: void): void {}
196
}
compiler/forget/src/HIR/InferReactiveScopes.ts
+3
-2
@@ -9,6 +9,7 @@ import invariant from "invariant";
9
import { retainWhere } from "../Common/utils";
10
import DisjointSet from "./DisjointSet";
11
import {
12
+ BlockId,
13
HIRFunction,
14
Instruction,
15
InstructionId,
@@ -282,7 +283,7 @@ class MergeOverlappingReactiveScopesVisitor
283
visitImplicitTerminal(): void | null {}
284
visitTerminal(terminal: BlockTerminal<void, void, void, void>): void {}
285
visitCase(test: void | null, block: void): void {}
285
- appendBlock(block: void, item: void, label?: string | undefined): void {}
286
+ appendBlock(block: void, item: void, label?: BlockId | undefined): void {}
287
leaveBlock(block: void): void {
288
this.scopes.pop();
289
if (this.scopes.length === 0) {
@@ -381,7 +382,7 @@ class AlignReactiveScopesToBlockScopeRangeVisitor
382
// no-ops
383
visitValue(value: InstructionValue): void {}
384
visitCase(test: void | null, block: void): void {}
384
- appendBlock(block: void, item: void, label?: string | undefined): void {}
385
+ appendBlock(block: void, item: void, label?: BlockId | undefined): void {}
386
}
387
388
function getInstructionScope(instr: Instruction): ReactiveScope | null {
compiler/forget/src/HIR/PrintHIRTree.ts
+7
-2
@@ -6,6 +6,7 @@
6
*/
7
8
import { assertExhaustive } from "../Common/utils";
9
+import { BlockId } from "../ControlFlowGraph";
10
import {
11
HIRFunction,
12
Instruction,
@@ -116,13 +117,17 @@ class PrintVisitor implements Visitor<Array<string>, string, string, string> {
117
return `${prefix}case ${test}: ${block.trimStart()}`;
118
}
119
}
119
- appendBlock(block: string[], item: string, label?: string | undefined): void {
120
+ appendBlock(
121
+ block: string[],
122
+ item: string,
123
+ label?: BlockId | undefined
124
+ ): void {
125
const prefix = " ".repeat(this.depth);
126
if (item !== "") {
127
block.push(`${prefix}${item.trimStart()}`);
128
}
129
if (label !== undefined) {
125
- block.push(`${prefix}${label}:`);
130
+ block.push(`${prefix}bb${label}:`);
131
}
132
}
133
leaveBlock(block: string[]): string {