Do not inline loop related `break` and `continue` statements.
Indeed, inlining them would mean moving from the scope of a cycle, to an
inner one, non-local control flow statements, and this would break the
semantics.
Implement a new beautify pass which simplifies away `SwitchBreakNode`s
that constitute the entire body of `case`s in `switch`es, that do not,
have a `default` case. In such situations indeed, the semantics is,
preserved by removing the `SwitchBreakNode`s.
We drop the assumption that each weaved `switch` must be nested inside
its related main `switch`, as a consequence of having generalized the
tiling algorithm in order to be able to emit a weaved `switch` as a AST
successors of the related main `switch`.
Perform a complete rewrite of the `SwitchNode` tiling routine.
The tiling now works in the following way:
- When encountering a node which will produce a `SwitchNode` (either a
standard `switch` or a dispatcher `switch`), we look for the following
situations:
1) We have a node, a successor (case) of the `switch`, which in turn
is the successor of all the other successors (cases) of the
`switch`.
2) We have a node, not a successor (case) of the `switch`, which is
the successor of all the successors (cases) of the `switch`.
- If we find such candidate node, this node will be the fallthrough of
the `switch`. In addition, depending on whether the `switch` dominates
the candidate fallthrough, we can incorporate it as the immediate
successor of the `SwitchNode` we are building.
- There is currently an exception to the above, due to how we currently
handle weaved `switch`es. In such cases, we mandate that the weaved
`switch` is nested inside the main corresponding `switch`. For this
reason, we have a special casing handling the "all inlined but one"
situation in the new code, while this part could in theory be merged
in the common criterion below, at the cost of dropping the invariant
of the nesting of weaved switch`es.
Simplify `switch` cases that are simplified away during the dispatcher
`switch` inlining beautify.
Usually, we can simplify ast nodes by replacing them with `nullptr`s,
but due to how the `switch` cases work, we need to handle them in a
custom way.
We introduce the `InlineDispatcherSwitch` beautify pass. Its goal is to
try and inline the body of some of the `case`s of a exit dispatcher, in
place of the `SetNode` corresponding to that `case`, if this doesn't
introduce duplication in the code (i.e., a single `SetNode` for that
specific case value is present).
Additionally, if the inlining procedure is able to completely remove the
necessity of an exit dispatcher altogether, the pass removes it.
The pass is able to handle chains of weaved dispatcher `switch`es
referring to the same original dispatcher `switch`, by handling the
inline operation and the possible simplification level-wise.
The inlining procedure, cannot take place if a `SetNode` is contained in
the body of the case we are trying to inline, since this can possibly
break the semantics of the state variable of a loop, by placing a
`SetNode` in a more internal loop.