@samitouri / QOS-React-2 / commits / 509aa9f0e5

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 {