-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Forward blockparams to critical edge blocks #7639
Comments
Specifically, we'll need to move the call to |
Trevor and I were discussing this earlier and I want to note one detail we discussed. There are three interesting kinds of branch edges for this purpose:
If a block has only one successor, we want to go ahead and pass block params along the edge. That successor may have other predecessors, in which case it needs to get different values according to which edge control flow arrived from. For a critical edge, we can move the block params from the original predecessor onto the out-edge of the new block introduced to split the edge; this is the main idea of this issue. But Trevor and I believe that Cranelift currently never has block params on blocks with only one predecessor, because they should be deleted by the We remove constant phis before the egraphs pass, so in theory that pass could break this invariant, but it doesn't currently modify control flow, so we don't believe it could break this today. That said, it's probably worth at least debug-asserting that we only pass block params to the first two kinds of edges. This gets slightly more tedious to implement if single-predecessor blocks can also have block params. (We also discussed that it might be useful to split critical edges before the egraphs pass, so computation which is only used on some branches isn't forced before the branch. And we considered the possibility of only allowing block params on unconditional branches in CLIF generally, forcing frontends to split critical edges. Neither of these is part of this issue or even obviously a good idea, but I wanted to write them down while I'm thinking about them.) |
This lets us stop allocating temporary VRegs for critical edges that have block parameters. That makes the register allocation problem a little smaller, and also allows reusing lower_branch_blockparam_args for all block parameters. Fixes bytecodealliance#7639, and unblocks bytecodealliance/regalloc2#170
Our block lowering order currently inserts new blocks on critical edges to enable register allocation. When these blocks are inserted on edges that targeted blocks with block params, we add block params to the new block, and forward all of its block parameters to the original target through an unconditional branch.
We could simplify this by instead removing the block parameters from the original branch instruction, and adding them only to the block inserted to split the critical edge. We would need to modify the following case in the machinst lowering code, to instead of processing the block params for each branch of a conditional branch, move the processing of those blockparams to the critical edge splitting block.
wasmtime/cranelift/codegen/src/machinst/lower.rs
Lines 1060 to 1073 in 5c8bce7
This should be a fine transformation to make, as the critical edge splitting block will be dominated by the block that defines the values that will be passed through to the blockparams of the original successor.
The text was updated successfully, but these errors were encountered: