[llvm-branch-commits] [cfe-branch] r288048 - Merging r287227:

Alexey Bataev via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Nov 28 09:55:43 PST 2016


Author: abataev
Date: Mon Nov 28 11:55:42 2016
New Revision: 288048

URL: http://llvm.org/viewvc/llvm-project?rev=288048&view=rev
Log:
Merging r287227:
------------------------------------------------------------------------
r287227 | abataev | 2016-11-17 15:12:05 +0000 (Thu, 17 Nov 2016) | 4 lines

[OPENMP] Fixed codegen for 'omp cancel' construct.

If 'omp cancel' construct is used in a worksharing construct it may
cause hanging of the software in case if reduction clause is used. Patch fixes this problem by avoiding extra reduction processing for branches that were canceled.
------------------------------------------------------------------------

Modified:
    cfe/branches/release_39/   (props changed)
    cfe/branches/release_39/lib/CodeGen/CGStmtOpenMP.cpp
    cfe/branches/release_39/lib/CodeGen/CodeGenFunction.h
    cfe/branches/release_39/test/OpenMP/cancel_codegen.cpp

Propchange: cfe/branches/release_39/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Nov 28 11:55:42 2016
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:275880,275967,276102,276350,276361,276473,276653,276716,276887,276891,276900,276979,276983,277095,277138,277141,277221,277307,277522,277743,277783,277796-277797,277852,277866,277889,277900,278139,278156,278234-278235,278393,278395,278763,278786,278988,280672,284110,284229,286103,286106,286129,286584,286944,286953,287025
+/cfe/trunk:275880,275967,276102,276350,276361,276473,276653,276716,276887,276891,276900,276979,276983,277095,277138,277141,277221,277307,277522,277743,277783,277796-277797,277852,277866,277889,277900,278139,278156,278234-278235,278393,278395,278763,278786,278988,280672,284110,284229,286103,286106,286129,286584,286944,286953,287025,287227
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_39/lib/CodeGen/CGStmtOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/CodeGen/CGStmtOpenMP.cpp?rev=288048&r1=288047&r2=288048&view=diff
==============================================================================
--- cfe/branches/release_39/lib/CodeGen/CGStmtOpenMP.cpp (original)
+++ cfe/branches/release_39/lib/CodeGen/CGStmtOpenMP.cpp Mon Nov 28 11:55:42 2016
@@ -1767,17 +1767,11 @@ void CodeGenFunction::EmitOMPOuterLoop(b
   EmitBlock(LoopExit.getBlock());
 
   // Tell the runtime we are done.
-  SourceLocation ELoc = S.getLocEnd();
-  auto &&CodeGen = [DynamicOrOrdered, ELoc](CodeGenFunction &CGF) {
+  auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) {
     if (!DynamicOrOrdered)
-      CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
+      CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
   };
-  CodeGen(*this);
-
-  OpenMPDirectiveKind DKind = S.getDirectiveKind();
-  if (DKind == OMPD_for || DKind == OMPD_parallel_for ||
-      DKind == OMPD_distribute_parallel_for)
-    OMPCancelStack.back().CodeGen = CodeGen;
+  OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
 }
 
 void CodeGenFunction::EmitOMPForOuterLoop(
@@ -1889,11 +1883,12 @@ void CodeGenFunction::EmitOMPDistributeO
 void CodeGenFunction::EmitOMPDistributeParallelForDirective(
     const OMPDistributeParallelForDirective &S) {
   OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
-  OMPCancelStackRAII CancelRegion(*this);
   CGM.getOpenMPRuntime().emitInlinedDirective(
       *this, OMPD_distribute_parallel_for,
       [&S](CodeGenFunction &CGF, PrePostActionTy &) {
         OMPLoopScope PreInitScope(CGF, S);
+        OMPCancelStackRAII CancelRegion(CGF, OMPD_distribute_parallel_for,
+                                        /*HasCancel=*/false);
         CGF.EmitStmt(
             cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
       });
@@ -2082,15 +2077,10 @@ bool CodeGenFunction::EmitOMPWorksharing
                          [](CodeGenFunction &) {});
         EmitBlock(LoopExit.getBlock());
         // Tell the runtime we are done.
-        SourceLocation ELoc = S.getLocEnd();
-        auto &&CodeGen = [ELoc](CodeGenFunction &CGF) {
-          CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
+        auto &&CodeGen = [&S](CodeGenFunction &CGF) {
+          CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
         };
-        CodeGen(*this);
-        OpenMPDirectiveKind DKind = S.getDirectiveKind();
-        if (DKind == OMPD_for || DKind == OMPD_parallel_for ||
-            DKind == OMPD_distribute_parallel_for)
-          OMPCancelStack.back().CodeGen = CodeGen;
+        OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
       } else {
         const bool IsMonotonic =
             Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static ||
@@ -2140,11 +2130,11 @@ void CodeGenFunction::EmitOMPForDirectiv
   bool HasLastprivates = false;
   auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
                                           PrePostActionTy &) {
+    OMPCancelStackRAII CancelRegion(CGF, OMPD_for, S.hasCancel());
     HasLastprivates = CGF.EmitOMPWorksharingLoop(S);
   };
   {
     OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
-    OMPCancelStackRAII CancelRegion(*this);
     CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
                                                 S.hasCancel());
   }
@@ -2187,7 +2177,6 @@ void CodeGenFunction::EmitSections(const
   bool HasLastprivates = false;
   auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF,
                                                     PrePostActionTy &) {
-    OMPCancelStackRAII CancelRegion(CGF);
     auto &C = CGF.CGM.getContext();
     auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
     // Emit helper vars inits.
@@ -2282,12 +2271,10 @@ void CodeGenFunction::EmitSections(const
     CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
                          [](CodeGenFunction &) {});
     // Tell the runtime we are done.
-    SourceLocation ELoc = S.getLocEnd();
-    auto &&FinalCodeGen = [ELoc](CodeGenFunction &CGF) {
-      CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
+    auto &&CodeGen = [&S](CodeGenFunction &CGF) {
+      CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd());
     };
-    FinalCodeGen(CGF);
-    CGF.OMPCancelStack.back().CodeGen = FinalCodeGen;
+    CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
     CGF.EmitOMPReductionClauseFinal(S);
     // Emit post-update of the reduction variables if IsLastIter != 0.
     emitPostUpdateForReductionClause(
@@ -2309,6 +2296,7 @@ void CodeGenFunction::EmitSections(const
     HasCancel = OSD->hasCancel();
   else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
     HasCancel = OPSD->hasCancel();
+  OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel);
   CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
                                               HasCancel);
   // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
@@ -2412,7 +2400,7 @@ void CodeGenFunction::EmitOMPParallelFor
   // Emit directive as a combined directive that consists of two implicit
   // directives: 'parallel' with 'for' directive.
   auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
-    OMPCancelStackRAII CancelRegion(CGF);
+    OMPCancelStackRAII CancelRegion(CGF, OMPD_parallel_for, S.hasCancel());
     CGF.EmitOMPWorksharingLoop(S);
   };
   emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen);
