Do not inline loop related `break` and `continue` statements.
Indeed, inlining them would mean moving from the scope of a cycle, to an
inner one, non-local control flow statements, and this would break the
semantics.
Delay the `SwitchBreaksFixer` beautify pass run.
Specifically, we run it last, as this pass computes information used
only by the backend, and the information it depends upon may be
invalidated by some passes that transform `switch`es (as the
`simplifyDualSwitch` pass).
Delay as much as possible the loop promotion passes, in order to catch
more opportunities.
Specifically, we now perform the loop promotion after the dual case
`switch` promotion pass.
Before this commit, it could happen that some duplicated dummy node
(used to mark backedges) could be left lingering in wrong regions when
collapsing a regions, if they were first iteration outlined.
This commit fixes the problem, by collecting them and letting
`updateNodes` take care of them, removing them from the containing
region and all its parents.
Before this commit, the DLAStep MergePointeesOfPointerUnion wasn't
really equipped for dealing with LayoutTypeSystemNodes representing
types imported from Model.
There was some code that tried to deal with them but it was mostly an
afterthought and it wasn't robust.
This commit fixes that, and is able to handle a strict superset of the
scenarios envisioned before, while preserving the property that nodes
representing types imported from Model should be preserved (in
particular their size).
Now ModelGEPs emitted by MakeModelGEP always forward the LLVM Type of
the operand representing the base address.
Before this commit they were occasionally using an integer type with the
size of the underlying `model::QualifiedType`, but that is not necessary
and may end up requiring `llvm::IntegerType`s that are very large, to
the point of not being supported by LLVM, for no additional advantage.
Before this commit, initModelTypes could return integers of the wrong
size for IntToPtrInst, whenever the integer being casted to pointer did
not have the exact same size of the pointer on the model.
This commit fixes the problem. Now initModelTypes, even if it might be
forced to return an integer type for IntToPtr, it makes sure that the
size of that integer matches the size of the pointer on the model.
This pass is dedicated to applying a bunch of peephole optimizations
that are useful for decompilation and haven't been implemented in LLVM
for whatever reason.
At the moment it only runs an optimization that tries to reduce the uses
of incoming values of PHINodes, under very specific condidtions, which
enables emitting less LocalVariables.
Before this commit, many passes in revng-c were skipping over
non-isolated functions.
Now revng-pipeline takes care of removing non-isolated functions so that
check can be omitted everywhere.
Over time, these tags have shifted to basically coincide with the Copy
and Assign tags. There's no need for them anymore they just make the
code more verbose and less straightforward.
Before this commit the `hasSideEffects` helper function was only a stub,
that was never updated to be aware of recent FunctionTags representing
custom opcodes without side-effects.
This commit updates it, so that now it is less aggressive in marking
harmless stuff as side-effectful.
This commits changes the ExitSSAPass to ensure that StoreInst are placed
ASAP, close to the computation of the incoming Values of the replaced
PHINode.
This generates IR that typically yields less local variables in
SwitchToStatements.
Various parts of revng replace `llvm::GlobalVariable`s representing CSVs
with Allocal/Load/Store. In particular, these are PromoteCSV,
RootAnalyzer and PromoteGlobalToLocalVars.
Before this commit, those places were sloppy when replacing CSVs with
Alloca/Load/Store, and did that iterating on a container sorted by
pointers. This caused Alloca/Load/Store to be emitted in different order
accross runs, which in turn caused more non-determinism down the
pipeline.
This commit fixes the non-deterministic behavior, sorting CSVs based on
their names, which should always be present and deterministic.
This lets up cleanly "bail out" after only some of the computation
is done. This way we avoid reading information we don't really use
from the model based on who is the specific user of the oracle.