Label each BasicBlock with the value it *must* return.
Most frontends that generate bitcode unify all of the return
statements of a function and return a phi node that has a return
value for each branch. This pass (
those returns backwards through the control flow graph as labels on
basic blocks. The function
blockReturn gives the return value
for a block, if there is a value that must be returned by that
The algorithm starts from the return instruction. Non-phi values are propagated backwards to all reachable blocks. Phi values are split and the algorithm propagates each phi incoming value back to the block it came from. A value can be propagated from a block BB to its predecessor block PB if (and only if) BB postdominates PB. Intuitively, the algorithm propagates a return value to a predecessor block if that predecessor block *must* return that value (hence postdominance).
- data BlockReturns
- class HasBlockReturns a where
- labelBlockReturns :: (HasFunction funcLike, HasPostdomTree funcLike, HasCFG funcLike) => funcLike -> BlockReturns
- blockReturn :: HasBlockReturns brs => brs -> BasicBlock -> Maybe Value
- blockReturns :: HasBlockReturns brs => brs -> BasicBlock -> Maybe [Value]
- instructionReturn :: HasBlockReturns brs => brs -> Instruction -> Maybe Value
- instructionReturns :: HasBlockReturns brs => brs -> Instruction -> Maybe [Value]
Label each BasicBlock with the value that it must return (if any).
Retrieve the Value that must be returned (if any) if the given BasicBlock executes.
Builds on the results from
blockReturn and reports *all* of the
values that each block can return (results may not include the
Return the Value that must be returned (if any) if the given Instruction is executed.