The `RegionCFG::initialize` method is now a template method, which
accepts as input any kind of object which exposes the `GraphTraits`.
In this way we can build a `RegionCFG` object not only starting from
LLVM IR, which can be very useful for testing purpose.
Since we also removed the information about the original
`llvm::BasicBlock` inside the `BasicBlockNode`, we need to keep this
link to later feed this information to the GHAST in an external data
structure (potentially a `std::map`).
The `BasicBlockNode` does not contain anymore any pointer to the
`llvm::BasicBlock` object that generated the `BasicBlockNode`.
This change is necessary for decoupling completely the `BasicBlockNode`
and `RegionCFG` classes from the LLVM IR, so that we can build up a
`RegionCFG` from any object which implements the `GraphTraits`.
The `RegionCFG` does not contain anymore a map between
`llvm::BasicBlock` and `BasicBlockNode`.
Once we compute the set of backedges, they should be fixed and should
not change during the restructuring phase, otherwise we may end-up
inserting loops including outlined node if the information about the
backedges changes completely during the analysis (edge that were
backedges and for which a corresponding SCS was computed become forward
edges, and viceversa, and this behaviors break our assumptions that
outlined node do not take part in loops ever).
This means that we need to keep updated the set of backedges computed at
the beginning instead of recomputing it at each restructuring iteration.
We need to take particular care in updating the information in presence
of the default `SetNode` inserted in case of an entry dispatcher.
The actual implementation is pretty naive, and the update of the
`Backedges` `std::set` is for sure not optimal, we should consider using
a `std::multimap` for it.
We should also consider updating the reverse postorder instead of
recomputing it, but at it seems that recomputing it may cause
sub-optimal restructuring, but no errors should be triggered.
This commit enlarges the set of external function calls we
detect. Basically, instead of assuming that the instruction jumping to
the external function is the call, we now also consider instructions in
previous basic blocks, as long as there's only one possible path
backward.
This commit improves the output of `--help` and reduces the output of
`--version`. This commit, when calling `opt`, injects a `LD_PRELOAD`
for `libasan.so` in case a `librevng*.so` library uses it.
Match correctly `IfCheckNodes` which have only the `then` or `else`
branch, that may appear due to conditional nodes blacklisting (the not
identified branch becomes the fallthrough branch).
New SCS merge step for situations in which we have an abnormal edge
exiting from an SCS.
This criterion, during the preprocessing of the metaregions, if an SCS
with an abnormal retreating edge is found (an abnormal retreating is a
retreating edge which target is outside the scope of the current SCS
under analysis), merges the metaregion under analysis with the one which
has been created starting from the backedge.
This preprocessing phase is made in a fixed point fashion.
When creating the collapsed node, remember to add in the substitution
phase of the old nodes of the regions (relative to the outer regions),
also any nodes added as default `SetNode`s for any entry dispatcher
inserted.
Add an assert which verify that all the targets of the retreating edges
fall inside the SCS under analysis.
Add other asserts to verify that the graphs passed to the comb pass are
acyclic after restructuring.
The `removeNotReachables` method now can take care of removing any
reference of the removed nodes from any `MetaRegion` which contains any
reference to it.
Now avoiding `predecessors()` iterator invalidation and enforcing
bounds check when using `ClonedMap` during first iteration outlining.
Also avoiding usage of `FirstCandidate` once the real head of a
`RegionCFG` has been elected (only `Head` ptr should be used).
We add an additional check for the conditional nodes blacklisting,
meaning that we need to verify that we dominates at least 1 of the
reachable sets for each branch departing from the conditional node.
`ClassSentinel` makes use of an undefined behavior to check if an object
has been destroyed. Disable this check in case of presence of address
sanitizer or even regular optimizations.
We now match the `IfCheckNode` trees created by the dispatchers
insertion as an unique switch.
To this we introduced a new `SwitchCheckNode` AST type, which cannot
inherith from the `SwitchNode` since the underlying container for the
`case`s is different (the index is saved as an `unsigned`, while instead
in the `SwitchNode` we use a `ConstantInt *`.