This is a follow-up to D120386 where we enabled interchange to get the optimal access pattern for multi-level loopnests. But currently loop interchange fails to interchange multi-level loopnests that have reduction operations inside the loopnest. This patch enables interchange of reduction loops with multi-level loopnests, for example the following loopnest should be interchanged three times to get the optimal access pattern:
; Triply nested loop with reduction, should be able to do interchange three times ; to get the ideal access pattern. unsigned f(int e[100][100][100], int f[100][100][100]) { unsigned x = 0; for (int a = 0; a < 100; a++) { for (int b = 0; b < 100; b++) { for (int c = 0; c < 100; c++) { x += e[c][b][a]; } } } return x; }
Currently interchange only supports reduction loops within 2-level loopnests. For loopnests with more than 2-levels like the case above, (after interchanging the b-loop and c-loop) the pass cannot recognize reduction phis and would bail out. This patch adds capability to recognize reduction phis for multi-level loopnests.
[style] https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements
I think the name findInnerReductionPhi implies that the search for the innermost loop happens in that function. Either that, or rename it to findReductionPhi.
findInnerReductionPhi is already a static helper function, you could wrap the new functionality into such a helper function as well.
[serious] This uses InnerMostLoop->getSubLoops().front() even if there are multiple nested loops inside (that hence do not even particpate in the loop interchange). Both loops might participate in the reduction.