This commit:
1. Introduces an alloca for stack arguments of a function. This enables
us to "write" to stack argument. In order to do so, we simply map the
relevant stack portion to the alloca that, since it's a memory
object, can be `load`'d from and `store`'d to.
Note that `llvm::Argument`s are always scalar since if the original
argument was an aggregate, it would have been passed as a pointer,
which is a scalar.
Note also that previously we were using scalar arguments as if they
were *pointers* to the stack arguments. This commit fixes that too
(and updates the tests accordingly).
2. Introduces an alloca for *scalar* stack arguments of a call site.
The alloca is then mapped to the corresponding part of the stack.
Previously, there was no redirection and negative offsets from
`_stack_frame` would pop up.
This commit splits in two stages handleCallSite and
handleMemoryAccess. Running the latter after all the call sites have
been handled, is necessary in order to properly replace certain memory
accesses targeting stack arguments of a call site.
This commit:
* Introduces `_` as a prefix for all non-user entities we emit in
decompiled code.
Also, some names have been changed to be more concise.
Specifically, the following entities have changed:
`_ENUM_UNDERLYING`, `_ABI`, `_REG`, `_padding_at_`,
`_artificial_struct_`, `_artificial_wrapper_`, `_stack`,
`_break_from_loop_`, `_var_`, `_stack_arguments`,
`_artificial_struct_returned_`, `_enum_max_value_`.
* Introduce _PACKED for `__attribute__((packed))`.
* `EnumEntry` name: drop the `EnumType` name prefix.
Before this commit, we were only copying the metadata attached to the
CallInst, but we need to copy also the attributes, otherwise we might
lose important information, such as `nomerge`.
We were not properly handling functions with a `CABIFunctionType` whose
return value covered multiple registers (e.g., a `uint64_t` being
returned through two registers in i386).
Also, we were not correctly handling `CABIFunctionType` returning a
integer type that is smaller than the register containing it (e.g., a
`uint32_t` being returned through `rax` in x86-64).
This commit fixes both situations.
If a function was returning a scalar, we used to forward the return type
from before Segregate. However, this was not OK in case a return value
was in a 64-bit register, but was actually using only the lower 32-bits.
This commit improves handling of such situation.
This commit enables to emit accesses with the square bracket array
access operator on pointers.
This is accomplished by adding an additional mandatory argument to
ModelGEP (AND NOT to ModelGEPRef) to represent this case.
MakeModelGEPPass is updated to take this into account, together with all
the other passes that handle ModelGEPs.
In SegregateStackAccesses sometimes we have to replace a call whose call
type does not match the callee type. Specifically when the return type
is a `StructType`, sometimes the call returns an identical `StructType`,
but with a different identity.
This commit adapts the return type of new calls on the fly.
SegregateStackAccesses creates new functions. Iterating over existing
functions while creating new ones is problematic, so we now first
collect all the functions we want to inspect and then process them.
SegregateStackAccesses and PromoteStackPointer were not handling
functions declarated (but not defined) properly.
This commit fixes this, in part by adopting `TaggedFunctionPass`.
Before this commit, calls were marked to push ALAP in the wrong order,
resulting in preventing to actually push them ALAP.
This commit fixes the ordering, reactivating the code motion.
Before this commit, we did not take into consideration that
revng_call_stack_arguments has reference semantics, and we were using
its AddressOf in call sites that were taking the stack arguments.
This commit fixes the problem, bypassing the call to AddressOf when
passing the arguments to calls.
This commit handles the situation in which we have a call site with
stack arguments, but it was not possible to determine the stack height
at the call site.
The solution is to simply ignore stack arguments and emit in the IR a
warning.
Add `ReadOnly` and `InaccessibleMemOnly` attributes to the following
functions:
- `revng_stack_frame`
- `revng_call_stack_arguments`
- `ModelGEP`
- `AddressOf`
This prevents `CSE` from grouping together any of these calls, while
still enabling `DCE` to remove calls that are not used.
Before this commit, SegregateStackAccessesPass always expected to find
calls stack_size_at_call_site markers injected by
InjectStackSizeProbesAtCallSitesPass.
This is not always true, because aggressive LLVM optimizations can
remove dead code.
As an example, if the user or some analysis earlier in the pipeline
wrongly marks registers as non-arguments, the optimization pipeline will
throw away and eliminate everything that descends from the initial
values of those registers.
This commit enables SegregateStackAccessesPass to cope with calls to
stack_size_at_call_site that were eliminated, and keep going just
considering the calls that are still there.