1. Hoist the logic to retrieve a model CallEdge from an llvm::CallInst
out of `getCallSitePrototype()`, in a separate `getCallEdge()`
function.
2. Modify `getCallSitePrototype()` so that the parent function's type is
optional.
Inject is meant to inject a model into an `llvm::Module`, but it fails
when operating on a Module that had no model metadata.
This commit fixes the bug.
In order to enable the optimizer to strip dead calls, ModelGEP,
SerializationMarker and AddressOf functions are marked as
`ReadNone` instead of `InaccessibleMemOnly`.
This DLAStep was moving edges improperly before this commit.
In particular, edges were detected solely looking at source and target
edge, not looking at the edge itself. This was leading to wrong results
whenever a node N1 had many outgoing edges to a child node N2, at
different offsets, where all the edges were moved instead of just the
correct ones.
In order to fix this, this commit:
- reworks the logic of `moveEdges`, switching to iterator-based logic
- reworks the struct OrderedChild used internally by
DLAComputeNonInterferingComponents, so that it is also iterator-based
- re-uses common code for field size computation
This commit moves the logic for the computation of field sizes to a
separate .cpp file.
At the moment this is only used by DLAComputeUpperMemberAccess, but in
the future it will also be re-used DLAComputeNonInterferingComponents,
which at the moment employs very similar code.
Before this commit the case where the DLA recovered narrower sizes for
stack arguments than what expected on the Model was not handled
properly.
Now the scenario is handled explicitly, in two ways
- if the DLA recovers a stack argument with struct type, the fields are
copied to the model in the type representing the stack argument;
- if the DLA recovers a stack argument with a type T that is non-struct,
then the type in the model representing that stack argument is a
struct with a single field at offset 0 and type T.
Before this commit, if the DLA was detecting stack sizes that were
smaller than expected by the Model, the size of struct recovered by the
DLA was edited in-place, enlarging it an possibly leading to a
malformed Model.
This commit fixes the problem:
- the size of the stack struct recovered by DLA is not changed
- the fields of the stack struct recovered by DLA are copied inside
inside the Model in the struct representing the stack
This commit fixes a use-after-poison bug.
DLADeduplicateUnionFields::runOnTypeSystem iterates over the DLA graph
while mutating it.
Due to iterations on copies of the edges, there were some edges to dead
nodes that were still hanging around and could be accessed.
This commit fixes the problem by not saving copies of the edges, but
saving LayoutTypeSystemNode * and iterating lazily on the edges starting
from the node itself every time.
In this way, if the graph is mutated, we never have outdated edges
pointing to dead nodes, and we don't have use-after-poison.
Before this commit, this method could not move Inheritance edges to
offsets different than 0.
This commit enables this action. Inheritance edges that are moved to
offset different than 0 become Instance edges.
This commit changes a bunch of methods of LayoutTypeSystem that were
dealing with edge removal and editing.
The previous version was using linear search with std::find_if on the
neighbours.
This commit switches to using std::set::lower_bound and
std::set::upper_bound, exploiting the fact that edges are ordered based
on the address of the target node.
This makes the code more concise and more efficient.
Inheritance edges have a specific semantic that must derive directly
from the binary, and are often treated specially by DLA steps.
For this reason is not correct to inject them late in the pipeline.
This DLA Step works iterating in post-order on a graph while mutating
it. The post-order traversal is done with llvm::post_order, which holds
an iterator to the next children to visit.
Before this commit, the mutation of the graph could invalidate this
iterator.
This commit fixes the iteration logic, by computing the post-order ahead
of time, without holding around iterators that could be invalidated.
This is possible thanks to the fact that the mutation applied by the
DLADeduplicateUnionFields step on the graph do not change the post-order
visit, so the order computed beforehand remains valid throughout all the
computation despite the mutations that could take place.
The assertGetLayoutTypePreConditions methods didn't really need to be
exposed as methods in a header. This commit moves them to static
standalone functions in the only place they're used.
Before this commit, the type parameter of AddressOf calls was
erroneously set to the same type of the associated ModelGEP.
This commit fixes the problem, setting the type parameter of AddressOf
calls to the pointee type.