Module ullbc_to_llbc

Source
Expand description

ULLBC to LLBC

We reconstruct the control-flow in the Unstructured LLBC.

The reconstruction algorithm is not written to be efficient (its complexity is probably very bad), but it was not written to be: this is still an early stage and we want the algorithm to generate the best reconstruction as possible. We still need to test the algorithm on more interesting examples, and will consider making it more efficient once it is a bit mature and well tested. Also note that we more importantly focus on making the algorithm sound: the reconstructed program must always be equivalent to the original MIR program, and the fact that the reconstruction preserves this property must be obvious.

Finally, we conjecture the execution time shouldn’t be too much a problem: we don’t expect the translation mechanism to be applied on super huge functions (which will be difficult to formally analyze), and the MIR graphs are actually not that big because statements are grouped into code blocks (a block is made of a list of statements, followed by a terminator - branchings and jumps can only be performed by terminators -, meaning that MIR graphs don’t have that many nodes and edges).

StructsΒ§

BlockInfo πŸ”’
Small utility
BlockWithRank πŸ”’
BlocksInfo πŸ”’
Information used to compute the switch exits. We compute this information for every block in the graph. Note that we make sure to use immutable sets because we rely a lot on cloning.
CfgInfo πŸ”’
This structure contains various information about a function’s CFG.
ExitInfo πŸ”’
The exits of a graph
FilteredLoopParents πŸ”’
LoopExitCandidateInfo πŸ”’
Transform

EnumsΒ§

GotoKind πŸ”’

FunctionsΒ§

block_is_error πŸ”’
The terminator of the block is a panic, etc.
block_is_switch πŸ”’
build_cfg_info πŸ”’
Build the CFGs (the β€œregular” CFG and the CFG without backward edges) and compute some information like the loop entries and the switch blocks.
build_cfg_partial_info_edges πŸ”’
can_reach_outer_exit πŸ”’
Auxiliary helper
compute_loop_exit_candidates πŸ”’
Compute the loop exit candidates.
compute_loop_exits πŸ”’
See compute_loop_switch_exits for explanations about what β€œexits” are.
compute_loop_switch_exits πŸ”’
Compute the exits for the loops and the switches (switch on integer and if … then … else …). We need to do this because control-flow in MIR is destructured: we have gotos everywhere.
compute_switch_exits πŸ”’
See compute_loop_switch_exits for explanations about what β€œexits” are.
compute_switch_exits_explore πŸ”’
Compute BlocksInfo for every block in the graph. This information is then used to compute the switch exits.
filter_loop_parents πŸ”’
get_goto_kind πŸ”’
is_terminal πŸ”’
Return true if whatever the path we take, evaluating the statement necessarily leads to:
is_terminal_explore πŸ”’
is_terminal_explore_block πŸ”’
list_reachable πŸ”’
List the nodes reachable from a starting point. We list the nodes and the depth (in the AST) at which they were found.
loop_entry_is_reachable_from_inner πŸ”’
Check if a loop entry is reachable from a node, in a graph where we remove the backward edges going directly to the loop entry.
make_ord_block_id πŸ”’
Create an OrdBlockId from a block id and a rank given by a map giving a sort (topological in our use cases) over the graph.
opt_block_unwrap_or_nop πŸ”’
register_children_as_loop_exit_candidates πŸ”’
Register a node and its children as exit candidates for a list of parent loops.
translate_block πŸ”’
Remark: some values are boxed (here, the returned statement) so that they are allocated on the heap. This reduces stack usage (we had problems with stack overflows in the past). A more efficient solution would be to use loops to make this code constant space, but that would require a serious rewriting.
translate_body πŸ”’
translate_body_aux πŸ”’
translate_child_block πŸ”’
parent_span: we need some span data for the new statement. We use the one for the parent terminator.
translate_statement πŸ”’
translate_terminator πŸ”’

Type AliasesΒ§

Cfg πŸ”’
Control-Flow Graph
FlowBlockId πŸ”’
For the rank we use:
OrdBlockId πŸ”’