Added a pass that removes the `bad_return_pc` check, which is useful
only when we want to preserve semantics, but it is useless and harmful
for decompilation.
Instead of rebuilding the dominator and postdominator at each iteration
of the inflate procedure, use the utilities introduced in LLVM 7.0 to
keep the data structures updated after each change to the RegionCFG.
Now, during the simplification of short-circuits the so called
`de-optimization` is also applied to the corresponding `RegionCFGTree`.
This allows us to avoid loss of information during the iterative
refinement phase, which basically divides for ever the existencies of
two nodes that have been cloned starting from a single original one.
We now perform the AST serialization directly on file, without using
stderr. In this way we can follow the evolution of simplifications and
changes to the AST tree.
After short-circuit simplification, we can have that a conditional node
corresponds to more than one `BasicBlockNode`.
This change reflects this fact, and takes care of merging blocks during
short-circuit simplification, and of representing this change in the
serialization.
Improved the `dumpOnDotFile` function to take as a parameter also a
sub-folder name.
Modified the `inflate` function to dump on file the graphs after each
modification.
Now the `isEqual` operator does what we call a `deep` comparison,
meaning for every type of `ASTNode` it recursively check if the
structures of the AST tree originating in that node can be considered
equivalent (e.g., two sequence nodes are considered equal if every node
they contain is in turn equal).
This operator gives more space to the short-circuit simplification,
which relies heavily on the `isEqual` operator.
First concept of short-circuit simplification.
The `isEqual` operator between ASTNodes is very limited (it does only
check if two nodes originate from the same `BasicBlock` in the original
IR.
Added a new pass that simply purge all the functions in a module from
the useless basic blocks that simply do the `pc` serialization.
Without this until we have available the optimization/comb iterative
refinement, we would not be able to test the short-circuit
simplification.
This commit drops the old FunctionBoundariesDetectionPass and introduces
a new one based on the results provided by the StackAnalysis. A very
similar pass, the ABIDetectionPass, is now available to offer the
results of the ABI analysis too.
These two new passes are a thin shim depending on the appropriate
version of the StackAnalysis (with or withour ABI anlysis) and simply
call `serializeMetadata`, which decorates the LLVM IR with the requested
information.
In addition to drop the old analysis, this commit also isolates the
function boundaries detection pass from `revamb` making it available as
a library only.
This commit does the following:
* It drops `revamb-dump` and transforms all the passes it featured in
passes that can be used directly from `opt`.
* It rename `revamb` to `revng-lift`.
* It introduces a script called `revng` which acts as a driver for the
whole rev.ng project. It replaces `translate`, `revcc`,
`csv-to-ld-options` and `revamb-dump`, since it offers an `opt`
subcommand which allows to easily invoke all the analysis passes.
* It makes the project a CMake package that can be easily used
externally.
* It allows to easily create libraries of analysis to use through
`revng-opt`.
This commit lets the reaching definitions analysis employ results from
the stack analysis to propagate definitions across functions
calls. Specifically, the stack analysis provides a list of registers
that might be clobbered by the callee: definitions concerning those are
not propagated, all the others are propagated.
This change is key to detect jump tables whose address has been
materialized *before* a function call. A test for such situation has
been introduced.
To make this work, the RDA now works over the CFG provided by the
function identification analysis.
The `FunctionCallIdentification` analysis now provides a custom view on
the CFG where 1) dispatcher-related basic blocks are absent, 2) nodes
performing functions calls have an edge to their return address and 3)
nodes ending with a return instruction have no successor.
This CFG is now employed by the reaching definitions analysis and OSRA.
Additionally, the implementation of the `visitSuccessors` and
`visitPredecessors` method has been reviewed. It now consists in a class
that needs to be inherited and for which two methods should be
implemented, one to perform the visit of a block and another one to
enumerate the successors.
In addition, all the users of `visitSuccessors`/`visitPredecessors` have
been updated, a simple set of tests has been introduced and
`GeneratedCodeBasicInfo::visitPredecessors` has been dropped.