@@ -3412,14 +3400,14 @@ void CodeGenFunction::EmitOMPCancelDirec
 
 CodeGenFunction::JumpDest
 CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
-  if (Kind == OMPD_parallel || Kind == OMPD_task)
+  if (Kind == OMPD_parallel || Kind == OMPD_task ||
+      Kind == OMPD_target_parallel)
     return ReturnBlock;
   assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
          Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
-         Kind == OMPD_distribute_parallel_for);
-  if (!OMPCancelStack.back().ExitBlock.isValid())
-    OMPCancelStack.back().ExitBlock = getJumpDestInCurrentScope("cancel.exit");
-  return OMPCancelStack.back().ExitBlock;
+         Kind == OMPD_distribute_parallel_for ||
+         Kind == OMPD_target_parallel_for);
+  return OMPCancelStack.getExitBlock();
 }
 
 // Generate the instructions for '#pragma omp target data' directive.

Modified: cfe/branches/release_39/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/CodeGen/CodeGenFunction.h?rev=288048&r1=288047&r2=288048&view=diff
==============================================================================
--- cfe/branches/release_39/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/branches/release_39/lib/CodeGen/CodeGenFunction.h Mon Nov 28 11:55:42 2016
@@ -965,33 +965,92 @@ private:
   };
   SmallVector<BreakContinue, 8> BreakContinueStack;
 
