1 //===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This contains code to emit OpenMP nodes as LLVM code. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CGCleanup.h" 15 #include "CGOpenMPRuntime.h" 16 #include "CodeGenFunction.h" 17 #include "CodeGenModule.h" 18 #include "TargetInfo.h" 19 #include "clang/AST/Stmt.h" 20 #include "clang/AST/StmtOpenMP.h" 21 #include "clang/AST/DeclOpenMP.h" 22 #include "llvm/IR/CallSite.h" 23 using namespace clang; 24 using namespace CodeGen; 25 26 namespace { 27 /// Lexical scope for OpenMP executable constructs, that handles correct codegen 28 /// for captured expressions. 29 class OMPLexicalScope : public CodeGenFunction::LexicalScope { 30 void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) { 31 for (const auto *C : S.clauses()) { 32 if (auto *CPI = OMPClauseWithPreInit::get(C)) { 33 if (auto *PreInit = cast_or_null<DeclStmt>(CPI->getPreInitStmt())) { 34 for (const auto *I : PreInit->decls()) { 35 if (!I->hasAttr<OMPCaptureNoInitAttr>()) 36 CGF.EmitVarDecl(cast<VarDecl>(*I)); 37 else { 38 CodeGenFunction::AutoVarEmission Emission = 39 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I)); 40 CGF.EmitAutoVarCleanups(Emission); 41 } 42 } 43 } 44 } 45 } 46 } 47 CodeGenFunction::OMPPrivateScope InlinedShareds; 48 49 static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) { 50 return CGF.LambdaCaptureFields.lookup(VD) || 51 (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) || 52 (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl)); 53 } 54 55 public: 56 OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S, 57 bool AsInlined = false, bool EmitPreInitStmt = true) 58 : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()), 59 InlinedShareds(CGF) { 60 if (EmitPreInitStmt) 61 emitPreInitStmt(CGF, S); 62 if (AsInlined) { 63 if (S.hasAssociatedStmt()) { 64 auto *CS = cast<CapturedStmt>(S.getAssociatedStmt()); 65 for (auto &C : CS->captures()) { 66 if (C.capturesVariable() || C.capturesVariableByCopy()) { 67 auto *VD = C.getCapturedVar(); 68 assert(VD == VD->getCanonicalDecl() && 69 "Canonical decl must be captured."); 70 DeclRefExpr DRE(const_cast<VarDecl *>(VD), 71 isCapturedVar(CGF, VD) || 72 (CGF.CapturedStmtInfo && 73 InlinedShareds.isGlobalVarCaptured(VD)), 74 VD->getType().getNonReferenceType(), VK_LValue, 75 SourceLocation()); 76 InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address { 77 return CGF.EmitLValue(&DRE).getAddress(); 78 }); 79 } 80 } 81 (void)InlinedShareds.Privatize(); 82 } 83 } 84 } 85 }; 86 87 /// Lexical scope for OpenMP parallel construct, that handles correct codegen 88 /// for captured expressions. 89 class OMPParallelScope final : public OMPLexicalScope { 90 bool EmitPreInitStmt(const OMPExecutableDirective &S) { 91 OpenMPDirectiveKind Kind = S.getDirectiveKind(); 92 return !(isOpenMPTargetExecutionDirective(Kind) || 93 isOpenMPLoopBoundSharingDirective(Kind)) && 94 isOpenMPParallelDirective(Kind); 95 } 96 97 public: 98 OMPParallelScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) 99 : OMPLexicalScope(CGF, S, 100 /*AsInlined=*/false, 101 /*EmitPreInitStmt=*/EmitPreInitStmt(S)) {} 102 }; 103 104 /// Lexical scope for OpenMP teams construct, that handles correct codegen 105 /// for captured expressions. 106 class OMPTeamsScope final : public OMPLexicalScope { 107 bool EmitPreInitStmt(const OMPExecutableDirective &S) { 108 OpenMPDirectiveKind Kind = S.getDirectiveKind(); 109 return !isOpenMPTargetExecutionDirective(Kind) && 110 isOpenMPTeamsDirective(Kind); 111 } 112 113 public: 114 OMPTeamsScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) 115 : OMPLexicalScope(CGF, S, 116 /*AsInlined=*/false, 117 /*EmitPreInitStmt=*/EmitPreInitStmt(S)) {} 118 }; 119 120 /// Private scope for OpenMP loop-based directives, that supports capturing 121 /// of used expression from loop statement. 122 class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { 123 void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopDirective &S) { 124 if (auto *LD = dyn_cast<OMPLoopDirective>(&S)) { 125 if (auto *PreInits = cast_or_null<DeclStmt>(LD->getPreInits())) { 126 for (const auto *I : PreInits->decls()) 127 CGF.EmitVarDecl(cast<VarDecl>(*I)); 128 } 129 } 130 } 131 132 public: 133 OMPLoopScope(CodeGenFunction &CGF, const OMPLoopDirective &S) 134 : CodeGenFunction::RunCleanupsScope(CGF) { 135 emitPreInitStmt(CGF, S); 136 } 137 }; 138 139 } // namespace 140 141 LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) { 142 if (auto *OrigDRE = dyn_cast<DeclRefExpr>(E)) { 143 if (auto *OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) { 144 OrigVD = OrigVD->getCanonicalDecl(); 145 bool IsCaptured = 146 LambdaCaptureFields.lookup(OrigVD) || 147 (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) || 148 (CurCodeDecl && isa<BlockDecl>(CurCodeDecl)); 149 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), IsCaptured, 150 OrigDRE->getType(), VK_LValue, OrigDRE->getExprLoc()); 151 return EmitLValue(&DRE); 152 } 153 } 154 return EmitLValue(E); 155 } 156 157 llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) { 158 auto &C = getContext(); 159 llvm::Value *Size = nullptr; 160 auto SizeInChars = C.getTypeSizeInChars(Ty); 161 if (SizeInChars.isZero()) { 162 // getTypeSizeInChars() returns 0 for a VLA. 163 while (auto *VAT = C.getAsVariableArrayType(Ty)) { 164 llvm::Value *ArraySize; 165 std::tie(ArraySize, Ty) = getVLASize(VAT); 166 Size = Size ? Builder.CreateNUWMul(Size, ArraySize) : ArraySize; 167 } 168 SizeInChars = C.getTypeSizeInChars(Ty); 169 if (SizeInChars.isZero()) 170 return llvm::ConstantInt::get(SizeTy, /*V=*/0); 171 Size = Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars)); 172 } else 173 Size = CGM.getSize(SizeInChars); 174 return Size; 175 } 176 177 void CodeGenFunction::GenerateOpenMPCapturedVars( 178 const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) { 179 const RecordDecl *RD = S.getCapturedRecordDecl(); 180 auto CurField = RD->field_begin(); 181 auto CurCap = S.captures().begin(); 182 for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(), 183 E = S.capture_init_end(); 184 I != E; ++I, ++CurField, ++CurCap) { 185 if (CurField->hasCapturedVLAType()) { 186 auto VAT = CurField->getCapturedVLAType(); 187 auto *Val = VLASizeMap[VAT->getSizeExpr()]; 188 CapturedVars.push_back(Val); 189 } else if (CurCap->capturesThis()) 190 CapturedVars.push_back(CXXThisValue); 191 else if (CurCap->capturesVariableByCopy()) { 192 llvm::Value *CV = 193 EmitLoadOfLValue(EmitLValue(*I), SourceLocation()).getScalarVal(); 194 195 // If the field is not a pointer, we need to save the actual value 196 // and load it as a void pointer. 197 if (!CurField->getType()->isAnyPointerType()) { 198 auto &Ctx = getContext(); 199 auto DstAddr = CreateMemTemp( 200 Ctx.getUIntPtrType(), 201 Twine(CurCap->getCapturedVar()->getName()) + ".casted"); 202 LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType()); 203 204 auto *SrcAddrVal = EmitScalarConversion( 205 DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()), 206 Ctx.getPointerType(CurField->getType()), SourceLocation()); 207 LValue SrcLV = 208 MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType()); 209 210 // Store the value using the source type pointer. 211 EmitStoreThroughLValue(RValue::get(CV), SrcLV); 212 213 // Load the value using the destination type pointer. 214 CV = EmitLoadOfLValue(DstLV, SourceLocation()).getScalarVal(); 215 } 216 CapturedVars.push_back(CV); 217 } else { 218 assert(CurCap->capturesVariable() && "Expected capture by reference."); 219 CapturedVars.push_back(EmitLValue(*I).getAddress().getPointer()); 220 } 221 } 222 } 223 224 static Address castValueFromUintptr(CodeGenFunction &CGF, QualType DstType, 225 StringRef Name, LValue AddrLV, 226 bool isReferenceType = false) { 227 ASTContext &Ctx = CGF.getContext(); 228 229 auto *CastedPtr = CGF.EmitScalarConversion( 230 AddrLV.getAddress().getPointer(), Ctx.getUIntPtrType(), 231 Ctx.getPointerType(DstType), SourceLocation()); 232 auto TmpAddr = 233 CGF.MakeNaturalAlignAddrLValue(CastedPtr, Ctx.getPointerType(DstType)) 234 .getAddress(); 235 236 // If we are dealing with references we need to return the address of the 237 // reference instead of the reference of the value. 238 if (isReferenceType) { 239 QualType RefType = Ctx.getLValueReferenceType(DstType); 240 auto *RefVal = TmpAddr.getPointer(); 241 TmpAddr = CGF.CreateMemTemp(RefType, Twine(Name) + ".ref"); 242 auto TmpLVal = CGF.MakeAddrLValue(TmpAddr, RefType); 243 CGF.EmitStoreThroughLValue(RValue::get(RefVal), TmpLVal, /*isInit*/ true); 244 } 245 246 return TmpAddr; 247 } 248 249 static QualType getCanonicalParamType(ASTContext &C, QualType T) { 250 if (T->isLValueReferenceType()) { 251 return C.getLValueReferenceType( 252 getCanonicalParamType(C, T.getNonReferenceType()), 253 /*SpelledAsLValue=*/false); 254 } 255 if (T->isPointerType()) 256 return C.getPointerType(getCanonicalParamType(C, T->getPointeeType())); 257 return C.getCanonicalParamType(T); 258 } 259 260 namespace { 261 /// Contains required data for proper outlined function codegen. 262 struct FunctionOptions { 263 /// Captured statement for which the function is generated. 264 const CapturedStmt *S = nullptr; 265 /// true if cast to/from UIntPtr is required for variables captured by 266 /// value. 267 const bool UIntPtrCastRequired = true; 268 /// true if only casted arguments must be registered as local args or VLA 269 /// sizes. 270 const bool RegisterCastedArgsOnly = false; 271 /// Name of the generated function. 272 const StringRef FunctionName; 273 explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired, 274 bool RegisterCastedArgsOnly, 275 StringRef FunctionName) 276 : S(S), UIntPtrCastRequired(UIntPtrCastRequired), 277 RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly), 278 FunctionName(FunctionName) {} 279 }; 280 } 281 282 static llvm::Function *emitOutlinedFunctionPrologue( 283 CodeGenFunction &CGF, FunctionArgList &Args, 284 llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> 285 &LocalAddrs, 286 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> 287 &VLASizes, 288 llvm::Value *&CXXThisValue, const FunctionOptions &FO) { 289 const CapturedDecl *CD = FO.S->getCapturedDecl(); 290 const RecordDecl *RD = FO.S->getCapturedRecordDecl(); 291 assert(CD->hasBody() && "missing CapturedDecl body"); 292 293 CXXThisValue = nullptr; 294 // Build the argument list. 295 CodeGenModule &CGM = CGF.CGM; 296 ASTContext &Ctx = CGM.getContext(); 297 FunctionArgList TargetArgs; 298 Args.append(CD->param_begin(), 299 std::next(CD->param_begin(), CD->getContextParamPosition())); 300 TargetArgs.append( 301 CD->param_begin(), 302 std::next(CD->param_begin(), CD->getContextParamPosition())); 303 auto I = FO.S->captures().begin(); 304 for (auto *FD : RD->fields()) { 305 QualType ArgType = FD->getType(); 306 IdentifierInfo *II = nullptr; 307 VarDecl *CapVar = nullptr; 308 309 // If this is a capture by copy and the type is not a pointer, the outlined 310 // function argument type should be uintptr and the value properly casted to 311 // uintptr. This is necessary given that the runtime library is only able to 312 // deal with pointers. We can pass in the same way the VLA type sizes to the 313 // outlined function. 314 if ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) || 315 I->capturesVariableArrayType()) { 316 if (FO.UIntPtrCastRequired) 317 ArgType = Ctx.getUIntPtrType(); 318 } 319 320 if (I->capturesVariable() || I->capturesVariableByCopy()) { 321 CapVar = I->getCapturedVar(); 322 II = CapVar->getIdentifier(); 323 } else if (I->capturesThis()) 324 II = &Ctx.Idents.get("this"); 325 else { 326 assert(I->capturesVariableArrayType()); 327 II = &Ctx.Idents.get("vla"); 328 } 329 if (ArgType->isVariablyModifiedType()) 330 ArgType = getCanonicalParamType(Ctx, ArgType.getNonReferenceType()); 331 auto *Arg = 332 ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(), II, 333 ArgType, ImplicitParamDecl::Other); 334 Args.emplace_back(Arg); 335 // Do not cast arguments if we emit function with non-original types. 336 TargetArgs.emplace_back( 337 FO.UIntPtrCastRequired 338 ? Arg 339 : CGM.getOpenMPRuntime().translateParameter(FD, Arg)); 340 ++I; 341 } 342 Args.append( 343 std::next(CD->param_begin(), CD->getContextParamPosition() + 1), 344 CD->param_end()); 345 TargetArgs.append( 346 std::next(CD->param_begin(), CD->getContextParamPosition() + 1), 347 CD->param_end()); 348 349 // Create the function declaration. 350 FunctionType::ExtInfo ExtInfo; 351 const CGFunctionInfo &FuncInfo = 352 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, TargetArgs); 353 llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo); 354 355 llvm::Function *F = 356 llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage, 357 FO.FunctionName, &CGM.getModule()); 358 CGM.SetInternalFunctionAttributes(CD, F, FuncInfo); 359 if (CD->isNothrow()) 360 F->setDoesNotThrow(); 361 362 // Generate the function. 363 CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs, 364 FO.S->getLocStart(), CD->getBody()->getLocStart()); 365 unsigned Cnt = CD->getContextParamPosition(); 366 I = FO.S->captures().begin(); 367 for (auto *FD : RD->fields()) { 368 // Do not map arguments if we emit function with non-original types. 369 Address LocalAddr(Address::invalid()); 370 if (!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) { 371 LocalAddr = CGM.getOpenMPRuntime().getParameterAddress(CGF, Args[Cnt], 372 TargetArgs[Cnt]); 373 } else { 374 LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]); 375 } 376 // If we are capturing a pointer by copy we don't need to do anything, just 377 // use the value that we get from the arguments. 378 if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) { 379 const VarDecl *CurVD = I->getCapturedVar(); 380 // If the variable is a reference we need to materialize it here. 381 if (CurVD->getType()->isReferenceType()) { 382 Address RefAddr = CGF.CreateMemTemp( 383 CurVD->getType(), CGM.getPointerAlign(), ".materialized_ref"); 384 CGF.EmitStoreOfScalar(LocalAddr.getPointer(), RefAddr, 385 /*Volatile=*/false, CurVD->getType()); 386 LocalAddr = RefAddr; 387 } 388 if (!FO.RegisterCastedArgsOnly) 389 LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}}); 390 ++Cnt; 391 ++I; 392 continue; 393 } 394 395 LValue ArgLVal = CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(), 396 AlignmentSource::Decl); 397 if (FD->hasCapturedVLAType()) { 398 if (FO.UIntPtrCastRequired) { 399 ArgLVal = CGF.MakeAddrLValue(castValueFromUintptr(CGF, FD->getType(), 400 Args[Cnt]->getName(), 401 ArgLVal), 402 FD->getType(), AlignmentSource::Decl); 403 } 404 auto *ExprArg = 405 CGF.EmitLoadOfLValue(ArgLVal, SourceLocation()).getScalarVal(); 406 auto VAT = FD->getCapturedVLAType(); 407 VLASizes.insert({Args[Cnt], {VAT->getSizeExpr(), ExprArg}}); 408 } else if (I->capturesVariable()) { 409 auto *Var = I->getCapturedVar(); 410 QualType VarTy = Var->getType(); 411 Address ArgAddr = ArgLVal.getAddress(); 412 if (!VarTy->isReferenceType()) { 413 if (ArgLVal.getType()->isLValueReferenceType()) { 414 ArgAddr = CGF.EmitLoadOfReference( 415 ArgAddr, ArgLVal.getType()->castAs<ReferenceType>()); 416 } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) { 417 assert(ArgLVal.getType()->isPointerType()); 418 ArgAddr = CGF.EmitLoadOfPointer( 419 ArgAddr, ArgLVal.getType()->castAs<PointerType>()); 420 } 421 } 422 if (!FO.RegisterCastedArgsOnly) { 423 LocalAddrs.insert( 424 {Args[Cnt], 425 {Var, Address(ArgAddr.getPointer(), Ctx.getDeclAlign(Var))}}); 426 } 427 } else if (I->capturesVariableByCopy()) { 428 assert(!FD->getType()->isAnyPointerType() && 429 "Not expecting a captured pointer."); 430 auto *Var = I->getCapturedVar(); 431 QualType VarTy = Var->getType(); 432 LocalAddrs.insert( 433 {Args[Cnt], 434 {Var, 435 FO.UIntPtrCastRequired 436 ? castValueFromUintptr(CGF, FD->getType(), Args[Cnt]->getName(), 437 ArgLVal, VarTy->isReferenceType()) 438 : ArgLVal.getAddress()}}); 439 } else { 440 // If 'this' is captured, load it into CXXThisValue. 441 assert(I->capturesThis()); 442 CXXThisValue = CGF.EmitLoadOfLValue(ArgLVal, Args[Cnt]->getLocation()) 443 .getScalarVal(); 444 LocalAddrs.insert({Args[Cnt], {nullptr, ArgLVal.getAddress()}}); 445 } 446 ++Cnt; 447 ++I; 448 } 449 450 return F; 451 } 452 453 llvm::Function * 454 CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) { 455 assert( 456 CapturedStmtInfo && 457 "CapturedStmtInfo should be set when generating the captured function"); 458 const CapturedDecl *CD = S.getCapturedDecl(); 459 // Build the argument list. 460 bool NeedWrapperFunction = 461 getDebugInfo() && 462 CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo; 463 FunctionArgList Args; 464 llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs; 465 llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes; 466 SmallString<256> Buffer; 467 llvm::raw_svector_ostream Out(Buffer); 468 Out << CapturedStmtInfo->getHelperName(); 469 if (NeedWrapperFunction) 470 Out << "_debug__"; 471 FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false, 472 Out.str()); 473 llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs, 474 VLASizes, CXXThisValue, FO); 475 for (const auto &LocalAddrPair : LocalAddrs) { 476 if (LocalAddrPair.second.first) { 477 setAddrOfLocalVar(LocalAddrPair.second.first, 478 LocalAddrPair.second.second); 479 } 480 } 481 for (const auto &VLASizePair : VLASizes) 482 VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second; 483 PGO.assignRegionCounters(GlobalDecl(CD), F); 484 CapturedStmtInfo->EmitBody(*this, CD->getBody()); 485 FinishFunction(CD->getBodyRBrace()); 486 if (!NeedWrapperFunction) 487 return F; 488 489 FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true, 490 /*RegisterCastedArgsOnly=*/true, 491 CapturedStmtInfo->getHelperName()); 492 CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true); 493 Args.clear(); 494 LocalAddrs.clear(); 495 VLASizes.clear(); 496 llvm::Function *WrapperF = 497 emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes, 498 WrapperCGF.CXXThisValue, WrapperFO); 499 llvm::SmallVector<llvm::Value *, 4> CallArgs; 500 for (const auto *Arg : Args) { 501 llvm::Value *CallArg; 502 auto I = LocalAddrs.find(Arg); 503 if (I != LocalAddrs.end()) { 504 LValue LV = WrapperCGF.MakeAddrLValue( 505 I->second.second, 506 I->second.first ? I->second.first->getType() : Arg->getType(), 507 AlignmentSource::Decl); 508 CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation()); 509 } else { 510 auto EI = VLASizes.find(Arg); 511 if (EI != VLASizes.end()) 512 CallArg = EI->second.second; 513 else { 514 LValue LV = WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg), 515 Arg->getType(), 516 AlignmentSource::Decl); 517 CallArg = WrapperCGF.EmitLoadOfScalar(LV, SourceLocation()); 518 } 519 } 520 CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType())); 521 } 522 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, S.getLocStart(), 523 F, CallArgs); 524 WrapperCGF.FinishFunction(); 525 return WrapperF; 526 } 527 528 //===----------------------------------------------------------------------===// 529 // OpenMP Directive Emission 530 //===----------------------------------------------------------------------===// 531 void CodeGenFunction::EmitOMPAggregateAssign( 532 Address DestAddr, Address SrcAddr, QualType OriginalType, 533 const llvm::function_ref<void(Address, Address)> &CopyGen) { 534 // Perform element-by-element initialization. 535 QualType ElementTy; 536 537 // Drill down to the base element type on both arrays. 538 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe(); 539 auto NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr); 540 SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType()); 541 542 auto SrcBegin = SrcAddr.getPointer(); 543 auto DestBegin = DestAddr.getPointer(); 544 // Cast from pointer to array type to pointer to single element. 545 auto DestEnd = Builder.CreateGEP(DestBegin, NumElements); 546 // The basic structure here is a while-do loop. 547 auto BodyBB = createBasicBlock("omp.arraycpy.body"); 548 auto DoneBB = createBasicBlock("omp.arraycpy.done"); 549 auto IsEmpty = 550 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty"); 551 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); 552 553 // Enter the loop body, making that address the current address. 554 auto EntryBB = Builder.GetInsertBlock(); 555 EmitBlock(BodyBB); 556 557 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy); 558 559 llvm::PHINode *SrcElementPHI = 560 Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast"); 561 SrcElementPHI->addIncoming(SrcBegin, EntryBB); 562 Address SrcElementCurrent = 563 Address(SrcElementPHI, 564 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize)); 565 566 llvm::PHINode *DestElementPHI = 567 Builder.CreatePHI(DestBegin->getType(), 2, "omp.arraycpy.destElementPast"); 568 DestElementPHI->addIncoming(DestBegin, EntryBB); 569 Address DestElementCurrent = 570 Address(DestElementPHI, 571 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize)); 572 573 // Emit copy. 574 CopyGen(DestElementCurrent, SrcElementCurrent); 575 576 // Shift the address forward by one element. 577 auto DestElementNext = Builder.CreateConstGEP1_32( 578 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element"); 579 auto SrcElementNext = Builder.CreateConstGEP1_32( 580 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element"); 581 // Check whether we've reached the end. 582 auto Done = 583 Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done"); 584 Builder.CreateCondBr(Done, DoneBB, BodyBB); 585 DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock()); 586 SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock()); 587 588 // Done. 589 EmitBlock(DoneBB, /*IsFinished=*/true); 590 } 591 592 void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr, 593 Address SrcAddr, const VarDecl *DestVD, 594 const VarDecl *SrcVD, const Expr *Copy) { 595 if (OriginalType->isArrayType()) { 596 auto *BO = dyn_cast<BinaryOperator>(Copy); 597 if (BO && BO->getOpcode() == BO_Assign) { 598 // Perform simple memcpy for simple copying. 599 EmitAggregateAssign(DestAddr, SrcAddr, OriginalType); 600 } else { 601 // For arrays with complex element types perform element by element 602 // copying. 603 EmitOMPAggregateAssign( 604 DestAddr, SrcAddr, OriginalType, 605 [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) { 606 // Working with the single array element, so have to remap 607 // destination and source variables to corresponding array 608 // elements. 609 CodeGenFunction::OMPPrivateScope Remap(*this); 610 Remap.addPrivate(DestVD, [DestElement]() -> Address { 611 return DestElement; 612 }); 613 Remap.addPrivate( 614 SrcVD, [SrcElement]() -> Address { return SrcElement; }); 615 (void)Remap.Privatize(); 616 EmitIgnoredExpr(Copy); 617 }); 618 } 619 } else { 620 // Remap pseudo source variable to private copy. 621 CodeGenFunction::OMPPrivateScope Remap(*this); 622 Remap.addPrivate(SrcVD, [SrcAddr]() -> Address { return SrcAddr; }); 623 Remap.addPrivate(DestVD, [DestAddr]() -> Address { return DestAddr; }); 624 (void)Remap.Privatize(); 625 // Emit copying of the whole variable. 626 EmitIgnoredExpr(Copy); 627 } 628 } 629 630 bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, 631 OMPPrivateScope &PrivateScope) { 632 if (!HaveInsertPoint()) 633 return false; 634 bool FirstprivateIsLastprivate = false; 635 llvm::DenseSet<const VarDecl *> Lastprivates; 636 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { 637 for (const auto *D : C->varlists()) 638 Lastprivates.insert( 639 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl()); 640 } 641 llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate; 642 CGCapturedStmtInfo CapturesInfo(cast<CapturedStmt>(*D.getAssociatedStmt())); 643 for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) { 644 auto IRef = C->varlist_begin(); 645 auto InitsRef = C->inits().begin(); 646 for (auto IInit : C->private_copies()) { 647 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 648 bool ThisFirstprivateIsLastprivate = 649 Lastprivates.count(OrigVD->getCanonicalDecl()) > 0; 650 auto *CapFD = CapturesInfo.lookup(OrigVD); 651 auto *FD = CapturedStmtInfo->lookup(OrigVD); 652 if (!ThisFirstprivateIsLastprivate && FD && (FD == CapFD) && 653 !FD->getType()->isReferenceType()) { 654 EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()); 655 ++IRef; 656 ++InitsRef; 657 continue; 658 } 659 FirstprivateIsLastprivate = 660 FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate; 661 if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) { 662 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); 663 auto *VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl()); 664 bool IsRegistered; 665 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), 666 /*RefersToEnclosingVariableOrCapture=*/FD != nullptr, 667 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc()); 668 Address OriginalAddr = EmitLValue(&DRE).getAddress(); 669 QualType Type = VD->getType(); 670 if (Type->isArrayType()) { 671 // Emit VarDecl with copy init for arrays. 672 // Get the address of the original variable captured in current 673 // captured region. 674 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address { 675 auto Emission = EmitAutoVarAlloca(*VD); 676 auto *Init = VD->getInit(); 677 if (!isa<CXXConstructExpr>(Init) || isTrivialInitializer(Init)) { 678 // Perform simple memcpy. 679 EmitAggregateAssign(Emission.getAllocatedAddress(), OriginalAddr, 680 Type); 681 } else { 682 EmitOMPAggregateAssign( 683 Emission.getAllocatedAddress(), OriginalAddr, Type, 684 [this, VDInit, Init](Address DestElement, 685 Address SrcElement) { 686 // Clean up any temporaries needed by the initialization. 687 RunCleanupsScope InitScope(*this); 688 // Emit initialization for single element. 689 setAddrOfLocalVar(VDInit, SrcElement); 690 EmitAnyExprToMem(Init, DestElement, 691 Init->getType().getQualifiers(), 692 /*IsInitializer*/ false); 693 LocalDeclMap.erase(VDInit); 694 }); 695 } 696 EmitAutoVarCleanups(Emission); 697 return Emission.getAllocatedAddress(); 698 }); 699 } else { 700 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address { 701 // Emit private VarDecl with copy init. 702 // Remap temp VDInit variable to the address of the original 703 // variable 704 // (for proper handling of captured global variables). 705 setAddrOfLocalVar(VDInit, OriginalAddr); 706 EmitDecl(*VD); 707 LocalDeclMap.erase(VDInit); 708 return GetAddrOfLocalVar(VD); 709 }); 710 } 711 assert(IsRegistered && 712 "firstprivate var already registered as private"); 713 // Silence the warning about unused variable. 714 (void)IsRegistered; 715 } 716 ++IRef; 717 ++InitsRef; 718 } 719 } 720 return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty(); 721 } 722 723 void CodeGenFunction::EmitOMPPrivateClause( 724 const OMPExecutableDirective &D, 725 CodeGenFunction::OMPPrivateScope &PrivateScope) { 726 if (!HaveInsertPoint()) 727 return; 728 llvm::DenseSet<const VarDecl *> EmittedAsPrivate; 729 for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) { 730 auto IRef = C->varlist_begin(); 731 for (auto IInit : C->private_copies()) { 732 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 733 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { 734 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); 735 bool IsRegistered = 736 PrivateScope.addPrivate(OrigVD, [&]() -> Address { 737 // Emit private VarDecl with copy init. 738 EmitDecl(*VD); 739 return GetAddrOfLocalVar(VD); 740 }); 741 assert(IsRegistered && "private var already registered as private"); 742 // Silence the warning about unused variable. 743 (void)IsRegistered; 744 } 745 ++IRef; 746 } 747 } 748 } 749 750 bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { 751 if (!HaveInsertPoint()) 752 return false; 753 // threadprivate_var1 = master_threadprivate_var1; 754 // operator=(threadprivate_var2, master_threadprivate_var2); 755 // ... 756 // __kmpc_barrier(&loc, global_tid); 757 llvm::DenseSet<const VarDecl *> CopiedVars; 758 llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr; 759 for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) { 760 auto IRef = C->varlist_begin(); 761 auto ISrcRef = C->source_exprs().begin(); 762 auto IDestRef = C->destination_exprs().begin(); 763 for (auto *AssignOp : C->assignment_ops()) { 764 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 765 QualType Type = VD->getType(); 766 if (CopiedVars.insert(VD->getCanonicalDecl()).second) { 767 // Get the address of the master variable. If we are emitting code with 768 // TLS support, the address is passed from the master as field in the 769 // captured declaration. 770 Address MasterAddr = Address::invalid(); 771 if (getLangOpts().OpenMPUseTLS && 772 getContext().getTargetInfo().isTLSSupported()) { 773 assert(CapturedStmtInfo->lookup(VD) && 774 "Copyin threadprivates should have been captured!"); 775 DeclRefExpr DRE(const_cast<VarDecl *>(VD), true, (*IRef)->getType(), 776 VK_LValue, (*IRef)->getExprLoc()); 777 MasterAddr = EmitLValue(&DRE).getAddress(); 778 LocalDeclMap.erase(VD); 779 } else { 780 MasterAddr = 781 Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD) 782 : CGM.GetAddrOfGlobal(VD), 783 getContext().getDeclAlign(VD)); 784 } 785 // Get the address of the threadprivate variable. 786 Address PrivateAddr = EmitLValue(*IRef).getAddress(); 787 if (CopiedVars.size() == 1) { 788 // At first check if current thread is a master thread. If it is, no 789 // need to copy data. 790 CopyBegin = createBasicBlock("copyin.not.master"); 791 CopyEnd = createBasicBlock("copyin.not.master.end"); 792 Builder.CreateCondBr( 793 Builder.CreateICmpNE( 794 Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy), 795 Builder.CreatePtrToInt(PrivateAddr.getPointer(), CGM.IntPtrTy)), 796 CopyBegin, CopyEnd); 797 EmitBlock(CopyBegin); 798 } 799 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl()); 800 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); 801 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp); 802 } 803 ++IRef; 804 ++ISrcRef; 805 ++IDestRef; 806 } 807 } 808 if (CopyEnd) { 809 // Exit out of copying procedure for non-master thread. 810 EmitBlock(CopyEnd, /*IsFinished=*/true); 811 return true; 812 } 813 return false; 814 } 815 816 bool CodeGenFunction::EmitOMPLastprivateClauseInit( 817 const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { 818 if (!HaveInsertPoint()) 819 return false; 820 bool HasAtLeastOneLastprivate = false; 821 llvm::DenseSet<const VarDecl *> SIMDLCVs; 822 if (isOpenMPSimdDirective(D.getDirectiveKind())) { 823 auto *LoopDirective = cast<OMPLoopDirective>(&D); 824 for (auto *C : LoopDirective->counters()) { 825 SIMDLCVs.insert( 826 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl()); 827 } 828 } 829 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; 830 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { 831 HasAtLeastOneLastprivate = true; 832 if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) 833 break; 834 auto IRef = C->varlist_begin(); 835 auto IDestRef = C->destination_exprs().begin(); 836 for (auto *IInit : C->private_copies()) { 837 // Keep the address of the original variable for future update at the end 838 // of the loop. 839 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 840 // Taskloops do not require additional initialization, it is done in 841 // runtime support library. 842 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) { 843 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); 844 PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() -> Address { 845 DeclRefExpr DRE( 846 const_cast<VarDecl *>(OrigVD), 847 /*RefersToEnclosingVariableOrCapture=*/CapturedStmtInfo->lookup( 848 OrigVD) != nullptr, 849 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc()); 850 return EmitLValue(&DRE).getAddress(); 851 }); 852 // Check if the variable is also a firstprivate: in this case IInit is 853 // not generated. Initialization of this variable will happen in codegen 854 // for 'firstprivate' clause. 855 if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) { 856 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); 857 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address { 858 // Emit private VarDecl with copy init. 859 EmitDecl(*VD); 860 return GetAddrOfLocalVar(VD); 861 }); 862 assert(IsRegistered && 863 "lastprivate var already registered as private"); 864 (void)IsRegistered; 865 } 866 } 867 ++IRef; 868 ++IDestRef; 869 } 870 } 871 return HasAtLeastOneLastprivate; 872 } 873 874 void CodeGenFunction::EmitOMPLastprivateClauseFinal( 875 const OMPExecutableDirective &D, bool NoFinals, 876 llvm::Value *IsLastIterCond) { 877 if (!HaveInsertPoint()) 878 return; 879 // Emit following code: 880 // if (<IsLastIterCond>) { 881 // orig_var1 = private_orig_var1; 882 // ... 883 // orig_varn = private_orig_varn; 884 // } 885 llvm::BasicBlock *ThenBB = nullptr; 886 llvm::BasicBlock *DoneBB = nullptr; 887 if (IsLastIterCond) { 888 ThenBB = createBasicBlock(".omp.lastprivate.then"); 889 DoneBB = createBasicBlock(".omp.lastprivate.done"); 890 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB); 891 EmitBlock(ThenBB); 892 } 893 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; 894 llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates; 895 if (auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) { 896 auto IC = LoopDirective->counters().begin(); 897 for (auto F : LoopDirective->finals()) { 898 auto *D = 899 cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl(); 900 if (NoFinals) 901 AlreadyEmittedVars.insert(D); 902 else 903 LoopCountersAndUpdates[D] = F; 904 ++IC; 905 } 906 } 907 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { 908 auto IRef = C->varlist_begin(); 909 auto ISrcRef = C->source_exprs().begin(); 910 auto IDestRef = C->destination_exprs().begin(); 911 for (auto *AssignOp : C->assignment_ops()) { 912 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 913 QualType Type = PrivateVD->getType(); 914 auto *CanonicalVD = PrivateVD->getCanonicalDecl(); 915 if (AlreadyEmittedVars.insert(CanonicalVD).second) { 916 // If lastprivate variable is a loop control variable for loop-based 917 // directive, update its value before copyin back to original 918 // variable. 919 if (auto *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) 920 EmitIgnoredExpr(FinalExpr); 921 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl()); 922 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); 923 // Get the address of the original variable. 924 Address OriginalAddr = GetAddrOfLocalVar(DestVD); 925 // Get the address of the private variable. 926 Address PrivateAddr = GetAddrOfLocalVar(PrivateVD); 927 if (auto RefTy = PrivateVD->getType()->getAs<ReferenceType>()) 928 PrivateAddr = 929 Address(Builder.CreateLoad(PrivateAddr), 930 getNaturalTypeAlignment(RefTy->getPointeeType())); 931 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp); 932 } 933 ++IRef; 934 ++ISrcRef; 935 ++IDestRef; 936 } 937 if (auto *PostUpdate = C->getPostUpdateExpr()) 938 EmitIgnoredExpr(PostUpdate); 939 } 940 if (IsLastIterCond) 941 EmitBlock(DoneBB, /*IsFinished=*/true); 942 } 943 944 void CodeGenFunction::EmitOMPReductionClauseInit( 945 const OMPExecutableDirective &D, 946 CodeGenFunction::OMPPrivateScope &PrivateScope) { 947 if (!HaveInsertPoint()) 948 return; 949 SmallVector<const Expr *, 4> Shareds; 950 SmallVector<const Expr *, 4> Privates; 951 SmallVector<const Expr *, 4> ReductionOps; 952 SmallVector<const Expr *, 4> LHSs; 953 SmallVector<const Expr *, 4> RHSs; 954 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { 955 auto IPriv = C->privates().begin(); 956 auto IRed = C->reduction_ops().begin(); 957 auto ILHS = C->lhs_exprs().begin(); 958 auto IRHS = C->rhs_exprs().begin(); 959 for (const auto *Ref : C->varlists()) { 960 Shareds.emplace_back(Ref); 961 Privates.emplace_back(*IPriv); 962 ReductionOps.emplace_back(*IRed); 963 LHSs.emplace_back(*ILHS); 964 RHSs.emplace_back(*IRHS); 965 std::advance(IPriv, 1); 966 std::advance(IRed, 1); 967 std::advance(ILHS, 1); 968 std::advance(IRHS, 1); 969 } 970 } 971 ReductionCodeGen RedCG(Shareds, Privates, ReductionOps); 972 unsigned Count = 0; 973 auto ILHS = LHSs.begin(); 974 auto IRHS = RHSs.begin(); 975 auto IPriv = Privates.begin(); 976 for (const auto *IRef : Shareds) { 977 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl()); 978 // Emit private VarDecl with reduction init. 979 RedCG.emitSharedLValue(*this, Count); 980 RedCG.emitAggregateType(*this, Count); 981 auto Emission = EmitAutoVarAlloca(*PrivateVD); 982 RedCG.emitInitialization(*this, Count, Emission.getAllocatedAddress(), 983 RedCG.getSharedLValue(Count), 984 [&Emission](CodeGenFunction &CGF) { 985 CGF.EmitAutoVarInit(Emission); 986 return true; 987 }); 988 EmitAutoVarCleanups(Emission); 989 Address BaseAddr = RedCG.adjustPrivateAddress( 990 *this, Count, Emission.getAllocatedAddress()); 991 bool IsRegistered = PrivateScope.addPrivate( 992 RedCG.getBaseDecl(Count), [BaseAddr]() -> Address { return BaseAddr; }); 993 assert(IsRegistered && "private var already registered as private"); 994 // Silence the warning about unused variable. 995 (void)IsRegistered; 996 997 auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl()); 998 auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl()); 999 QualType Type = PrivateVD->getType(); 1000 bool isaOMPArraySectionExpr = isa<OMPArraySectionExpr>(IRef); 1001 if (isaOMPArraySectionExpr && Type->isVariablyModifiedType()) { 1002 // Store the address of the original variable associated with the LHS 1003 // implicit variable. 1004 PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() -> Address { 1005 return RedCG.getSharedLValue(Count).getAddress(); 1006 }); 1007 PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address { 1008 return GetAddrOfLocalVar(PrivateVD); 1009 }); 1010 } else if ((isaOMPArraySectionExpr && Type->isScalarType()) || 1011 isa<ArraySubscriptExpr>(IRef)) { 1012 // Store the address of the original variable associated with the LHS 1013 // implicit variable. 1014 PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() -> Address { 1015 return RedCG.getSharedLValue(Count).getAddress(); 1016 }); 1017 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address { 1018 return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD), 1019 ConvertTypeForMem(RHSVD->getType()), 1020 "rhs.begin"); 1021 }); 1022 } else { 1023 QualType Type = PrivateVD->getType(); 1024 bool IsArray = getContext().getAsArrayType(Type) != nullptr; 1025 Address OriginalAddr = RedCG.getSharedLValue(Count).getAddress(); 1026 // Store the address of the original variable associated with the LHS 1027 // implicit variable. 1028 if (IsArray) { 1029 OriginalAddr = Builder.CreateElementBitCast( 1030 OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin"); 1031 } 1032 PrivateScope.addPrivate( 1033 LHSVD, [OriginalAddr]() -> Address { return OriginalAddr; }); 1034 PrivateScope.addPrivate( 1035 RHSVD, [this, PrivateVD, RHSVD, IsArray]() -> Address { 1036 return IsArray 1037 ? Builder.CreateElementBitCast( 1038 GetAddrOfLocalVar(PrivateVD), 1039 ConvertTypeForMem(RHSVD->getType()), "rhs.begin") 1040 : GetAddrOfLocalVar(PrivateVD); 1041 }); 1042 } 1043 ++ILHS; 1044 ++IRHS; 1045 ++IPriv; 1046 ++Count; 1047 } 1048 } 1049 1050 void CodeGenFunction::EmitOMPReductionClauseFinal( 1051 const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) { 1052 if (!HaveInsertPoint()) 1053 return; 1054 llvm::SmallVector<const Expr *, 8> Privates; 1055 llvm::SmallVector<const Expr *, 8> LHSExprs; 1056 llvm::SmallVector<const Expr *, 8> RHSExprs; 1057 llvm::SmallVector<const Expr *, 8> ReductionOps; 1058 bool HasAtLeastOneReduction = false; 1059 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { 1060 HasAtLeastOneReduction = true; 1061 Privates.append(C->privates().begin(), C->privates().end()); 1062 LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); 1063 RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); 1064 ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end()); 1065 } 1066 if (HasAtLeastOneReduction) { 1067 bool WithNowait = D.getSingleClause<OMPNowaitClause>() || 1068 isOpenMPParallelDirective(D.getDirectiveKind()) || 1069 D.getDirectiveKind() == OMPD_simd; 1070 bool SimpleReduction = D.getDirectiveKind() == OMPD_simd; 1071 // Emit nowait reduction if nowait clause is present or directive is a 1072 // parallel directive (it always has implicit barrier). 1073 CGM.getOpenMPRuntime().emitReduction( 1074 *this, D.getLocEnd(), Privates, LHSExprs, RHSExprs, ReductionOps, 1075 {WithNowait, SimpleReduction, ReductionKind}); 1076 } 1077 } 1078 1079 static void emitPostUpdateForReductionClause( 1080 CodeGenFunction &CGF, const OMPExecutableDirective &D, 1081 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) { 1082 if (!CGF.HaveInsertPoint()) 1083 return; 1084 llvm::BasicBlock *DoneBB = nullptr; 1085 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { 1086 if (auto *PostUpdate = C->getPostUpdateExpr()) { 1087 if (!DoneBB) { 1088 if (auto *Cond = CondGen(CGF)) { 1089 // If the first post-update expression is found, emit conditional 1090 // block if it was requested. 1091 auto *ThenBB = CGF.createBasicBlock(".omp.reduction.pu"); 1092 DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done"); 1093 CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB); 1094 CGF.EmitBlock(ThenBB); 1095 } 1096 } 1097 CGF.EmitIgnoredExpr(PostUpdate); 1098 } 1099 } 1100 if (DoneBB) 1101 CGF.EmitBlock(DoneBB, /*IsFinished=*/true); 1102 } 1103 1104 namespace { 1105 /// Codegen lambda for appending distribute lower and upper bounds to outlined 1106 /// parallel function. This is necessary for combined constructs such as 1107 /// 'distribute parallel for' 1108 typedef llvm::function_ref<void(CodeGenFunction &, 1109 const OMPExecutableDirective &, 1110 llvm::SmallVectorImpl<llvm::Value *> &)> 1111 CodeGenBoundParametersTy; 1112 } // anonymous namespace 1113 1114 static void emitCommonOMPParallelDirective( 1115 CodeGenFunction &CGF, const OMPExecutableDirective &S, 1116 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen, 1117 const CodeGenBoundParametersTy &CodeGenBoundParameters) { 1118 const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel); 1119 auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction( 1120 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); 1121 if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) { 1122 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); 1123 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(), 1124 /*IgnoreResultAssign*/ true); 1125 CGF.CGM.getOpenMPRuntime().emitNumThreadsClause( 1126 CGF, NumThreads, NumThreadsClause->getLocStart()); 1127 } 1128 if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) { 1129 CodeGenFunction::RunCleanupsScope ProcBindScope(CGF); 1130 CGF.CGM.getOpenMPRuntime().emitProcBindClause( 1131 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart()); 1132 } 1133 const Expr *IfCond = nullptr; 1134 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 1135 if (C->getNameModifier() == OMPD_unknown || 1136 C->getNameModifier() == OMPD_parallel) { 1137 IfCond = C->getCondition(); 1138 break; 1139 } 1140 } 1141 1142 OMPParallelScope Scope(CGF, S); 1143 llvm::SmallVector<llvm::Value *, 16> CapturedVars; 1144 // Combining 'distribute' with 'for' requires sharing each 'distribute' chunk 1145 // lower and upper bounds with the pragma 'for' chunking mechanism. 1146 // The following lambda takes care of appending the lower and upper bound 1147 // parameters when necessary 1148 CodeGenBoundParameters(CGF, S, CapturedVars); 1149 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); 1150 CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn, 1151 CapturedVars, IfCond); 1152 } 1153 1154 static void emitEmptyBoundParameters(CodeGenFunction &, 1155 const OMPExecutableDirective &, 1156 llvm::SmallVectorImpl<llvm::Value *> &) {} 1157 1158 void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { 1159 // Emit parallel region as a standalone region. 1160 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 1161 OMPPrivateScope PrivateScope(CGF); 1162 bool Copyins = CGF.EmitOMPCopyinClause(S); 1163 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); 1164 if (Copyins) { 1165 // Emit implicit barrier to synchronize threads and avoid data races on 1166 // propagation master's thread values of threadprivate variables to local 1167 // instances of that variables of all other implicit threads. 1168 CGF.CGM.getOpenMPRuntime().emitBarrierCall( 1169 CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, 1170 /*ForceSimpleCall=*/true); 1171 } 1172 CGF.EmitOMPPrivateClause(S, PrivateScope); 1173 CGF.EmitOMPReductionClauseInit(S, PrivateScope); 1174 (void)PrivateScope.Privatize(); 1175 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 1176 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); 1177 }; 1178 emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen, 1179 emitEmptyBoundParameters); 1180 emitPostUpdateForReductionClause( 1181 *this, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 1182 } 1183 1184 void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, 1185 JumpDest LoopExit) { 1186 RunCleanupsScope BodyScope(*this); 1187 // Update counters values on current iteration. 1188 for (auto I : D.updates()) { 1189 EmitIgnoredExpr(I); 1190 } 1191 // Update the linear variables. 1192 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { 1193 for (auto *U : C->updates()) 1194 EmitIgnoredExpr(U); 1195 } 1196 1197 // On a continue in the body, jump to the end. 1198 auto Continue = getJumpDestInCurrentScope("omp.body.continue"); 1199 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 1200 // Emit loop body. 1201 EmitStmt(D.getBody()); 1202 // The end (updates/cleanups). 1203 EmitBlock(Continue.getBlock()); 1204 BreakContinueStack.pop_back(); 1205 } 1206 1207 void CodeGenFunction::EmitOMPInnerLoop( 1208 const Stmt &S, bool RequiresCleanup, const Expr *LoopCond, 1209 const Expr *IncExpr, 1210 const llvm::function_ref<void(CodeGenFunction &)> &BodyGen, 1211 const llvm::function_ref<void(CodeGenFunction &)> &PostIncGen) { 1212 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end"); 1213 1214 // Start the loop with a block that tests the condition. 1215 auto CondBlock = createBasicBlock("omp.inner.for.cond"); 1216 EmitBlock(CondBlock); 1217 const SourceRange &R = S.getSourceRange(); 1218 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()), 1219 SourceLocToDebugLoc(R.getEnd())); 1220 1221 // If there are any cleanups between here and the loop-exit scope, 1222 // create a block to stage a loop exit along. 1223 auto ExitBlock = LoopExit.getBlock(); 1224 if (RequiresCleanup) 1225 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup"); 1226 1227 auto LoopBody = createBasicBlock("omp.inner.for.body"); 1228 1229 // Emit condition. 1230 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S)); 1231 if (ExitBlock != LoopExit.getBlock()) { 1232 EmitBlock(ExitBlock); 1233 EmitBranchThroughCleanup(LoopExit); 1234 } 1235 1236 EmitBlock(LoopBody); 1237 incrementProfileCounter(&S); 1238 1239 // Create a block for the increment. 1240 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc"); 1241 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 1242 1243 BodyGen(*this); 1244 1245 // Emit "IV = IV + 1" and a back-edge to the condition block. 1246 EmitBlock(Continue.getBlock()); 1247 EmitIgnoredExpr(IncExpr); 1248 PostIncGen(*this); 1249 BreakContinueStack.pop_back(); 1250 EmitBranch(CondBlock); 1251 LoopStack.pop(); 1252 // Emit the fall-through block. 1253 EmitBlock(LoopExit.getBlock()); 1254 } 1255 1256 bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { 1257 if (!HaveInsertPoint()) 1258 return false; 1259 // Emit inits for the linear variables. 1260 bool HasLinears = false; 1261 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { 1262 for (auto *Init : C->inits()) { 1263 HasLinears = true; 1264 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl()); 1265 if (auto *Ref = dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) { 1266 AutoVarEmission Emission = EmitAutoVarAlloca(*VD); 1267 auto *OrigVD = cast<VarDecl>(Ref->getDecl()); 1268 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), 1269 CapturedStmtInfo->lookup(OrigVD) != nullptr, 1270 VD->getInit()->getType(), VK_LValue, 1271 VD->getInit()->getExprLoc()); 1272 EmitExprAsInit(&DRE, VD, MakeAddrLValue(Emission.getAllocatedAddress(), 1273 VD->getType()), 1274 /*capturedByInit=*/false); 1275 EmitAutoVarCleanups(Emission); 1276 } else 1277 EmitVarDecl(*VD); 1278 } 1279 // Emit the linear steps for the linear clauses. 1280 // If a step is not constant, it is pre-calculated before the loop. 1281 if (auto CS = cast_or_null<BinaryOperator>(C->getCalcStep())) 1282 if (auto SaveRef = cast<DeclRefExpr>(CS->getLHS())) { 1283 EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl())); 1284 // Emit calculation of the linear step. 1285 EmitIgnoredExpr(CS); 1286 } 1287 } 1288 return HasLinears; 1289 } 1290 1291 void CodeGenFunction::EmitOMPLinearClauseFinal( 1292 const OMPLoopDirective &D, 1293 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) { 1294 if (!HaveInsertPoint()) 1295 return; 1296 llvm::BasicBlock *DoneBB = nullptr; 1297 // Emit the final values of the linear variables. 1298 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { 1299 auto IC = C->varlist_begin(); 1300 for (auto *F : C->finals()) { 1301 if (!DoneBB) { 1302 if (auto *Cond = CondGen(*this)) { 1303 // If the first post-update expression is found, emit conditional 1304 // block if it was requested. 1305 auto *ThenBB = createBasicBlock(".omp.linear.pu"); 1306 DoneBB = createBasicBlock(".omp.linear.pu.done"); 1307 Builder.CreateCondBr(Cond, ThenBB, DoneBB); 1308 EmitBlock(ThenBB); 1309 } 1310 } 1311 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl()); 1312 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), 1313 CapturedStmtInfo->lookup(OrigVD) != nullptr, 1314 (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); 1315 Address OrigAddr = EmitLValue(&DRE).getAddress(); 1316 CodeGenFunction::OMPPrivateScope VarScope(*this); 1317 VarScope.addPrivate(OrigVD, [OrigAddr]() -> Address { return OrigAddr; }); 1318 (void)VarScope.Privatize(); 1319 EmitIgnoredExpr(F); 1320 ++IC; 1321 } 1322 if (auto *PostUpdate = C->getPostUpdateExpr()) 1323 EmitIgnoredExpr(PostUpdate); 1324 } 1325 if (DoneBB) 1326 EmitBlock(DoneBB, /*IsFinished=*/true); 1327 } 1328 1329 static void emitAlignedClause(CodeGenFunction &CGF, 1330 const OMPExecutableDirective &D) { 1331 if (!CGF.HaveInsertPoint()) 1332 return; 1333 for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) { 1334 unsigned ClauseAlignment = 0; 1335 if (auto AlignmentExpr = Clause->getAlignment()) { 1336 auto AlignmentCI = 1337 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr)); 1338 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue()); 1339 } 1340 for (auto E : Clause->varlists()) { 1341 unsigned Alignment = ClauseAlignment; 1342 if (Alignment == 0) { 1343 // OpenMP [2.8.1, Description] 1344 // If no optional parameter is specified, implementation-defined default 1345 // alignments for SIMD instructions on the target platforms are assumed. 1346 Alignment = 1347 CGF.getContext() 1348 .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign( 1349 E->getType()->getPointeeType())) 1350 .getQuantity(); 1351 } 1352 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && 1353 "alignment is not power of 2"); 1354 if (Alignment != 0) { 1355 llvm::Value *PtrValue = CGF.EmitScalarExpr(E); 1356 CGF.EmitAlignmentAssumption(PtrValue, Alignment); 1357 } 1358 } 1359 } 1360 } 1361 1362 void CodeGenFunction::EmitOMPPrivateLoopCounters( 1363 const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) { 1364 if (!HaveInsertPoint()) 1365 return; 1366 auto I = S.private_counters().begin(); 1367 for (auto *E : S.counters()) { 1368 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 1369 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()); 1370 (void)LoopScope.addPrivate(VD, [&]() -> Address { 1371 // Emit var without initialization. 1372 if (!LocalDeclMap.count(PrivateVD)) { 1373 auto VarEmission = EmitAutoVarAlloca(*PrivateVD); 1374 EmitAutoVarCleanups(VarEmission); 1375 } 1376 DeclRefExpr DRE(const_cast<VarDecl *>(PrivateVD), 1377 /*RefersToEnclosingVariableOrCapture=*/false, 1378 (*I)->getType(), VK_LValue, (*I)->getExprLoc()); 1379 return EmitLValue(&DRE).getAddress(); 1380 }); 1381 if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) || 1382 VD->hasGlobalStorage()) { 1383 (void)LoopScope.addPrivate(PrivateVD, [&]() -> Address { 1384 DeclRefExpr DRE(const_cast<VarDecl *>(VD), 1385 LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD), 1386 E->getType(), VK_LValue, E->getExprLoc()); 1387 return EmitLValue(&DRE).getAddress(); 1388 }); 1389 } 1390 ++I; 1391 } 1392 } 1393 1394 static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, 1395 const Expr *Cond, llvm::BasicBlock *TrueBlock, 1396 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) { 1397 if (!CGF.HaveInsertPoint()) 1398 return; 1399 { 1400 CodeGenFunction::OMPPrivateScope PreCondScope(CGF); 1401 CGF.EmitOMPPrivateLoopCounters(S, PreCondScope); 1402 (void)PreCondScope.Privatize(); 1403 // Get initial values of real counters. 1404 for (auto I : S.inits()) { 1405 CGF.EmitIgnoredExpr(I); 1406 } 1407 } 1408 // Check that loop is executed at least one time. 1409 CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount); 1410 } 1411 1412 void CodeGenFunction::EmitOMPLinearClause( 1413 const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { 1414 if (!HaveInsertPoint()) 1415 return; 1416 llvm::DenseSet<const VarDecl *> SIMDLCVs; 1417 if (isOpenMPSimdDirective(D.getDirectiveKind())) { 1418 auto *LoopDirective = cast<OMPLoopDirective>(&D); 1419 for (auto *C : LoopDirective->counters()) { 1420 SIMDLCVs.insert( 1421 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl()); 1422 } 1423 } 1424 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { 1425 auto CurPrivate = C->privates().begin(); 1426 for (auto *E : C->varlists()) { 1427 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 1428 auto *PrivateVD = 1429 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl()); 1430 if (!SIMDLCVs.count(VD->getCanonicalDecl())) { 1431 bool IsRegistered = PrivateScope.addPrivate(VD, [&]() -> Address { 1432 // Emit private VarDecl with copy init. 1433 EmitVarDecl(*PrivateVD); 1434 return GetAddrOfLocalVar(PrivateVD); 1435 }); 1436 assert(IsRegistered && "linear var already registered as private"); 1437 // Silence the warning about unused variable. 1438 (void)IsRegistered; 1439 } else 1440 EmitVarDecl(*PrivateVD); 1441 ++CurPrivate; 1442 } 1443 } 1444 } 1445 1446 static void emitSimdlenSafelenClause(CodeGenFunction &CGF, 1447 const OMPExecutableDirective &D, 1448 bool IsMonotonic) { 1449 if (!CGF.HaveInsertPoint()) 1450 return; 1451 if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) { 1452 RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(), 1453 /*ignoreResult=*/true); 1454 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); 1455 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue()); 1456 // In presence of finite 'safelen', it may be unsafe to mark all 1457 // the memory instructions parallel, because loop-carried 1458 // dependences of 'safelen' iterations are possible. 1459 if (!IsMonotonic) 1460 CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>()); 1461 } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) { 1462 RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(), 1463 /*ignoreResult=*/true); 1464 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); 1465 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue()); 1466 // In presence of finite 'safelen', it may be unsafe to mark all 1467 // the memory instructions parallel, because loop-carried 1468 // dependences of 'safelen' iterations are possible. 1469 CGF.LoopStack.setParallel(false); 1470 } 1471 } 1472 1473 void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D, 1474 bool IsMonotonic) { 1475 // Walk clauses and process safelen/lastprivate. 1476 LoopStack.setParallel(!IsMonotonic); 1477 LoopStack.setVectorizeEnable(true); 1478 emitSimdlenSafelenClause(*this, D, IsMonotonic); 1479 } 1480 1481 void CodeGenFunction::EmitOMPSimdFinal( 1482 const OMPLoopDirective &D, 1483 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) { 1484 if (!HaveInsertPoint()) 1485 return; 1486 llvm::BasicBlock *DoneBB = nullptr; 1487 auto IC = D.counters().begin(); 1488 auto IPC = D.private_counters().begin(); 1489 for (auto F : D.finals()) { 1490 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl()); 1491 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl()); 1492 auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD); 1493 if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) || 1494 OrigVD->hasGlobalStorage() || CED) { 1495 if (!DoneBB) { 1496 if (auto *Cond = CondGen(*this)) { 1497 // If the first post-update expression is found, emit conditional 1498 // block if it was requested. 1499 auto *ThenBB = createBasicBlock(".omp.final.then"); 1500 DoneBB = createBasicBlock(".omp.final.done"); 1501 Builder.CreateCondBr(Cond, ThenBB, DoneBB); 1502 EmitBlock(ThenBB); 1503 } 1504 } 1505 Address OrigAddr = Address::invalid(); 1506 if (CED) 1507 OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress(); 1508 else { 1509 DeclRefExpr DRE(const_cast<VarDecl *>(PrivateVD), 1510 /*RefersToEnclosingVariableOrCapture=*/false, 1511 (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc()); 1512 OrigAddr = EmitLValue(&DRE).getAddress(); 1513 } 1514 OMPPrivateScope VarScope(*this); 1515 VarScope.addPrivate(OrigVD, 1516 [OrigAddr]() -> Address { return OrigAddr; }); 1517 (void)VarScope.Privatize(); 1518 EmitIgnoredExpr(F); 1519 } 1520 ++IC; 1521 ++IPC; 1522 } 1523 if (DoneBB) 1524 EmitBlock(DoneBB, /*IsFinished=*/true); 1525 } 1526 1527 static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF, 1528 const OMPLoopDirective &S, 1529 CodeGenFunction::JumpDest LoopExit) { 1530 CGF.EmitOMPLoopBody(S, LoopExit); 1531 CGF.EmitStopPoint(&S); 1532 } 1533 1534 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { 1535 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 1536 OMPLoopScope PreInitScope(CGF, S); 1537 // if (PreCond) { 1538 // for (IV in 0..LastIteration) BODY; 1539 // <Final counter/linear vars updates>; 1540 // } 1541 // 1542 1543 // Emit: if (PreCond) - begin. 1544 // If the condition constant folds and can be elided, avoid emitting the 1545 // whole loop. 1546 bool CondConstant; 1547 llvm::BasicBlock *ContBlock = nullptr; 1548 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { 1549 if (!CondConstant) 1550 return; 1551 } else { 1552 auto *ThenBlock = CGF.createBasicBlock("simd.if.then"); 1553 ContBlock = CGF.createBasicBlock("simd.if.end"); 1554 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock, 1555 CGF.getProfileCount(&S)); 1556 CGF.EmitBlock(ThenBlock); 1557 CGF.incrementProfileCounter(&S); 1558 } 1559 1560 // Emit the loop iteration variable. 1561 const Expr *IVExpr = S.getIterationVariable(); 1562 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); 1563 CGF.EmitVarDecl(*IVDecl); 1564 CGF.EmitIgnoredExpr(S.getInit()); 1565 1566 // Emit the iterations count variable. 1567 // If it is not a variable, Sema decided to calculate iterations count on 1568 // each iteration (e.g., it is foldable into a constant). 1569 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 1570 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 1571 // Emit calculation of the iterations count. 1572 CGF.EmitIgnoredExpr(S.getCalcLastIteration()); 1573 } 1574 1575 CGF.EmitOMPSimdInit(S); 1576 1577 emitAlignedClause(CGF, S); 1578 (void)CGF.EmitOMPLinearClauseInit(S); 1579 { 1580 OMPPrivateScope LoopScope(CGF); 1581 CGF.EmitOMPPrivateLoopCounters(S, LoopScope); 1582 CGF.EmitOMPLinearClause(S, LoopScope); 1583 CGF.EmitOMPPrivateClause(S, LoopScope); 1584 CGF.EmitOMPReductionClauseInit(S, LoopScope); 1585 bool HasLastprivateClause = 1586 CGF.EmitOMPLastprivateClauseInit(S, LoopScope); 1587 (void)LoopScope.Privatize(); 1588 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), 1589 S.getInc(), 1590 [&S](CodeGenFunction &CGF) { 1591 CGF.EmitOMPLoopBody(S, JumpDest()); 1592 CGF.EmitStopPoint(&S); 1593 }, 1594 [](CodeGenFunction &) {}); 1595 CGF.EmitOMPSimdFinal( 1596 S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 1597 // Emit final copy of the lastprivate variables at the end of loops. 1598 if (HasLastprivateClause) 1599 CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true); 1600 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd); 1601 emitPostUpdateForReductionClause( 1602 CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 1603 } 1604 CGF.EmitOMPLinearClauseFinal( 1605 S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 1606 // Emit: if (PreCond) - end. 1607 if (ContBlock) { 1608 CGF.EmitBranch(ContBlock); 1609 CGF.EmitBlock(ContBlock, true); 1610 } 1611 }; 1612 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 1613 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); 1614 } 1615 1616 void CodeGenFunction::EmitOMPOuterLoop( 1617 bool DynamicOrOrdered, bool IsMonotonic, const OMPLoopDirective &S, 1618 CodeGenFunction::OMPPrivateScope &LoopScope, 1619 const CodeGenFunction::OMPLoopArguments &LoopArgs, 1620 const CodeGenFunction::CodeGenLoopTy &CodeGenLoop, 1621 const CodeGenFunction::CodeGenOrderedTy &CodeGenOrdered) { 1622 auto &RT = CGM.getOpenMPRuntime(); 1623 1624 const Expr *IVExpr = S.getIterationVariable(); 1625 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 1626 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 1627 1628 auto LoopExit = getJumpDestInCurrentScope("omp.dispatch.end"); 1629 1630 // Start the loop with a block that tests the condition. 1631 auto CondBlock = createBasicBlock("omp.dispatch.cond"); 1632 EmitBlock(CondBlock); 1633 const SourceRange &R = S.getSourceRange(); 1634 LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()), 1635 SourceLocToDebugLoc(R.getEnd())); 1636 1637 llvm::Value *BoolCondVal = nullptr; 1638 if (!DynamicOrOrdered) { 1639 // UB = min(UB, GlobalUB) or 1640 // UB = min(UB, PrevUB) for combined loop sharing constructs (e.g. 1641 // 'distribute parallel for') 1642 EmitIgnoredExpr(LoopArgs.EUB); 1643 // IV = LB 1644 EmitIgnoredExpr(LoopArgs.Init); 1645 // IV < UB 1646 BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond); 1647 } else { 1648 BoolCondVal = 1649 RT.emitForNext(*this, S.getLocStart(), IVSize, IVSigned, LoopArgs.IL, 1650 LoopArgs.LB, LoopArgs.UB, LoopArgs.ST); 1651 } 1652 1653 // If there are any cleanups between here and the loop-exit scope, 1654 // create a block to stage a loop exit along. 1655 auto ExitBlock = LoopExit.getBlock(); 1656 if (LoopScope.requiresCleanups()) 1657 ExitBlock = createBasicBlock("omp.dispatch.cleanup"); 1658 1659 auto LoopBody = createBasicBlock("omp.dispatch.body"); 1660 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); 1661 if (ExitBlock != LoopExit.getBlock()) { 1662 EmitBlock(ExitBlock); 1663 EmitBranchThroughCleanup(LoopExit); 1664 } 1665 EmitBlock(LoopBody); 1666 1667 // Emit "IV = LB" (in case of static schedule, we have already calculated new 1668 // LB for loop condition and emitted it above). 1669 if (DynamicOrOrdered) 1670 EmitIgnoredExpr(LoopArgs.Init); 1671 1672 // Create a block for the increment. 1673 auto Continue = getJumpDestInCurrentScope("omp.dispatch.inc"); 1674 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 1675 1676 // Generate !llvm.loop.parallel metadata for loads and stores for loops 1677 // with dynamic/guided scheduling and without ordered clause. 1678 if (!isOpenMPSimdDirective(S.getDirectiveKind())) 1679 LoopStack.setParallel(!IsMonotonic); 1680 else 1681 EmitOMPSimdInit(S, IsMonotonic); 1682 1683 SourceLocation Loc = S.getLocStart(); 1684 1685 // when 'distribute' is not combined with a 'for': 1686 // while (idx <= UB) { BODY; ++idx; } 1687 // when 'distribute' is combined with a 'for' 1688 // (e.g. 'distribute parallel for') 1689 // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; } 1690 EmitOMPInnerLoop( 1691 S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr, 1692 [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) { 1693 CodeGenLoop(CGF, S, LoopExit); 1694 }, 1695 [IVSize, IVSigned, Loc, &CodeGenOrdered](CodeGenFunction &CGF) { 1696 CodeGenOrdered(CGF, Loc, IVSize, IVSigned); 1697 }); 1698 1699 EmitBlock(Continue.getBlock()); 1700 BreakContinueStack.pop_back(); 1701 if (!DynamicOrOrdered) { 1702 // Emit "LB = LB + Stride", "UB = UB + Stride". 1703 EmitIgnoredExpr(LoopArgs.NextLB); 1704 EmitIgnoredExpr(LoopArgs.NextUB); 1705 } 1706 1707 EmitBranch(CondBlock); 1708 LoopStack.pop(); 1709 // Emit the fall-through block. 1710 EmitBlock(LoopExit.getBlock()); 1711 1712 // Tell the runtime we are done. 1713 auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) { 1714 if (!DynamicOrOrdered) 1715 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd(), 1716 S.getDirectiveKind()); 1717 }; 1718 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen); 1719 } 1720 1721 void CodeGenFunction::EmitOMPForOuterLoop( 1722 const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic, 1723 const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, 1724 const OMPLoopArguments &LoopArgs, 1725 const CodeGenDispatchBoundsTy &CGDispatchBounds) { 1726 auto &RT = CGM.getOpenMPRuntime(); 1727 1728 // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime). 1729 const bool DynamicOrOrdered = 1730 Ordered || RT.isDynamic(ScheduleKind.Schedule); 1731 1732 assert((Ordered || 1733 !RT.isStaticNonchunked(ScheduleKind.Schedule, 1734 LoopArgs.Chunk != nullptr)) && 1735 "static non-chunked schedule does not need outer loop"); 1736 1737 // Emit outer loop. 1738 // 1739 // OpenMP [2.7.1, Loop Construct, Description, table 2-1] 1740 // When schedule(dynamic,chunk_size) is specified, the iterations are 1741 // distributed to threads in the team in chunks as the threads request them. 1742 // Each thread executes a chunk of iterations, then requests another chunk, 1743 // until no chunks remain to be distributed. Each chunk contains chunk_size 1744 // iterations, except for the last chunk to be distributed, which may have 1745 // fewer iterations. When no chunk_size is specified, it defaults to 1. 1746 // 1747 // When schedule(guided,chunk_size) is specified, the iterations are assigned 1748 // to threads in the team in chunks as the executing threads request them. 1749 // Each thread executes a chunk of iterations, then requests another chunk, 1750 // until no chunks remain to be assigned. For a chunk_size of 1, the size of 1751 // each chunk is proportional to the number of unassigned iterations divided 1752 // by the number of threads in the team, decreasing to 1. For a chunk_size 1753 // with value k (greater than 1), the size of each chunk is determined in the 1754 // same way, with the restriction that the chunks do not contain fewer than k 1755 // iterations (except for the last chunk to be assigned, which may have fewer 1756 // than k iterations). 1757 // 1758 // When schedule(auto) is specified, the decision regarding scheduling is 1759 // delegated to the compiler and/or runtime system. The programmer gives the 1760 // implementation the freedom to choose any possible mapping of iterations to 1761 // threads in the team. 1762 // 1763 // When schedule(runtime) is specified, the decision regarding scheduling is 1764 // deferred until run time, and the schedule and chunk size are taken from the 1765 // run-sched-var ICV. If the ICV is set to auto, the schedule is 1766 // implementation defined 1767 // 1768 // while(__kmpc_dispatch_next(&LB, &UB)) { 1769 // idx = LB; 1770 // while (idx <= UB) { BODY; ++idx; 1771 // __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only. 1772 // } // inner loop 1773 // } 1774 // 1775 // OpenMP [2.7.1, Loop Construct, Description, table 2-1] 1776 // When schedule(static, chunk_size) is specified, iterations are divided into 1777 // chunks of size chunk_size, and the chunks are assigned to the threads in 1778 // the team in a round-robin fashion in the order of the thread number. 1779 // 1780 // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) { 1781 // while (idx <= UB) { BODY; ++idx; } // inner loop 1782 // LB = LB + ST; 1783 // UB = UB + ST; 1784 // } 1785 // 1786 1787 const Expr *IVExpr = S.getIterationVariable(); 1788 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 1789 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 1790 1791 if (DynamicOrOrdered) { 1792 auto DispatchBounds = CGDispatchBounds(*this, S, LoopArgs.LB, LoopArgs.UB); 1793 llvm::Value *LBVal = DispatchBounds.first; 1794 llvm::Value *UBVal = DispatchBounds.second; 1795 CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal, 1796 LoopArgs.Chunk}; 1797 RT.emitForDispatchInit(*this, S.getLocStart(), ScheduleKind, IVSize, 1798 IVSigned, Ordered, DipatchRTInputValues); 1799 } else { 1800 CGOpenMPRuntime::StaticRTInput StaticInit( 1801 IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB, 1802 LoopArgs.ST, LoopArgs.Chunk); 1803 RT.emitForStaticInit(*this, S.getLocStart(), S.getDirectiveKind(), 1804 ScheduleKind, StaticInit); 1805 } 1806 1807 auto &&CodeGenOrdered = [Ordered](CodeGenFunction &CGF, SourceLocation Loc, 1808 const unsigned IVSize, 1809 const bool IVSigned) { 1810 if (Ordered) { 1811 CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(CGF, Loc, IVSize, 1812 IVSigned); 1813 } 1814 }; 1815 1816 OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST, 1817 LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB); 1818 OuterLoopArgs.IncExpr = S.getInc(); 1819 OuterLoopArgs.Init = S.getInit(); 1820 OuterLoopArgs.Cond = S.getCond(); 1821 OuterLoopArgs.NextLB = S.getNextLowerBound(); 1822 OuterLoopArgs.NextUB = S.getNextUpperBound(); 1823 EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs, 1824 emitOMPLoopBodyWithStopPoint, CodeGenOrdered); 1825 } 1826 1827 static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc, 1828 const unsigned IVSize, const bool IVSigned) {} 1829 1830 void CodeGenFunction::EmitOMPDistributeOuterLoop( 1831 OpenMPDistScheduleClauseKind ScheduleKind, const OMPLoopDirective &S, 1832 OMPPrivateScope &LoopScope, const OMPLoopArguments &LoopArgs, 1833 const CodeGenLoopTy &CodeGenLoopContent) { 1834 1835 auto &RT = CGM.getOpenMPRuntime(); 1836 1837 // Emit outer loop. 1838 // Same behavior as a OMPForOuterLoop, except that schedule cannot be 1839 // dynamic 1840 // 1841 1842 const Expr *IVExpr = S.getIterationVariable(); 1843 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 1844 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 1845 1846 CGOpenMPRuntime::StaticRTInput StaticInit( 1847 IVSize, IVSigned, /* Ordered = */ false, LoopArgs.IL, LoopArgs.LB, 1848 LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk); 1849 RT.emitDistributeStaticInit(*this, S.getLocStart(), ScheduleKind, StaticInit); 1850 1851 // for combined 'distribute' and 'for' the increment expression of distribute 1852 // is store in DistInc. For 'distribute' alone, it is in Inc. 1853 Expr *IncExpr; 1854 if (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())) 1855 IncExpr = S.getDistInc(); 1856 else 1857 IncExpr = S.getInc(); 1858 1859 // this routine is shared by 'omp distribute parallel for' and 1860 // 'omp distribute': select the right EUB expression depending on the 1861 // directive 1862 OMPLoopArguments OuterLoopArgs; 1863 OuterLoopArgs.LB = LoopArgs.LB; 1864 OuterLoopArgs.UB = LoopArgs.UB; 1865 OuterLoopArgs.ST = LoopArgs.ST; 1866 OuterLoopArgs.IL = LoopArgs.IL; 1867 OuterLoopArgs.Chunk = LoopArgs.Chunk; 1868 OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 1869 ? S.getCombinedEnsureUpperBound() 1870 : S.getEnsureUpperBound(); 1871 OuterLoopArgs.IncExpr = IncExpr; 1872 OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 1873 ? S.getCombinedInit() 1874 : S.getInit(); 1875 OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 1876 ? S.getCombinedCond() 1877 : S.getCond(); 1878 OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 1879 ? S.getCombinedNextLowerBound() 1880 : S.getNextLowerBound(); 1881 OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 1882 ? S.getCombinedNextUpperBound() 1883 : S.getNextUpperBound(); 1884 1885 EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, S, 1886 LoopScope, OuterLoopArgs, CodeGenLoopContent, 1887 emitEmptyOrdered); 1888 } 1889 1890 /// Emit a helper variable and return corresponding lvalue. 1891 static LValue EmitOMPHelperVar(CodeGenFunction &CGF, 1892 const DeclRefExpr *Helper) { 1893 auto VDecl = cast<VarDecl>(Helper->getDecl()); 1894 CGF.EmitVarDecl(*VDecl); 1895 return CGF.EmitLValue(Helper); 1896 } 1897 1898 static std::pair<LValue, LValue> 1899 emitDistributeParallelForInnerBounds(CodeGenFunction &CGF, 1900 const OMPExecutableDirective &S) { 1901 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S); 1902 LValue LB = 1903 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable())); 1904 LValue UB = 1905 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable())); 1906 1907 // When composing 'distribute' with 'for' (e.g. as in 'distribute 1908 // parallel for') we need to use the 'distribute' 1909 // chunk lower and upper bounds rather than the whole loop iteration 1910 // space. These are parameters to the outlined function for 'parallel' 1911 // and we copy the bounds of the previous schedule into the 1912 // the current ones. 1913 LValue PrevLB = CGF.EmitLValue(LS.getPrevLowerBoundVariable()); 1914 LValue PrevUB = CGF.EmitLValue(LS.getPrevUpperBoundVariable()); 1915 llvm::Value *PrevLBVal = CGF.EmitLoadOfScalar(PrevLB, SourceLocation()); 1916 PrevLBVal = CGF.EmitScalarConversion( 1917 PrevLBVal, LS.getPrevLowerBoundVariable()->getType(), 1918 LS.getIterationVariable()->getType(), SourceLocation()); 1919 llvm::Value *PrevUBVal = CGF.EmitLoadOfScalar(PrevUB, SourceLocation()); 1920 PrevUBVal = CGF.EmitScalarConversion( 1921 PrevUBVal, LS.getPrevUpperBoundVariable()->getType(), 1922 LS.getIterationVariable()->getType(), SourceLocation()); 1923 1924 CGF.EmitStoreOfScalar(PrevLBVal, LB); 1925 CGF.EmitStoreOfScalar(PrevUBVal, UB); 1926 1927 return {LB, UB}; 1928 } 1929 1930 /// if the 'for' loop has a dispatch schedule (e.g. dynamic, guided) then 1931 /// we need to use the LB and UB expressions generated by the worksharing 1932 /// code generation support, whereas in non combined situations we would 1933 /// just emit 0 and the LastIteration expression 1934 /// This function is necessary due to the difference of the LB and UB 1935 /// types for the RT emission routines for 'for_static_init' and 1936 /// 'for_dispatch_init' 1937 static std::pair<llvm::Value *, llvm::Value *> 1938 emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF, 1939 const OMPExecutableDirective &S, 1940 Address LB, Address UB) { 1941 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S); 1942 const Expr *IVExpr = LS.getIterationVariable(); 1943 // when implementing a dynamic schedule for a 'for' combined with a 1944 // 'distribute' (e.g. 'distribute parallel for'), the 'for' loop 1945 // is not normalized as each team only executes its own assigned 1946 // distribute chunk 1947 QualType IteratorTy = IVExpr->getType(); 1948 llvm::Value *LBVal = CGF.EmitLoadOfScalar(LB, /*Volatile=*/false, IteratorTy, 1949 SourceLocation()); 1950 llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, /*Volatile=*/false, IteratorTy, 1951 SourceLocation()); 1952 return {LBVal, UBVal}; 1953 } 1954 1955 static void emitDistributeParallelForDistributeInnerBoundParams( 1956 CodeGenFunction &CGF, const OMPExecutableDirective &S, 1957 llvm::SmallVectorImpl<llvm::Value *> &CapturedVars) { 1958 const auto &Dir = cast<OMPLoopDirective>(S); 1959 LValue LB = 1960 CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable())); 1961 auto LBCast = CGF.Builder.CreateIntCast( 1962 CGF.Builder.CreateLoad(LB.getAddress()), CGF.SizeTy, /*isSigned=*/false); 1963 CapturedVars.push_back(LBCast); 1964 LValue UB = 1965 CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable())); 1966 1967 auto UBCast = CGF.Builder.CreateIntCast( 1968 CGF.Builder.CreateLoad(UB.getAddress()), CGF.SizeTy, /*isSigned=*/false); 1969 CapturedVars.push_back(UBCast); 1970 } 1971 1972 static void 1973 emitInnerParallelForWhenCombined(CodeGenFunction &CGF, 1974 const OMPLoopDirective &S, 1975 CodeGenFunction::JumpDest LoopExit) { 1976 auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF, 1977 PrePostActionTy &) { 1978 CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(), 1979 emitDistributeParallelForInnerBounds, 1980 emitDistributeParallelForDispatchBounds); 1981 }; 1982 1983 emitCommonOMPParallelDirective( 1984 CGF, S, OMPD_for, CGInlinedWorksharingLoop, 1985 emitDistributeParallelForDistributeInnerBoundParams); 1986 } 1987 1988 void CodeGenFunction::EmitOMPDistributeParallelForDirective( 1989 const OMPDistributeParallelForDirective &S) { 1990 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 1991 CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined, 1992 S.getDistInc()); 1993 }; 1994 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 1995 OMPCancelStackRAII CancelRegion(*this, OMPD_distribute_parallel_for, 1996 /*HasCancel=*/false); 1997 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen, 1998 /*HasCancel=*/false); 1999 } 2000 2001 void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective( 2002 const OMPDistributeParallelForSimdDirective &S) { 2003 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2004 CGM.getOpenMPRuntime().emitInlinedDirective( 2005 *this, OMPD_distribute_parallel_for_simd, 2006 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2007 OMPLoopScope PreInitScope(CGF, S); 2008 CGF.EmitStmt( 2009 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2010 }); 2011 } 2012 2013 void CodeGenFunction::EmitOMPDistributeSimdDirective( 2014 const OMPDistributeSimdDirective &S) { 2015 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2016 CGM.getOpenMPRuntime().emitInlinedDirective( 2017 *this, OMPD_distribute_simd, 2018 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2019 OMPLoopScope PreInitScope(CGF, S); 2020 CGF.EmitStmt( 2021 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2022 }); 2023 } 2024 2025 void CodeGenFunction::EmitOMPTargetParallelForSimdDirective( 2026 const OMPTargetParallelForSimdDirective &S) { 2027 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2028 CGM.getOpenMPRuntime().emitInlinedDirective( 2029 *this, OMPD_target_parallel_for_simd, 2030 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2031 OMPLoopScope PreInitScope(CGF, S); 2032 CGF.EmitStmt( 2033 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2034 }); 2035 } 2036 2037 void CodeGenFunction::EmitOMPTargetSimdDirective( 2038 const OMPTargetSimdDirective &S) { 2039 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2040 CGM.getOpenMPRuntime().emitInlinedDirective( 2041 *this, OMPD_target_simd, [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2042 OMPLoopScope PreInitScope(CGF, S); 2043 CGF.EmitStmt( 2044 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2045 }); 2046 } 2047 2048 void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective( 2049 const OMPTeamsDistributeSimdDirective &S) { 2050 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2051 CGM.getOpenMPRuntime().emitInlinedDirective( 2052 *this, OMPD_teams_distribute_simd, 2053 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2054 OMPLoopScope PreInitScope(CGF, S); 2055 CGF.EmitStmt( 2056 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2057 }); 2058 } 2059 2060 void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective( 2061 const OMPTeamsDistributeParallelForSimdDirective &S) { 2062 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2063 CGM.getOpenMPRuntime().emitInlinedDirective( 2064 *this, OMPD_teams_distribute_parallel_for_simd, 2065 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2066 OMPLoopScope PreInitScope(CGF, S); 2067 CGF.EmitStmt( 2068 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2069 }); 2070 } 2071 2072 void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective( 2073 const OMPTeamsDistributeParallelForDirective &S) { 2074 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2075 CGM.getOpenMPRuntime().emitInlinedDirective( 2076 *this, OMPD_teams_distribute_parallel_for, 2077 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2078 OMPLoopScope PreInitScope(CGF, S); 2079 CGF.EmitStmt( 2080 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2081 }); 2082 } 2083 2084 void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective( 2085 const OMPTargetTeamsDistributeDirective &S) { 2086 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2087 CGM.getOpenMPRuntime().emitInlinedDirective( 2088 *this, OMPD_target_teams_distribute, 2089 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2090 CGF.EmitStmt( 2091 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2092 }); 2093 } 2094 2095 void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective( 2096 const OMPTargetTeamsDistributeParallelForDirective &S) { 2097 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2098 CGM.getOpenMPRuntime().emitInlinedDirective( 2099 *this, OMPD_target_teams_distribute_parallel_for, 2100 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2101 CGF.EmitStmt( 2102 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2103 }); 2104 } 2105 2106 void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective( 2107 const OMPTargetTeamsDistributeParallelForSimdDirective &S) { 2108 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2109 CGM.getOpenMPRuntime().emitInlinedDirective( 2110 *this, OMPD_target_teams_distribute_parallel_for_simd, 2111 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2112 CGF.EmitStmt( 2113 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2114 }); 2115 } 2116 2117 void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective( 2118 const OMPTargetTeamsDistributeSimdDirective &S) { 2119 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2120 CGM.getOpenMPRuntime().emitInlinedDirective( 2121 *this, OMPD_target_teams_distribute_simd, 2122 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2123 CGF.EmitStmt( 2124 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2125 }); 2126 } 2127 2128 namespace { 2129 struct ScheduleKindModifiersTy { 2130 OpenMPScheduleClauseKind Kind; 2131 OpenMPScheduleClauseModifier M1; 2132 OpenMPScheduleClauseModifier M2; 2133 ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind, 2134 OpenMPScheduleClauseModifier M1, 2135 OpenMPScheduleClauseModifier M2) 2136 : Kind(Kind), M1(M1), M2(M2) {} 2137 }; 2138 } // namespace 2139 2140 bool CodeGenFunction::EmitOMPWorksharingLoop( 2141 const OMPLoopDirective &S, Expr *EUB, 2142 const CodeGenLoopBoundsTy &CodeGenLoopBounds, 2143 const CodeGenDispatchBoundsTy &CGDispatchBounds) { 2144 // Emit the loop iteration variable. 2145 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable()); 2146 auto IVDecl = cast<VarDecl>(IVExpr->getDecl()); 2147 EmitVarDecl(*IVDecl); 2148 2149 // Emit the iterations count variable. 2150 // If it is not a variable, Sema decided to calculate iterations count on each 2151 // iteration (e.g., it is foldable into a constant). 2152 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 2153 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 2154 // Emit calculation of the iterations count. 2155 EmitIgnoredExpr(S.getCalcLastIteration()); 2156 } 2157 2158 auto &RT = CGM.getOpenMPRuntime(); 2159 2160 bool HasLastprivateClause; 2161 // Check pre-condition. 2162 { 2163 OMPLoopScope PreInitScope(*this, S); 2164 // Skip the entire loop if we don't meet the precondition. 2165 // If the condition constant folds and can be elided, avoid emitting the 2166 // whole loop. 2167 bool CondConstant; 2168 llvm::BasicBlock *ContBlock = nullptr; 2169 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { 2170 if (!CondConstant) 2171 return false; 2172 } else { 2173 auto *ThenBlock = createBasicBlock("omp.precond.then"); 2174 ContBlock = createBasicBlock("omp.precond.end"); 2175 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock, 2176 getProfileCount(&S)); 2177 EmitBlock(ThenBlock); 2178 incrementProfileCounter(&S); 2179 } 2180 2181 bool Ordered = false; 2182 if (auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) { 2183 if (OrderedClause->getNumForLoops()) 2184 RT.emitDoacrossInit(*this, S); 2185 else 2186 Ordered = true; 2187 } 2188 2189 llvm::DenseSet<const Expr *> EmittedFinals; 2190 emitAlignedClause(*this, S); 2191 bool HasLinears = EmitOMPLinearClauseInit(S); 2192 // Emit helper vars inits. 2193 2194 std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S); 2195 LValue LB = Bounds.first; 2196 LValue UB = Bounds.second; 2197 LValue ST = 2198 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); 2199 LValue IL = 2200 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); 2201 2202 // Emit 'then' code. 2203 { 2204 OMPPrivateScope LoopScope(*this); 2205 if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) { 2206 // Emit implicit barrier to synchronize threads and avoid data races on 2207 // initialization of firstprivate variables and post-update of 2208 // lastprivate variables. 2209 CGM.getOpenMPRuntime().emitBarrierCall( 2210 *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, 2211 /*ForceSimpleCall=*/true); 2212 } 2213 EmitOMPPrivateClause(S, LoopScope); 2214 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope); 2215 EmitOMPReductionClauseInit(S, LoopScope); 2216 EmitOMPPrivateLoopCounters(S, LoopScope); 2217 EmitOMPLinearClause(S, LoopScope); 2218 (void)LoopScope.Privatize(); 2219 2220 // Detect the loop schedule kind and chunk. 2221 llvm::Value *Chunk = nullptr; 2222 OpenMPScheduleTy ScheduleKind; 2223 if (auto *C = S.getSingleClause<OMPScheduleClause>()) { 2224 ScheduleKind.Schedule = C->getScheduleKind(); 2225 ScheduleKind.M1 = C->getFirstScheduleModifier(); 2226 ScheduleKind.M2 = C->getSecondScheduleModifier(); 2227 if (const auto *Ch = C->getChunkSize()) { 2228 Chunk = EmitScalarExpr(Ch); 2229 Chunk = EmitScalarConversion(Chunk, Ch->getType(), 2230 S.getIterationVariable()->getType(), 2231 S.getLocStart()); 2232 } 2233 } 2234 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 2235 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 2236 // OpenMP 4.5, 2.7.1 Loop Construct, Description. 2237 // If the static schedule kind is specified or if the ordered clause is 2238 // specified, and if no monotonic modifier is specified, the effect will 2239 // be as if the monotonic modifier was specified. 2240 if (RT.isStaticNonchunked(ScheduleKind.Schedule, 2241 /* Chunked */ Chunk != nullptr) && 2242 !Ordered) { 2243 if (isOpenMPSimdDirective(S.getDirectiveKind())) 2244 EmitOMPSimdInit(S, /*IsMonotonic=*/true); 2245 // OpenMP [2.7.1, Loop Construct, Description, table 2-1] 2246 // When no chunk_size is specified, the iteration space is divided into 2247 // chunks that are approximately equal in size, and at most one chunk is 2248 // distributed to each thread. Note that the size of the chunks is 2249 // unspecified in this case. 2250 CGOpenMPRuntime::StaticRTInput StaticInit( 2251 IVSize, IVSigned, Ordered, IL.getAddress(), LB.getAddress(), 2252 UB.getAddress(), ST.getAddress()); 2253 RT.emitForStaticInit(*this, S.getLocStart(), S.getDirectiveKind(), 2254 ScheduleKind, StaticInit); 2255 auto LoopExit = 2256 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit")); 2257 // UB = min(UB, GlobalUB); 2258 EmitIgnoredExpr(S.getEnsureUpperBound()); 2259 // IV = LB; 2260 EmitIgnoredExpr(S.getInit()); 2261 // while (idx <= UB) { BODY; ++idx; } 2262 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), 2263 S.getInc(), 2264 [&S, LoopExit](CodeGenFunction &CGF) { 2265 CGF.EmitOMPLoopBody(S, LoopExit); 2266 CGF.EmitStopPoint(&S); 2267 }, 2268 [](CodeGenFunction &) {}); 2269 EmitBlock(LoopExit.getBlock()); 2270 // Tell the runtime we are done. 2271 auto &&CodeGen = [&S](CodeGenFunction &CGF) { 2272 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd(), 2273 S.getDirectiveKind()); 2274 }; 2275 OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen); 2276 } else { 2277 const bool IsMonotonic = 2278 Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static || 2279 ScheduleKind.Schedule == OMPC_SCHEDULE_unknown || 2280 ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic || 2281 ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic; 2282 // Emit the outer loop, which requests its work chunk [LB..UB] from 2283 // runtime and runs the inner loop to process it. 2284 const OMPLoopArguments LoopArguments(LB.getAddress(), UB.getAddress(), 2285 ST.getAddress(), IL.getAddress(), 2286 Chunk, EUB); 2287 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered, 2288 LoopArguments, CGDispatchBounds); 2289 } 2290 if (isOpenMPSimdDirective(S.getDirectiveKind())) { 2291 EmitOMPSimdFinal(S, 2292 [&](CodeGenFunction &CGF) -> llvm::Value * { 2293 return CGF.Builder.CreateIsNotNull( 2294 CGF.EmitLoadOfScalar(IL, S.getLocStart())); 2295 }); 2296 } 2297 EmitOMPReductionClauseFinal( 2298 S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind()) 2299 ? /*Parallel and Simd*/ OMPD_parallel_for_simd 2300 : /*Parallel only*/ OMPD_parallel); 2301 // Emit post-update of the reduction variables if IsLastIter != 0. 2302 emitPostUpdateForReductionClause( 2303 *this, S, [&](CodeGenFunction &CGF) -> llvm::Value * { 2304 return CGF.Builder.CreateIsNotNull( 2305 CGF.EmitLoadOfScalar(IL, S.getLocStart())); 2306 }); 2307 // Emit final copy of the lastprivate variables if IsLastIter != 0. 2308 if (HasLastprivateClause) 2309 EmitOMPLastprivateClauseFinal( 2310 S, isOpenMPSimdDirective(S.getDirectiveKind()), 2311 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getLocStart()))); 2312 } 2313 EmitOMPLinearClauseFinal(S, [&](CodeGenFunction &CGF) -> llvm::Value * { 2314 return CGF.Builder.CreateIsNotNull( 2315 CGF.EmitLoadOfScalar(IL, S.getLocStart())); 2316 }); 2317 // We're now done with the loop, so jump to the continuation block. 2318 if (ContBlock) { 2319 EmitBranch(ContBlock); 2320 EmitBlock(ContBlock, true); 2321 } 2322 } 2323 return HasLastprivateClause; 2324 } 2325 2326 /// The following two functions generate expressions for the loop lower 2327 /// and upper bounds in case of static and dynamic (dispatch) schedule 2328 /// of the associated 'for' or 'distribute' loop. 2329 static std::pair<LValue, LValue> 2330 emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S) { 2331 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S); 2332 LValue LB = 2333 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable())); 2334 LValue UB = 2335 EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable())); 2336 return {LB, UB}; 2337 } 2338 2339 /// When dealing with dispatch schedules (e.g. dynamic, guided) we do not 2340 /// consider the lower and upper bound expressions generated by the 2341 /// worksharing loop support, but we use 0 and the iteration space size as 2342 /// constants 2343 static std::pair<llvm::Value *, llvm::Value *> 2344 emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S, 2345 Address LB, Address UB) { 2346 const OMPLoopDirective &LS = cast<OMPLoopDirective>(S); 2347 const Expr *IVExpr = LS.getIterationVariable(); 2348 const unsigned IVSize = CGF.getContext().getTypeSize(IVExpr->getType()); 2349 llvm::Value *LBVal = CGF.Builder.getIntN(IVSize, 0); 2350 llvm::Value *UBVal = CGF.EmitScalarExpr(LS.getLastIteration()); 2351 return {LBVal, UBVal}; 2352 } 2353 2354 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { 2355 bool HasLastprivates = false; 2356 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF, 2357 PrePostActionTy &) { 2358 OMPCancelStackRAII CancelRegion(CGF, OMPD_for, S.hasCancel()); 2359 HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), 2360 emitForLoopBounds, 2361 emitDispatchForLoopBounds); 2362 }; 2363 { 2364 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2365 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, 2366 S.hasCancel()); 2367 } 2368 2369 // Emit an implicit barrier at the end. 2370 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { 2371 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for); 2372 } 2373 } 2374 2375 void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { 2376 bool HasLastprivates = false; 2377 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF, 2378 PrePostActionTy &) { 2379 HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), 2380 emitForLoopBounds, 2381 emitDispatchForLoopBounds); 2382 }; 2383 { 2384 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2385 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); 2386 } 2387 2388 // Emit an implicit barrier at the end. 2389 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { 2390 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for); 2391 } 2392 } 2393 2394 static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, 2395 const Twine &Name, 2396 llvm::Value *Init = nullptr) { 2397 auto LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty); 2398 if (Init) 2399 CGF.EmitStoreThroughLValue(RValue::get(Init), LVal, /*isInit*/ true); 2400 return LVal; 2401 } 2402 2403 void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { 2404 auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt(); 2405 auto *CS = dyn_cast<CompoundStmt>(Stmt); 2406 bool HasLastprivates = false; 2407 auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF, 2408 PrePostActionTy &) { 2409 auto &C = CGF.CGM.getContext(); 2410 auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 2411 // Emit helper vars inits. 2412 LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.", 2413 CGF.Builder.getInt32(0)); 2414 auto *GlobalUBVal = CS != nullptr ? CGF.Builder.getInt32(CS->size() - 1) 2415 : CGF.Builder.getInt32(0); 2416 LValue UB = 2417 createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal); 2418 LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.", 2419 CGF.Builder.getInt32(1)); 2420 LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.", 2421 CGF.Builder.getInt32(0)); 2422 // Loop counter. 2423 LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv."); 2424 OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue); 2425 CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV); 2426 OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue); 2427 CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB); 2428 // Generate condition for loop. 2429 BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue, 2430 OK_Ordinary, S.getLocStart(), FPOptions()); 2431 // Increment for loop counter. 2432 UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary, 2433 S.getLocStart()); 2434 auto BodyGen = [Stmt, CS, &S, &IV](CodeGenFunction &CGF) { 2435 // Iterate through all sections and emit a switch construct: 2436 // switch (IV) { 2437 // case 0: 2438 // <SectionStmt[0]>; 2439 // break; 2440 // ... 2441 // case <NumSection> - 1: 2442 // <SectionStmt[<NumSection> - 1]>; 2443 // break; 2444 // } 2445 // .omp.sections.exit: 2446 auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit"); 2447 auto *SwitchStmt = CGF.Builder.CreateSwitch( 2448 CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB, 2449 CS == nullptr ? 1 : CS->size()); 2450 if (CS) { 2451 unsigned CaseNumber = 0; 2452 for (auto *SubStmt : CS->children()) { 2453 auto CaseBB = CGF.createBasicBlock(".omp.sections.case"); 2454 CGF.EmitBlock(CaseBB); 2455 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB); 2456 CGF.EmitStmt(SubStmt); 2457 CGF.EmitBranch(ExitBB); 2458 ++CaseNumber; 2459 } 2460 } else { 2461 auto CaseBB = CGF.createBasicBlock(".omp.sections.case"); 2462 CGF.EmitBlock(CaseBB); 2463 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB); 2464 CGF.EmitStmt(Stmt); 2465 CGF.EmitBranch(ExitBB); 2466 } 2467 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 2468 }; 2469 2470 CodeGenFunction::OMPPrivateScope LoopScope(CGF); 2471 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) { 2472 // Emit implicit barrier to synchronize threads and avoid data races on 2473 // initialization of firstprivate variables and post-update of lastprivate 2474 // variables. 2475 CGF.CGM.getOpenMPRuntime().emitBarrierCall( 2476 CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, 2477 /*ForceSimpleCall=*/true); 2478 } 2479 CGF.EmitOMPPrivateClause(S, LoopScope); 2480 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); 2481 CGF.EmitOMPReductionClauseInit(S, LoopScope); 2482 (void)LoopScope.Privatize(); 2483 2484 // Emit static non-chunked loop. 2485 OpenMPScheduleTy ScheduleKind; 2486 ScheduleKind.Schedule = OMPC_SCHEDULE_static; 2487 CGOpenMPRuntime::StaticRTInput StaticInit( 2488 /*IVSize=*/32, /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), 2489 LB.getAddress(), UB.getAddress(), ST.getAddress()); 2490 CGF.CGM.getOpenMPRuntime().emitForStaticInit( 2491 CGF, S.getLocStart(), S.getDirectiveKind(), ScheduleKind, StaticInit); 2492 // UB = min(UB, GlobalUB); 2493 auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart()); 2494 auto *MinUBGlobalUB = CGF.Builder.CreateSelect( 2495 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal); 2496 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB); 2497 // IV = LB; 2498 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV); 2499 // while (idx <= UB) { BODY; ++idx; } 2500 CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen, 2501 [](CodeGenFunction &) {}); 2502 // Tell the runtime we are done. 2503 auto &&CodeGen = [&S](CodeGenFunction &CGF) { 2504 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocEnd(), 2505 S.getDirectiveKind()); 2506 }; 2507 CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen); 2508 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); 2509 // Emit post-update of the reduction variables if IsLastIter != 0. 2510 emitPostUpdateForReductionClause( 2511 CGF, S, [&](CodeGenFunction &CGF) -> llvm::Value * { 2512 return CGF.Builder.CreateIsNotNull( 2513 CGF.EmitLoadOfScalar(IL, S.getLocStart())); 2514 }); 2515 2516 // Emit final copy of the lastprivate variables if IsLastIter != 0. 2517 if (HasLastprivates) 2518 CGF.EmitOMPLastprivateClauseFinal( 2519 S, /*NoFinals=*/false, 2520 CGF.Builder.CreateIsNotNull( 2521 CGF.EmitLoadOfScalar(IL, S.getLocStart()))); 2522 }; 2523 2524 bool HasCancel = false; 2525 if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S)) 2526 HasCancel = OSD->hasCancel(); 2527 else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S)) 2528 HasCancel = OPSD->hasCancel(); 2529 OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel); 2530 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen, 2531 HasCancel); 2532 // Emit barrier for lastprivates only if 'sections' directive has 'nowait' 2533 // clause. Otherwise the barrier will be generated by the codegen for the 2534 // directive. 2535 if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) { 2536 // Emit implicit barrier to synchronize threads and avoid data races on 2537 // initialization of firstprivate variables. 2538 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), 2539 OMPD_unknown); 2540 } 2541 } 2542 2543 void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) { 2544 { 2545 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2546 EmitSections(S); 2547 } 2548 // Emit an implicit barrier at the end. 2549 if (!S.getSingleClause<OMPNowaitClause>()) { 2550 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), 2551 OMPD_sections); 2552 } 2553 } 2554 2555 void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) { 2556 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2557 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2558 }; 2559 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2560 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen, 2561 S.hasCancel()); 2562 } 2563 2564 void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { 2565 llvm::SmallVector<const Expr *, 8> CopyprivateVars; 2566 llvm::SmallVector<const Expr *, 8> DestExprs; 2567 llvm::SmallVector<const Expr *, 8> SrcExprs; 2568 llvm::SmallVector<const Expr *, 8> AssignmentOps; 2569 // Check if there are any 'copyprivate' clauses associated with this 2570 // 'single' construct. 2571 // Build a list of copyprivate variables along with helper expressions 2572 // (<source>, <destination>, <destination>=<source> expressions) 2573 for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) { 2574 CopyprivateVars.append(C->varlists().begin(), C->varlists().end()); 2575 DestExprs.append(C->destination_exprs().begin(), 2576 C->destination_exprs().end()); 2577 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end()); 2578 AssignmentOps.append(C->assignment_ops().begin(), 2579 C->assignment_ops().end()); 2580 } 2581 // Emit code for 'single' region along with 'copyprivate' clauses 2582 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 2583 Action.Enter(CGF); 2584 OMPPrivateScope SingleScope(CGF); 2585 (void)CGF.EmitOMPFirstprivateClause(S, SingleScope); 2586 CGF.EmitOMPPrivateClause(S, SingleScope); 2587 (void)SingleScope.Privatize(); 2588 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2589 }; 2590 { 2591 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2592 CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(), 2593 CopyprivateVars, DestExprs, 2594 SrcExprs, AssignmentOps); 2595 } 2596 // Emit an implicit barrier at the end (to avoid data race on firstprivate 2597 // init or if no 'nowait' clause was specified and no 'copyprivate' clause). 2598 if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) { 2599 CGM.getOpenMPRuntime().emitBarrierCall( 2600 *this, S.getLocStart(), 2601 S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single); 2602 } 2603 } 2604 2605 void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { 2606 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 2607 Action.Enter(CGF); 2608 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2609 }; 2610 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2611 CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getLocStart()); 2612 } 2613 2614 void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { 2615 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 2616 Action.Enter(CGF); 2617 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2618 }; 2619 Expr *Hint = nullptr; 2620 if (auto *HintClause = S.getSingleClause<OMPHintClause>()) 2621 Hint = HintClause->getHint(); 2622 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2623 CGM.getOpenMPRuntime().emitCriticalRegion(*this, 2624 S.getDirectiveName().getAsString(), 2625 CodeGen, S.getLocStart(), Hint); 2626 } 2627 2628 void CodeGenFunction::EmitOMPParallelForDirective( 2629 const OMPParallelForDirective &S) { 2630 // Emit directive as a combined directive that consists of two implicit 2631 // directives: 'parallel' with 'for' directive. 2632 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2633 OMPCancelStackRAII CancelRegion(CGF, OMPD_parallel_for, S.hasCancel()); 2634 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, 2635 emitDispatchForLoopBounds); 2636 }; 2637 emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen, 2638 emitEmptyBoundParameters); 2639 } 2640 2641 void CodeGenFunction::EmitOMPParallelForSimdDirective( 2642 const OMPParallelForSimdDirective &S) { 2643 // Emit directive as a combined directive that consists of two implicit 2644 // directives: 'parallel' with 'for' directive. 2645 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2646 CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds, 2647 emitDispatchForLoopBounds); 2648 }; 2649 emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen, 2650 emitEmptyBoundParameters); 2651 } 2652 2653 void CodeGenFunction::EmitOMPParallelSectionsDirective( 2654 const OMPParallelSectionsDirective &S) { 2655 // Emit directive as a combined directive that consists of two implicit 2656 // directives: 'parallel' with 'sections' directive. 2657 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2658 CGF.EmitSections(S); 2659 }; 2660 emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen, 2661 emitEmptyBoundParameters); 2662 } 2663 2664 void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, 2665 const RegionCodeGenTy &BodyGen, 2666 const TaskGenTy &TaskGen, 2667 OMPTaskDataTy &Data) { 2668 // Emit outlined function for task construct. 2669 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 2670 auto *I = CS->getCapturedDecl()->param_begin(); 2671 auto *PartId = std::next(I); 2672 auto *TaskT = std::next(I, 4); 2673 // Check if the task is final 2674 if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) { 2675 // If the condition constant folds and can be elided, try to avoid emitting 2676 // the condition and the dead arm of the if/else. 2677 auto *Cond = Clause->getCondition(); 2678 bool CondConstant; 2679 if (ConstantFoldsToSimpleInteger(Cond, CondConstant)) 2680 Data.Final.setInt(CondConstant); 2681 else 2682 Data.Final.setPointer(EvaluateExprAsBool(Cond)); 2683 } else { 2684 // By default the task is not final. 2685 Data.Final.setInt(/*IntVal=*/false); 2686 } 2687 // Check if the task has 'priority' clause. 2688 if (const auto *Clause = S.getSingleClause<OMPPriorityClause>()) { 2689 auto *Prio = Clause->getPriority(); 2690 Data.Priority.setInt(/*IntVal=*/true); 2691 Data.Priority.setPointer(EmitScalarConversion( 2692 EmitScalarExpr(Prio), Prio->getType(), 2693 getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1), 2694 Prio->getExprLoc())); 2695 } 2696 // The first function argument for tasks is a thread id, the second one is a 2697 // part id (0 for tied tasks, >=0 for untied task). 2698 llvm::DenseSet<const VarDecl *> EmittedAsPrivate; 2699 // Get list of private variables. 2700 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) { 2701 auto IRef = C->varlist_begin(); 2702 for (auto *IInit : C->private_copies()) { 2703 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 2704 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { 2705 Data.PrivateVars.push_back(*IRef); 2706 Data.PrivateCopies.push_back(IInit); 2707 } 2708 ++IRef; 2709 } 2710 } 2711 EmittedAsPrivate.clear(); 2712 // Get list of firstprivate variables. 2713 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) { 2714 auto IRef = C->varlist_begin(); 2715 auto IElemInitRef = C->inits().begin(); 2716 for (auto *IInit : C->private_copies()) { 2717 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 2718 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { 2719 Data.FirstprivateVars.push_back(*IRef); 2720 Data.FirstprivateCopies.push_back(IInit); 2721 Data.FirstprivateInits.push_back(*IElemInitRef); 2722 } 2723 ++IRef; 2724 ++IElemInitRef; 2725 } 2726 } 2727 // Get list of lastprivate variables (for taskloops). 2728 llvm::DenseMap<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs; 2729 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) { 2730 auto IRef = C->varlist_begin(); 2731 auto ID = C->destination_exprs().begin(); 2732 for (auto *IInit : C->private_copies()) { 2733 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 2734 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { 2735 Data.LastprivateVars.push_back(*IRef); 2736 Data.LastprivateCopies.push_back(IInit); 2737 } 2738 LastprivateDstsOrigs.insert( 2739 {cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()), 2740 cast<DeclRefExpr>(*IRef)}); 2741 ++IRef; 2742 ++ID; 2743 } 2744 } 2745 SmallVector<const Expr *, 4> LHSs; 2746 SmallVector<const Expr *, 4> RHSs; 2747 for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) { 2748 auto IPriv = C->privates().begin(); 2749 auto IRed = C->reduction_ops().begin(); 2750 auto ILHS = C->lhs_exprs().begin(); 2751 auto IRHS = C->rhs_exprs().begin(); 2752 for (const auto *Ref : C->varlists()) { 2753 Data.ReductionVars.emplace_back(Ref); 2754 Data.ReductionCopies.emplace_back(*IPriv); 2755 Data.ReductionOps.emplace_back(*IRed); 2756 LHSs.emplace_back(*ILHS); 2757 RHSs.emplace_back(*IRHS); 2758 std::advance(IPriv, 1); 2759 std::advance(IRed, 1); 2760 std::advance(ILHS, 1); 2761 std::advance(IRHS, 1); 2762 } 2763 } 2764 Data.Reductions = CGM.getOpenMPRuntime().emitTaskReductionInit( 2765 *this, S.getLocStart(), LHSs, RHSs, Data); 2766 // Build list of dependences. 2767 for (const auto *C : S.getClausesOfKind<OMPDependClause>()) 2768 for (auto *IRef : C->varlists()) 2769 Data.Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef)); 2770 auto &&CodeGen = [&Data, &S, CS, &BodyGen, &LastprivateDstsOrigs]( 2771 CodeGenFunction &CGF, PrePostActionTy &Action) { 2772 // Set proper addresses for generated private copies. 2773 OMPPrivateScope Scope(CGF); 2774 if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() || 2775 !Data.LastprivateVars.empty()) { 2776 enum { PrivatesParam = 2, CopyFnParam = 3 }; 2777 auto *CopyFn = CGF.Builder.CreateLoad( 2778 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3))); 2779 auto *PrivatesPtr = CGF.Builder.CreateLoad( 2780 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2))); 2781 // Map privates. 2782 llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs; 2783 llvm::SmallVector<llvm::Value *, 16> CallArgs; 2784 CallArgs.push_back(PrivatesPtr); 2785 for (auto *E : Data.PrivateVars) { 2786 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 2787 Address PrivatePtr = CGF.CreateMemTemp( 2788 CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr"); 2789 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr)); 2790 CallArgs.push_back(PrivatePtr.getPointer()); 2791 } 2792 for (auto *E : Data.FirstprivateVars) { 2793 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 2794 Address PrivatePtr = 2795 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), 2796 ".firstpriv.ptr.addr"); 2797 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr)); 2798 CallArgs.push_back(PrivatePtr.getPointer()); 2799 } 2800 for (auto *E : Data.LastprivateVars) { 2801 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 2802 Address PrivatePtr = 2803 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), 2804 ".lastpriv.ptr.addr"); 2805 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr)); 2806 CallArgs.push_back(PrivatePtr.getPointer()); 2807 } 2808 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getLocStart(), 2809 CopyFn, CallArgs); 2810 for (auto &&Pair : LastprivateDstsOrigs) { 2811 auto *OrigVD = cast<VarDecl>(Pair.second->getDecl()); 2812 DeclRefExpr DRE( 2813 const_cast<VarDecl *>(OrigVD), 2814 /*RefersToEnclosingVariableOrCapture=*/CGF.CapturedStmtInfo->lookup( 2815 OrigVD) != nullptr, 2816 Pair.second->getType(), VK_LValue, Pair.second->getExprLoc()); 2817 Scope.addPrivate(Pair.first, [&CGF, &DRE]() { 2818 return CGF.EmitLValue(&DRE).getAddress(); 2819 }); 2820 } 2821 for (auto &&Pair : PrivatePtrs) { 2822 Address Replacement(CGF.Builder.CreateLoad(Pair.second), 2823 CGF.getContext().getDeclAlign(Pair.first)); 2824 Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; }); 2825 } 2826 } 2827 if (Data.Reductions) { 2828 OMPLexicalScope LexScope(CGF, S, /*AsInlined=*/true); 2829 ReductionCodeGen RedCG(Data.ReductionVars, Data.ReductionCopies, 2830 Data.ReductionOps); 2831 llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad( 2832 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9))); 2833 for (unsigned Cnt = 0, E = Data.ReductionVars.size(); Cnt < E; ++Cnt) { 2834 RedCG.emitSharedLValue(CGF, Cnt); 2835 RedCG.emitAggregateType(CGF, Cnt); 2836 Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem( 2837 CGF, S.getLocStart(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); 2838 Replacement = 2839 Address(CGF.EmitScalarConversion( 2840 Replacement.getPointer(), CGF.getContext().VoidPtrTy, 2841 CGF.getContext().getPointerType( 2842 Data.ReductionCopies[Cnt]->getType()), 2843 SourceLocation()), 2844 Replacement.getAlignment()); 2845 Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement); 2846 Scope.addPrivate(RedCG.getBaseDecl(Cnt), 2847 [Replacement]() { return Replacement; }); 2848 // FIXME: This must removed once the runtime library is fixed. 2849 // Emit required threadprivate variables for 2850 // initilizer/combiner/finalizer. 2851 CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getLocStart(), 2852 RedCG, Cnt); 2853 } 2854 } 2855 // Privatize all private variables except for in_reduction items. 2856 (void)Scope.Privatize(); 2857 SmallVector<const Expr *, 4> InRedVars; 2858 SmallVector<const Expr *, 4> InRedPrivs; 2859 SmallVector<const Expr *, 4> InRedOps; 2860 SmallVector<const Expr *, 4> TaskgroupDescriptors; 2861 for (const auto *C : S.getClausesOfKind<OMPInReductionClause>()) { 2862 auto IPriv = C->privates().begin(); 2863 auto IRed = C->reduction_ops().begin(); 2864 auto ITD = C->taskgroup_descriptors().begin(); 2865 for (const auto *Ref : C->varlists()) { 2866 InRedVars.emplace_back(Ref); 2867 InRedPrivs.emplace_back(*IPriv); 2868 InRedOps.emplace_back(*IRed); 2869 TaskgroupDescriptors.emplace_back(*ITD); 2870 std::advance(IPriv, 1); 2871 std::advance(IRed, 1); 2872 std::advance(ITD, 1); 2873 } 2874 } 2875 // Privatize in_reduction items here, because taskgroup descriptors must be 2876 // privatized earlier. 2877 OMPPrivateScope InRedScope(CGF); 2878 if (!InRedVars.empty()) { 2879 ReductionCodeGen RedCG(InRedVars, InRedPrivs, InRedOps); 2880 for (unsigned Cnt = 0, E = InRedVars.size(); Cnt < E; ++Cnt) { 2881 RedCG.emitSharedLValue(CGF, Cnt); 2882 RedCG.emitAggregateType(CGF, Cnt); 2883 // The taskgroup descriptor variable is always implicit firstprivate and 2884 // privatized already during procoessing of the firstprivates. 2885 llvm::Value *ReductionsPtr = CGF.EmitLoadOfScalar( 2886 CGF.EmitLValue(TaskgroupDescriptors[Cnt]), SourceLocation()); 2887 Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem( 2888 CGF, S.getLocStart(), ReductionsPtr, RedCG.getSharedLValue(Cnt)); 2889 Replacement = Address( 2890 CGF.EmitScalarConversion( 2891 Replacement.getPointer(), CGF.getContext().VoidPtrTy, 2892 CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()), 2893 SourceLocation()), 2894 Replacement.getAlignment()); 2895 Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement); 2896 InRedScope.addPrivate(RedCG.getBaseDecl(Cnt), 2897 [Replacement]() { return Replacement; }); 2898 // FIXME: This must removed once the runtime library is fixed. 2899 // Emit required threadprivate variables for 2900 // initilizer/combiner/finalizer. 2901 CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getLocStart(), 2902 RedCG, Cnt); 2903 } 2904 } 2905 (void)InRedScope.Privatize(); 2906 2907 Action.Enter(CGF); 2908 BodyGen(CGF); 2909 }; 2910 auto *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( 2911 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied, 2912 Data.NumberOfParts); 2913 OMPLexicalScope Scope(*this, S); 2914 TaskGen(*this, OutlinedFn, Data); 2915 } 2916 2917 void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { 2918 // Emit outlined function for task construct. 2919 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 2920 auto CapturedStruct = GenerateCapturedStmtArgument(*CS); 2921 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); 2922 const Expr *IfCond = nullptr; 2923 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 2924 if (C->getNameModifier() == OMPD_unknown || 2925 C->getNameModifier() == OMPD_task) { 2926 IfCond = C->getCondition(); 2927 break; 2928 } 2929 } 2930 2931 OMPTaskDataTy Data; 2932 // Check if we should emit tied or untied task. 2933 Data.Tied = !S.getSingleClause<OMPUntiedClause>(); 2934 auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) { 2935 CGF.EmitStmt(CS->getCapturedStmt()); 2936 }; 2937 auto &&TaskGen = [&S, SharedsTy, CapturedStruct, 2938 IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn, 2939 const OMPTaskDataTy &Data) { 2940 CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getLocStart(), S, OutlinedFn, 2941 SharedsTy, CapturedStruct, IfCond, 2942 Data); 2943 }; 2944 EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data); 2945 } 2946 2947 void CodeGenFunction::EmitOMPTaskyieldDirective( 2948 const OMPTaskyieldDirective &S) { 2949 CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getLocStart()); 2950 } 2951 2952 void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) { 2953 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_barrier); 2954 } 2955 2956 void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) { 2957 CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getLocStart()); 2958 } 2959 2960 void CodeGenFunction::EmitOMPTaskgroupDirective( 2961 const OMPTaskgroupDirective &S) { 2962 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 2963 Action.Enter(CGF); 2964 if (const Expr *E = S.getReductionRef()) { 2965 SmallVector<const Expr *, 4> LHSs; 2966 SmallVector<const Expr *, 4> RHSs; 2967 OMPTaskDataTy Data; 2968 for (const auto *C : S.getClausesOfKind<OMPTaskReductionClause>()) { 2969 auto IPriv = C->privates().begin(); 2970 auto IRed = C->reduction_ops().begin(); 2971 auto ILHS = C->lhs_exprs().begin(); 2972 auto IRHS = C->rhs_exprs().begin(); 2973 for (const auto *Ref : C->varlists()) { 2974 Data.ReductionVars.emplace_back(Ref); 2975 Data.ReductionCopies.emplace_back(*IPriv); 2976 Data.ReductionOps.emplace_back(*IRed); 2977 LHSs.emplace_back(*ILHS); 2978 RHSs.emplace_back(*IRHS); 2979 std::advance(IPriv, 1); 2980 std::advance(IRed, 1); 2981 std::advance(ILHS, 1); 2982 std::advance(IRHS, 1); 2983 } 2984 } 2985 llvm::Value *ReductionDesc = 2986 CGF.CGM.getOpenMPRuntime().emitTaskReductionInit(CGF, S.getLocStart(), 2987 LHSs, RHSs, Data); 2988 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 2989 CGF.EmitVarDecl(*VD); 2990 CGF.EmitStoreOfScalar(ReductionDesc, CGF.GetAddrOfLocalVar(VD), 2991 /*Volatile=*/false, E->getType()); 2992 } 2993 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2994 }; 2995 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 2996 CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getLocStart()); 2997 } 2998 2999 void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) { 3000 CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> { 3001 if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>()) { 3002 return llvm::makeArrayRef(FlushClause->varlist_begin(), 3003 FlushClause->varlist_end()); 3004 } 3005 return llvm::None; 3006 }(), S.getLocStart()); 3007 } 3008 3009 void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S, 3010 const CodeGenLoopTy &CodeGenLoop, 3011 Expr *IncExpr) { 3012 // Emit the loop iteration variable. 3013 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable()); 3014 auto IVDecl = cast<VarDecl>(IVExpr->getDecl()); 3015 EmitVarDecl(*IVDecl); 3016 3017 // Emit the iterations count variable. 3018 // If it is not a variable, Sema decided to calculate iterations count on each 3019 // iteration (e.g., it is foldable into a constant). 3020 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 3021 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 3022 // Emit calculation of the iterations count. 3023 EmitIgnoredExpr(S.getCalcLastIteration()); 3024 } 3025 3026 auto &RT = CGM.getOpenMPRuntime(); 3027 3028 bool HasLastprivateClause = false; 3029 // Check pre-condition. 3030 { 3031 OMPLoopScope PreInitScope(*this, S); 3032 // Skip the entire loop if we don't meet the precondition. 3033 // If the condition constant folds and can be elided, avoid emitting the 3034 // whole loop. 3035 bool CondConstant; 3036 llvm::BasicBlock *ContBlock = nullptr; 3037 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { 3038 if (!CondConstant) 3039 return; 3040 } else { 3041 auto *ThenBlock = createBasicBlock("omp.precond.then"); 3042 ContBlock = createBasicBlock("omp.precond.end"); 3043 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock, 3044 getProfileCount(&S)); 3045 EmitBlock(ThenBlock); 3046 incrementProfileCounter(&S); 3047 } 3048 3049 // Emit 'then' code. 3050 { 3051 // Emit helper vars inits. 3052 3053 LValue LB = EmitOMPHelperVar( 3054 *this, cast<DeclRefExpr>( 3055 (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 3056 ? S.getCombinedLowerBoundVariable() 3057 : S.getLowerBoundVariable()))); 3058 LValue UB = EmitOMPHelperVar( 3059 *this, cast<DeclRefExpr>( 3060 (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 3061 ? S.getCombinedUpperBoundVariable() 3062 : S.getUpperBoundVariable()))); 3063 LValue ST = 3064 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); 3065 LValue IL = 3066 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); 3067 3068 OMPPrivateScope LoopScope(*this); 3069 if (EmitOMPFirstprivateClause(S, LoopScope)) { 3070 // Emit implicit barrier to synchronize threads and avoid data races on 3071 // initialization of firstprivate variables and post-update of 3072 // lastprivate variables. 3073 CGM.getOpenMPRuntime().emitBarrierCall( 3074 *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, 3075 /*ForceSimpleCall=*/true); 3076 } 3077 EmitOMPPrivateClause(S, LoopScope); 3078 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope); 3079 EmitOMPPrivateLoopCounters(S, LoopScope); 3080 (void)LoopScope.Privatize(); 3081 3082 // Detect the distribute schedule kind and chunk. 3083 llvm::Value *Chunk = nullptr; 3084 OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown; 3085 if (auto *C = S.getSingleClause<OMPDistScheduleClause>()) { 3086 ScheduleKind = C->getDistScheduleKind(); 3087 if (const auto *Ch = C->getChunkSize()) { 3088 Chunk = EmitScalarExpr(Ch); 3089 Chunk = EmitScalarConversion(Chunk, Ch->getType(), 3090 S.getIterationVariable()->getType(), 3091 S.getLocStart()); 3092 } 3093 } 3094 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 3095 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 3096 3097 // OpenMP [2.10.8, distribute Construct, Description] 3098 // If dist_schedule is specified, kind must be static. If specified, 3099 // iterations are divided into chunks of size chunk_size, chunks are 3100 // assigned to the teams of the league in a round-robin fashion in the 3101 // order of the team number. When no chunk_size is specified, the 3102 // iteration space is divided into chunks that are approximately equal 3103 // in size, and at most one chunk is distributed to each team of the 3104 // league. The size of the chunks is unspecified in this case. 3105 if (RT.isStaticNonchunked(ScheduleKind, 3106 /* Chunked */ Chunk != nullptr)) { 3107 CGOpenMPRuntime::StaticRTInput StaticInit( 3108 IVSize, IVSigned, /* Ordered = */ false, IL.getAddress(), 3109 LB.getAddress(), UB.getAddress(), ST.getAddress()); 3110 RT.emitDistributeStaticInit(*this, S.getLocStart(), ScheduleKind, 3111 StaticInit); 3112 auto LoopExit = 3113 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit")); 3114 // UB = min(UB, GlobalUB); 3115 EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 3116 ? S.getCombinedEnsureUpperBound() 3117 : S.getEnsureUpperBound()); 3118 // IV = LB; 3119 EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 3120 ? S.getCombinedInit() 3121 : S.getInit()); 3122 3123 Expr *Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()) 3124 ? S.getCombinedCond() 3125 : S.getCond(); 3126 3127 // for distribute alone, codegen 3128 // while (idx <= UB) { BODY; ++idx; } 3129 // when combined with 'for' (e.g. as in 'distribute parallel for') 3130 // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; } 3131 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), Cond, IncExpr, 3132 [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) { 3133 CodeGenLoop(CGF, S, LoopExit); 3134 }, 3135 [](CodeGenFunction &) {}); 3136 EmitBlock(LoopExit.getBlock()); 3137 // Tell the runtime we are done. 3138 RT.emitForStaticFinish(*this, S.getLocStart(), S.getDirectiveKind()); 3139 } else { 3140 // Emit the outer loop, which requests its work chunk [LB..UB] from 3141 // runtime and runs the inner loop to process it. 3142 const OMPLoopArguments LoopArguments = { 3143 LB.getAddress(), UB.getAddress(), ST.getAddress(), IL.getAddress(), 3144 Chunk}; 3145 EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments, 3146 CodeGenLoop); 3147 } 3148 3149 // Emit final copy of the lastprivate variables if IsLastIter != 0. 3150 if (HasLastprivateClause) 3151 EmitOMPLastprivateClauseFinal( 3152 S, /*NoFinals=*/false, 3153 Builder.CreateIsNotNull( 3154 EmitLoadOfScalar(IL, S.getLocStart()))); 3155 } 3156 3157 // We're now done with the loop, so jump to the continuation block. 3158 if (ContBlock) { 3159 EmitBranch(ContBlock); 3160 EmitBlock(ContBlock, true); 3161 } 3162 } 3163 } 3164 3165 void CodeGenFunction::EmitOMPDistributeDirective( 3166 const OMPDistributeDirective &S) { 3167 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 3168 3169 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); 3170 }; 3171 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 3172 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen, 3173 false); 3174 } 3175 3176 static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM, 3177 const CapturedStmt *S) { 3178 CodeGenFunction CGF(CGM, /*suppressNewContext=*/true); 3179 CodeGenFunction::CGCapturedStmtInfo CapStmtInfo; 3180 CGF.CapturedStmtInfo = &CapStmtInfo; 3181 auto *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S); 3182 Fn->addFnAttr(llvm::Attribute::NoInline); 3183 return Fn; 3184 } 3185 3186 void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) { 3187 if (!S.getAssociatedStmt()) { 3188 for (const auto *DC : S.getClausesOfKind<OMPDependClause>()) 3189 CGM.getOpenMPRuntime().emitDoacrossOrdered(*this, DC); 3190 return; 3191 } 3192 auto *C = S.getSingleClause<OMPSIMDClause>(); 3193 auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF, 3194 PrePostActionTy &Action) { 3195 if (C) { 3196 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 3197 llvm::SmallVector<llvm::Value *, 16> CapturedVars; 3198 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); 3199 auto *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS); 3200 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getLocStart(), 3201 OutlinedFn, CapturedVars); 3202 } else { 3203 Action.Enter(CGF); 3204 CGF.EmitStmt( 3205 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 3206 } 3207 }; 3208 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 3209 CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getLocStart(), !C); 3210 } 3211 3212 static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val, 3213 QualType SrcType, QualType DestType, 3214 SourceLocation Loc) { 3215 assert(CGF.hasScalarEvaluationKind(DestType) && 3216 "DestType must have scalar evaluation kind."); 3217 assert(!Val.isAggregate() && "Must be a scalar or complex."); 3218 return Val.isScalar() 3219 ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestType, 3220 Loc) 3221 : CGF.EmitComplexToScalarConversion(Val.getComplexVal(), SrcType, 3222 DestType, Loc); 3223 } 3224 3225 static CodeGenFunction::ComplexPairTy 3226 convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, 3227 QualType DestType, SourceLocation Loc) { 3228 assert(CGF.getEvaluationKind(DestType) == TEK_Complex && 3229 "DestType must have complex evaluation kind."); 3230 CodeGenFunction::ComplexPairTy ComplexVal; 3231 if (Val.isScalar()) { 3232 // Convert the input element to the element type of the complex. 3233 auto DestElementType = DestType->castAs<ComplexType>()->getElementType(); 3234 auto ScalarVal = CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, 3235 DestElementType, Loc); 3236 ComplexVal = CodeGenFunction::ComplexPairTy( 3237 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType())); 3238 } else { 3239 assert(Val.isComplex() && "Must be a scalar or complex."); 3240 auto SrcElementType = SrcType->castAs<ComplexType>()->getElementType(); 3241 auto DestElementType = DestType->castAs<ComplexType>()->getElementType(); 3242 ComplexVal.first = CGF.EmitScalarConversion( 3243 Val.getComplexVal().first, SrcElementType, DestElementType, Loc); 3244 ComplexVal.second = CGF.EmitScalarConversion( 3245 Val.getComplexVal().second, SrcElementType, DestElementType, Loc); 3246 } 3247 return ComplexVal; 3248 } 3249 3250 static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst, 3251 LValue LVal, RValue RVal) { 3252 if (LVal.isGlobalReg()) { 3253 CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal); 3254 } else { 3255 CGF.EmitAtomicStore(RVal, LVal, 3256 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent 3257 : llvm::AtomicOrdering::Monotonic, 3258 LVal.isVolatile(), /*IsInit=*/false); 3259 } 3260 } 3261 3262 void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal, 3263 QualType RValTy, SourceLocation Loc) { 3264 switch (getEvaluationKind(LVal.getType())) { 3265 case TEK_Scalar: 3266 EmitStoreThroughLValue(RValue::get(convertToScalarValue( 3267 *this, RVal, RValTy, LVal.getType(), Loc)), 3268 LVal); 3269 break; 3270 case TEK_Complex: 3271 EmitStoreOfComplex( 3272 convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal, 3273 /*isInit=*/false); 3274 break; 3275 case TEK_Aggregate: 3276 llvm_unreachable("Must be a scalar or complex."); 3277 } 3278 } 3279 3280 static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, 3281 const Expr *X, const Expr *V, 3282 SourceLocation Loc) { 3283 // v = x; 3284 assert(V->isLValue() && "V of 'omp atomic read' is not lvalue"); 3285 assert(X->isLValue() && "X of 'omp atomic read' is not lvalue"); 3286 LValue XLValue = CGF.EmitLValue(X); 3287 LValue VLValue = CGF.EmitLValue(V); 3288 RValue Res = XLValue.isGlobalReg() 3289 ? CGF.EmitLoadOfLValue(XLValue, Loc) 3290 : CGF.EmitAtomicLoad( 3291 XLValue, Loc, 3292 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent 3293 : llvm::AtomicOrdering::Monotonic, 3294 XLValue.isVolatile()); 3295 // OpenMP, 2.12.6, atomic Construct 3296 // Any atomic construct with a seq_cst clause forces the atomically 3297 // performed operation to include an implicit flush operation without a 3298 // list. 3299 if (IsSeqCst) 3300 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); 3301 CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc); 3302 } 3303 3304 static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, 3305 const Expr *X, const Expr *E, 3306 SourceLocation Loc) { 3307 // x = expr; 3308 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue"); 3309 emitSimpleAtomicStore(CGF, IsSeqCst, CGF.EmitLValue(X), CGF.EmitAnyExpr(E)); 3310 // OpenMP, 2.12.6, atomic Construct 3311 // Any atomic construct with a seq_cst clause forces the atomically 3312 // performed operation to include an implicit flush operation without a 3313 // list. 3314 if (IsSeqCst) 3315 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); 3316 } 3317 3318 static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X, 3319 RValue Update, 3320 BinaryOperatorKind BO, 3321 llvm::AtomicOrdering AO, 3322 bool IsXLHSInRHSPart) { 3323 auto &Context = CGF.CGM.getContext(); 3324 // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x' 3325 // expression is simple and atomic is allowed for the given type for the 3326 // target platform. 3327 if (BO == BO_Comma || !Update.isScalar() || 3328 !Update.getScalarVal()->getType()->isIntegerTy() || 3329 !X.isSimple() || (!isa<llvm::ConstantInt>(Update.getScalarVal()) && 3330 (Update.getScalarVal()->getType() != 3331 X.getAddress().getElementType())) || 3332 !X.getAddress().getElementType()->isIntegerTy() || 3333 !Context.getTargetInfo().hasBuiltinAtomic( 3334 Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment()))) 3335 return std::make_pair(false, RValue::get(nullptr)); 3336 3337 llvm::AtomicRMWInst::BinOp RMWOp; 3338 switch (BO) { 3339 case BO_Add: 3340 RMWOp = llvm::AtomicRMWInst::Add; 3341 break; 3342 case BO_Sub: 3343 if (!IsXLHSInRHSPart) 3344 return std::make_pair(false, RValue::get(nullptr)); 3345 RMWOp = llvm::AtomicRMWInst::Sub; 3346 break; 3347 case BO_And: 3348 RMWOp = llvm::AtomicRMWInst::And; 3349 break; 3350 case BO_Or: 3351 RMWOp = llvm::AtomicRMWInst::Or; 3352 break; 3353 case BO_Xor: 3354 RMWOp = llvm::AtomicRMWInst::Xor; 3355 break; 3356 case BO_LT: 3357 RMWOp = X.getType()->hasSignedIntegerRepresentation() 3358 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min 3359 : llvm::AtomicRMWInst::Max) 3360 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin 3361 : llvm::AtomicRMWInst::UMax); 3362 break; 3363 case BO_GT: 3364 RMWOp = X.getType()->hasSignedIntegerRepresentation() 3365 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max 3366 : llvm::AtomicRMWInst::Min) 3367 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax 3368 : llvm::AtomicRMWInst::UMin); 3369 break; 3370 case BO_Assign: 3371 RMWOp = llvm::AtomicRMWInst::Xchg; 3372 break; 3373 case BO_Mul: 3374 case BO_Div: 3375 case BO_Rem: 3376 case BO_Shl: 3377 case BO_Shr: 3378 case BO_LAnd: 3379 case BO_LOr: 3380 return std::make_pair(false, RValue::get(nullptr)); 3381 case BO_PtrMemD: 3382 case BO_PtrMemI: 3383 case BO_LE: 3384 case BO_GE: 3385 case BO_EQ: 3386 case BO_NE: 3387 case BO_AddAssign: 3388 case BO_SubAssign: 3389 case BO_AndAssign: 3390 case BO_OrAssign: 3391 case BO_XorAssign: 3392 case BO_MulAssign: 3393 case BO_DivAssign: 3394 case BO_RemAssign: 3395 case BO_ShlAssign: 3396 case BO_ShrAssign: 3397 case BO_Comma: 3398 llvm_unreachable("Unsupported atomic update operation"); 3399 } 3400 auto *UpdateVal = Update.getScalarVal(); 3401 if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) { 3402 UpdateVal = CGF.Builder.CreateIntCast( 3403 IC, X.getAddress().getElementType(), 3404 X.getType()->hasSignedIntegerRepresentation()); 3405 } 3406 auto *Res = CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(), UpdateVal, AO); 3407 return std::make_pair(true, RValue::get(Res)); 3408 } 3409 3410 std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr( 3411 LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, 3412 llvm::AtomicOrdering AO, SourceLocation Loc, 3413 const llvm::function_ref<RValue(RValue)> &CommonGen) { 3414 // Update expressions are allowed to have the following forms: 3415 // x binop= expr; -> xrval + expr; 3416 // x++, ++x -> xrval + 1; 3417 // x--, --x -> xrval - 1; 3418 // x = x binop expr; -> xrval binop expr 3419 // x = expr Op x; - > expr binop xrval; 3420 auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart); 3421 if (!Res.first) { 3422 if (X.isGlobalReg()) { 3423 // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop 3424 // 'xrval'. 3425 EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X); 3426 } else { 3427 // Perform compare-and-swap procedure. 3428 EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified()); 3429 } 3430 } 3431 return Res; 3432 } 3433 3434 static void EmitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst, 3435 const Expr *X, const Expr *E, 3436 const Expr *UE, bool IsXLHSInRHSPart, 3437 SourceLocation Loc) { 3438 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) && 3439 "Update expr in 'atomic update' must be a binary operator."); 3440 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts()); 3441 // Update expressions are allowed to have the following forms: 3442 // x binop= expr; -> xrval + expr; 3443 // x++, ++x -> xrval + 1; 3444 // x--, --x -> xrval - 1; 3445 // x = x binop expr; -> xrval binop expr 3446 // x = expr Op x; - > expr binop xrval; 3447 assert(X->isLValue() && "X of 'omp atomic update' is not lvalue"); 3448 LValue XLValue = CGF.EmitLValue(X); 3449 RValue ExprRValue = CGF.EmitAnyExpr(E); 3450 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent 3451 : llvm::AtomicOrdering::Monotonic; 3452 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts()); 3453 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts()); 3454 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS; 3455 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS; 3456 auto Gen = 3457 [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) -> RValue { 3458 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); 3459 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue); 3460 return CGF.EmitAnyExpr(UE); 3461 }; 3462 (void)CGF.EmitOMPAtomicSimpleUpdateExpr( 3463 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen); 3464 // OpenMP, 2.12.6, atomic Construct 3465 // Any atomic construct with a seq_cst clause forces the atomically 3466 // performed operation to include an implicit flush operation without a 3467 // list. 3468 if (IsSeqCst) 3469 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); 3470 } 3471 3472 static RValue convertToType(CodeGenFunction &CGF, RValue Value, 3473 QualType SourceType, QualType ResType, 3474 SourceLocation Loc) { 3475 switch (CGF.getEvaluationKind(ResType)) { 3476 case TEK_Scalar: 3477 return RValue::get( 3478 convertToScalarValue(CGF, Value, SourceType, ResType, Loc)); 3479 case TEK_Complex: { 3480 auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc); 3481 return RValue::getComplex(Res.first, Res.second); 3482 } 3483 case TEK_Aggregate: 3484 break; 3485 } 3486 llvm_unreachable("Must be a scalar or complex."); 3487 } 3488 3489 static void EmitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst, 3490 bool IsPostfixUpdate, const Expr *V, 3491 const Expr *X, const Expr *E, 3492 const Expr *UE, bool IsXLHSInRHSPart, 3493 SourceLocation Loc) { 3494 assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue"); 3495 assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue"); 3496 RValue NewVVal; 3497 LValue VLValue = CGF.EmitLValue(V); 3498 LValue XLValue = CGF.EmitLValue(X); 3499 RValue ExprRValue = CGF.EmitAnyExpr(E); 3500 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent 3501 : llvm::AtomicOrdering::Monotonic; 3502 QualType NewVValType; 3503 if (UE) { 3504 // 'x' is updated with some additional value. 3505 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) && 3506 "Update expr in 'atomic capture' must be a binary operator."); 3507 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts()); 3508 // Update expressions are allowed to have the following forms: 3509 // x binop= expr; -> xrval + expr; 3510 // x++, ++x -> xrval + 1; 3511 // x--, --x -> xrval - 1; 3512 // x = x binop expr; -> xrval binop expr 3513 // x = expr Op x; - > expr binop xrval; 3514 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts()); 3515 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts()); 3516 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS; 3517 NewVValType = XRValExpr->getType(); 3518 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS; 3519 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr, 3520 IsPostfixUpdate](RValue XRValue) -> RValue { 3521 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); 3522 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue); 3523 RValue Res = CGF.EmitAnyExpr(UE); 3524 NewVVal = IsPostfixUpdate ? XRValue : Res; 3525 return Res; 3526 }; 3527 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr( 3528 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen); 3529 if (Res.first) { 3530 // 'atomicrmw' instruction was generated. 3531 if (IsPostfixUpdate) { 3532 // Use old value from 'atomicrmw'. 3533 NewVVal = Res.second; 3534 } else { 3535 // 'atomicrmw' does not provide new value, so evaluate it using old 3536 // value of 'x'. 3537 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); 3538 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second); 3539 NewVVal = CGF.EmitAnyExpr(UE); 3540 } 3541 } 3542 } else { 3543 // 'x' is simply rewritten with some 'expr'. 3544 NewVValType = X->getType().getNonReferenceType(); 3545 ExprRValue = convertToType(CGF, ExprRValue, E->getType(), 3546 X->getType().getNonReferenceType(), Loc); 3547 auto &&Gen = [&NewVVal, ExprRValue](RValue XRValue) -> RValue { 3548 NewVVal = XRValue; 3549 return ExprRValue; 3550 }; 3551 // Try to perform atomicrmw xchg, otherwise simple exchange. 3552 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr( 3553 XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO, 3554 Loc, Gen); 3555 if (Res.first) { 3556 // 'atomicrmw' instruction was generated. 3557 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue; 3558 } 3559 } 3560 // Emit post-update store to 'v' of old/new 'x' value. 3561 CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc); 3562 // OpenMP, 2.12.6, atomic Construct 3563 // Any atomic construct with a seq_cst clause forces the atomically 3564 // performed operation to include an implicit flush operation without a 3565 // list. 3566 if (IsSeqCst) 3567 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); 3568 } 3569 3570 static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, 3571 bool IsSeqCst, bool IsPostfixUpdate, 3572 const Expr *X, const Expr *V, const Expr *E, 3573 const Expr *UE, bool IsXLHSInRHSPart, 3574 SourceLocation Loc) { 3575 switch (Kind) { 3576 case OMPC_read: 3577 EmitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc); 3578 break; 3579 case OMPC_write: 3580 EmitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc); 3581 break; 3582 case OMPC_unknown: 3583 case OMPC_update: 3584 EmitOMPAtomicUpdateExpr(CGF, IsSeqCst, X, E, UE, IsXLHSInRHSPart, Loc); 3585 break; 3586 case OMPC_capture: 3587 EmitOMPAtomicCaptureExpr(CGF, IsSeqCst, IsPostfixUpdate, V, X, E, UE, 3588 IsXLHSInRHSPart, Loc); 3589 break; 3590 case OMPC_if: 3591 case OMPC_final: 3592 case OMPC_num_threads: 3593 case OMPC_private: 3594 case OMPC_firstprivate: 3595 case OMPC_lastprivate: 3596 case OMPC_reduction: 3597 case OMPC_task_reduction: 3598 case OMPC_in_reduction: 3599 case OMPC_safelen: 3600 case OMPC_simdlen: 3601 case OMPC_collapse: 3602 case OMPC_default: 3603 case OMPC_seq_cst: 3604 case OMPC_shared: 3605 case OMPC_linear: 3606 case OMPC_aligned: 3607 case OMPC_copyin: 3608 case OMPC_copyprivate: 3609 case OMPC_flush: 3610 case OMPC_proc_bind: 3611 case OMPC_schedule: 3612 case OMPC_ordered: 3613 case OMPC_nowait: 3614 case OMPC_untied: 3615 case OMPC_threadprivate: 3616 case OMPC_depend: 3617 case OMPC_mergeable: 3618 case OMPC_device: 3619 case OMPC_threads: 3620 case OMPC_simd: 3621 case OMPC_map: 3622 case OMPC_num_teams: 3623 case OMPC_thread_limit: 3624 case OMPC_priority: 3625 case OMPC_grainsize: 3626 case OMPC_nogroup: 3627 case OMPC_num_tasks: 3628 case OMPC_hint: 3629 case OMPC_dist_schedule: 3630 case OMPC_defaultmap: 3631 case OMPC_uniform: 3632 case OMPC_to: 3633 case OMPC_from: 3634 case OMPC_use_device_ptr: 3635 case OMPC_is_device_ptr: 3636 llvm_unreachable("Clause is not allowed in 'omp atomic'."); 3637 } 3638 } 3639 3640 void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { 3641 bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>(); 3642 OpenMPClauseKind Kind = OMPC_unknown; 3643 for (auto *C : S.clauses()) { 3644 // Find first clause (skip seq_cst clause, if it is first). 3645 if (C->getClauseKind() != OMPC_seq_cst) { 3646 Kind = C->getClauseKind(); 3647 break; 3648 } 3649 } 3650 3651 const auto *CS = 3652 S.getAssociatedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true); 3653 if (const auto *EWC = dyn_cast<ExprWithCleanups>(CS)) { 3654 enterFullExpression(EWC); 3655 } 3656 // Processing for statements under 'atomic capture'. 3657 if (const auto *Compound = dyn_cast<CompoundStmt>(CS)) { 3658 for (const auto *C : Compound->body()) { 3659 if (const auto *EWC = dyn_cast<ExprWithCleanups>(C)) { 3660 enterFullExpression(EWC); 3661 } 3662 } 3663 } 3664 3665 auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF, 3666 PrePostActionTy &) { 3667 CGF.EmitStopPoint(CS); 3668 EmitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(), 3669 S.getV(), S.getExpr(), S.getUpdateExpr(), 3670 S.isXLHSInRHSPart(), S.getLocStart()); 3671 }; 3672 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 3673 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen); 3674 } 3675 3676 static void emitCommonOMPTargetDirective(CodeGenFunction &CGF, 3677 const OMPExecutableDirective &S, 3678 const RegionCodeGenTy &CodeGen) { 3679 assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind())); 3680 CodeGenModule &CGM = CGF.CGM; 3681 const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt()); 3682 3683 llvm::Function *Fn = nullptr; 3684 llvm::Constant *FnID = nullptr; 3685 3686 const Expr *IfCond = nullptr; 3687 // Check for the at most one if clause associated with the target region. 3688 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 3689 if (C->getNameModifier() == OMPD_unknown || 3690 C->getNameModifier() == OMPD_target) { 3691 IfCond = C->getCondition(); 3692 break; 3693 } 3694 } 3695 3696 // Check if we have any device clause associated with the directive. 3697 const Expr *Device = nullptr; 3698 if (auto *C = S.getSingleClause<OMPDeviceClause>()) { 3699 Device = C->getDevice(); 3700 } 3701 3702 // Check if we have an if clause whose conditional always evaluates to false 3703 // or if we do not have any targets specified. If so the target region is not 3704 // an offload entry point. 3705 bool IsOffloadEntry = true; 3706 if (IfCond) { 3707 bool Val; 3708 if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val) 3709 IsOffloadEntry = false; 3710 } 3711 if (CGM.getLangOpts().OMPTargetTriples.empty()) 3712 IsOffloadEntry = false; 3713 3714 assert(CGF.CurFuncDecl && "No parent declaration for target region!"); 3715 StringRef ParentName; 3716 // In case we have Ctors/Dtors we use the complete type variant to produce 3717 // the mangling of the device outlined kernel. 3718 if (auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl)) 3719 ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete)); 3720 else if (auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl)) 3721 ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete)); 3722 else 3723 ParentName = 3724 CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl))); 3725 3726 // Emit target region as a standalone region. 3727 CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID, 3728 IsOffloadEntry, CodeGen); 3729 OMPLexicalScope Scope(CGF, S); 3730 llvm::SmallVector<llvm::Value *, 16> CapturedVars; 3731 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars); 3732 CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device, 3733 CapturedVars); 3734 } 3735 3736 static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S, 3737 PrePostActionTy &Action) { 3738 CodeGenFunction::OMPPrivateScope PrivateScope(CGF); 3739 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); 3740 CGF.EmitOMPPrivateClause(S, PrivateScope); 3741 (void)PrivateScope.Privatize(); 3742 3743 Action.Enter(CGF); 3744 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 3745 } 3746 3747 void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM, 3748 StringRef ParentName, 3749 const OMPTargetDirective &S) { 3750 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 3751 emitTargetRegion(CGF, S, Action); 3752 }; 3753 llvm::Function *Fn; 3754 llvm::Constant *Addr; 3755 // Emit target region as a standalone region. 3756 CGM.getOpenMPRuntime().emitTargetOutlinedFunction( 3757 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); 3758 assert(Fn && Addr && "Target device function emission failed."); 3759 } 3760 3761 void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) { 3762 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 3763 emitTargetRegion(CGF, S, Action); 3764 }; 3765 emitCommonOMPTargetDirective(*this, S, CodeGen); 3766 } 3767 3768 static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, 3769 const OMPExecutableDirective &S, 3770 OpenMPDirectiveKind InnermostKind, 3771 const RegionCodeGenTy &CodeGen) { 3772 const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams); 3773 auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction( 3774 S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); 3775 3776 const OMPNumTeamsClause *NT = S.getSingleClause<OMPNumTeamsClause>(); 3777 const OMPThreadLimitClause *TL = S.getSingleClause<OMPThreadLimitClause>(); 3778 if (NT || TL) { 3779 Expr *NumTeams = (NT) ? NT->getNumTeams() : nullptr; 3780 Expr *ThreadLimit = (TL) ? TL->getThreadLimit() : nullptr; 3781 3782 CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit, 3783 S.getLocStart()); 3784 } 3785 3786 OMPTeamsScope Scope(CGF, S); 3787 llvm::SmallVector<llvm::Value *, 16> CapturedVars; 3788 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); 3789 CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getLocStart(), OutlinedFn, 3790 CapturedVars); 3791 } 3792 3793 void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) { 3794 // Emit teams region as a standalone region. 3795 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 3796 OMPPrivateScope PrivateScope(CGF); 3797 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); 3798 CGF.EmitOMPPrivateClause(S, PrivateScope); 3799 CGF.EmitOMPReductionClauseInit(S, PrivateScope); 3800 (void)PrivateScope.Privatize(); 3801 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 3802 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); 3803 }; 3804 emitCommonOMPTeamsDirective(*this, S, OMPD_teams, CodeGen); 3805 emitPostUpdateForReductionClause( 3806 *this, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 3807 } 3808 3809 static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action, 3810 const OMPTargetTeamsDirective &S) { 3811 auto *CS = S.getCapturedStmt(OMPD_teams); 3812 Action.Enter(CGF); 3813 auto &&CodeGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) { 3814 // TODO: Add support for clauses. 3815 CGF.EmitStmt(CS->getCapturedStmt()); 3816 }; 3817 emitCommonOMPTeamsDirective(CGF, S, OMPD_teams, CodeGen); 3818 } 3819 3820 void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction( 3821 CodeGenModule &CGM, StringRef ParentName, 3822 const OMPTargetTeamsDirective &S) { 3823 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 3824 emitTargetTeamsRegion(CGF, Action, S); 3825 }; 3826 llvm::Function *Fn; 3827 llvm::Constant *Addr; 3828 // Emit target region as a standalone region. 3829 CGM.getOpenMPRuntime().emitTargetOutlinedFunction( 3830 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); 3831 assert(Fn && Addr && "Target device function emission failed."); 3832 } 3833 3834 void CodeGenFunction::EmitOMPTargetTeamsDirective( 3835 const OMPTargetTeamsDirective &S) { 3836 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 3837 emitTargetTeamsRegion(CGF, Action, S); 3838 }; 3839 emitCommonOMPTargetDirective(*this, S, CodeGen); 3840 } 3841 3842 void CodeGenFunction::EmitOMPTeamsDistributeDirective( 3843 const OMPTeamsDistributeDirective &S) { 3844 3845 auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 3846 CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc()); 3847 }; 3848 3849 // Emit teams region as a standalone region. 3850 auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF, 3851 PrePostActionTy &) { 3852 OMPPrivateScope PrivateScope(CGF); 3853 CGF.EmitOMPReductionClauseInit(S, PrivateScope); 3854 (void)PrivateScope.Privatize(); 3855 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute, 3856 CodeGenDistribute); 3857 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams); 3858 }; 3859 emitCommonOMPTeamsDirective(*this, S, OMPD_teams, CodeGen); 3860 emitPostUpdateForReductionClause(*this, S, 3861 [](CodeGenFunction &) { return nullptr; }); 3862 } 3863 3864 void CodeGenFunction::EmitOMPCancellationPointDirective( 3865 const OMPCancellationPointDirective &S) { 3866 CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getLocStart(), 3867 S.getCancelRegion()); 3868 } 3869 3870 void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) { 3871 const Expr *IfCond = nullptr; 3872 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 3873 if (C->getNameModifier() == OMPD_unknown || 3874 C->getNameModifier() == OMPD_cancel) { 3875 IfCond = C->getCondition(); 3876 break; 3877 } 3878 } 3879 CGM.getOpenMPRuntime().emitCancelCall(*this, S.getLocStart(), IfCond, 3880 S.getCancelRegion()); 3881 } 3882 3883 CodeGenFunction::JumpDest 3884 CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) { 3885 if (Kind == OMPD_parallel || Kind == OMPD_task || 3886 Kind == OMPD_target_parallel) 3887 return ReturnBlock; 3888 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections || 3889 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for || 3890 Kind == OMPD_distribute_parallel_for || 3891 Kind == OMPD_target_parallel_for); 3892 return OMPCancelStack.getExitBlock(); 3893 } 3894 3895 void CodeGenFunction::EmitOMPUseDevicePtrClause( 3896 const OMPClause &NC, OMPPrivateScope &PrivateScope, 3897 const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) { 3898 const auto &C = cast<OMPUseDevicePtrClause>(NC); 3899 auto OrigVarIt = C.varlist_begin(); 3900 auto InitIt = C.inits().begin(); 3901 for (auto PvtVarIt : C.private_copies()) { 3902 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl()); 3903 auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl()); 3904 auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl()); 3905 3906 // In order to identify the right initializer we need to match the 3907 // declaration used by the mapping logic. In some cases we may get 3908 // OMPCapturedExprDecl that refers to the original declaration. 3909 const ValueDecl *MatchingVD = OrigVD; 3910 if (auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) { 3911 // OMPCapturedExprDecl are used to privative fields of the current 3912 // structure. 3913 auto *ME = cast<MemberExpr>(OED->getInit()); 3914 assert(isa<CXXThisExpr>(ME->getBase()) && 3915 "Base should be the current struct!"); 3916 MatchingVD = ME->getMemberDecl(); 3917 } 3918 3919 // If we don't have information about the current list item, move on to 3920 // the next one. 3921 auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD); 3922 if (InitAddrIt == CaptureDeviceAddrMap.end()) 3923 continue; 3924 3925 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address { 3926 // Initialize the temporary initialization variable with the address we 3927 // get from the runtime library. We have to cast the source address 3928 // because it is always a void *. References are materialized in the 3929 // privatization scope, so the initialization here disregards the fact 3930 // the original variable is a reference. 3931 QualType AddrQTy = 3932 getContext().getPointerType(OrigVD->getType().getNonReferenceType()); 3933 llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy); 3934 Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy); 3935 setAddrOfLocalVar(InitVD, InitAddr); 3936 3937 // Emit private declaration, it will be initialized by the value we 3938 // declaration we just added to the local declarations map. 3939 EmitDecl(*PvtVD); 3940 3941 // The initialization variables reached its purpose in the emission 3942 // ofthe previous declaration, so we don't need it anymore. 3943 LocalDeclMap.erase(InitVD); 3944 3945 // Return the address of the private variable. 3946 return GetAddrOfLocalVar(PvtVD); 3947 }); 3948 assert(IsRegistered && "firstprivate var already registered as private"); 3949 // Silence the warning about unused variable. 3950 (void)IsRegistered; 3951 3952 ++OrigVarIt; 3953 ++InitIt; 3954 } 3955 } 3956 3957 // Generate the instructions for '#pragma omp target data' directive. 3958 void CodeGenFunction::EmitOMPTargetDataDirective( 3959 const OMPTargetDataDirective &S) { 3960 CGOpenMPRuntime::TargetDataInfo Info(/*RequiresDevicePointerInfo=*/true); 3961 3962 // Create a pre/post action to signal the privatization of the device pointer. 3963 // This action can be replaced by the OpenMP runtime code generation to 3964 // deactivate privatization. 3965 bool PrivatizeDevicePointers = false; 3966 class DevicePointerPrivActionTy : public PrePostActionTy { 3967 bool &PrivatizeDevicePointers; 3968 3969 public: 3970 explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers) 3971 : PrePostActionTy(), PrivatizeDevicePointers(PrivatizeDevicePointers) {} 3972 void Enter(CodeGenFunction &CGF) override { 3973 PrivatizeDevicePointers = true; 3974 } 3975 }; 3976 DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers); 3977 3978 auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers]( 3979 CodeGenFunction &CGF, PrePostActionTy &Action) { 3980 auto &&InnermostCodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 3981 CGF.EmitStmt( 3982 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 3983 }; 3984 3985 // Codegen that selects wheather to generate the privatization code or not. 3986 auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers, 3987 &InnermostCodeGen](CodeGenFunction &CGF, 3988 PrePostActionTy &Action) { 3989 RegionCodeGenTy RCG(InnermostCodeGen); 3990 PrivatizeDevicePointers = false; 3991 3992 // Call the pre-action to change the status of PrivatizeDevicePointers if 3993 // needed. 3994 Action.Enter(CGF); 3995 3996 if (PrivatizeDevicePointers) { 3997 OMPPrivateScope PrivateScope(CGF); 3998 // Emit all instances of the use_device_ptr clause. 3999 for (const auto *C : S.getClausesOfKind<OMPUseDevicePtrClause>()) 4000 CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope, 4001 Info.CaptureDeviceAddrMap); 4002 (void)PrivateScope.Privatize(); 4003 RCG(CGF); 4004 } else 4005 RCG(CGF); 4006 }; 4007 4008 // Forward the provided action to the privatization codegen. 4009 RegionCodeGenTy PrivRCG(PrivCodeGen); 4010 PrivRCG.setAction(Action); 4011 4012 // Notwithstanding the body of the region is emitted as inlined directive, 4013 // we don't use an inline scope as changes in the references inside the 4014 // region are expected to be visible outside, so we do not privative them. 4015 OMPLexicalScope Scope(CGF, S); 4016 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data, 4017 PrivRCG); 4018 }; 4019 4020 RegionCodeGenTy RCG(CodeGen); 4021 4022 // If we don't have target devices, don't bother emitting the data mapping 4023 // code. 4024 if (CGM.getLangOpts().OMPTargetTriples.empty()) { 4025 RCG(*this); 4026 return; 4027 } 4028 4029 // Check if we have any if clause associated with the directive. 4030 const Expr *IfCond = nullptr; 4031 if (auto *C = S.getSingleClause<OMPIfClause>()) 4032 IfCond = C->getCondition(); 4033 4034 // Check if we have any device clause associated with the directive. 4035 const Expr *Device = nullptr; 4036 if (auto *C = S.getSingleClause<OMPDeviceClause>()) 4037 Device = C->getDevice(); 4038 4039 // Set the action to signal privatization of device pointers. 4040 RCG.setAction(PrivAction); 4041 4042 // Emit region code. 4043 CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, RCG, 4044 Info); 4045 } 4046 4047 void CodeGenFunction::EmitOMPTargetEnterDataDirective( 4048 const OMPTargetEnterDataDirective &S) { 4049 // If we don't have target devices, don't bother emitting the data mapping 4050 // code. 4051 if (CGM.getLangOpts().OMPTargetTriples.empty()) 4052 return; 4053 4054 // Check if we have any if clause associated with the directive. 4055 const Expr *IfCond = nullptr; 4056 if (auto *C = S.getSingleClause<OMPIfClause>()) 4057 IfCond = C->getCondition(); 4058 4059 // Check if we have any device clause associated with the directive. 4060 const Expr *Device = nullptr; 4061 if (auto *C = S.getSingleClause<OMPDeviceClause>()) 4062 Device = C->getDevice(); 4063 4064 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device); 4065 } 4066 4067 void CodeGenFunction::EmitOMPTargetExitDataDirective( 4068 const OMPTargetExitDataDirective &S) { 4069 // If we don't have target devices, don't bother emitting the data mapping 4070 // code. 4071 if (CGM.getLangOpts().OMPTargetTriples.empty()) 4072 return; 4073 4074 // Check if we have any if clause associated with the directive. 4075 const Expr *IfCond = nullptr; 4076 if (auto *C = S.getSingleClause<OMPIfClause>()) 4077 IfCond = C->getCondition(); 4078 4079 // Check if we have any device clause associated with the directive. 4080 const Expr *Device = nullptr; 4081 if (auto *C = S.getSingleClause<OMPDeviceClause>()) 4082 Device = C->getDevice(); 4083 4084 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device); 4085 } 4086 4087 static void emitTargetParallelRegion(CodeGenFunction &CGF, 4088 const OMPTargetParallelDirective &S, 4089 PrePostActionTy &Action) { 4090 // Get the captured statement associated with the 'parallel' region. 4091 auto *CS = S.getCapturedStmt(OMPD_parallel); 4092 Action.Enter(CGF); 4093 auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &) { 4094 CodeGenFunction::OMPPrivateScope PrivateScope(CGF); 4095 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); 4096 CGF.EmitOMPPrivateClause(S, PrivateScope); 4097 CGF.EmitOMPReductionClauseInit(S, PrivateScope); 4098 (void)PrivateScope.Privatize(); 4099 // TODO: Add support for clauses. 4100 CGF.EmitStmt(CS->getCapturedStmt()); 4101 CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel); 4102 }; 4103 emitCommonOMPParallelDirective(CGF, S, OMPD_parallel, CodeGen, 4104 emitEmptyBoundParameters); 4105 emitPostUpdateForReductionClause( 4106 CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 4107 } 4108 4109 void CodeGenFunction::EmitOMPTargetParallelDeviceFunction( 4110 CodeGenModule &CGM, StringRef ParentName, 4111 const OMPTargetParallelDirective &S) { 4112 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 4113 emitTargetParallelRegion(CGF, S, Action); 4114 }; 4115 llvm::Function *Fn; 4116 llvm::Constant *Addr; 4117 // Emit target region as a standalone region. 4118 CGM.getOpenMPRuntime().emitTargetOutlinedFunction( 4119 S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen); 4120 assert(Fn && Addr && "Target device function emission failed."); 4121 } 4122 4123 void CodeGenFunction::EmitOMPTargetParallelDirective( 4124 const OMPTargetParallelDirective &S) { 4125 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 4126 emitTargetParallelRegion(CGF, S, Action); 4127 }; 4128 emitCommonOMPTargetDirective(*this, S, CodeGen); 4129 } 4130 4131 void CodeGenFunction::EmitOMPTargetParallelForDirective( 4132 const OMPTargetParallelForDirective &S) { 4133 OMPLexicalScope Scope(*this, S, /*AsInlined=*/true); 4134 CGM.getOpenMPRuntime().emitInlinedDirective( 4135 *this, OMPD_target_parallel_for, 4136 [&S](CodeGenFunction &CGF, PrePostActionTy &) { 4137 OMPLoopScope PreInitScope(CGF, S); 4138 CGF.EmitStmt( 4139 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 4140 }); 4141 } 4142 4143 /// Emit a helper variable and return corresponding lvalue. 4144 static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper, 4145 const ImplicitParamDecl *PVD, 4146 CodeGenFunction::OMPPrivateScope &Privates) { 4147 auto *VDecl = cast<VarDecl>(Helper->getDecl()); 4148 Privates.addPrivate( 4149 VDecl, [&CGF, PVD]() -> Address { return CGF.GetAddrOfLocalVar(PVD); }); 4150 } 4151 4152 void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) { 4153 assert(isOpenMPTaskLoopDirective(S.getDirectiveKind())); 4154 // Emit outlined function for task construct. 4155 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 4156 auto CapturedStruct = GenerateCapturedStmtArgument(*CS); 4157 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); 4158 const Expr *IfCond = nullptr; 4159 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 4160 if (C->getNameModifier() == OMPD_unknown || 4161 C->getNameModifier() == OMPD_taskloop) { 4162 IfCond = C->getCondition(); 4163 break; 4164 } 4165 } 4166 4167 OMPTaskDataTy Data; 4168 // Check if taskloop must be emitted without taskgroup. 4169 Data.Nogroup = S.getSingleClause<OMPNogroupClause>(); 4170 // TODO: Check if we should emit tied or untied task. 4171 Data.Tied = true; 4172 // Set scheduling for taskloop 4173 if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) { 4174 // grainsize clause 4175 Data.Schedule.setInt(/*IntVal=*/false); 4176 Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize())); 4177 } else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) { 4178 // num_tasks clause 4179 Data.Schedule.setInt(/*IntVal=*/true); 4180 Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks())); 4181 } 4182 4183 auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) { 4184 // if (PreCond) { 4185 // for (IV in 0..LastIteration) BODY; 4186 // <Final counter/linear vars updates>; 4187 // } 4188 // 4189 4190 // Emit: if (PreCond) - begin. 4191 // If the condition constant folds and can be elided, avoid emitting the 4192 // whole loop. 4193 bool CondConstant; 4194 llvm::BasicBlock *ContBlock = nullptr; 4195 OMPLoopScope PreInitScope(CGF, S); 4196 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { 4197 if (!CondConstant) 4198 return; 4199 } else { 4200 auto *ThenBlock = CGF.createBasicBlock("taskloop.if.then"); 4201 ContBlock = CGF.createBasicBlock("taskloop.if.end"); 4202 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock, 4203 CGF.getProfileCount(&S)); 4204 CGF.EmitBlock(ThenBlock); 4205 CGF.incrementProfileCounter(&S); 4206 } 4207 4208 if (isOpenMPSimdDirective(S.getDirectiveKind())) 4209 CGF.EmitOMPSimdInit(S); 4210 4211 OMPPrivateScope LoopScope(CGF); 4212 // Emit helper vars inits. 4213 enum { LowerBound = 5, UpperBound, Stride, LastIter }; 4214 auto *I = CS->getCapturedDecl()->param_begin(); 4215 auto *LBP = std::next(I, LowerBound); 4216 auto *UBP = std::next(I, UpperBound); 4217 auto *STP = std::next(I, Stride); 4218 auto *LIP = std::next(I, LastIter); 4219 mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP, 4220 LoopScope); 4221 mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP, 4222 LoopScope); 4223 mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope); 4224 mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP, 4225 LoopScope); 4226 CGF.EmitOMPPrivateLoopCounters(S, LoopScope); 4227 bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); 4228 (void)LoopScope.Privatize(); 4229 // Emit the loop iteration variable. 4230 const Expr *IVExpr = S.getIterationVariable(); 4231 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); 4232 CGF.EmitVarDecl(*IVDecl); 4233 CGF.EmitIgnoredExpr(S.getInit()); 4234 4235 // Emit the iterations count variable. 4236 // If it is not a variable, Sema decided to calculate iterations count on 4237 // each iteration (e.g., it is foldable into a constant). 4238 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 4239 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 4240 // Emit calculation of the iterations count. 4241 CGF.EmitIgnoredExpr(S.getCalcLastIteration()); 4242 } 4243 4244 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), 4245 S.getInc(), 4246 [&S](CodeGenFunction &CGF) { 4247 CGF.EmitOMPLoopBody(S, JumpDest()); 4248 CGF.EmitStopPoint(&S); 4249 }, 4250 [](CodeGenFunction &) {}); 4251 // Emit: if (PreCond) - end. 4252 if (ContBlock) { 4253 CGF.EmitBranch(ContBlock); 4254 CGF.EmitBlock(ContBlock, true); 4255 } 4256 // Emit final copy of the lastprivate variables if IsLastIter != 0. 4257 if (HasLastprivateClause) { 4258 CGF.EmitOMPLastprivateClauseFinal( 4259 S, isOpenMPSimdDirective(S.getDirectiveKind()), 4260 CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar( 4261 CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false, 4262 (*LIP)->getType(), S.getLocStart()))); 4263 } 4264 }; 4265 auto &&TaskGen = [&S, SharedsTy, CapturedStruct, 4266 IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn, 4267 const OMPTaskDataTy &Data) { 4268 auto &&CodeGen = [&](CodeGenFunction &CGF, PrePostActionTy &) { 4269 OMPLoopScope PreInitScope(CGF, S); 4270 CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getLocStart(), S, 4271 OutlinedFn, SharedsTy, 4272 CapturedStruct, IfCond, Data); 4273 }; 4274 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop, 4275 CodeGen); 4276 }; 4277 if (Data.Nogroup) 4278 EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data); 4279 else { 4280 CGM.getOpenMPRuntime().emitTaskgroupRegion( 4281 *this, 4282 [&S, &BodyGen, &TaskGen, &Data](CodeGenFunction &CGF, 4283 PrePostActionTy &Action) { 4284 Action.Enter(CGF); 4285 CGF.EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data); 4286 }, 4287 S.getLocStart()); 4288 } 4289 } 4290 4291 void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) { 4292 EmitOMPTaskLoopBasedDirective(S); 4293 } 4294 4295 void CodeGenFunction::EmitOMPTaskLoopSimdDirective( 4296 const OMPTaskLoopSimdDirective &S) { 4297 EmitOMPTaskLoopBasedDirective(S); 4298 } 4299 4300 // Generate the instructions for '#pragma omp target update' directive. 4301 void CodeGenFunction::EmitOMPTargetUpdateDirective( 4302 const OMPTargetUpdateDirective &S) { 4303 // If we don't have target devices, don't bother emitting the data mapping 4304 // code. 4305 if (CGM.getLangOpts().OMPTargetTriples.empty()) 4306 return; 4307 4308 // Check if we have any if clause associated with the directive. 4309 const Expr *IfCond = nullptr; 4310 if (auto *C = S.getSingleClause<OMPIfClause>()) 4311 IfCond = C->getCondition(); 4312 4313 // Check if we have any device clause associated with the directive. 4314 const Expr *Device = nullptr; 4315 if (auto *C = S.getSingleClause<OMPDeviceClause>()) 4316 Device = C->getDevice(); 4317 4318 CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device); 4319 } 4320