Drop the `MaterializeLoopScopes` pass after the re-design the loop
matching stage to work entirely on `clift`, without the need to insert a
`scope_closer` edge to guide the emission.
Simultaneously, drop the DAGify `Head` metadata insertion, since it will
not be checked anymore during the `MaterializeLoopScopes` pass.
We now ensure that even in case of blocks disconnected from the entry,
the `isDAG` function still search for loops in such parts of the graph.
This is achieved by instantiating multiple `scc_iterator` on the blocks
composing the underlying `Graph`.
During the `Head` election phase, we now introduce the following
additional criterion:
When processing a `GenericRegion` nested into an outer one (its
`ParentRegion`), if the inner `Region` contains the block that has been
elected as `Head` of the `ParentRegion`, we also force that block to be
the `Head` of the inner `GenericRegion`.
We add a unit test to check this behavior.
The `MaterializeLoopScopes` is a scope-inducing transformation, with the
goal of inserting a `scope_closer` edge targeting the immediate post
dominator, outside each `GenericRegion`, in order to materialize the
scope representing the body of each `GenericRegion` on the `ScopeGraph`.
Perform the abnormal (late) entries normalization in the DAGify pass.
In this way, we are exploiting the information computed by
`GenericRegionInfo` as close as possible to where it is computed the
first time (in DAGify).
Actualize the unit tests to reflect these changes.
Introduce a consistency check for loops having an empty body and not
being `DoWhile`s (the only type of empty loops admitted) before they
reach the serialization backend.
When attempting to simplify away a dummy that simply connects a
Predecessor and a Successor, fail if Predecessor and Successor are
already connected.
In order to handle such failure, we need to decorate a lot of function
on the stack trace in order to be able to propagate the failure code.
We now reduce the number of cases in which we restart the collection of
the `DivergenceDescriptor`s after a IDS modification on the `ScopeGraph`
is performed.
We previously restarted the collection after each IDS transformation.
Now, restart is only performed after IDS is applied on a `Conditional`
node whose all successors are divergent exits which are `goto` exits.
After such `Conditional` is processed, it may happen that a new `goto`
exit becomes divergent for another `Conditional` upwards in the
`ScopeGraph`.
Therefore, if we do not restart, it may happen that a non-`goto` exit is
processed before a `goto` exit, which may lead to suboptimal situations
in the emitted number of `goto`s, due to how IDS interacts with
`MaterializeTrivialGotos`.
When performing the IDS procedure for a divergence which is entered
through multiple `Successor`s of the `Conditional`, we insert a `Head`
header which collects the entry to the scope, in order to maintain
decidedness if there is a common post-dominator to all the `Successor`s
(similar to what weaving did).
Perform the IDS transformation, by taking into account possible multiple
divergent scopes for a certain conditional node at the same time.
This reduces the run times, since it reduces the number of time IDS is
called on a conditional, but mostly proceduce a more _compact_
`ScopeGraph`, where all the divergent scopes for a certain conditional
node rejoing the path toward the one true exit in a single point,
instead of having a chain of IDS resulting regions.
Make IDS unit tests compliant with the new multiple divergence
implementation.