r352526 - [OPENMP]Make the loop with unsigned counter countable.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 29 10:51:58 PST 2019


Author: abataev
Date: Tue Jan 29 10:51:58 2019
New Revision: 352526

URL: http://llvm.org/viewvc/llvm-project?rev=352526&view=rev
Log:
[OPENMP]Make the loop with unsigned counter countable.

According to the report, better to keep the original strict compare
operation as the loop condition with unsigned loop counters to make the
loop countable. This allows further loop transformations.

Modified:
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/for_codegen.cpp
    cfe/trunk/test/OpenMP/ordered_codegen.cpp
    cfe/trunk/test/OpenMP/parallel_for_codegen.cpp

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=352526&r1=352525&r2=352526&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Tue Jan 29 10:51:58 2019
@@ -4008,6 +4008,8 @@ public:
   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
   /// True if the step should be subtracted.
   bool shouldSubtractStep() const { return SubtractStep; }
+  /// True, if the compare operator is strict (<, > or !=).
+  bool isStrictTestOp() const { return TestIsStrictOp; }
   /// Build the expression to calculate the number of iterations.
   Expr *buildNumIterations(
       Scope *S, const bool LimitedType,
@@ -4080,7 +4082,8 @@ bool OpenMPIterationSpaceChecker::setLCD
   return false;
 }
 
-bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, llvm::Optional<bool> LessOp,
+bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
+                                        llvm::Optional<bool> LessOp,
                                         bool StrictOp, SourceRange SR,
                                         SourceLocation SL) {
   // State consistency checking to ensure correct usage.
@@ -4647,10 +4650,12 @@ Expr *OpenMPIterationSpaceChecker::build
   if (VarType->isIntegerType() || VarType->isPointerType() ||
       SemaRef.getLangOpts().CPlusPlus) {
     // Upper - Lower
-    Expr *Upper =
-        TestIsLessOp.getValue() ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
-    Expr *Lower =
-        TestIsLessOp.getValue() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
+    Expr *Upper = TestIsLessOp.getValue()
+                      ? Cnt
+                      : tryBuildCapture(SemaRef, UB, Captures).get();
+    Expr *Lower = TestIsLessOp.getValue()
+                      ? tryBuildCapture(SemaRef, LB, Captures).get()
+                      : Cnt;
     if (!Upper || !Lower)
       return nullptr;
 
@@ -4686,6 +4691,9 @@ Expr *OpenMPIterationSpaceChecker::build
 
 /// Iteration space of a single for loop.
 struct LoopIterationSpace final {
+  /// True if the condition operator is the strict compare operator (<, > or
+  /// !=).
+  bool IsStrictCompare = false;
   /// Condition of the loop.
   Expr *PreCond = nullptr;
   /// This expression calculates the number of iterations in the loop.
@@ -4892,6 +4900,7 @@ static bool checkOpenMPIterationSpace(
   ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
   ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
   ResultIterSpace.Subtract = ISC.shouldSubtractStep();
+  ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp();
 
   HasErrors |= (ResultIterSpace.PreCond == nullptr ||
                 ResultIterSpace.NumIterations == nullptr ||
@@ -5139,8 +5148,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
   // This is helper routine for loop directives (e.g., 'for', 'simd',
   // 'for simd', etc.).
   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
-  SmallVector<LoopIterationSpace, 4> IterSpaces;
-  IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount));
+  SmallVector<LoopIterationSpace, 4> IterSpaces(
+      std::max(OrderedLoopCount, NestedLoopCount));
   Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
   for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
     if (checkOpenMPIterationSpace(
@@ -5446,25 +5455,55 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
     }
   }
 
-  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
+  bool UseStrictCompare =
+      RealVType->hasUnsignedIntegerRepresentation() &&
+      llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
+        return LIS.IsStrictCompare;
+      });
+  // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
+  // unsigned IV)) for worksharing loops.
   SourceLocation CondLoc = AStmt->getBeginLoc();
+  Expr *BoundUB = UB.get();
+  if (UseStrictCompare) {
+    BoundUB =
+        SemaRef
+            .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
+                        SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
+            .get();
+    BoundUB =
+        SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
+  }
   ExprResult Cond =
       (isOpenMPWorksharingDirective(DKind) ||
        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
-          ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
+          ? SemaRef.BuildBinOp(CurScope, CondLoc,
+                               UseStrictCompare ? BO_LT : BO_LE, IV.get(),
+                               BoundUB)
           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
                                NumIterations.get());
   ExprResult CombDistCond;
   if (isOpenMPLoopBoundSharingDirective(DKind)) {
-    CombDistCond =
-        SemaRef.BuildBinOp(
-            CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get());
+    CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
+                                      NumIterations.get());
   }
 
   ExprResult CombCond;
   if (isOpenMPLoopBoundSharingDirective(DKind)) {
+    Expr *BoundCombUB = CombUB.get();
+    if (UseStrictCompare) {
+      BoundCombUB =
+          SemaRef
+              .BuildBinOp(
+                  CurScope, CondLoc, BO_Add, BoundCombUB,
+                  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
+              .get();
+      BoundCombUB =
+          SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
+              .get();
+    }
     CombCond =
-        SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
+        SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
+                           IV.get(), BoundCombUB);
   }
   // Loop increment (IV = IV + 1)
   SourceLocation IncLoc = AStmt->getBeginLoc();
