Introduce the hybrid beautifier aiming to simplify double `not`s (one on
the IR side (e.g., a `icmp ne`), and one on the `ExprNode` side on the
`GHAST` in the form of a `NotNode`.
To do this hybrid beautifier, we basically need to do the following:
- Implement a preliminary collection phase which computes which
`ExprNode`s are affected by which `BasicBlock`.
- Compute the so-called consesus, i.e., verify that for all the
`ExprNode`s affected by a certain `BasicBlock`, the transformation
would be beneficial in terms of output. Basically:
1) That the number of `!(!=)` transformed into `(==)` outscores the
number of correlated `(!=)` which are transformed into `!(==)`.
2) That the number of `!(==)` transformed into `(!=)` outscores the
number of correlated `(==)` which are transformed into `!(!=)`.
- Actually perform the transformation for those situations where the
consensus agrees.
A bug introduced no loop promotion by mistake, we now correctly exit the
loop promotion routine if the loop has been already promoted to `while`
or `do-while` loop.
Ensure that no backedges are left after the restructuring of all the
metaregions.
This additional assertion should help ensuring that no entries in the
`Backedges` set are left after the restructuring process, in turn making
it easier to spot bugs if backedges references are not handled correctly
during the steps of the restructuring.
Assign a value to cloned and collapsed nodes in terms of shortest path
from entry, which is a criterion we use to elect region entry.
The shortest path is computed at the beginning for the nodes present in
the CFG, but needs to keep updated for additional nodes that we insert
that may become loop entry candidates.
During the creation of the exit dispatcher, take care of removing from
the `Backedges` set the additional backedge that is collapsed in case
two exiting backedges do target the same destination.
When this is not done, a ghost backedge is left inside the set, making
it not coherent with the state of the graph.
In addition, we add an assertion which ensures that during this phase of
the restructuring dummy nodes are present only as source of retreating
edges, and have one and only one successor.
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
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.