As with other loop opts, we should add a diagnostic product flag to allow us to disable Loop Peeling. This gives us a workaround when Loop Peeling causes problems, allows us to further simplify a graph for debugging purposes when Loop Peeling is not required to trigger a bug, and also possibly enables us to stress loop opts more with different loop shapes (as an addition to StressLoopPeeling).
But we need to be careful and distinguish the different uses of Loop Peeling. We currently have the following uses of Loop Peeling:
1. Part of normal iteration splitting
2. Part of empty loop removal to ensure a zero trip guard
3. Part of maximal unrolling for an iteration count that is a non power of two.
4. Part of creating a loop nest for long counted loops in order to get a safepoint in the outer loop.
There are different ways to approach this:
i. Disable Loop Peeling only for the first case where we decide to apply Loop Peeling as an optimization not as a helper for another optimization.
ii. Disable Loop Peeling entirely, possibly making the loop opts of case 2-4 non-applicable. This might require new bailout paths.
iii. Allow to choose between (i), (ii) or none to be applicable by using different modes for the flag (e.g. integer flag instead of boolean).
[~thartmann] and my suggestion is to go with approach (ii) with only a single boolean flag to turn on/off Loop Peeling completely. Additionally, we could add messages for TraceLoopOpts and other optimization specific trace flags to inform about the non-applicability when Loop Peeling would have been required but it's turned off.
But we need to be careful and distinguish the different uses of Loop Peeling. We currently have the following uses of Loop Peeling:
1. Part of normal iteration splitting
2. Part of empty loop removal to ensure a zero trip guard
3. Part of maximal unrolling for an iteration count that is a non power of two.
4. Part of creating a loop nest for long counted loops in order to get a safepoint in the outer loop.
There are different ways to approach this:
i. Disable Loop Peeling only for the first case where we decide to apply Loop Peeling as an optimization not as a helper for another optimization.
ii. Disable Loop Peeling entirely, possibly making the loop opts of case 2-4 non-applicable. This might require new bailout paths.
iii. Allow to choose between (i), (ii) or none to be applicable by using different modes for the flag (e.g. integer flag instead of boolean).
[~thartmann] and my suggestion is to go with approach (ii) with only a single boolean flag to turn on/off Loop Peeling completely. Additionally, we could add messages for TraceLoopOpts and other optimization specific trace flags to inform about the non-applicability when Loop Peeling would have been required but it's turned off.