`ExprNode` and its child classes use LLVM-style RTTI.
Until now their destruction was not handled properly, causing the
constructor-destructor type mismatch warnings on ASAN.
Despite this all the code was working properly, but just for luck,
because of the fact that these classes are very shallow.
This commit fixes the issue, and allow `ExprNode` and its child classes
to be extended without worrying about wrong destructors being invoked.
Replicate the changes made by this commit
f2a0df309f78e1b5d7c5f81ada5110523644559e perfomed by Pietro on the
branch containing the development fixes for `revng-c`.
Add new headers files (terminating with `BB`, as `BasicBlockNodeBB.h`),
which will be used as the new header files by the users, and which
contain a declaration of the template instantiation, and a `using`
aliasing the instantiation.
This has been made to comply with the `-Wundefined-func-template` flag,
automatically enabled when using `-Weverything`
Added a new attribute for the `ContinueNode`, which tells if a
`ContinueNode` should be considered implicit. An implicit continue node
means that it can be dropped without it altering the semantics of the
code (e.g., when the `continue` is the last statement inside the body of
a cycle).
This attribute enables us to avoid directly dropping the continue node,
which would also cause the computation attached to this node to be
dropped, also in the output of the decompiler pass.
This commit restores the old implementation of `getBasicBlockPC` (which
was changed in an incompatible and wrong way) and fixes the bug the
original change tried to fix: in function isolation, jumping from a
function to a basic block that doesn't start with `newpc` now leads to a
basic block containing an `unreachable`.
Enhanced the `findReachableNodes` algorithm, with a new `StackSet`
parallel data structure which is used to quickly check if we are
encountering a node already on the visit stack.
Modified the `findReachableNodes` to include in the returned set of
nodes also nodes which are encountered on self loop paths and that
should consequently be included in this set.
The new SCS merging criterion, checks that there are no abnormal
retreating nodes between SCS, meaning retreatings which exit from the
current SCS and do not point to the head of another SCS.
This kind of situation, if ignored could cause the introduction of some
cycles between outlined nodes and existing nodes, inserting new cycles
during the restructuring, which is a behavior which we aim to avoid.
When outlining nodes, we now include them in eventual parent metaregions
that included the nodes collapsed.
This should lead to minor duplication (as in the `cp` benchmark), since
we avoid duplicating two times nodes if also the external region causes
the first iteration outlining.
The method which computes the weight for a `BasicBlockNode` now relies
on a new `WeightTraits` which is specialized for `BasicBlock` and for
`DotNode`.
In this way, we can change the implementation of the `getWeight` method
without having to modify the implementation inside the `revng` project.
* Introduce `ShrinkInstructionOperandsPass`: a transformation shrinking
operands and the results of instructions if they are
zero/sign-extended immediately before and after the instruction.
* Introduce `ConstantRangeSet`: similar to `ConstantRange` but allows
disjoint ranges.
* Introduce `MaterializedValue`: a class that can represent a constant
value or a symbol plus offset pair.
* Introduce `DropHelperCallsPass`: a transformation removing calls to
helpers and replacing them with a function call reading the CSVs that
the helper reads and writing the CSVs that the helper writes
(according to CSAA).
* Introduce `DropRangeMetadataPass`: a transformation dropping the
`range` metadata, which, in certain situations, lowers the quality of
the results provided by `LazyValueInfo`.
* Introduce `AdvancedValueInfo`: an analysis exploiting results of
`LazyValueInfo` but collecting them as `ConstantRangeSet` with a
monotone framework. It produces `MaterializedValue`.
* Anticipate linking of helpers: `AVI` requires `CSAA`, which requires
helper functions to be linked in.
* Drop `--no-link`.
* Force x86-64 `DataLayout`.
* Reorganize harvesting to either collect simple literals or go with
(incremental) `AVI`.
* Drop `SET`, `OSRA`, the reaching definition analysis, the
`SimplifyComparisonsPass` and all the sumjump-related code: e now
clone `root`, optimize it and analyze it with `AVI`.
* Temporarily drop the `NoReturnAnalysis`.
* Link `libLLVMInstCombine`, `libLLVMCodeGen` and `libLLVMPasses`.
* Introduce tests for `AdvancedValueInfo`,
`ShrinkInstructionOperandsPass` and `ConstantRangeSet`.
* Fix test results.
* Add `llvm.bswap.i64` and `@pc` to the LLVM template module for unit
tests.
Any stack pointer value greater than or equal to the original one used
to be OK for stack analysis to recognize an instruction as a
return. This commit changes this policy by collecting the value of the
stack pointer on all the return points and, at the end, elect a final
stack pointer value. All non-compliant returns are marked a
`BranchType::BrokenReturn`. The function is now considered fake only if
all the return instructions agree on a specific value of the stack
pointer, and it's lower than the original one.
* Drop `BranchType::IndirectTail`.
* `s/BranchType::FunctionSummary/BranchType::RegularFunction/`.
A series of algorithms working on `llvm::GraphTraits`.
* `nodesBetween` computes the set of nodes on all the paths from a node
A to B.
* Factor out code to iterate over infinite loops into
`exitless_scc_range`.
* Introduce unit tests.
Let the user provide the list of the basic blocks to visit, in a
specific order. This is useful when the same graph has to be visited
multiple times to avoid having `MonotoneFramework` recompute the reverse
post order each time.
* Introduce `KeyContainer::compare` and drop the `getKey` method.
* Let users of ZipMapIterator specify a trait class instead of using the
default one.
* `GeneratedCodeBasicInfo::getCSVUsedByHelperCall` and
`GeneratedCodeBasicInfo::extractCSVs`: make the call argument an
`Instruction`.
* Introduce `blockByName`
* Introduce `getUniqueUser`.
* Fix linking issues.
Implement a new `getWeight` method for the `BasicBlockNode` class.
This method is later used in the `untangle` pass to obtain an estimate
of the weight in terms of original instructions of the node under
analysis.
In case of a collapsed node the method recursively explore all the
collapsed region and return the sum of the weights of the nodes
composing the collapsed region.
Improve the computation of the weight for the nodes between the
immediate postdominator and all the exits from the region.
To do this we exploit the `findReachableNodes` helper function, since at
this point all the exits from the region are connected to the `Sink`
node.
Introduce the untangle pass.
This preprocessing phase is in charge of the untangling optimization.
This optimization searches for conditional node, where, if a branch is
completely inlined (i.e., the entire path until reaching the exit is
duplicated and directly attached to it) we can save duplication in the
combing phase.
The untanle is based on a euristics, which consists of estimating the
duplication that could be introduced by the combing (computing the
weight for the nodes not dominated from the conditional node, of both
branches), with respect to the weight of duplicating the path that will
be inlined (the weight of all the nodes of the branch inlined plus the
weight of the nodes from the immediate postdominator of the conditional
until the exits).
The current implementation of the untangle is very conservative (no
untangle is performed if the `then` and `else` branches share some
nodes, or if there isn't at least one of the two branches which
dominates all the nodes until the postdominator).
The euristics also does not take into consideration the weight for
collapsed nodes.
Implementation of the `comb` algorithm without dominator and
postdominator trees.
The comb now uses a list of nodes kept in reverse postorder (and updated
at each dummy insertion, node duplication and node removal), and various
sets of nodes that contains elements still to eplore under a certain
conditional node, nodes already visited, and so on.
Also the set of immediate post dominator (the point at which the comb
stops during its exploration) is computed only once at the beginning of
the algorithm, and simply kept updated at dummy insertion and removal.
The phase that checked if a conditional node dominates all the nodes
until the postdominator, has been replaced by a check which looks if all
the predecessors of a certain node have been visited during the current
exploration (which is perfomed in reverse postorder). If this condition
does not verify, it means that there is an incoming arc incoming in the
node under analysis which is not dominated by the current conditional
node.
There is still margin for improving the performance of this, this is
only a first implementation.
If the `-decompiled-prefix` is passed to the `revng opt` command the
decompilation pass takes care of serializing the decompiled code of each
function in a different file.
The filename is composed by the prefix string passed as parameter and by
the function name.
To avoid skeing the results the serialization of `DOT` intermediate file
for both restructuring and AST semplification passes are now serialized
only when the corresponding loggers (`CombLogger` and `BeautifyLogger`)
are enabled.
When a retreating edge involves as source node a `SetNode` belonging to
an internal region (which should be the default `SetNode` that remains
outside the collpased node), move it just after the `CheckNode` that is
being introduced, so that the semantics of the code remains untouched.