-  /// Data for exit block for proper support of OpenMP cancellation constructs.
-  struct OMPCancel {
-    JumpDest ExitBlock;
-    llvm::function_ref<void(CodeGenFunction &CGF)> CodeGen;
-    OMPCancel() : CodeGen([](CodeGenFunction &CGF) {}) {}
+  /// Handles cancellation exit points in OpenMP-related constructs.
+  class OpenMPCancelExitStack {
+    /// Tracks cancellation exit point and join point for cancel-related exit
+    /// and normal exit.
+    struct CancelExit {
+      CancelExit() = default;
+      CancelExit(OpenMPDirectiveKind Kind, JumpDest ExitBlock,
+                 JumpDest ContBlock)
+          : Kind(Kind), ExitBlock(ExitBlock), ContBlock(ContBlock) {}
+      OpenMPDirectiveKind Kind = OMPD_unknown;
+      /// true if the exit block has been emitted already by the special
+      /// emitExit() call, false if the default codegen is used.
+      bool HasBeenEmitted = false;
+      JumpDest ExitBlock;
+      JumpDest ContBlock;
+    };
+
+    SmallVector<CancelExit, 8> Stack;
+
+  public:
+    OpenMPCancelExitStack() : Stack(1) {}
+    ~OpenMPCancelExitStack() = default;
+    /// Fetches the exit block for the current OpenMP construct.
+    JumpDest getExitBlock() const { return Stack.back().ExitBlock; }
+    /// Emits exit block with special codegen procedure specific for the related
+    /// OpenMP construct + emits code for normal construct cleanup.
+    void emitExit(CodeGenFunction &CGF, OpenMPDirectiveKind Kind,
+                  const llvm::function_ref<void(CodeGenFunction &)> &CodeGen) {
+      if (Stack.back().Kind == Kind && getExitBlock().isValid()) {
+        assert(CGF.getOMPCancelDestination(Kind).isValid());
+        assert(CGF.HaveInsertPoint());
+        assert(!Stack.back().HasBeenEmitted);
+        auto IP = CGF.Builder.saveAndClearIP();
+        CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
+        CodeGen(CGF);
+        CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
+        CGF.Builder.restoreIP(IP);
+        Stack.back().HasBeenEmitted = true;
+      }
+      CodeGen(CGF);
+    }
+    /// Enter the cancel supporting \a Kind construct.
+    /// \param Kind OpenMP directive that supports cancel constructs.
+    /// \param HasCancel true, if the construct has inner cancel directive,
+    /// false otherwise.
+    void enter(CodeGenFunction &CGF, OpenMPDirectiveKind Kind, bool HasCancel) {
+      Stack.push_back({Kind,
+                       HasCancel ? CGF.getJumpDestInCurrentScope("cancel.exit")
+                                 : JumpDest(),
+                       HasCancel ? CGF.getJumpDestInCurrentScope("cancel.cont")
+                                 : JumpDest()});
+    }
+    /// Emits default exit point for the cancel construct (if the special one
+    /// has not be used) + join point for cancel/normal exits.
+    void exit(CodeGenFunction &CGF) {
+      if (getExitBlock().isValid()) {
+        assert(CGF.getOMPCancelDestination(Stack.back().Kind).isValid());
+        bool HaveIP = CGF.HaveInsertPoint();
+        if (!Stack.back().HasBeenEmitted) {
+          if (HaveIP)
+            CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
+          CGF.EmitBlock(Stack.back().ExitBlock.getBlock());
+          CGF.EmitBranchThroughCleanup(Stack.back().ContBlock);
+        }
+        CGF.EmitBlock(Stack.back().ContBlock.getBlock());
+        if (!HaveIP) {
+          CGF.Builder.CreateUnreachable();
+          CGF.Builder.ClearInsertionPoint();
+        }
+      }
+      Stack.pop_back();
+    }
   };
-  SmallVector<OMPCancel, 8> OMPCancelStack;
+  OpenMPCancelExitStack OMPCancelStack;
 
   /// Controls insertion of cancellation exit blocks in worksharing constructs.
   class OMPCancelStackRAII {
     CodeGenFunction &CGF;
 
   public:
-    OMPCancelStackRAII(CodeGenFunction &CGF) : CGF(CGF) {
-      CGF.OMPCancelStack.push_back({});
-    }
-    ~OMPCancelStackRAII() {
-      if (CGF.HaveInsertPoint() &&
-          CGF.OMPCancelStack.back().ExitBlock.isValid()) {
-        auto CJD = CGF.getJumpDestInCurrentScope("cancel.cont");
-        CGF.EmitBranchThroughCleanup(CJD);
-        CGF.EmitBlock(CGF.OMPCancelStack.back().ExitBlock.getBlock());
-        CGF.OMPCancelStack.back().CodeGen(CGF);
-        CGF.EmitBranchThroughCleanup(CJD);
-        CGF.EmitBlock(CJD.getBlock());
-      }
+    OMPCancelStackRAII(CodeGenFunction &CGF, OpenMPDirectiveKind Kind,
+                       bool HasCancel)
+        : CGF(CGF) {
+      CGF.OMPCancelStack.enter(CGF, Kind, HasCancel);
     }
+    ~OMPCancelStackRAII() { CGF.OMPCancelStack.exit(CGF); }
   };
 
   CodeGenPGO PGO;

Modified: cfe/branches/release_39/test/OpenMP/cancel_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/test/OpenMP/cancel_codegen.cpp?rev=288048&r1=288047&r2=288048&view=diff
==============================================================================
--- cfe/branches/release_39/test/OpenMP/cancel_codegen.cpp (original)
+++ cfe/branches/release_39/test/OpenMP/cancel_codegen.cpp Mon Nov 28 11:55:42 2016
@@ -92,7 +92,7 @@ for (int i = 0; i < argc; ++i) {
 }
 // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
 int r = 0;
-#pragma omp parallel for reduction(+:r)
+#pragma omp parallel for reduction(+: r)
 for (int i = 0; i < argc; ++i) {
 #pragma omp cancel for
   r += i;




More information about the llvm-branch-commits mailing list