Do not mark loop var free blocks as reachable after all -- as we
can't construct SSA for unreachable blocks, this would cause
issues down the line.
Instead add an extra UNREACHABLE_FREE flag and retain only the
FREE instruction during NOP removal. (If we retain all
instructions in the BB we might leave a jump instruction that goes
into the nowhere.)
We need to be careful about correctly handling that undef results
in a null value. Otherwise, apart from simply generating incorrect
results, we may also end up performing non-monotonic lattice
transitions, thus causing an infinite type inference loop (see
test).
Extract a helper function for handling ASSIGN_DIM and ASSIGN_*
with ASSIGN_DIM ev uniformly. Previously the code was copy pasted
for each ASSIGN_* op, but the variable names were not correctly
adjusted (tmp vs orig), so the type inference result was wrong.
Also sligthly improve handling:
* Result cannot be false, will always be converted to array.
* If the dim is a CONST string operand, we don't have to assume
numeric strings.
* If the inserted value may be undef, the array may contain null.
This slightly improves calls to regular function and method calls in cost of a bit slower generator initialization.
Separate call frame for generators, allocated on heap, now created by ZEND_GENERATOR_CREATE instruction.
If the pi target has multiple predecessors, we need to place a
phi there. However it's not possible to express this in terms of
dominance frontiers, so we need to explicitly add it to the phi
set.
This does not yet solve the problem of non-minimal SSA for the
case where the target has multiple predecessors, but dominates
all predecessors (apart from the one creating the pi) -- but
that's an existing issue.
Previously the phi set was first computed during def propagation
and then computed again (per-block) during actual phi placement.
This commit changes this to store the phi set computed during
def propagation.
This makes SSA construction slightly faster (5%), but the main
purpose here is to pave the way for the next commit.
This also fixes a potential issue with the handling of irreducible
loops -- they generated additional phis, but these were not
accounted for in def propagation. (Though I'm not sure if we can
even have any irreducible loops right now.)