@samitouri / QOS-React / commits / 2a049044bb

Add and use eachTerminalSuccessor()

Joe Savona committed Nov 8, 2022 at 14:45 UTC 2a049044bbd0ed76ccc88f6c9d34783158b444b3
25 files changed +101 -109
compiler/forget/src/HIR/EnterSSA.ts
+7 -17
@@ -2,7 +2,6 @@ import { assertExhaustive } from "../Common/utils";
2 import { invariant } from "../CompilerError";
3 import {
4 BasicBlock,
5 - BlockId,
5 HIRFunction,
6 Identifier,
7 Instruction,
@@ -11,6 +10,7 @@ import {
10 } from "./HIR";
11 import { Environment } from "./HIRBuilder";
12 import { printIdentifier } from "./PrintHIR";
13 +import { eachTerminalSuccessor } from "./visitors";
14
15 type IncompletePhi = {
16 oldId: Identifier;
@@ -186,7 +186,7 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
186 }
187
188 for (const instr of block.instructions) {
189 - rewriteUses(instr, builder);
189 + rewriteInstructionUses(instr, builder);
190
191 if (instr.lvalue != null) {
192 const oldPlace = instr.lvalue.place;
@@ -200,9 +200,9 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
200 }
201 }
202
203 - const outputs = rewriteUsesAndCollectOutputs(block, builder);
204 - const outputBlocks = outputs.map((id) => func.body.blocks.get(id)!);
205 - for (const output of outputBlocks) {
203 + rewriteTerminalOperands(block, builder);
204 + for (const outputId of eachTerminalSuccessor(block.terminal)) {
205 + const output = func.body.blocks.get(outputId)!;
206 let count;
207 if (builder.unsealedPreds.has(output)) {
208 count = builder.unsealedPreds.get(output)! - 1;
@@ -218,11 +218,7 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
218 }
219 }
220
221 -function rewriteUsesAndCollectOutputs(
222 - block: BasicBlock,
223 - builder: SSABuilder
224 -): Array<BlockId> {
225 - const outputs: Array<BlockId> = [];
221 +function rewriteTerminalOperands(block: BasicBlock, builder: SSABuilder): void {
222 const { terminal } = block;
223 switch (terminal.kind) {
224 case "return":
@@ -233,14 +229,11 @@ function rewriteUsesAndCollectOutputs(
229 break;
230 }
231 case "goto": {
236 - outputs.push(terminal.block);
232 break;
233 }
234 case "if": {
235 const { consequent, alternate } = terminal;
236 terminal.test = builder.getPlace(terminal.test);
242 - outputs.push(alternate);
243 - outputs.push(consequent);
237 break;
238 }
239 case "switch": {
@@ -250,7 +243,6 @@ function rewriteUsesAndCollectOutputs(
243 if (case_.test) {
244 case_.test = builder.getPlace(case_.test);
245 }
253 - outputs.push(case_.block);
246 }
247 break;
248 }
@@ -261,11 +253,9 @@ function rewriteUsesAndCollectOutputs(
253 );
254 }
255 }
264 -
265 - return outputs;
256 }
257
268 -function rewriteUses(instr: Instruction, builder: SSABuilder) {
258 +function rewriteInstructionUses(instr: Instruction, builder: SSABuilder) {
259 const instrValue = instr.value;
260
261 switch (instrValue.kind) {
compiler/forget/src/HIR/HIRBuilder.ts
+3 -29
@@ -19,7 +19,7 @@ import {
19 Terminal,
20 } from "./HIR";
21 import { printInstruction } from "./PrintHIR";
22 -import { mapTerminalSuccessors } from "./visitors";
22 +import { eachTerminalSuccessor, mapTerminalSuccessors } from "./visitors";
23
24 // *******************************************************************************************
25 // *******************************************************************************************
@@ -512,34 +512,8 @@ function markPredecessors(func: HIR) {
512
513 const { terminal } = block;
514
515 - switch (terminal.kind) {
516 - case "return":
517 - case "throw": {
518 - break;
519 - }
520 - case "goto": {
521 - visit(terminal.block, block);
522 - break;
523 - }
524 - case "if": {
525 - const { consequent, alternate } = terminal;
526 - visit(alternate, block);
527 - visit(consequent, block);
528 - break;
529 - }
530 - case "switch": {
531 - const { cases } = terminal;
532 - for (const case_ of [...cases]) {
533 - visit(case_.block, block);
534 - }
535 - break;
536 - }
537 - default: {
538 - assertExhaustive(
539 - terminal,
540 - `Unexpected terminal kind '${(terminal as any).kind}'`
541 - );
542 - }
515 + for (const successor of eachTerminalSuccessor(terminal)) {
516 + visit(successor, block);
517 }
518 }
519 visit(func.entry, null);
compiler/forget/src/HIR/InferReferenceEffects.ts
+5 -14
@@ -16,15 +16,14 @@ import {
16 InstructionValue,
17 Phi,
18 Place,
19 - Terminal,
19 ValueKind,
20 } from "./HIR";
21 +import { printMixedHIR, printPlace, printSourceLocation } from "./PrintHIR";
22 import {
23 eachInstructionOperand,
24 eachTerminalOperand,
25 - mapTerminalSuccessors,
25 + eachTerminalSuccessor,
26 } from "./visitors";
27 -import { printMixedHIR, printPlace, printSourceLocation } from "./PrintHIR";
27
28 /**
29 * For every usage of a value in the given function, infers the effect or action
@@ -137,17 +136,9 @@ export default function inferReferenceEffects(fn: HIRFunction) {
136 const environment = incomingEnvironment.clone();
137 inferBlock(environment, block);
138
140 - // TODO: add a `forEachTerminalSuccessor` helper, we don't actually want the result
141 - // here
142 - const _ = mapTerminalSuccessors(
143 - block.terminal,
144 - (nextBlockId, isFallthrough) => {
145 - if (!isFallthrough) {
146 - queue(nextBlockId, environment);
147 - }
148 - return nextBlockId;
149 - }
150 - );
139 + for (const nextBlockId of eachTerminalSuccessor(block.terminal)) {
140 + queue(nextBlockId, environment);
141 + }
142 }
143 }
144 }
compiler/forget/src/HIR/visitors.ts
+37
@@ -129,6 +129,43 @@ export function mapTerminalSuccessors(
129 }
130 }
131
132 +/**
133 + * Iterates over the successor block ids of the provided terminal. The function is called
134 + * specifically for the successors that define the standard control flow, and not
135 + * pseduo-successors such as fallthroughs.
136 + */
137 +export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
138 + switch (terminal.kind) {
139 + case "goto": {
140 + yield terminal.block;
141 + break;
142 + }
143 + case "if": {
144 + yield terminal.consequent;
145 + yield terminal.alternate;
146 + break;
147 + }
148 + case "switch": {
149 + for (const case_ of terminal.cases) {
150 + yield case_.block;
151 + }
152 + break;
153 + }
154 + case "return": {
155 + break;
156 + }
157 + case "throw": {
158 + break;
159 + }
160 + default: {
161 + assertExhaustive(
162 + terminal,
163 + `Unexpected terminal kind '${(terminal as any as Terminal).kind}'`
164 + );
165 + }
166 + }
167 +}
168 +
169 export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
170 switch (terminal.kind) {
171 case "if": {
compiler/forget/src/__tests__/fixtures/hir/component.expect.md
+4 -4
@@ -43,7 +43,7 @@ bb0:
43 [6] Const mutate max$32 = Call mutate Math$8.max(read $31, read maxItems$28)
44 Goto bb1
45 bb1:
46 - predecessor blocks: bb0 bb4 bb7
46 + predecessor blocks: bb0 bb7 bb4
47 If (read items$27) then:bb3 else:bb2
48 bb3:
49 predecessor blocks: bb1
@@ -59,8 +59,8 @@ bb9:
59 [10] Const mutate $39 = Call mutate seen$30.has(mutate item$10)
60 Goto bb7
61 bb7:
62 - predecessor blocks: bb9 bb8
63 - $40: phi(bb9: $39, bb8: $37)
62 + predecessor blocks: bb8 bb9
63 + $40: phi(bb8: $37, bb9: $39)
64 If (read $40) then:bb1 else:bb4
65 bb4:
66 predecessor blocks: bb7
@@ -71,7 +71,7 @@ bb4:
71 [15] Const mutate $49 = Binary read renderedItems$29.length >= read max$32
72 If (read $49) then:bb2 else:bb1
73 bb2:
74 - predecessor blocks: bb1 bb4
74 + predecessor blocks: bb4 bb1
75 [16] Const mutate count$52 = read renderedItems$29.length
76 [17] Const mutate $53 = "div"
77 [18] Const mutate $54 = "\n "
compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md
+2 -2
@@ -118,7 +118,7 @@ bb2:
118 [3] Call mutate a$4.push(read props$3.c)
119 Goto bb1
120 bb1:
121 - predecessor blocks: bb0 bb2
121 + predecessor blocks: bb2 bb0
122 [4] Call mutate a$4.push(read props$3.d)
123 Return freeze a$4
124 ```
@@ -218,7 +218,7 @@ bb2:
218 [3] Call mutate a$4.push(read props$3.c)
219 Goto bb1
220 bb1:
221 - predecessor blocks: bb2 bb0
221 + predecessor blocks: bb0 bb2
222 [4] Call mutate a$4.push(read props$3.d)
223 Return freeze a$4
224 ```
compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md
+4 -4
@@ -75,14 +75,14 @@ bb2:
75 [3] Call mutate a$7.push(read props$6.p0)
76 Goto bb1
77 bb1:
78 - predecessor blocks: bb0 bb2
78 + predecessor blocks: bb2 bb0
79 If (read props$6.p1) then:bb4 else:bb3
80 bb4:
81 predecessor blocks: bb1
82 [4] Call mutate b$8.push(read props$6.p2)
83 Goto bb3
84 bb3:
85 - predecessor blocks: bb1 bb4
85 + predecessor blocks: bb4 bb1
86 [5] Const mutate $16 = JSX <read Foo$4 a={freeze a$7} b={freeze b$8} ></read Foo$4>
87 Return read $16
88 ```
@@ -120,14 +120,14 @@ bb2:
120 [4] Call mutate a$9.push(read props$8.p0)
121 Goto bb1
122 bb1:
123 - predecessor blocks: bb0 bb2
123 + predecessor blocks: bb2 bb0
124 If (read props$8.p1) then:bb4 else:bb3
125 bb4:
126 predecessor blocks: bb1
127 [5] Call mutate b$10.push(read props$8.p2)
128 Goto bb3
129 bb3:
130 - predecessor blocks: bb1 bb4
130 + predecessor blocks: bb4 bb1
131 [6] Const mutate $19 = JSX <read Foo$6 a={freeze a$9} b={freeze b$10} ></read Foo$6>
132 Return read $19
133 ```
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md
+2 -2
@@ -39,8 +39,8 @@ bb3:
39 [5] Reassign mutate a$12 = Array []
40 Goto bb1
41 bb1:
42 - predecessor blocks: bb3 bb2
43 - a$14: phi(bb3: a$12, bb2: a$11)
42 + predecessor blocks: bb2 bb3
43 + a$14: phi(bb2: a$11, bb3: a$12)
44 [6] Call read useFreeze$5(freeze a$14)
45 [7] Call read useFreeze$5(read a$14)
46 [8] Call mutate call$6(read a$14)
compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md
+1 -1
@@ -106,7 +106,7 @@ bb2:
106 [4] Call mutate mutate$5(mutate b$10)
107 Goto bb1
108 bb1:
109 - predecessor blocks: bb0 bb2
109 + predecessor blocks: bb2 bb0
110 [5] Const mutate $14 = JSX <read Foo$6 a={freeze a$9} b={freeze b$10} ></read Foo$6>
111 Return read $14
112 ```
compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md
+1 -1
@@ -84,7 +84,7 @@ bb2:
84 [3] Call mutate foo$5(mutate a$9, mutate b$10)
85 Goto bb1
86 bb1:
87 - predecessor blocks: bb0 bb2
87 + predecessor blocks: bb2 bb0
88 [4] Const mutate $14 = JSX <read Foo$6 a={freeze a$9} b={freeze b$10} ></read Foo$6>
89 Return read $14
90 ```
compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md
+6 -6
@@ -34,8 +34,8 @@ bb3:
34 [3] Const mutate $7 = read $5
35 Goto bb1
36 bb1:
37 - predecessor blocks: bb3 bb2
38 - $8: phi(bb3: $7, bb2: $6)
37 + predecessor blocks: bb2 bb3
38 + $8: phi(bb2: $6, bb3: $7)
39 Return freeze $8
40 ```
41
@@ -67,8 +67,8 @@ bb3:
67 [3] Const mutate $7 = Call mutate g$4()
68 Goto bb1
69 bb1:
70 - predecessor blocks: bb3 bb2
71 - $8: phi(bb3: $7, bb2: $6)
70 + predecessor blocks: bb2 bb3
71 + $8: phi(bb2: $6, bb3: $7)
72 Return freeze $8
73 ```
74
@@ -102,8 +102,8 @@ bb3:
102 [5] Const mutate $13 = Call mutate g$7()
103 Goto bb1
104 bb1:
105 - predecessor blocks: bb3 bb2
106 - $14: phi(bb3: $13, bb2: $12)
105 + predecessor blocks: bb2 bb3
106 + $14: phi(bb2: $12, bb3: $13)
107 Return freeze $14
108 ```
109
compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md
+5 -5
@@ -97,11 +97,11 @@ bb3:
97 [12] Const mutate $29 = Call mutate cond$8(mutate a$21)
98 If (read $29) then:bb2 else:bb1
99 bb2:
100 - predecessor blocks: bb1 bb3
101 - a$30: phi(bb1: a$18, bb3: a$21)
102 - b$31: phi(bb1: b$20, bb3: b$23)
103 - c$32: phi(bb1: c$22, bb3: c$25)
104 - d$33[-1:14]: phi(bb1: d$24, bb3: d$26)
100 + predecessor blocks: bb3 bb1
101 + a$30: phi(bb3: a$21, bb1: a$18)
102 + b$31: phi(bb3: b$23, bb1: b$20)
103 + c$32: phi(bb3: c$25, bb1: c$22)
104 + d$33[-1:14]: phi(bb3: d$26, bb1: d$24)
105 If (read a$30) then:bb7 else:bb7
106 bb7:
107 predecessor blocks: bb2
compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md
+1 -1
@@ -83,7 +83,7 @@ bb3:
83 [7] Const mutate $21 = Call mutate cond$7(mutate a$12)
84 If (read $21) then:bb2 else:bb1
85 bb2:
86 - predecessor blocks: bb1 bb3
86 + predecessor blocks: bb3 bb1
87 If (read a$12) then:bb7 else:bb7
88 bb7:
89 predecessor blocks: bb2
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+2 -2
@@ -32,8 +32,8 @@ bb2:
32 [4] Reassign mutate x$9 = Array []
33 Goto bb1
34 bb1:
35 - predecessor blocks: bb0 bb2
36 - x$11: phi(bb0: x$7, bb2: x$9)
35 + predecessor blocks: bb2 bb0
36 + x$11: phi(bb2: x$9, bb0: x$7)
37 [5] Let mutate _$12 = JSX <read Component$0 x={freeze x$11} ></read Component$0>
38 [6] Call read y$8.push(read props$6.p2)
39 [7] Const mutate $15 = JSX <read Component$0 x={read x$11} y={read y$8} ></read Component$0>
compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md
+2 -2
@@ -72,8 +72,8 @@ bb13:
72 [9] Reassign mutate x$15 = read props$6.c
73 Goto bb1
74 bb1:
75 - predecessor blocks: bb13 bb12 bb8 bb6 bb4
76 - x$16: phi(bb13: x$15, bb12: x$14, bb8: x$11, bb6: x$12, bb4: x$13)
75 + predecessor blocks: bb8 bb6 bb4 bb12 bb13
76 + x$16: phi(bb8: x$11, bb6: x$12, bb4: x$13, bb12: x$14, bb13: x$15)
77 [10] read x$16
78 Return
79 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md
+1 -1
@@ -48,7 +48,7 @@ bb2:
48 [6] Let mutate _$15 = JSX <read $14 a={freeze a$11} ></read $14>
49 Goto bb1
50 bb1:
51 - predecessor blocks: bb0 bb2
51 + predecessor blocks: bb2 bb0
52 [7] Call mutate foo$4(read a$11, mutate b$12)
53 [8] Const mutate $19 = "div"
54 [9] Const mutate $20 = JSX <read $19 a={freeze a$11} b={freeze b$12} ></read $19>
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md
+4 -4
@@ -31,8 +31,8 @@ bb2:
31 [5] Reassign mutate x$11 = 3
32 Goto bb1
33 bb1:
34 - predecessor blocks: bb0 bb2
35 - x$17: phi(bb0: x$7, bb2: x$11)
34 + predecessor blocks: bb2 bb0
35 + x$17: phi(bb2: x$11, bb0: x$7)
36 [6] Const mutate $12 = 3
37 [7] Const mutate $14 = Binary read y$8 === read $12
38 If (read $14) then:bb4 else:bb3
@@ -41,8 +41,8 @@ bb4:
41 [8] Reassign mutate x$15 = 5
42 Goto bb3
43 bb3:
44 - predecessor blocks: bb1 bb4
45 - x$16: phi(bb1: x$17, bb4: x$15)
44 + predecessor blocks: bb4 bb1
45 + x$16: phi(bb4: x$15, bb1: x$17)
46 [9] Reassign mutate y$18 = read x$16
47 Return
48 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md
+2 -2
@@ -28,8 +28,8 @@ bb2:
28 [5] Reassign mutate x$9 = 3
29 Goto bb1
30 bb1:
31 - predecessor blocks: bb0 bb2
32 - x$10: phi(bb0: x$5, bb2: x$9)
31 + predecessor blocks: bb2 bb0
32 + x$10: phi(bb2: x$9, bb0: x$5)
33 [6] Reassign mutate y$11 = read x$10
34 Return
35 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md
+1 -1
@@ -22,7 +22,7 @@ bb0:
22 [1] Let mutate items$5 = Array []
23 Goto bb1
24 bb1:
25 - predecessor blocks: bb0 bb3 bb5
25 + predecessor blocks: bb0 bb5 bb3
26 If (read items$5) then:bb3 else:bb2
27 bb3:
28 predecessor blocks: bb1
compiler/forget/src/__tests__/fixtures/hir/ssa-if-else.expect.md
+1 -1
@@ -31,7 +31,7 @@ bb3:
31 [4] Let mutate z$8 = read x$5
32 Goto bb1
33 bb1:
34 - predecessor blocks: bb3 bb2
34 + predecessor blocks: bb2 bb3
35 Return
36 ```
37
compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md
+3 -3
@@ -36,9 +36,9 @@ bb3:
36 [6] Reassign mutate y$11 = 3
37 Goto bb1
38 bb1:
39 - predecessor blocks: bb3 bb2
40 - x$12: phi(bb3: x$6, bb2: x$10)
41 - y$13: phi(bb3: y$11, bb2: y$7)
39 + predecessor blocks: bb2 bb3
40 + x$12: phi(bb2: x$10, bb3: x$6)
41 + y$13: phi(bb2: y$7, bb3: y$11)
42 [7] Let mutate t$14 = Object { x: read x$12, y: read y$13 }
43 Return freeze t$14
44 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md
+2 -2
@@ -26,8 +26,8 @@ bb2:
26 [4] Reassign mutate x$7 = 2
27 Goto bb1
28 bb1:
29 - predecessor blocks: bb0 bb2
30 - x$8: phi(bb0: x$4, bb2: x$7)
29 + predecessor blocks: bb2 bb0
30 + x$8: phi(bb2: x$7, bb0: x$4)
31 Return read x$8
32 ```
33
compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md
+2 -2
@@ -33,8 +33,8 @@ bb3:
33 [5] Reassign mutate y$9 = 2
34 Goto bb1
35 bb1:
36 - predecessor blocks: bb3 bb2
37 - y$10: phi(bb3: y$9, bb2: y$8)
36 + predecessor blocks: bb2 bb3
37 + y$10: phi(bb2: y$8, bb3: y$9)
38 [6] Let mutate x$11 = read y$10
39 Return
40 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-single-if.expect.md
+1 -1
@@ -25,7 +25,7 @@ bb2:
25 [3] Let mutate z$6 = Binary read x$4 + read y$5
26 Goto bb1
27 bb1:
28 - predecessor blocks: bb0 bb2
28 + predecessor blocks: bb2 bb0
29 Return
30 ```
31
compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md
+2 -2
@@ -25,8 +25,8 @@ bb2:
25 [4] Reassign mutate x$7 = 2
26 Goto bb1
27 bb1:
28 - predecessor blocks: bb0 bb2
29 - x$8: phi(bb0: x$4, bb2: x$7)
28 + predecessor blocks: bb2 bb0
29 + x$8: phi(bb2: x$7, bb0: x$4)
30 Throw read x$8
31 ```
32