@samitouri / QOS-React-2 / commits / 4505218911

Ensure unique BlockId for nested functions

This PR ensures that we use a single id space for the `BlockId`s in both top-level functions as well as any nested FunctionExpressions (note, we already do this for `IdentifierId`). This will make it easier for follow-ups to merge the CFG of nested functions (ie useMemo bodies) with the parent without block id collisions.

Joe Savona committed Apr 5, 2023 at 09:01 UTC 4505218911f019746172b1b39e1d1184619fad58
2 files changed +14 -18
compiler/forget/src/HIR/Environment.ts
+7
@@ -7,10 +7,12 @@ import {
7 GlobalRegistry,
8 } from "./Globals";
9 import {
10 + BlockId,
11 BuiltInType,
12 Effect,
13 FunctionType,
14 IdentifierId,
15 + makeBlockId,
16 makeIdentifierId,
17 ObjectType,
18 PolyType,
@@ -37,6 +39,7 @@ export class Environment {
39 #globals: GlobalRegistry;
40 #shapes: ShapeRegistry;
41 #nextIdentifer: number = 0;
42 + #nextBlock: number = 0;
43
44 constructor(config: EnvironmentConfig | null) {
45 this.#shapes = DEFAULT_SHAPES;
@@ -62,6 +65,10 @@ export class Environment {
65 return makeIdentifierId(this.#nextIdentifer++);
66 }
67
68 + get nextBlockId(): BlockId {
69 + return makeBlockId(this.#nextBlock++);
70 + }
71 +
72 getGlobalDeclaration(name: string): Global | null {
73 let resolvedGlobal: Global | null = this.#globals.get(name) ?? null;
74 if (resolvedGlobal === null) {
compiler/forget/src/HIR/HIRBuilder.ts
+7 -18
@@ -76,9 +76,8 @@ function newBlock(id: BlockId, kind: BlockKind): WipBlock {
76 */
77 export default class HIRBuilder {
78 #completed: Map<BlockId, BasicBlock> = new Map();
79 - #nextId: BlockId = makeBlockId(1);
80 - #current: WipBlock = newBlock(makeBlockId(0), "block");
81 - #entry: BlockId = makeBlockId(0);
79 + #current: WipBlock;
80 + #entry: BlockId;
81 #scopes: Array<Scope> = [];
82 #context: t.Identifier[];
83 #bindings: Map<string, { node: t.Identifier; identifier: Identifier }> =
@@ -107,18 +106,8 @@ export default class HIRBuilder {
106 this.#env = env;
107 this.parentFunction = parentFunction;
108 this.#context = context;
110 - }
111 -
112 - debug(): string {
113 - return JSON.stringify(
114 - {
115 - completed: this.#completed,
116 - current: this.#current,
117 - nextId: this.#nextId,
118 - },
119 - null,
120 - 2
121 - );
109 + this.#entry = makeBlockId(env.nextBlockId);
110 + this.#current = newBlock(this.#entry, "block");
111 }
112
113 currentBlockKind(): BlockKind {
@@ -304,7 +293,7 @@ export default class HIRBuilder {
293 preds: new Set(),
294 phis: new Set(),
295 });
307 - const nextId = makeBlockId(this.#nextId++);
296 + const nextId = this.#env.nextBlockId;
297 this.#current = newBlock(nextId, nextBlockKind);
298 }
299
@@ -331,7 +320,7 @@ export default class HIRBuilder {
320 * call `complete()` to save it without setting it as the current block.
321 */
322 reserve(kind: BlockKind): WipBlock {
334 - return newBlock(makeBlockId(this.#nextId++), kind);
323 + return newBlock(makeBlockId(this.#env.nextBlockId), kind);
324 }
325
326 /**
@@ -357,7 +346,7 @@ export default class HIRBuilder {
346 */
347 enter(nextBlockKind: BlockKind, fn: (blockId: BlockId) => Terminal): BlockId {
348 const current = this.#current;
360 - const nextId = makeBlockId(this.#nextId++);
349 + const nextId = this.#env.nextBlockId;
350 this.#current = newBlock(nextId, nextBlockKind);
351 const terminal = fn(nextId);
352 const { id: blockId, kind, instructions } = this.#current;