diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp index fb7bc7c4be6c8..e101943a3f615 100644 --- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp +++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp @@ -231,18 +231,26 @@ static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx, std::swap(DepMatrix[I][ToIndx], DepMatrix[I][FromIndx]); } -// After interchanging, check if the direction vector is valid. +// Check if a direction vector is lexicographically positive. Return true if it +// is positive, nullopt if it is "zero", otherwise false. // [Theorem] A permutation of the loops in a perfect nest is legal if and only // if the direction matrix, after the same permutation is applied to its // columns, has no ">" direction as the leftmost non-"=" direction in any row. -static bool isLexicographicallyPositive(std::vector &DV) { - for (unsigned char Direction : DV) { +static std::optional isLexicographicallyPositive(std::vector &DV, + unsigned Begin, + unsigned End) { + ArrayRef DVRef(DV); + for (unsigned char Direction : DVRef.slice(Begin, End - Begin)) { if (Direction == '<') return true; if (Direction == '>' || Direction == '*') return false; } - return true; + return std::nullopt; +} + +static std::optional isLexicographicallyPositive(std::vector &DV) { + return isLexicographicallyPositive(DV, 0, DV.size()); } // Checks if it is legal to interchange 2 loops. @@ -256,10 +264,19 @@ static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix, // Create temporary DepVector check its lexicographical order // before and after swapping OuterLoop vs InnerLoop Cur = DepMatrix[Row]; - if (!isLexicographicallyPositive(Cur)) + + // If the surrounding loops already ensure that the direction vector is + // lexicographically positive, nothing within the loop will be able to break + // the dependence. In such a case we can skip the subsequent check. + if (isLexicographicallyPositive(Cur, 0, OuterLoopId) == true) + continue; + + // Check if the direction vector is lexicographically positive (or zero) + // for both before/after exchanged. + if (isLexicographicallyPositive(Cur) == false) return false; std::swap(Cur[InnerLoopId], Cur[OuterLoopId]); - if (!isLexicographicallyPositive(Cur)) + if (isLexicographicallyPositive(Cur) == false) return false; } return true;