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 *`.
The condition inside the `IfNode`s are now represented using a custom
`ExprNode` object, which has a new hierarchy of possible nodes present
in an expression (`not`, `and` and `or`).
Moved the `flipEmptyThen` post-processing inside the beautify pass.
The ownership of the `ExprNode` is kept inside the `ASTTree` object.
This means that during the flattening we also need to transfer these
objects and to adjust the pointers inside the `IfNode`s.
Remove the pointer to the corresponding `BasicBlockNode` inside each
`ASTNode`.
We now keep directly a pointer to the original `llvm::BasicBlock`.
To do this we need to explicitly mantain some information, like the
emptyness of the node (dummy node in the `RegionCFG`).
Some little changes (like the way we retrieve the CFGNode corresponding
to an ASTNode) in the flattening have been necessary too.
Add the `IfCheckNode` AST node type, which represents the `Check` nodes
in the RegionCFG. We need an explicit type in the AST since, with the
enforce pass drop before decompilation, we need to handle the code
emission for these type of nodes.
The type has been implemented as a derived type from the `IfNode`, since
they share a lot of similarities, in order to avoid modifications to the
AST simplification functions.
The methods that should not be invoked have been (as the ones that
modify the conditions of the nodes) override and implemented with an
`revng_abort` function
Add a new AST node type for representing the nodes which set the value
for the state variable before an entry or exit dispatcher.
In this way, when printing the decompiled code we do not need to inspect
the node further.
Removed the `Switch` BBNode, which was used to create the intermediates
nodes for making an original `switch` node a nested tree of `if` checks.
Also removed the `IfEqual` AST node, which was used to represent the
intermediate check nodes in the AST, for later reconstructing the
original `Switch` node in the AST, when possible.
Remove from the `IfEqualNode` the reference to the BBNode corresponding
to the original `switch`, since we cannot have the guarantee that this
node will remain allocated in the same place (the pointer could be
invalidated).
Also insert other fixes.
Add a new AST node type for representing the nodes created starting from
the dummy nodes built in place of a `switch` statement.
These nodes contain also the information needed for emitting the code
relative to the checks performed by the node (the condition and the case
value).
This node type inherits from the `IfNode` node type, to avoid
reimplementing all the methods for its handling and transformation.
Add a pass which removes the `unexpectedpc` as successor of the `switch`
instructions. This simplifies the subsequent analyses.
This pass also removes the unreachable basic blocks dandling around (as
the `unexpectedpc` and `anypc` blocks when they are not needed).
When a `while` loop is matched and promoted, add to every `continue`
node in the current scope the instructions needed for the computation of
the loop condition.
Match `do-while` and `while` loops, transform the in our AST preserving the
information about the `IfNode` which computes the condition of loop, and
emit them in the decompiled code.
Also added a pass which removes useless continue nodes.
In certain locations we were using a `std::vector`, taking a reference
to it, adding elements and ending up in a reference invalidation issue.
This commit replaces those `std::vectors` with `std::deque` which do not
present this issue.
This commit introduces the `enforce-abi` pass, which consumes the
information provided by the ABI analysis and enforces them in the
isolated functions adding actual arguments.
This commit also rewrites the logic of `ResultsPool::finalize` and
changes the semantic of `Yes` statements on arguments to `YesOrDead`.
`empty-newpc` is a simple pass suppose to provide an empty body for
the `newpc` function, allowing further optimization pass to take out
all its calls.
`ZipMapIterator` allows you to iterate in parallel over two
`std::map`-like containers.
In the ABI analysis, this allows us to be much more efficient. In
practice, if we have two maps with M and N elements, we pass from
performing N*log(N) + M*log(M) queries to the size of the union of the
set of keys of the two maps.
The `BFSVisitorBase` can go forward and backward starting from a certain
instruction. When going backward, it used to skip the starting
instruction.
For simmetry purposes, this commit changes that.
In the stack analysis, we used to consider helper functions as indirect
calls. However, the `CPUStateAccessAnalysis` provides us accurate
information about what an helper function does.
This commit transforms calls to helper functions in a series of ABI IR
instructions reading all the input registers of the helper functions and
a series of instructions writing the output registers.
Note that, while this is a serious improvement over considering them
indirect function calls, it's still suboptimal since
`CPUStateAccessAnalysis` doesn't provide us information as fine-grained
as the ABI analysis.
Previously, to enumerate all the CSVs we had to go through the
`GlobalVariable` of a `Module` and see if the were being used in
rev.ng-generated code.
Now we have a named metadata for that: `revng.csv`.
We used to save the type of a block in the `revng.block.type` metadata
as a number. This commit serializes it as a string.
In order to do this, the `BlockType` enum has been promoted to a
namespace with the usual `getName` and `fromName` functions.
`LazySmallBitVector` was lacking a comparison operator, which prevented
it from being used as the key of a `std::map`.
This commit implements such operator, along with the `reserve` method.
`extern` declarations of template specializations for Logger<true> and
Logger<false> caused weak symbols to be emitted in librevngSupport.so
and into its users.
Dynamic loading then failed because both symbols were weak.
This commit removes the `extern` declarations so that dynamic loading
succeeds.