pick up your "const_fold_datafold_parent" tool that you used for unrolling tailloops. It takes as input a dataflow parent and a constant value for each output wire of the internal input node, and returns as output a constant value for each input wire of the internal output node. Of course your notion of constant value must be large enough to contain "unknown".
[A] for a CFG, collect a constant value for each input wire of the CFG node. Apply "const_fold_dataflow_parent" to the entry block using the constant values of the CFG inputs. Now you have a constant value for each input wire of the output node of the entry block.
Consider the tag of the constant value for the control (first) wire the output node of the entry block.
If it is unknown, we cannot proceed.
If it corresponds to the Exit node, we can replace the whole CFG with a DFG containing the entry node(we must modify it a little, fixing up the control output by inserting a conditional that panics in all but the appropriate tag, where it forwards the contents of the sum).
If it corresponds to a non-exit block B:
Insert a DFG before the CFG containing a copy of the entry block, with the same fixup as before.
Inside the CFG: swap the entry node and B (control flow edges change as well to target the same block as before). Change the inputs of the CFG node to match the outputs of the new DFG. These are guaranteed to be the same as the inputs of B. If B is the entry node, this step is the identity.
goto [A], using the constant values we obtained from [A] last time. Be careful to guard here against infinite unrolling.
How to unroll a CFG:
pick up your "const_fold_datafold_parent" tool that you used for unrolling tailloops. It takes as input a dataflow parent and a constant value for each output wire of the internal input node, and returns as output a constant value for each input wire of the internal output node. Of course your notion of constant value must be large enough to contain "unknown".
[A] for a CFG, collect a constant value for each input wire of the CFG node. Apply "const_fold_dataflow_parent" to the entry block using the constant values of the CFG inputs. Now you have a constant value for each input wire of the output node of the entry block. Consider the tag of the constant value for the control (first) wire the output node of the entry block.