The `Head` election now works in a bottom-up fashion (child regions are
processed before the parent ones), and ensures that the `Head` election
process is coherent across multiple nested regions.
This means that:
1) The late entries are coherent between the nested regions. If a node
is selected as a late entry for a region, the parent region must
follow this decision too.
2) If a node which is a `Head` candidate for a parent region, is
selected as the `Head` for a child region, the same choice must be
performed for the parent region too.
Before this commit the port number was incorrectly increased when there
were no arguments in a function type, causing edges to be routed in a
less accurate way.
This commit fixes the problem.
This uses the "rank=source" feature of graphviz, that allows to select
what are the nodes with mimimal rank in a graph.
We use this to mark all the nodes that represent functions and segments
so that the graph layout is more deterministic and readable across
multiple runs when the input Model is very similar.
Add another container for LLVM modules. This one stores one
`llvm::Module` per function (all modules share the same
`llvm::LLVMContext` for performance reasons).
In the constructor of `InitRevng` also call all the `llvm::initialize*`
functions. This is done to be less implementation-specific and having
these functions be called in
`LLVMPipelineRegistry.libraryInitialization`.
`/` is now supported in names except for the parts of the model that use
the name as the key, i.e., `DynamicFunction` and `LocalIdentifier`.
Eventually, `/` should be allowed there as well, but we first need to
make sure that when they end up in a location they are properly
escaped/unescaped.
LLVM purges loads from `nullptr` in functions not marked with
`null_pointer_is_valid`. This can lead to uninitialized accesses to tiny
code variables, which in turn lead to cross-`TranslationBlock` phis
which can prevent argumentless outlining.
Adding to the `root` function the `null_pointer_is_valid` attribute
fixes this problem.
With this commit, the `simplifyTerminator` helper function used by IDS
stops trying to merge the default cases with one of the other cases
arbitrarily.
Now, if the `UnreachableSuccessor` was reached via the default case, the
default case is still arbitrarily redirected to an arbitrary case
successor, but the case and the default do not get merged.
This keeps the logic of the transform simpler, and also allows for
easier successive manipulation by planned upcoming transforms.