Joe Savona 1d5d89b8be [js/rust] Improve constant propagation
Makes the same improvement to constant propagation in both the JS and Rust 
versions. The core algorithm only populates phi variables if all operands have a 
known value (no back edges) and all those values are the same: this allows us to 
propagate constants in most cases and simply punts on handling propagating 
values that are affected by loops. However, since we collapse if statements into 
gotos when the test condition is a constant, there can be cases where a phi that 
originally existed will be pruned out: 

``` 

// bb0 

let x1; 

if (true) { 

// bb1 

x2 = 1; 

} else { 

// bb2 

x3 = 2; // this block becomes unreachable 

} 

// bb3 

x4 = phi(bb1: x2, bb2: x3); // this phi will get pruned s.t. x4 = x2 = 1 

return x4; 

``` 

However, the algorithm doesn't prune phis until _after_ applying constants, so 
currently we would see this phi node w different inputs and not propagate a 
constant for the final usage of x, even though it will clearly be `1`. 

The change is to make constant propagation use fixpoint iteration, iterating so 
long as terminals changed on the previous iteration. If no terminals change the 
algorithm completes in a single pass, but if terminals do change then we update 
phis and continue. As you can see from the new test case this allows us to find 
arbitrary length sequences of values and terminals that can be pruned.
2023-07-13 09:53:36 +09:00
Languages
JavaScript 67.1%
TypeScript 29.4%
HTML 1.5%
CSS 1.1%
C++ 0.6%
Other 0.2%