@@ -5541,7 +5580,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
   SourceLocation DistIncLoc = AStmt->getBeginLoc();
   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
   if (isOpenMPLoopBoundSharingDirective(DKind)) {
-    DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
+    DistCond = SemaRef.BuildBinOp(
+        CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
     assert(DistCond.isUsable() && "distribute cond expr was not built");
 
     DistInc =
@@ -5565,10 +5605,24 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin
     PrevEUB =
         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
 
-    // Build IV <= PrevUB to be used in parallel for is in combination with
-    // a distribute directive with schedule(static, 1)
+    // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
+    // parallel for is in combination with a distribute directive with
+    // schedule(static, 1)
+    Expr *BoundPrevUB = PrevUB.get();
+    if (UseStrictCompare) {
+      BoundPrevUB =
+          SemaRef
+              .BuildBinOp(
+                  CurScope, CondLoc, BO_Add, BoundPrevUB,
+                  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
+              .get();
+      BoundPrevUB =
+          SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
+              .get();
+    }
     ParForInDistCond =
-        SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.get());
+        SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
+                           IV.get(), BoundPrevUB);
   }
 
   // Build updates and final values of the loop counters.

Modified: cfe/trunk/test/OpenMP/for_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_codegen.cpp?rev=352526&r1=352525&r2=352526&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/for_codegen.cpp Tue Jan 29 10:51:58 2019
@@ -203,7 +203,8 @@ void dynamic1(float *a, float *b, float
 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
 
 // CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
   for (unsigned long long i = 131071; i < 2147483647; i += 127) {
 // CHECK: [[LOOP1_BODY]]
@@ -244,7 +245,8 @@ void guided7(float *a, float *b, float *
 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
 
 // CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
   for (unsigned long long i = 131071; i < 2147483647; i += 127) {
 // CHECK: [[LOOP1_BODY]]

Modified: cfe/trunk/test/OpenMP/ordered_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_codegen.cpp?rev=352526&r1=352525&r2=352526&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/ordered_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/ordered_codegen.cpp Tue Jan 29 10:51:58 2019
@@ -78,7 +78,8 @@ void dynamic1(float *a, float *b, float
 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
 
 // CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
   for (unsigned long long i = 131071; i < 2147483647; i += 127) {
 // CHECK: [[LOOP1_BODY]]

Modified: cfe/trunk/test/OpenMP/parallel_for_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_codegen.cpp?rev=352526&r1=352525&r2=352526&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_codegen.cpp Tue Jan 29 10:51:58 2019
@@ -197,7 +197,8 @@ void dynamic1(float *a, float *b, float
 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
 
 // CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
   for (unsigned long long i = 131071; i < 2147483647; i += 127) {
 // CHECK: [[LOOP1_BODY]]
@@ -239,7 +240,8 @@ void guided7(float *a, float *b, float *
 // CHECK: [[IV:%.+]] = load i64, i64* [[OMP_IV]]
 
 // CHECK-NEXT: [[UB:%.+]] = load i64, i64* [[OMP_UB]]
-// CHECK-NEXT: [[CMP:%.+]] = icmp ule i64 [[IV]], [[UB]]
+// CHECK-NEXT: [[BOUND:%.+]] = add i64 [[UB]], 1
+// CHECK-NEXT: [[CMP:%.+]] = icmp ult i64 [[IV]], [[BOUND]]
 // CHECK-NEXT: br i1 [[CMP]], label %[[LOOP1_BODY:[^,]+]], label %[[LOOP1_END:[^,]+]]
   for (unsigned long long i = 131071; i < 2147483647; i += 127) {
 // CHECK: [[LOOP1_BODY]]




More information about the cfe-commits mailing list