We used to mark call to noreturn functions as killers, but this is not
correct.
Note that this is a temporary solution, we need to explicitly handle
such situations.
Generated code now either jumps to `anypc` or `unexpectedpc`. The latter
one is to be considered a safety measure and will be populated with an
unreachable instruction on the decompilation pipeline.
This commit makes `PCH::getUniqueJumpTarget` more robust:
1. We bail out only if we find a non-constant write to a field of
`MetaAddress` for which we already have a value. Before, any
non-constant write would lead to bailing out.
2. In case we meet an helper, we now bail out only if we didn't saw any
write to a portion of the `MetaAddress`.
This commit extracts a plain `struct` from the `MetaAddress` class. This
enables us to use `MetaAddress` from C and therefore, runtime.
The definition of such `struct`, `PlainMetaAddress`, is in
`PlainMetaAddress.h`, which is included by `early-linked.c`.
A function to print the content of a `PlainMetaAddress` has also been
introduced.
Also, anticipating the linkage of `early-linked.c` triggered a
superflous assertion in `CPUStateAccessAnalysis`. This commit removes
it.
* Introduce GCBI::buildDispatcher
* Introduce GCBI::getJumpTarget{,Block} and GCBI::getBlocksGeneratedByPC
to easily map `BasicBlock *` to jump targets and viceversa.
* PCH::buildDispatcher now returns a list of the newly created basic
blocks.
* Other minor changes
This function was intended to check that backedges are entirely enclosed
inside metaregions, i.e. that we cannot have a backedge jumping from a
metaregion to an outer or an inner one.
Before this commit, the assertion was tautological.
When DLA is activated, a larger variety of combinations between integers
and pointers operands need to be handled when emitting C code from LLVM
Instructions.
This commit removes some assertions that do not hold anymore about some
operands not being pointers, handles a set of new cases with strange
mixtures of pointer and integer operands, and introduces a fail path for
cases that are not handled when emitting code based on DLA results.
Before this commit, we assumed that given a Value V, if only a single
entry was found for in ValueLayouts, it meant that is was a scalar type.
This assumption was wrong, because it could be a struct type for which
we didn't have information about memory access for all fields but one.
This caused some struct type to be wrongly identified as scalar types.
This commit fixes the issue.
Before this commit, the creation of layouts in the DLA was very
aggressive, treating almost every instruction as if it could be an
address (hence creating a layout for it).
This commit adds assertions and narrows down the number of cases where
an instruction is actually considered an address.
Specifically, the following kinds of instructions are not considered
addresses anymore:
- Mul
- SDiv
- UDiv
- SRem
- URem
- AShr
- LShr
- Shl
- And
- Xor
- Or
Before this commit, we assumed integer-to-pointer casts were only
widening, never narrowing.
Turns out this is not true. For instance, narrowing casts happen when
decompiling s390x code.
With this commit, the decompiler can handle that case gracefully.
A logical bug prevented to properly identify some leaf Values in SCEVs
as base addresses, restricting such Value leaves to only be CallInst to
isolated Functions.
This commit fixes this bug and enables to identify base addresses that
are not CallInst.
This commit is just a skeleton. In order to actually build those member
accesses, we still need to compute the proper nested dla::Layouts for
which we want to emit those member accesses.
This commit fixes a bug due to interacting behaviors between
MarkForSerialization, AddSCEVBarrierPass, and the emission in C of calls
to revng_init_local_sp.
These interacting behaviors caused the following quirks:
- At the beginning of Functions that contained a call to
`revng_init_local_sp()`, that call was actually emitted twice.
The first time was due to the actual call to `revng_init_local_sp()`,
while the second was due to the first call being wrapped from a call
to `revng_scev_barrier_*`.
Now we properly emit only one call.
- The original call to `revng_init_local_sp()` was supposed to generate
a local variable, to be used in various places across the function.
However, due to the fact that the call was not properly labeled by
MarkForSerialization, there was no local variable, causing calls to
`revng_init_local_sp()` to be scattered around the body of the
functions, follwed by various arithmetic operations.
This behavior has been fixed as well, and we now emit the local
variable correctly.
Before this commit, the DLA code made very strong assumptions about
Functions that returned struct types.
In particular, calls to such Functions were expected to have at most a
number of uses equal to the number of fields of the returned struct.
Moreover, such uses were only expected to be ExtractValueInst.
Now, we still assume that such uses are ExtractValueInst, but we don't
make any strong assumption on their number anymore.
This makes the DLA code less reliant on specific form of LLVM IR, so we
can also drop -gvn-hoist from the decompilation test pipeline.
This commit introduces a new LatticeElement for the
MarkAnalysis::Analysis MonotoneFramework.
Before this it used a IntersectionMonotoneSet.
This commit extends the set transforming it into a map, that holds the
set of Instructions with side-effects that taint each pending
instruction.
This is not used yet. The behavior is identical to the old one.
It will be used in future commits to prevent serialization when
possible, to increase the quality of emitted C code, thanks to the fact
that serializing less instructions means less local variables in C.