dillon1000/react

Commit

[rust] Initial port of EnterSSA

This is a first pass at porting EnterSSA to Rust. First pass in the sense that 
it's hard to fully test it, and also in the sense that we'll likely figure out 
even better ways to work w the HIR as we iterate. Oh and i didn't do recusing 
into function expressions yet, since we can't even represent function 
expressions yet, and that may require modifying the design a bit (though i have 
an idea that i think will work, which is for the Builder to have an optional 
parent. When we encounter a block with no predecessors, we check the parent. I 
_think_ this will make all the borrowing "just work"). 

A few notes: 

Rust's compilation model parallelizes and incrementally computes at the crate 
granularity, so builds are faster if we split up our code into more but smaller 
crates. Setting up a clean dependency graph can dramatically improve build 
performance too. For example, to run the `fixtures` tests we can build `estree` 
and `hir` in parallel, then once those build _all_ of our other crates can be 
built in parallel until we get to `fixtures` which depends on the everything 
else. The various passes don't have any build dependencies on each other so they 
can build in parallel. Hence the new code for SSA stuff is in a separate 
`hir-ssa` crate. We should similarly group other passes (approximately one crate 
per folder in the babel-plugin-react-forget/src/ directory, eg SSA, Inference, 
Optimization, etc). 

Second, shared mutable ownership can be modeled in Rust but requires wrappers 
such as `Rc<RefCell<>>`. It's generally more efficient and more idiomatic to 
rethink the data model and algorithm. For EnterSSA, the Builder object holds a 
reference into the HIR that it only ever reads, and the pass (which drives the 
builder) also holds a reference into the HIR, which it mutates. The previous PR 
split up Blocks and Instructions, and the value of that is more apparent in 
`enter_ssa()`. The Rust equivalent of the builder holds a _shared_ (immutable) 
reference to just the HIR's blocks, while the pass (driving the builder) holds a 
_unique_ (mutable) reference to just the HIR's instructions. This lets us keep 
the overall feel of the algorithm while keeping Rust happy. 

Also note that the other change — to making operands be InstrIx indices into the 
instructions array — means that the SSA logic is simpler. Most instructions 
don't have to be visited at all, since they don't deal with loads/stores. 
Terminals also don't need to be visited, since they reference instructions, not 
identifiers. The Phi concept seems to just work too. 

I also updated the printer to print predecessors and phis.
Browse files
Changed paths17 files
First-parent comparison
M compiler/forget/crates/build-hir/src/build.rs ModifiedM compiler/forget/crates/build-hir/src/builder.rs ModifiedM compiler/forget/crates/fixtures/Cargo.toml ModifiedA compiler/forget/crates/fixtures/tests/fixtures/ssa-reassign-if.js AddedM compiler/forget/crates/fixtures/tests/fixtures_test.rs ModifiedM compiler/forget/crates/fixtures/tests/snapshots/[email protected] ModifiedM compiler/forget/crates/fixtures/tests/snapshots/[email protected] ModifiedM compiler/forget/crates/fixtures/tests/snapshots/[email protected] ModifiedM compiler/forget/crates/fixtures/tests/snapshots/[email protected] ModifiedA compiler/forget/crates/fixtures/tests/snapshots/[email protected] AddedM compiler/forget/crates/hir-ssa/Cargo.toml ModifiedM compiler/forget/crates/hir-ssa/src/enter.rs ModifiedM compiler/forget/crates/hir/src/basic_block.rs ModifiedM compiler/forget/crates/hir/src/function.rs ModifiedM compiler/forget/crates/hir/src/instruction.rs ModifiedM compiler/forget/crates/hir/src/print.rs ModifiedM compiler/forget/crates/hir/src/types.rs Modified
Patch

Files changed

Rendering syntax-highlighted changes…