[OpenMP] Prepare Sema for initial implementation for pragma 'distribute parallel for'

https://reviews.llvm.org/D29922

This patch adds two fields for use in the implementation of 'distribute parallel for':

The increment expression for the distribute loop. As the chunk assigned to a team is executed by multiple threads within the 'parallel for' region, the increment expression has to correspond to the value returned by the related runtime call (for_static_init).
The upper bound of the innermost loop ('for' in 'distribute parallel for') is not the globalUB expression normally used for pragma 'for' when found in isolation. It is instead the upper bound of the chunk assigned to the team ('distribute' loop). In this way, we prevent teams from executing chunks assigned to other teams.
The use of these two fields can be see in a related explanatory patch:
https://reviews.llvm.org/D29508

llvm-svn: 295497
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 458ba3a..8711505 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4181,6 +4181,36 @@
       return 0;
   }
 
+  // Create: increment expression for distribute loop when combined in a same
+  // directive with for as IV = IV + ST; ensure upper bound expression based
+  // on PrevUB instead of NumIterations - used to implement 'for' when found
+  // in combination with 'distribute', like in 'distribute parallel for'
+  SourceLocation DistIncLoc;
+  ExprResult DistCond, DistInc, PrevEUB;
+  if (isOpenMPLoopBoundSharingDirective(DKind)) {
+    DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
+    assert(DistCond.isUsable() && "distribute cond expr was not built");
+
+    DistInc =
+        SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
+    assert(DistInc.isUsable() && "distribute inc expr was not built");
+    DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
+                                 DistInc.get());
+    DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
+    assert(DistInc.isUsable() && "distribute inc expr was not built");
+
+    // Build expression: UB = min(UB, prevUB) for #for in composite or combined
+    // construct
+    SourceLocation DistEUBLoc;
+    ExprResult IsUBGreater =
+        SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
+    ExprResult CondOp = SemaRef.ActOnConditionalOp(
+        DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
+    PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
+                                 CondOp.get());
+    PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
+  }
+
   // Build updates and final values of the loop counters.
   bool HasErrors = false;
   Built.Counters.resize(NestedLoopCount);
@@ -4295,6 +4325,8 @@
   Built.NUB = NextUB.get();
   Built.PrevLB = PrevLB.get();
   Built.PrevUB = PrevUB.get();
+  Built.DistInc = DistInc.get();
+  Built.PrevEUB = PrevEUB.get();
 
   Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
   // Fill data for doacross depend clauses.