Because it's often hard to predict the specific location of an argument when
non-natural alignment is concerned, this adds an extra check allowing
the cases to pass if they would be well-formed if only some pesky
"extra" bytes were to disappear.
Since dwarf sometimes misdetects abi pretty badly, to maintain
the usefulness of the test, it's beneficial to sometimes discard
the "detected" ABI by overriding it by the known value.
This also add a check ensuring that all the functions presents in
the artifact are also present in the binary.
The complicated error handling logic turned out to be more of
a nuisance than a useful debugging tool. This commit removes it
in favour of `revng_abort`'ing or `revng_check`'ing to make sure
the actual state is consistent with the expectations.
It also adds namespace to `std::size_t` mentions.
This introduces `emplace` and `emplace_or_assign` members
allowing population of the container without copying values in.
It also reworks the batch insertion. On top of adding the ability
to move the elements in (without making a copy) and constructing
them in place, it also makes the non-assign version of the inserter
a lot safer by explicitly asserting the fact that while it was
in use no duplicates were added to the vector. Before now,
the duplicates were just silently removed from the container.
It also optimizes the batch insertion somewhat by using non-stable
`std::sort` for unique case as well as replacing `std::unique`
invocation with `std::find_adjacent`.
`getUniqueString` returns a dedup'd char array `GlobalVariable` given a
string. We used to rely on named metadata to dedup them. However, this
lead to issues with `LLVMContainer` cloning and linking.
The new implementation uses the name of the variable as the
de-decuplication key, circumventing the problem entirely and improving
performance.
This commit introduces `BasicBlockID` as the unique identifier for a
`efa::BasicBlock` into the CFG. A `BasicBlockID` is defined by a
`MetaAddress` plus an incremental integer. This enables us to have
multiple instances of the same block in a single function, which is
particularly useful when inlining multiple times the same function.
Apart from this, the commit also does the following:
* It drops representing `MetaAddress`es a `structs` in the IR. This created
several issues related to ABI. We now represent them as strings.
* It defines more functions in `support.h`, instead of defining prototypes
by hand in `CodeGenerator.cpp` and the like. Specifically, `unknownPC`
and `raise_exception_helper`. We also introduce a C "constructor" for
`PlainMetaAddress`.
* It significantly reduces the API of `GeneratedCodeBasicInfo`, which
was supposed to be put on a diet since a long time. Specifically,
many jump target related methods have been moved to free functions in
`IRHelpers.h`. Also `GCBI::getSuccessors` has been pushed into its
only user, `PruneRetSuccessors`, to prevent further usage of a
deprecated API. In the future, it would be nice to drop it entirely.
* It introduces `efa::BasicBlock::InlinedFrom`.
* Introduce an enum to represent named argument indices for `newpc`.
This enables us to more effectively manipulate its argument list.
* It improves the verification and error reporting for
`efa::FunctionMetadata`.
* Update tests.
This commit is preliminary to another piece of work to improve the
generality of inlining beyond the simple "fake function" scenario, for
which the feature was originally conceived.
TrackingContainer is a wrapper around KeyedObjectContainers (notably,
SortedVector) intended to figure out which elements of the underlying
container have been accessed.
`DocumentError`s are the inteded way of propagating errors from the
pipeline to the frontend when a location is required to inform the user
of the error whereabouts.
This commit completes the support of various rare PrimitiveTypes, that
has been added opportunistically over time and has remained inconsistent
across the codebase:
- float80_t
- float96_t
- generic80_t
- generic96_t
The first two are necessary because on some platforms long double is
either 10 or 12 bytes wide.
The second two are necessary because the Generic PrimitiveType should
allow all non-zero byte sizes allowed by any other PrimitiveType.
The architecture-specific pointer (generic register) size is used
instead.
For all the ABIs we support the value of this parameter was already
set to its pointer size. We might need to reintroduce the parameter
in the future if we want to support a super-exotic ABI with different
stack alignment requirements, but that seems highly unlikely.
This also introduces the argument extension helper for one stop all
treating small arguments when they are put into a register or pushed
into the stack.
Use model::Function::Key for the Function rank instead of the naked
MetaAddress as it allows forward-compatibility if the model::Function
key is ever changed.
Use a std::tuple<uint64_t> for TypeField as it's the current type for
{Struct,Enum,Union}Field.key()