Change the call to the `Initialize` method in order to forward a
`GraphT` parameter instead of a `NodeRed` one. This is needed so that
external users can pass a node wrapped inside a graph object, that later
the `po_iterator_ext` will unwrap using the `getEntryNode` method.
This way of doing things, has the advantage of enabling us to pass also
nodes wrapped in Filtered GraphTraits, and to operate on them (beacause
the `GraphT` template parameter will be a wrapped object, we can't rely
on `po_iterator_begin` to specify the Graph Traits, because it doesn't
accept a GT template parameter, and therefore the parameter must be of
the same type of the first template parameter, on which type the
GraphTraits will be initialized.
During the RPOT visit used in the weaving pass, ignore the edge
conducting to the `unexpectedpc` basic block, by adding it to the set of
nodes not touched during the rpot computation.
This is done due to the fact that we know a priori that the edge
conduting to the `unexpectedpc` block has been inlined in a
pre-processing phase, and therefore we do not want to explore this part
of the graph.
A better solution would be to just implement the rpot visit over the
same filtered graph.
Add a pre-processing pass that mark as inlined all the edges connecting
the `switch` statements recovered by revng with their default case
pointing to the `UnexpectedPC` block.
Handle the situation in which the immediate post dominator of a
conditional node is the `VirtualRoot` node on the filtered post
dominator tree. In this case, we do not have a correspondent node on the
graph, and so we must handle this situation in an ad-hoc manner.
In this case, we extend the `findReachableNodes` helper function in
order to be able to perform the visit even if the `Target` parameter is
`nullptr`. In this situation, simply, we continue our visit and we
consider every node that as no successors (which means that virtually
the node is connected to the `VirtualRoot` node) as a possible `Target`
for our visit.
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.
We now add every conditional node to the set of node processed by the
`inflate` procedure. The postdom computation done on the inline filtered
postdominator tree should automatically avoid the duplication which was
previosuly prevented by the conditonal blacklisting.
Insert all the conditional nodes in the `ConditionalNodesSet`, in order
to make conditional blacklisting ineffective.
The conditional nodes previously blacklisted should now not generate
duplication thanks to the new way in which the IFPDT is built. In
particular, a node that previously was blacklisted, now should have on
of his successors (or itself) as the immediate postdominator.
Initialize a Filtered PostDomTree, ignoring the inlined edges.
This PostDomTree should be useful to compute the post-dominance taking
into account only the "main" exit path towards the "non-inlined" edges.
Move the standard switches edge tagging out of the weaving procedure, in
a dedicated method, so that the correct functioning of the decompilation
pipeline does not depend on the execution of the weaving.
In this way we can independently disable the weaving.
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.
This commit fixes the detection of the revng-c include file in build
directory, using the PathList facility provided by revng.
Before this commit, running revng-c from build directory failed to
properly identify the revng-c include if it was not already installed
but only available in the build directory itself.
EnforceABI promotes global variables representing parts of the CPU
states to arguments and return values of isolated functions.
This commit enables the promotion of CSV that are used in isolated
functions only indirectly, through `ConstantExpr`s casts.
This helper function is now able to replace also uses that are inside
`ConstantExpr`s.
Before this commit they were not substituted correctly, causing problems
down the decompilation pipeline.
Before this commit, switches were treated as normal conditional nodes.
This was wrong, because treating a switch as a conditional node does not
guarantee that all the parts of the control flow representing each case
are really combed.
This commit removes switch nodes from conditional nodes, and creates a
dummy for each case. All the dummy cases are treated as conditional
nodes inducing duplication separately, instead of the actual switch.
This has the consequence of enabling the combing to proper comb the
switch cases from each other, without altering the combing algorithm.
Each switch case is combed until the combing finds the post-dominator
of the switch, not the post-dominator of the case.
This method was used to sort vector of nodes either in post-order or in
reverse-post-order.
It had 2 problems:
- the boolean argument used to select between POT and RPOT was no longer
used, since all the remaining call sites passed false.
- it was expensive to call, because it took a vector, it created a set
from it, and performed a reverse-post-order-traversal of the whole
graph while pushing the nodes to sort back into a newly allocated
vector. This was particularly problematic because in one of the call
sites a reverse-post-order-traversal was already available, but the
method did calculate a new one nonetheless.
The method is removed in this commit.
All the call sites have been modified to use the
reverse-post-order-traversal object if already available, and they
avoid allocating a new set for the computation and a new vector for the
results. The initialization is now performed directly into a set, and
the sorted results are pushed into a vector. This effectively saves the
allocation of a vector in each call site.
The weaving routine included a check that the candidate node for weaving
was not one of the case blocks of the switch. This check was likely
introduce to mask an old malfunction, caused by a missing update of the
CaseSet data structure, that has since then been removed.
This check was now useless and this commit removes it.
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.