Perform the ALAP Variable Declaration process.
The process is structured in the following stages:
- We start by collecting all the `Variable`s that need to be assigned in
a `ASTNode`.
- We build a `GenericGraph` where each `ASTNode` is connected with its
child nodes, and also its immediate successor.
- We perform a walk in post order over this graph, and for each
`ASTNode` we decide if the current node could be the ALAP location
where we can declare the `Variable`, i.e., where we dominate all its
uses.
This commit does various things oriented at reducing the number of local
variables emitted in C:
- MarkAssignments now know that @Copy and @Assign involving
@LocalVariable only have side effects that affect the local variable
itself; this enables to reduce the number of times we're forced to
emit a local variable due to interfering side effects
- Drop the @AssignmentMarker FunctionTag; AddAssignmentMarkerPass now
doesn't emit @AssignmentMarker anymore; instead it emits groups of
@LocalVariable, @Copy, and @Assign, which benefit from the previous
point
- Drop 2 MarkAssignments::Reasons: HasManyUses and HasUsesOutsideOfBB;
both these have now been aggregated into the AlwaysAssign reason for
simplicity, representing all reasons non involving side effects
- Update BeautifyGHAST and how it reasons about side effects when
beautifying; before this commit it used @AssignmentMarker, now it
looks at @Assign
- Simplify ExitSSA; before this commit it was trying hard to be smart on
where it emitted the store instructions representing the incoming
values of the PHI that was being destroyed; this seemed smart when we
originally did it but it generated C code that was not really better
to read, so this useless complexity is finally gone
If we find values to be used outside their scope, we need to always
mark them for assignment, so that they have a dedicated variable that
is declared in the right scope. To do this we:
1. Export the logic that decides if a value needs a top-scope variable
in a public header, to be used by both `VariableScopeAnalysis` and
`MarkAssignments`.
2. Add the `HasUsesOutsideBB` reason for assignment markers
The beautification library was split into a separate library for
historical reason, having to do with LLVM passes, their dependencies,
and dirty hacks we had around.
Now the LLVM passes, and the hacks are gone, so we can merge back
everything together.
Now that the late stage of the decompilation pipeline is managed with
revng-pipeline, and we have a standalone tool for decompilation, we
have no need to use LLVM passes anymore for those stages.
This commit also renames the directories to avoid the confusing Pass
suffix, not what LLVM passes are gone.
This commit replace the old CBackendPass with a standalone tool:
revng-decompile.
This pass at the moment runs the three stages of decompilation:
- CFG restructuring
- Beautify GHAST
- C Code generation
This flag was used with the old C backend to decompile only a single
function from a binary.
The logic of selecting functions in a binary for decompilation is now
part of revng-pipeline, so the -single-decompilation option and the
associated TargetFunctionOption library can be dropped.