Count the number of duplication (needed later in the `Mark` pass) right
before the AST generation phase, where the `RegionCFG` will be destroyed
by the tiling matching.
Change the interface of the `findReachableNodes` helper function, so
that now accepts arguments passed by pointer instead of by reference.
Also, the helper function now does not accept a `nullptr` `Source`
parameter.
The `Successors` and `Predecessors` field on the `BasicBlockNode` are
now promoted from being a `std::pair` composed by the pointer to the
successor and the set representing the cases, to a pair between the
pointer to the successor and a new struct called `EdgeInfo`.
This struct is used to contain both the information about the cases, the
information representing whether and edge is inlined or not, and
possibly more information in the future.
Before this commit, the original llvm BasicBlock was not embedded
properly in the GHAST SwitchNodes. This caused problems and crashes in
decompilation.
This commit SwitchNode constructors so the that the BasicBlock properly
reaches the GHAST and it is printed correctly by the decompiler.
Before this commit, the C statements before an IfNode or a SwitchNode
were not guaranteed to be emitted if they were not involved in the
computation of the branch condition.
This commit fixes this problem.
This was broken after the introduction of `SwitchDispatcherNode`,
because
both `SwitchDispatcherNode` and `RegularSwitchNode` used the `isEqual`
method from `SwitchNode`.
Now the `isEqual` method is implemented only for the `ASTNode` base
class, and each leaf of the llvm-RTTI hierarchy of `ASTNode` properly
implements the comparison.
In presence of a switch node, which contains a case made up of
entirely a sequence of empty nodes (simplified by the
`simplifyAtomicSequence` recursive function), enable the removal of the
aforementioned case from the switch node.
This commit removes a call to untangle() that was performed before the
whole combing algorithm on the root RegionCFG.
The call was redundant before introducing the weaving, and became
plainly wrong after adding the weaving, because it ended up trying to
untangle the root RegionCFG before weaving (which is supposed to run
first).
Removing the dedicated call fixes the bug, because weaving is performed
first as part of the call to generateAst().
We now emit `RegularSwitch` node type creating the vector containing the
case values by inspecting the actual values of the `ConstantInt` in the
IR.
Due to the introduction of weaving, we can have a cascade of switches,
and in this case the top switch should bring to a certain weaving switch
for multiple values of the case label.
For this reason, switch case are now represented by sets, which are
usually populated by a single value, but in presence of a weaving
switches they can represent the fact that for each value contained in
the set we must take a certain case label.
The backend of the decompiler has been updated to reflect this change,
in order to emit all the values for a certain `CaseSet` in `or` if the
size of the seat is greater than 1.
Reorganize attribute `Kind` incorporating it into the `Type` attribute,
by lowering its memory footprint.
Modified the constructors, some accessors and helpers accordingly.
Introduced various untangle algorithm improvements:
- Improve untangle edge reorganization: improve the criterion used for
reorganizing the edges between the old postdominator and the cloned
one, after an inline procedure is attempted during the untangle.
- Untangle counter: introduce two new counters which take into account
the number of times the untangle procedure is attempted and the actual
times it is performed.
- Disable not dominated restriction: disable the criterion which
restricts the untangle opportunities if we do not dominate entirely
at least one of the two branches. This has likely broken the
assumption that the postdominators of nodes do not changes after each
untangle step has been carried out.
- Change dominance criterion: the dominance of the nodes belonging to
the `then` and `else` nodes is now checked not with respect to the
conditional node, but to the `then` and `else` edges of the conditional
node.
- Untangle eager inlining: now, when the untangle procedure finds a
suitable candidate for the inlining, proceed the complete inlining
starting from the selected branch. By default new clones of all the
nodes till the exit are created and attached to the branch, while the
original nodes are detached. An additional pass which removes eventual
dandling nodes (nodes which are not reachable from the entry node of
the graph) is performed after the eager inlining. This means that if
no other incoming edges to this group of nodes is present the original
nodes will be purged.
The post dominator now is updated during the inlining analysis, and
the paths conducting to inlined exits are not taken into account for
the post dominator computation.
- Enable untangle for mixed branches: perform the untangle even if the
`then` and `else` branches share nodes. This was not feasible before
because without the eager inlining we couldn't decide which edge to
attach to the new postdominator clone. This problem is not present
anymore, so we can handle any kind of topology in the untangle.
- Improved also the analysis information serialized by the decompiler.
Add a flag to enable the decompilation of a single function.
In order to have a single flag shared between the `RestructureCFGPass`
and the `CDecompilerPass`, we added a new dedicated decompilation unit
called `TargetFunctionOption`.
`ExprNode` and its child classes use LLVM-style RTTI.
Until now their destruction was not handled properly, causing the
constructor-destructor type mismatch warnings on ASAN.
Despite this all the code was working properly, but just for luck,
because of the fact that these classes are very shallow.
This commit fixes the issue, and allow `ExprNode` and its child classes
to be extended without worrying about wrong destructors being invoked.