The generation of tiles for nodes with two successors was broken for
nodes with two successors because it assumed that at least one of them
was inlined.
This is may not be true in general.
This commit fixes the tile generation for those cases.
Before this commit, outgoing edges from switch nodes were not created
with correct case labels.
For a while we assumed this was fine as long as we fixed them later,
with the tagCaseEdges() method.
However, we didn't realize that adding labels later could not handle
correctly come situation, namely switches with a case that was a set
node followed by a break node to the outermost RegionCFG.
The only way to handle that situation correctly without pattern matching
is to construct the RegionCFG with the correct labels in the first
place.
This is exactly what this commit does.
We now do not generate again the AST for collapsed node that have been
duplicated.
If we encounter a region for which the AST was already generated, we
simply use the already computed AST (also because the tiling now
destroys the `RegionCFG` while it build the AST).
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.
When generating the AST, we now iterate directly on the non-filtered
graph in post order, instead of computing a depth first iteration on the
dominator tree built on the non filtered graph.
Handle the situation where we have 2 successors, and we dominate only 1
node.
This tile can be generated only when we have 2 successors, and one of
this successors is an inlined node. No common postdominator in
contemplated in this tile.
Handle the situation where we have 2 successor nodes, but we only
dominate 1 of them.
This tile can generate different situations, depending on the actual
structure: we can have a diamond shaped region with an inlined edge, we
can have a diamond without the postdominator and no inlined edge.
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.
Under certain conditions, we ended up having code in the ABI IR which
was not reachable. This was due to the fact that a certain instruction
was initially detected as an indirect call, triggering inclusion in the
function of the fallthrough code, and then as a return, which has no
successors within the function.
This commit simply prunes the ABI IR in the finalization method.