/// \brief Emits code for OpenMP parallel directive in the parallel region. static void EmitOMPParallelCall(CodeGenFunction &CGF, const OMPParallelDirective &S, llvm::Value *OutlinedFn, llvm::Value *CapturedStruct) { if (auto C = S.getSingleClause(/*K*/ OMPC_num_threads)) { CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); auto NumThreadsClause = cast<OMPNumThreadsClause>(C); auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(), /*IgnoreResultAssign*/ true); CGF.CGM.getOpenMPRuntime().EmitOMPNumThreadsClause( CGF, NumThreads, NumThreadsClause->getLocStart()); } CGF.CGM.getOpenMPRuntime().EmitOMPParallelCall(CGF, S.getLocStart(), OutlinedFn, CapturedStruct); }
void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto CapturedStruct = GenerateCapturedStmtArgument(*CS); auto OutlinedFn = CGM.getOpenMPRuntime().EmitOpenMPOutlinedFunction( S, *CS->getCapturedDecl()->param_begin()); if (auto C = S.getSingleClause(/*K*/ OMPC_if)) { auto Cond = cast<OMPIfClause>(C)->getCondition(); EmitOMPIfClause(*this, Cond, [&](bool ThenBlock) { if (ThenBlock) EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct); else CGM.getOpenMPRuntime().EmitOMPSerialCall(*this, S.getLocStart(), OutlinedFn, CapturedStruct); }); } else EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct); }
void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt()); llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS); llvm::Value *OutlinedFn; { CodeGenFunction CGF(CGM, true); CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind()); CGF.CapturedStmtInfo = &CGInfo; OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS); } // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/) llvm::Value *Args[] = { CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()), Builder.getInt32(1), // Number of arguments after 'microtask' argument // (there is only one additional argument - 'context') Builder.CreateBitCast(OutlinedFn, CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()), EmitCastToVoidPtr(CapturedStruct)}; llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction( CGOpenMPRuntime::OMPRTL__kmpc_fork_call); EmitRuntimeCall(RTLFn, Args); }