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.
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.
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.
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.
Implement the DAGify pass. This pass, using the results exposed by the
`GenericRegionInfo` analysis, transforms all the retreating edges of
each identified `GenericRegion`, processed in a bottom-up fashion, into
a `goto` edge on the `ScopeGraph`.