Author: abataev
Date: Wed May 16 06:36:30 2018
New Revision: 332467

URL: http://llvm.org/viewvc/llvm-project?rev=332467&view=rev
Log:
[OPENMP, NVPTX] Add check for SPMD mode in orphaned parallel directives.

If the orphaned directive is executed in SPMD mode, we need to emit the
check for the SPMD mode and run the orphaned parallel directive in
sequential mode.

Modified:
    cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
    cfe/trunk/test/OpenMP/nvptx_target_codegen.cpp

Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp?rev=332467&r1=332466&r2=332467&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp Wed May 16 06:36:30 2018
@@ -96,6 +96,8 @@ enum OpenMPRTLFunctionNVPTX {
   /// Call to uint16_t __kmpc_parallel_level(ident_t *loc, kmp_int32
   /// global_tid);
   OMPRTL_NVPTX__kmpc_parallel_level,
+  /// Call to int8_t __kmpc_is_spmd_exec_mode();
+  OMPRTL_NVPTX__kmpc_is_spmd_exec_mode,
 };
 
 /// Pre(post)-action for different OpenMP constructs specialized for NVPTX.
@@ -220,8 +222,7 @@ class CheckVarsEscapingDeclContext final
                "Parameter captured by value with variably modified type");
         EscapedParameters.insert(VD);
       }
-    } else if (VD->getType()->isAnyPointerType() ||
-               VD->getType()->isReferenceType())
+    } else if (VD->getType()->isReferenceType())
       // Do not globalize variables with reference or pointer type.
       return;
     if (VD->getType()->isVariablyModifiedType())
@@ -317,8 +318,18 @@ public:
       return;
     if (D->hasAssociatedStmt()) {
       if (const auto *S =
-              dyn_cast_or_null<CapturedStmt>(D->getAssociatedStmt()))
+              dyn_cast_or_null<CapturedStmt>(D->getAssociatedStmt())) {
+        // Do not analyze directives that do not actually require capturing,
+        // like `omp for` or `omp simd` directives.
+        llvm::SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
+        getOpenMPCaptureRegions(CaptureRegions, D->getDirectiveKind());
+        if (CaptureRegions.size() == 1 &&
+            CaptureRegions.back() == OMPD_unknown) {
+          VisitStmt(S->getCapturedStmt());
+          return;
+        }
         VisitOpenMPCapturedStmt(S);
+      }
     }
   }
   void VisitCapturedStmt(const CapturedStmt *S) {
@@ -1411,6 +1422,12 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntime
     RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_parallel_level");
     break;
   }
+  case OMPRTL_NVPTX__kmpc_is_spmd_exec_mode: {
+    // Build int8_t __kmpc_is_spmd_exec_mode();
+    auto *FnTy = llvm::FunctionType::get(CGM.Int8Ty, /*isVarArg=*/false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_is_spmd_exec_mode");
+    break;
+  }
   }
   return RTLFn;
 }
@@ -1828,7 +1845,9 @@ void CGOpenMPRuntimeNVPTX::emitNonSPMDPa
       RCG(CGF);
     } else {
       // Check for master and then parallelism:
-      // if (is_master) {
+      // if (__kmpc_is_spmd_exec_mode()) {
+      //  Serialized execution.
+      // } else if (is_master) {
       //   Worker call.
       // } else if (__kmpc_parallel_level(loc, gtid)) {
       //   Serialized execution.
@@ -1837,13 +1856,22 @@ void CGOpenMPRuntimeNVPTX::emitNonSPMDPa
       // }
       CGBuilderTy &Bld = CGF.Builder;
       llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".exit");
+      llvm::BasicBlock *SPMDCheckBB = CGF.createBasicBlock(".spmdcheck");
       llvm::BasicBlock *MasterCheckBB = CGF.createBasicBlock(".mastercheck");
       llvm::BasicBlock *ParallelCheckBB =
           CGF.createBasicBlock(".parallelcheck");
+      llvm::Value *IsSPMD = Bld.CreateIsNotNull(CGF.EmitNounwindRuntimeCall(
+          createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_is_spmd_exec_mode)));
+      Bld.CreateCondBr(IsSPMD, SPMDCheckBB, MasterCheckBB);
+      CGF.EmitBlock(SPMDCheckBB);
+      SeqGen(CGF, Action);
+      CGF.EmitBranch(ExitBB);
+      CGF.EmitBlock(MasterCheckBB);
+      llvm::BasicBlock *MasterThenBB = CGF.createBasicBlock("master.then");
       llvm::Value *IsMaster =
           Bld.CreateICmpEQ(getNVPTXThreadID(CGF), getMasterThreadID(CGF));
-      Bld.CreateCondBr(IsMaster, MasterCheckBB, ParallelCheckBB);
-      CGF.EmitBlock(MasterCheckBB);
+      Bld.CreateCondBr(IsMaster, MasterThenBB, ParallelCheckBB);
+      CGF.EmitBlock(MasterThenBB);
       L0ParallelGen(CGF, Action);
       CGF.EmitBranch(ExitBB);
       // There is no need to emit line number for unconditional branch.

Modified: cfe/trunk/test/OpenMP/nvptx_target_codegen.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/nvptx_target_codegen.cpp?rev=332467&r1=332466&r2=332467&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/nvptx_target_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/nvptx_target_codegen.cpp Wed May 16 06:36:30 2018
@@ -561,6 +561,16 @@ int baz(int f, double &a) {
   // CHECK: [[F_PTR:%.+]] = getelementptr inbounds 
%struct._globalized_locals_ty, %struct._globalized_locals_ty* [[REC_ADDR]], i32 
0, i32 0
   // CHECK: store i32 %{{.+}}, i32* [[F_PTR]],
   // CHECK: store i32 [[GTID]], i32* [[GTID_ADDR]],
+
+  // CHECK: [[RES:%.+]] = call i8 @__kmpc_is_spmd_exec_mode()
+  // CHECK: icmp ne i8 [[RES]], 0
+  // CHECK: br i1
+
+  // CHECK: call void @__kmpc_serialized_parallel(%struct.ident_t* @{{.+}}, 
i32 [[GTID]])
+  // CHECK: call void [[OUTLINED:@.+]](i32* [[GTID_ADDR]], i32* [[ZERO_ADDR]], 
i32* [[F_PTR]], double* %{{.+}})
+  // CHECK: call void @__kmpc_end_serialized_parallel(%struct.ident_t* 
@{{.+}}, i32 [[GTID]])
+  // CHECK: br label
+
   // CHECK: icmp eq i32
   // CHECK: br i1
 


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to