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

Extract eachBlockOperand to its own visitor

Follow up for #757: - Adds a new visitor which iterates over every Place within a BasicBlock - Remove unused entryBlock binding - Comments

Lauren Tan committed Nov 9, 2022 at 16:37 UTC e64ef9e1e04f333f0a820cd698ff039a11efd959
2 files changed +26 -24
compiler/forget/src/HIR/LeaveSSA.ts
+12 -23
@@ -1,11 +1,14 @@
1 -import { invariant } from "../CompilerError";
2 -import { HIRFunction, Identifier, Place } from "./HIR";
3 -import { eachInstructionOperand, eachTerminalOperand } from "./visitors";
1 +import { BasicBlock, HIRFunction, Identifier, Phi, Place } from "./HIR";
2 +import { eachBlockOperand } from "./visitors";
3
4 +/**
5 + * Leaves SSA form by building up a mapping of SSA'd {@link Identifier}s to their original
6 + * {@link Identifier}, then rewriting all {@link Place}s within a {@link BasicBlock} to reference
7 + * the original id. This allows us to skip adding instruction copies when removing {@link Phi}s,
8 + * while still allowing shadowing to work.
9 + */
10 export default function leaveSSA(fn: HIRFunction) {
11 const ir = fn.body;
7 - const entryBlock = ir.blocks.get(ir.entry);
8 - invariant(entryBlock, "expected to find the entry basic block");
12 const originalIdMap = new Map<
13 /* SSA'd id */ Identifier,
14 /* original id*/ Identifier
@@ -25,26 +28,12 @@ export default function leaveSSA(fn: HIRFunction) {
28 return;
29 }
30
28 - function tryRewrite(place: Place) {
29 - const originalId = originalIdMap.get(place.identifier);
30 - if (originalId != null) {
31 - place.identifier = originalId;
32 - }
33 - }
34 -
31 for (const [, block] of ir.blocks) {
36 - for (const instr of block.instructions) {
37 - // LValues also need to be rewritten as they might be declaring or reassigning an identifier
38 - // that was previously SSA'd.
39 - if (instr.lvalue != null) {
40 - tryRewrite(instr.lvalue.place);
32 + for (const place of eachBlockOperand(block)) {
33 + const originalId = originalIdMap.get(place.identifier);
34 + if (originalId != null) {
35 + place.identifier = originalId;
36 }
42 - for (const place of eachInstructionOperand(instr)) {
43 - tryRewrite(place);
44 - }
45 - }
46 - for (const place of eachTerminalOperand(block.terminal)) {
47 - tryRewrite(place);
37 }
38 }
39 }
compiler/forget/src/HIR/visitors.ts
+14 -1
@@ -6,7 +6,7 @@
6 */
7
8 import { assertExhaustive } from "../Common/utils";
9 -import { BlockId, Instruction, Place, Terminal } from "./HIR";
9 +import { BasicBlock, BlockId, Instruction, Place, Terminal } from "./HIR";
10
11 export function* eachInstructionOperand(instr: Instruction): Iterable<Place> {
12 const instrValue = instr.value;
@@ -304,3 +304,16 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
304 }
305 }
306 }
307 +
308 +/**
309 + * Iterates over all {@link Place}s within a {@link BasicBlock}.
310 + */
311 +export function* eachBlockOperand(block: BasicBlock): Iterable<Place> {
312 + for (const instr of block.instructions) {
313 + yield* eachInstructionOperand(instr);
314 + if (instr.lvalue != null) {
315 + yield instr.lvalue.place;
316 + }
317 + }
318 + yield* eachTerminalOperand(block.terminal);
319 +}