[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.
This commit is contained in:
Sathya Gunasekaran
2023-01-04 18:09:24 +00:00
parent e4642326d3
commit 09bdf3553f
3 changed files with 49 additions and 6 deletions
+15 -6
View File
@@ -162,13 +162,15 @@ export default class HIRBuilder {
entry: this.#entry,
};
logHIR("Build (pre-shrink)", ir);
// First reduce indirections and prune unreachable blocks
// First reduce indirections
let shrunk = shrink(ir);
logHIR("Build (shrunk)", shrunk);
// then convert to reverse postorder
const rpo = reversePostorderBlocks(shrunk);
removeUnreachableFallthroughs(rpo);
markInstructionIds(rpo);
markPredecessors(rpo);
return rpo;
}
@@ -356,7 +358,7 @@ export default class HIRBuilder {
}
/**
* Helper to shrink a CFG to eliminate unreachable node and eliminate jump-only blocks.
* Helper to shrink a CFG eliminate jump-only blocks.
*/
function shrink(func: HIR): HIR {
const gotos = new Map();
@@ -406,8 +408,17 @@ function shrink(func: HIR): HIR {
});
}
return { blocks, entry: func.entry };
}
function removeUnreachableFallthroughs(func: HIR) {
const visited: Set<BlockId> = new Set();
for (const [_, block] of func.blocks) {
visited.add(block.id);
}
// Cleanup any fallthrough blocks that weren't visited
for (const block of blocks.values()) {
for (const [_, block] of func.blocks) {
if (
block.terminal.kind === "if" ||
block.terminal.kind === "switch" ||
@@ -415,15 +426,13 @@ function shrink(func: HIR): HIR {
) {
if (
block.terminal.fallthrough !== null &&
!blocks.has(block.terminal.fallthrough)
!visited.has(block.terminal.fallthrough)
) {
block.terminal.fallthrough = null;
}
}
}
return { blocks, entry: func.entry };
}
/**
* Converts the graph to reverse-postorder, with predecessor blocks appearing
* before successors except in the case of back links (ie loops).
@@ -0,0 +1,27 @@
## Input
```javascript
function foo(a, b) {
if (a == null) {
return null;
} else {
return b;
}
}
```
## Code
```javascript
function foo(a, b) {
if (a == null) {
return null;
} else {
return b;
}
}
```
@@ -0,0 +1,7 @@
function foo(a, b) {
if (a == null) {
return null;
} else {
return b;
}
}