@samitouri / QOS-React-2 / commits / 09bdf3553f

[hir] Remove unreachable fallthroughs separately from shrink

shrink visits all the fallthroughs even if they are unreachable so this isn't the right place to prune unreachable blocks. This PR moves pruning into a separate pass.

Sathya Gunasekaran committed Jan 4, 2023 at 18:09 UTC 09bdf3553f9de20ee17fe2e1fc3f6e8ba11efaef
3 files changed +49 -6
compiler/forget/src/HIR/HIRBuilder.ts
+15 -6
@@ -162,13 +162,15 @@ export default class HIRBuilder {
162 entry: this.#entry,
163 };
164 logHIR("Build (pre-shrink)", ir);
165 - // First reduce indirections and prune unreachable blocks
165 + // First reduce indirections
166 let shrunk = shrink(ir);
167 logHIR("Build (shrunk)", shrunk);
168 // then convert to reverse postorder
169 const rpo = reversePostorderBlocks(shrunk);
170 + removeUnreachableFallthroughs(rpo);
171 markInstructionIds(rpo);
172 markPredecessors(rpo);
173 +
174 return rpo;
175 }
176
@@ -356,7 +358,7 @@ export default class HIRBuilder {
358 }
359
360 /**
359 - * Helper to shrink a CFG to eliminate unreachable node and eliminate jump-only blocks.
361 + * Helper to shrink a CFG eliminate jump-only blocks.
362 */
363 function shrink(func: HIR): HIR {
364 const gotos = new Map();
@@ -406,8 +408,17 @@ function shrink(func: HIR): HIR {
408 });
409 }
410
411 + return { blocks, entry: func.entry };
412 +}
413 +
414 +function removeUnreachableFallthroughs(func: HIR) {
415 + const visited: Set<BlockId> = new Set();
416 + for (const [_, block] of func.blocks) {
417 + visited.add(block.id);
418 + }
419 +
420 // Cleanup any fallthrough blocks that weren't visited
410 - for (const block of blocks.values()) {
421 + for (const [_, block] of func.blocks) {
422 if (
423 block.terminal.kind === "if" ||
424 block.terminal.kind === "switch" ||
@@ -415,15 +426,13 @@ function shrink(func: HIR): HIR {
426 ) {
427 if (
428 block.terminal.fallthrough !== null &&
418 - !blocks.has(block.terminal.fallthrough)
429 + !visited.has(block.terminal.fallthrough)
430 ) {
431 block.terminal.fallthrough = null;
432 }
433 }
434 }
424 - return { blocks, entry: func.entry };
435 }
426 -
436 /**
437 * Converts the graph to reverse-postorder, with predecessor blocks appearing
438 * before successors except in the case of back links (ie loops).
compiler/forget/src/__tests__/fixtures/hir/return-conditional.expect.md new
+27
@@ -0,0 +1,27 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function foo(a, b) {
6 + if (a == null) {
7 + return null;
8 + } else {
9 + return b;
10 + }
11 +}
12 +
13 +```
14 +
15 +## Code
16 +
17 +```javascript
18 +function foo(a, b) {
19 + if (a == null) {
20 + return null;
21 + } else {
22 + return b;
23 + }
24 +}
25 +
26 +```
27 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/return-conditional.js new
+7
@@ -0,0 +1,7 @@
1 +function foo(a, b) {
2 + if (a == null) {
3 + return null;
4 + } else {
5 + return b;
6 + }
7 +}