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 48 public: 49 OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) 50 : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()) { 51 emitPreInitStmt(CGF, S); 52 } 53 }; 54 55 /// Private scope for OpenMP loop-based directives, that supports capturing 56 /// of used expression from loop statement. 57 class OMPLoopScope : public CodeGenFunction::RunCleanupsScope { 58 void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopDirective &S) { 59 if (auto *LD = dyn_cast<OMPLoopDirective>(&S)) { 60 if (auto *PreInits = cast_or_null<DeclStmt>(LD->getPreInits())) { 61 for (const auto *I : PreInits->decls()) 62 CGF.EmitVarDecl(cast<VarDecl>(*I)); 63 } 64 } 65 } 66 67 public: 68 OMPLoopScope(CodeGenFunction &CGF, const OMPLoopDirective &S) 69 : CodeGenFunction::RunCleanupsScope(CGF) { 70 emitPreInitStmt(CGF, S); 71 } 72 }; 73 74 } // namespace 75 76 llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) { 77 auto &C = getContext(); 78 llvm::Value *Size = nullptr; 79 auto SizeInChars = C.getTypeSizeInChars(Ty); 80 if (SizeInChars.isZero()) { 81 // getTypeSizeInChars() returns 0 for a VLA. 82 while (auto *VAT = C.getAsVariableArrayType(Ty)) { 83 llvm::Value *ArraySize; 84 std::tie(ArraySize, Ty) = getVLASize(VAT); 85 Size = Size ? Builder.CreateNUWMul(Size, ArraySize) : ArraySize; 86 } 87 SizeInChars = C.getTypeSizeInChars(Ty); 88 if (SizeInChars.isZero()) 89 return llvm::ConstantInt::get(SizeTy, /*V=*/0); 90 Size = Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars)); 91 } else 92 Size = CGM.getSize(SizeInChars); 93 return Size; 94 } 95 96 void CodeGenFunction::GenerateOpenMPCapturedVars( 97 const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) { 98 const RecordDecl *RD = S.getCapturedRecordDecl(); 99 auto CurField = RD->field_begin(); 100 auto CurCap = S.captures().begin(); 101 for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(), 102 E = S.capture_init_end(); 103 I != E; ++I, ++CurField, ++CurCap) { 104 if (CurField->hasCapturedVLAType()) { 105 auto VAT = CurField->getCapturedVLAType(); 106 auto *Val = VLASizeMap[VAT->getSizeExpr()]; 107 CapturedVars.push_back(Val); 108 } else if (CurCap->capturesThis()) 109 CapturedVars.push_back(CXXThisValue); 110 else if (CurCap->capturesVariableByCopy()) 111 CapturedVars.push_back( 112 EmitLoadOfLValue(EmitLValue(*I), SourceLocation()).getScalarVal()); 113 else { 114 assert(CurCap->capturesVariable() && "Expected capture by reference."); 115 CapturedVars.push_back(EmitLValue(*I).getAddress().getPointer()); 116 } 117 } 118 } 119 120 static Address castValueFromUintptr(CodeGenFunction &CGF, QualType DstType, 121 StringRef Name, LValue AddrLV, 122 bool isReferenceType = false) { 123 ASTContext &Ctx = CGF.getContext(); 124 125 auto *CastedPtr = CGF.EmitScalarConversion( 126 AddrLV.getAddress().getPointer(), Ctx.getUIntPtrType(), 127 Ctx.getPointerType(DstType), SourceLocation()); 128 auto TmpAddr = 129 CGF.MakeNaturalAlignAddrLValue(CastedPtr, Ctx.getPointerType(DstType)) 130 .getAddress(); 131 132 // If we are dealing with references we need to return the address of the 133 // reference instead of the reference of the value. 134 if (isReferenceType) { 135 QualType RefType = Ctx.getLValueReferenceType(DstType); 136 auto *RefVal = TmpAddr.getPointer(); 137 TmpAddr = CGF.CreateMemTemp(RefType, Twine(Name) + ".ref"); 138 auto TmpLVal = CGF.MakeAddrLValue(TmpAddr, RefType); 139 CGF.EmitScalarInit(RefVal, TmpLVal); 140 } 141 142 return TmpAddr; 143 } 144 145 llvm::Function * 146 CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) { 147 assert( 148 CapturedStmtInfo && 149 "CapturedStmtInfo should be set when generating the captured function"); 150 const CapturedDecl *CD = S.getCapturedDecl(); 151 const RecordDecl *RD = S.getCapturedRecordDecl(); 152 assert(CD->hasBody() && "missing CapturedDecl body"); 153 154 // Build the argument list. 155 ASTContext &Ctx = CGM.getContext(); 156 FunctionArgList Args; 157 Args.append(CD->param_begin(), 158 std::next(CD->param_begin(), CD->getContextParamPosition())); 159 auto I = S.captures().begin(); 160 for (auto *FD : RD->fields()) { 161 QualType ArgType = FD->getType(); 162 IdentifierInfo *II = nullptr; 163 VarDecl *CapVar = nullptr; 164 165 // If this is a capture by copy and the type is not a pointer, the outlined 166 // function argument type should be uintptr and the value properly casted to 167 // uintptr. This is necessary given that the runtime library is only able to 168 // deal with pointers. We can pass in the same way the VLA type sizes to the 169 // outlined function. 170 if ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) || 171 I->capturesVariableArrayType()) 172 ArgType = Ctx.getUIntPtrType(); 173 174 if (I->capturesVariable() || I->capturesVariableByCopy()) { 175 CapVar = I->getCapturedVar(); 176 II = CapVar->getIdentifier(); 177 } else if (I->capturesThis()) 178 II = &getContext().Idents.get("this"); 179 else { 180 assert(I->capturesVariableArrayType()); 181 II = &getContext().Idents.get("vla"); 182 } 183 if (ArgType->isVariablyModifiedType()) 184 ArgType = getContext().getVariableArrayDecayedType(ArgType); 185 Args.push_back(ImplicitParamDecl::Create(getContext(), nullptr, 186 FD->getLocation(), II, ArgType)); 187 ++I; 188 } 189 Args.append( 190 std::next(CD->param_begin(), CD->getContextParamPosition() + 1), 191 CD->param_end()); 192 193 // Create the function declaration. 194 FunctionType::ExtInfo ExtInfo; 195 const CGFunctionInfo &FuncInfo = 196 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args); 197 llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo); 198 199 llvm::Function *F = llvm::Function::Create( 200 FuncLLVMTy, llvm::GlobalValue::InternalLinkage, 201 CapturedStmtInfo->getHelperName(), &CGM.getModule()); 202 CGM.SetInternalFunctionAttributes(CD, F, FuncInfo); 203 if (CD->isNothrow()) 204 F->addFnAttr(llvm::Attribute::NoUnwind); 205 206 // Generate the function. 207 StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getLocation(), 208 CD->getBody()->getLocStart()); 209 unsigned Cnt = CD->getContextParamPosition(); 210 I = S.captures().begin(); 211 for (auto *FD : RD->fields()) { 212 // If we are capturing a pointer by copy we don't need to do anything, just 213 // use the value that we get from the arguments. 214 if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) { 215 setAddrOfLocalVar(I->getCapturedVar(), GetAddrOfLocalVar(Args[Cnt])); 216 ++Cnt; 217 ++I; 218 continue; 219 } 220 221 LValue ArgLVal = 222 MakeAddrLValue(GetAddrOfLocalVar(Args[Cnt]), Args[Cnt]->getType(), 223 AlignmentSource::Decl); 224 if (FD->hasCapturedVLAType()) { 225 LValue CastedArgLVal = 226 MakeAddrLValue(castValueFromUintptr(*this, FD->getType(), 227 Args[Cnt]->getName(), ArgLVal), 228 FD->getType(), AlignmentSource::Decl); 229 auto *ExprArg = 230 EmitLoadOfLValue(CastedArgLVal, SourceLocation()).getScalarVal(); 231 auto VAT = FD->getCapturedVLAType(); 232 VLASizeMap[VAT->getSizeExpr()] = ExprArg; 233 } else if (I->capturesVariable()) { 234 auto *Var = I->getCapturedVar(); 235 QualType VarTy = Var->getType(); 236 Address ArgAddr = ArgLVal.getAddress(); 237 if (!VarTy->isReferenceType()) { 238 ArgAddr = EmitLoadOfReference( 239 ArgAddr, ArgLVal.getType()->castAs<ReferenceType>()); 240 } 241 setAddrOfLocalVar( 242 Var, Address(ArgAddr.getPointer(), getContext().getDeclAlign(Var))); 243 } else if (I->capturesVariableByCopy()) { 244 assert(!FD->getType()->isAnyPointerType() && 245 "Not expecting a captured pointer."); 246 auto *Var = I->getCapturedVar(); 247 QualType VarTy = Var->getType(); 248 setAddrOfLocalVar(I->getCapturedVar(), 249 castValueFromUintptr(*this, FD->getType(), 250 Args[Cnt]->getName(), ArgLVal, 251 VarTy->isReferenceType())); 252 } else { 253 // If 'this' is captured, load it into CXXThisValue. 254 assert(I->capturesThis()); 255 CXXThisValue = 256 EmitLoadOfLValue(ArgLVal, Args[Cnt]->getLocation()).getScalarVal(); 257 } 258 ++Cnt; 259 ++I; 260 } 261 262 PGO.assignRegionCounters(GlobalDecl(CD), F); 263 CapturedStmtInfo->EmitBody(*this, CD->getBody()); 264 FinishFunction(CD->getBodyRBrace()); 265 266 return F; 267 } 268 269 //===----------------------------------------------------------------------===// 270 // OpenMP Directive Emission 271 //===----------------------------------------------------------------------===// 272 void CodeGenFunction::EmitOMPAggregateAssign( 273 Address DestAddr, Address SrcAddr, QualType OriginalType, 274 const llvm::function_ref<void(Address, Address)> &CopyGen) { 275 // Perform element-by-element initialization. 276 QualType ElementTy; 277 278 // Drill down to the base element type on both arrays. 279 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe(); 280 auto NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr); 281 SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType()); 282 283 auto SrcBegin = SrcAddr.getPointer(); 284 auto DestBegin = DestAddr.getPointer(); 285 // Cast from pointer to array type to pointer to single element. 286 auto DestEnd = Builder.CreateGEP(DestBegin, NumElements); 287 // The basic structure here is a while-do loop. 288 auto BodyBB = createBasicBlock("omp.arraycpy.body"); 289 auto DoneBB = createBasicBlock("omp.arraycpy.done"); 290 auto IsEmpty = 291 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty"); 292 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); 293 294 // Enter the loop body, making that address the current address. 295 auto EntryBB = Builder.GetInsertBlock(); 296 EmitBlock(BodyBB); 297 298 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy); 299 300 llvm::PHINode *SrcElementPHI = 301 Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast"); 302 SrcElementPHI->addIncoming(SrcBegin, EntryBB); 303 Address SrcElementCurrent = 304 Address(SrcElementPHI, 305 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize)); 306 307 llvm::PHINode *DestElementPHI = 308 Builder.CreatePHI(DestBegin->getType(), 2, "omp.arraycpy.destElementPast"); 309 DestElementPHI->addIncoming(DestBegin, EntryBB); 310 Address DestElementCurrent = 311 Address(DestElementPHI, 312 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize)); 313 314 // Emit copy. 315 CopyGen(DestElementCurrent, SrcElementCurrent); 316 317 // Shift the address forward by one element. 318 auto DestElementNext = Builder.CreateConstGEP1_32( 319 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element"); 320 auto SrcElementNext = Builder.CreateConstGEP1_32( 321 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element"); 322 // Check whether we've reached the end. 323 auto Done = 324 Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done"); 325 Builder.CreateCondBr(Done, DoneBB, BodyBB); 326 DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock()); 327 SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock()); 328 329 // Done. 330 EmitBlock(DoneBB, /*IsFinished=*/true); 331 } 332 333 /// Check if the combiner is a call to UDR combiner and if it is so return the 334 /// UDR decl used for reduction. 335 static const OMPDeclareReductionDecl * 336 getReductionInit(const Expr *ReductionOp) { 337 if (auto *CE = dyn_cast<CallExpr>(ReductionOp)) 338 if (auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee())) 339 if (auto *DRE = 340 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts())) 341 if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) 342 return DRD; 343 return nullptr; 344 } 345 346 static void emitInitWithReductionInitializer(CodeGenFunction &CGF, 347 const OMPDeclareReductionDecl *DRD, 348 const Expr *InitOp, 349 Address Private, Address Original, 350 QualType Ty) { 351 if (DRD->getInitializer()) { 352 std::pair<llvm::Function *, llvm::Function *> Reduction = 353 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD); 354 auto *CE = cast<CallExpr>(InitOp); 355 auto *OVE = cast<OpaqueValueExpr>(CE->getCallee()); 356 const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 357 const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 358 auto *LHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr()); 359 auto *RHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr()); 360 CodeGenFunction::OMPPrivateScope PrivateScope(CGF); 361 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()), 362 [=]() -> Address { return Private; }); 363 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()), 364 [=]() -> Address { return Original; }); 365 (void)PrivateScope.Privatize(); 366 RValue Func = RValue::get(Reduction.second); 367 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func); 368 CGF.EmitIgnoredExpr(InitOp); 369 } else { 370 llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty); 371 auto *GV = new llvm::GlobalVariable( 372 CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true, 373 llvm::GlobalValue::PrivateLinkage, Init, ".init"); 374 LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty); 375 RValue InitRVal; 376 switch (CGF.getEvaluationKind(Ty)) { 377 case TEK_Scalar: 378 InitRVal = CGF.EmitLoadOfLValue(LV, SourceLocation()); 379 break; 380 case TEK_Complex: 381 InitRVal = 382 RValue::getComplex(CGF.EmitLoadOfComplex(LV, SourceLocation())); 383 break; 384 case TEK_Aggregate: 385 InitRVal = RValue::getAggregate(LV.getAddress()); 386 break; 387 } 388 OpaqueValueExpr OVE(SourceLocation(), Ty, VK_RValue); 389 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal); 390 CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(), 391 /*IsInitializer=*/false); 392 } 393 } 394 395 /// \brief Emit initialization of arrays of complex types. 396 /// \param DestAddr Address of the array. 397 /// \param Type Type of array. 398 /// \param Init Initial expression of array. 399 /// \param SrcAddr Address of the original array. 400 static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr, 401 QualType Type, const Expr *Init, 402 Address SrcAddr = Address::invalid()) { 403 auto *DRD = getReductionInit(Init); 404 // Perform element-by-element initialization. 405 QualType ElementTy; 406 407 // Drill down to the base element type on both arrays. 408 auto ArrayTy = Type->getAsArrayTypeUnsafe(); 409 auto NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr); 410 DestAddr = 411 CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType()); 412 if (DRD) 413 SrcAddr = 414 CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType()); 415 416 llvm::Value *SrcBegin = nullptr; 417 if (DRD) 418 SrcBegin = SrcAddr.getPointer(); 419 auto DestBegin = DestAddr.getPointer(); 420 // Cast from pointer to array type to pointer to single element. 421 auto DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements); 422 // The basic structure here is a while-do loop. 423 auto BodyBB = CGF.createBasicBlock("omp.arrayinit.body"); 424 auto DoneBB = CGF.createBasicBlock("omp.arrayinit.done"); 425 auto IsEmpty = 426 CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty"); 427 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); 428 429 // Enter the loop body, making that address the current address. 430 auto EntryBB = CGF.Builder.GetInsertBlock(); 431 CGF.EmitBlock(BodyBB); 432 433 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy); 434 435 llvm::PHINode *SrcElementPHI = nullptr; 436 Address SrcElementCurrent = Address::invalid(); 437 if (DRD) { 438 SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2, 439 "omp.arraycpy.srcElementPast"); 440 SrcElementPHI->addIncoming(SrcBegin, EntryBB); 441 SrcElementCurrent = 442 Address(SrcElementPHI, 443 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize)); 444 } 445 llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI( 446 DestBegin->getType(), 2, "omp.arraycpy.destElementPast"); 447 DestElementPHI->addIncoming(DestBegin, EntryBB); 448 Address DestElementCurrent = 449 Address(DestElementPHI, 450 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize)); 451 452 // Emit copy. 453 { 454 CodeGenFunction::RunCleanupsScope InitScope(CGF); 455 if (DRD) { 456 emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent, 457 SrcElementCurrent, ElementTy); 458 } else 459 CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(), 460 /*IsInitializer=*/false); 461 } 462 463 if (DRD) { 464 // Shift the address forward by one element. 465 auto SrcElementNext = CGF.Builder.CreateConstGEP1_32( 466 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element"); 467 SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock()); 468 } 469 470 // Shift the address forward by one element. 471 auto DestElementNext = CGF.Builder.CreateConstGEP1_32( 472 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element"); 473 // Check whether we've reached the end. 474 auto Done = 475 CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done"); 476 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB); 477 DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock()); 478 479 // Done. 480 CGF.EmitBlock(DoneBB, /*IsFinished=*/true); 481 } 482 483 void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr, 484 Address SrcAddr, const VarDecl *DestVD, 485 const VarDecl *SrcVD, const Expr *Copy) { 486 if (OriginalType->isArrayType()) { 487 auto *BO = dyn_cast<BinaryOperator>(Copy); 488 if (BO && BO->getOpcode() == BO_Assign) { 489 // Perform simple memcpy for simple copying. 490 EmitAggregateAssign(DestAddr, SrcAddr, OriginalType); 491 } else { 492 // For arrays with complex element types perform element by element 493 // copying. 494 EmitOMPAggregateAssign( 495 DestAddr, SrcAddr, OriginalType, 496 [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) { 497 // Working with the single array element, so have to remap 498 // destination and source variables to corresponding array 499 // elements. 500 CodeGenFunction::OMPPrivateScope Remap(*this); 501 Remap.addPrivate(DestVD, [DestElement]() -> Address { 502 return DestElement; 503 }); 504 Remap.addPrivate( 505 SrcVD, [SrcElement]() -> Address { return SrcElement; }); 506 (void)Remap.Privatize(); 507 EmitIgnoredExpr(Copy); 508 }); 509 } 510 } else { 511 // Remap pseudo source variable to private copy. 512 CodeGenFunction::OMPPrivateScope Remap(*this); 513 Remap.addPrivate(SrcVD, [SrcAddr]() -> Address { return SrcAddr; }); 514 Remap.addPrivate(DestVD, [DestAddr]() -> Address { return DestAddr; }); 515 (void)Remap.Privatize(); 516 // Emit copying of the whole variable. 517 EmitIgnoredExpr(Copy); 518 } 519 } 520 521 bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, 522 OMPPrivateScope &PrivateScope) { 523 if (!HaveInsertPoint()) 524 return false; 525 bool FirstprivateIsLastprivate = false; 526 llvm::DenseSet<const VarDecl *> Lastprivates; 527 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { 528 for (const auto *D : C->varlists()) 529 Lastprivates.insert( 530 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl()); 531 } 532 llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate; 533 for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) { 534 auto IRef = C->varlist_begin(); 535 auto InitsRef = C->inits().begin(); 536 for (auto IInit : C->private_copies()) { 537 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 538 FirstprivateIsLastprivate = 539 FirstprivateIsLastprivate || 540 (Lastprivates.count(OrigVD->getCanonicalDecl()) > 0); 541 if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) { 542 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); 543 auto *VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl()); 544 bool IsRegistered; 545 DeclRefExpr DRE( 546 const_cast<VarDecl *>(OrigVD), 547 /*RefersToEnclosingVariableOrCapture=*/CapturedStmtInfo->lookup( 548 OrigVD) != nullptr, 549 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc()); 550 Address OriginalAddr = EmitLValue(&DRE).getAddress(); 551 QualType Type = VD->getType(); 552 if (Type->isArrayType()) { 553 // Emit VarDecl with copy init for arrays. 554 // Get the address of the original variable captured in current 555 // captured region. 556 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address { 557 auto Emission = EmitAutoVarAlloca(*VD); 558 auto *Init = VD->getInit(); 559 if (!isa<CXXConstructExpr>(Init) || isTrivialInitializer(Init)) { 560 // Perform simple memcpy. 561 EmitAggregateAssign(Emission.getAllocatedAddress(), OriginalAddr, 562 Type); 563 } else { 564 EmitOMPAggregateAssign( 565 Emission.getAllocatedAddress(), OriginalAddr, Type, 566 [this, VDInit, Init](Address DestElement, 567 Address SrcElement) { 568 // Clean up any temporaries needed by the initialization. 569 RunCleanupsScope InitScope(*this); 570 // Emit initialization for single element. 571 setAddrOfLocalVar(VDInit, SrcElement); 572 EmitAnyExprToMem(Init, DestElement, 573 Init->getType().getQualifiers(), 574 /*IsInitializer*/ false); 575 LocalDeclMap.erase(VDInit); 576 }); 577 } 578 EmitAutoVarCleanups(Emission); 579 return Emission.getAllocatedAddress(); 580 }); 581 } else { 582 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address { 583 // Emit private VarDecl with copy init. 584 // Remap temp VDInit variable to the address of the original 585 // variable 586 // (for proper handling of captured global variables). 587 setAddrOfLocalVar(VDInit, OriginalAddr); 588 EmitDecl(*VD); 589 LocalDeclMap.erase(VDInit); 590 return GetAddrOfLocalVar(VD); 591 }); 592 } 593 assert(IsRegistered && 594 "firstprivate var already registered as private"); 595 // Silence the warning about unused variable. 596 (void)IsRegistered; 597 } 598 ++IRef; 599 ++InitsRef; 600 } 601 } 602 return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty(); 603 } 604 605 void CodeGenFunction::EmitOMPPrivateClause( 606 const OMPExecutableDirective &D, 607 CodeGenFunction::OMPPrivateScope &PrivateScope) { 608 if (!HaveInsertPoint()) 609 return; 610 llvm::DenseSet<const VarDecl *> EmittedAsPrivate; 611 for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) { 612 auto IRef = C->varlist_begin(); 613 for (auto IInit : C->private_copies()) { 614 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 615 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { 616 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); 617 bool IsRegistered = 618 PrivateScope.addPrivate(OrigVD, [&]() -> Address { 619 // Emit private VarDecl with copy init. 620 EmitDecl(*VD); 621 return GetAddrOfLocalVar(VD); 622 }); 623 assert(IsRegistered && "private var already registered as private"); 624 // Silence the warning about unused variable. 625 (void)IsRegistered; 626 } 627 ++IRef; 628 } 629 } 630 } 631 632 bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { 633 if (!HaveInsertPoint()) 634 return false; 635 // threadprivate_var1 = master_threadprivate_var1; 636 // operator=(threadprivate_var2, master_threadprivate_var2); 637 // ... 638 // __kmpc_barrier(&loc, global_tid); 639 llvm::DenseSet<const VarDecl *> CopiedVars; 640 llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr; 641 for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) { 642 auto IRef = C->varlist_begin(); 643 auto ISrcRef = C->source_exprs().begin(); 644 auto IDestRef = C->destination_exprs().begin(); 645 for (auto *AssignOp : C->assignment_ops()) { 646 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 647 QualType Type = VD->getType(); 648 if (CopiedVars.insert(VD->getCanonicalDecl()).second) { 649 // Get the address of the master variable. If we are emitting code with 650 // TLS support, the address is passed from the master as field in the 651 // captured declaration. 652 Address MasterAddr = Address::invalid(); 653 if (getLangOpts().OpenMPUseTLS && 654 getContext().getTargetInfo().isTLSSupported()) { 655 assert(CapturedStmtInfo->lookup(VD) && 656 "Copyin threadprivates should have been captured!"); 657 DeclRefExpr DRE(const_cast<VarDecl *>(VD), true, (*IRef)->getType(), 658 VK_LValue, (*IRef)->getExprLoc()); 659 MasterAddr = EmitLValue(&DRE).getAddress(); 660 LocalDeclMap.erase(VD); 661 } else { 662 MasterAddr = 663 Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD) 664 : CGM.GetAddrOfGlobal(VD), 665 getContext().getDeclAlign(VD)); 666 } 667 // Get the address of the threadprivate variable. 668 Address PrivateAddr = EmitLValue(*IRef).getAddress(); 669 if (CopiedVars.size() == 1) { 670 // At first check if current thread is a master thread. If it is, no 671 // need to copy data. 672 CopyBegin = createBasicBlock("copyin.not.master"); 673 CopyEnd = createBasicBlock("copyin.not.master.end"); 674 Builder.CreateCondBr( 675 Builder.CreateICmpNE( 676 Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy), 677 Builder.CreatePtrToInt(PrivateAddr.getPointer(), CGM.IntPtrTy)), 678 CopyBegin, CopyEnd); 679 EmitBlock(CopyBegin); 680 } 681 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl()); 682 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); 683 EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp); 684 } 685 ++IRef; 686 ++ISrcRef; 687 ++IDestRef; 688 } 689 } 690 if (CopyEnd) { 691 // Exit out of copying procedure for non-master thread. 692 EmitBlock(CopyEnd, /*IsFinished=*/true); 693 return true; 694 } 695 return false; 696 } 697 698 bool CodeGenFunction::EmitOMPLastprivateClauseInit( 699 const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { 700 if (!HaveInsertPoint()) 701 return false; 702 bool HasAtLeastOneLastprivate = false; 703 llvm::DenseSet<const VarDecl *> SIMDLCVs; 704 if (isOpenMPSimdDirective(D.getDirectiveKind())) { 705 auto *LoopDirective = cast<OMPLoopDirective>(&D); 706 for (auto *C : LoopDirective->counters()) { 707 SIMDLCVs.insert( 708 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl()); 709 } 710 } 711 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; 712 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { 713 HasAtLeastOneLastprivate = true; 714 auto IRef = C->varlist_begin(); 715 auto IDestRef = C->destination_exprs().begin(); 716 for (auto *IInit : C->private_copies()) { 717 // Keep the address of the original variable for future update at the end 718 // of the loop. 719 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 720 if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) { 721 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); 722 PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() -> Address { 723 DeclRefExpr DRE( 724 const_cast<VarDecl *>(OrigVD), 725 /*RefersToEnclosingVariableOrCapture=*/CapturedStmtInfo->lookup( 726 OrigVD) != nullptr, 727 (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc()); 728 return EmitLValue(&DRE).getAddress(); 729 }); 730 // Check if the variable is also a firstprivate: in this case IInit is 731 // not generated. Initialization of this variable will happen in codegen 732 // for 'firstprivate' clause. 733 if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) { 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 && 742 "lastprivate var already registered as private"); 743 (void)IsRegistered; 744 } 745 } 746 ++IRef; 747 ++IDestRef; 748 } 749 } 750 return HasAtLeastOneLastprivate; 751 } 752 753 void CodeGenFunction::EmitOMPLastprivateClauseFinal( 754 const OMPExecutableDirective &D, bool NoFinals, 755 llvm::Value *IsLastIterCond) { 756 if (!HaveInsertPoint()) 757 return; 758 // Emit following code: 759 // if (<IsLastIterCond>) { 760 // orig_var1 = private_orig_var1; 761 // ... 762 // orig_varn = private_orig_varn; 763 // } 764 llvm::BasicBlock *ThenBB = nullptr; 765 llvm::BasicBlock *DoneBB = nullptr; 766 if (IsLastIterCond) { 767 ThenBB = createBasicBlock(".omp.lastprivate.then"); 768 DoneBB = createBasicBlock(".omp.lastprivate.done"); 769 Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB); 770 EmitBlock(ThenBB); 771 } 772 llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; 773 llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates; 774 if (auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) { 775 auto IC = LoopDirective->counters().begin(); 776 for (auto F : LoopDirective->finals()) { 777 auto *D = 778 cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl(); 779 if (NoFinals) 780 AlreadyEmittedVars.insert(D); 781 else 782 LoopCountersAndUpdates[D] = F; 783 ++IC; 784 } 785 } 786 for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { 787 auto IRef = C->varlist_begin(); 788 auto ISrcRef = C->source_exprs().begin(); 789 auto IDestRef = C->destination_exprs().begin(); 790 for (auto *AssignOp : C->assignment_ops()) { 791 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 792 QualType Type = PrivateVD->getType(); 793 auto *CanonicalVD = PrivateVD->getCanonicalDecl(); 794 if (AlreadyEmittedVars.insert(CanonicalVD).second) { 795 // If lastprivate variable is a loop control variable for loop-based 796 // directive, update its value before copyin back to original 797 // variable. 798 if (auto *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) 799 EmitIgnoredExpr(FinalExpr); 800 auto *SrcVD = cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl()); 801 auto *DestVD = cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl()); 802 // Get the address of the original variable. 803 Address OriginalAddr = GetAddrOfLocalVar(DestVD); 804 // Get the address of the private variable. 805 Address PrivateAddr = GetAddrOfLocalVar(PrivateVD); 806 if (auto RefTy = PrivateVD->getType()->getAs<ReferenceType>()) 807 PrivateAddr = 808 Address(Builder.CreateLoad(PrivateAddr), 809 getNaturalTypeAlignment(RefTy->getPointeeType())); 810 EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp); 811 } 812 ++IRef; 813 ++ISrcRef; 814 ++IDestRef; 815 } 816 if (auto *PostUpdate = C->getPostUpdateExpr()) 817 EmitIgnoredExpr(PostUpdate); 818 } 819 if (IsLastIterCond) 820 EmitBlock(DoneBB, /*IsFinished=*/true); 821 } 822 823 static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, 824 LValue BaseLV, llvm::Value *Addr) { 825 Address Tmp = Address::invalid(); 826 Address TopTmp = Address::invalid(); 827 Address MostTopTmp = Address::invalid(); 828 BaseTy = BaseTy.getNonReferenceType(); 829 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) && 830 !CGF.getContext().hasSameType(BaseTy, ElTy)) { 831 Tmp = CGF.CreateMemTemp(BaseTy); 832 if (TopTmp.isValid()) 833 CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp); 834 else 835 MostTopTmp = Tmp; 836 TopTmp = Tmp; 837 BaseTy = BaseTy->getPointeeType(); 838 } 839 llvm::Type *Ty = BaseLV.getPointer()->getType(); 840 if (Tmp.isValid()) 841 Ty = Tmp.getElementType(); 842 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty); 843 if (Tmp.isValid()) { 844 CGF.Builder.CreateStore(Addr, Tmp); 845 return MostTopTmp; 846 } 847 return Address(Addr, BaseLV.getAlignment()); 848 } 849 850 static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, 851 LValue BaseLV) { 852 BaseTy = BaseTy.getNonReferenceType(); 853 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) && 854 !CGF.getContext().hasSameType(BaseTy, ElTy)) { 855 if (auto *PtrTy = BaseTy->getAs<PointerType>()) 856 BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy); 857 else { 858 BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(), 859 BaseTy->castAs<ReferenceType>()); 860 } 861 BaseTy = BaseTy->getPointeeType(); 862 } 863 return CGF.MakeAddrLValue( 864 Address( 865 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 866 BaseLV.getPointer(), CGF.ConvertTypeForMem(ElTy)->getPointerTo()), 867 BaseLV.getAlignment()), 868 BaseLV.getType(), BaseLV.getAlignmentSource()); 869 } 870 871 void CodeGenFunction::EmitOMPReductionClauseInit( 872 const OMPExecutableDirective &D, 873 CodeGenFunction::OMPPrivateScope &PrivateScope) { 874 if (!HaveInsertPoint()) 875 return; 876 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { 877 auto ILHS = C->lhs_exprs().begin(); 878 auto IRHS = C->rhs_exprs().begin(); 879 auto IPriv = C->privates().begin(); 880 auto IRed = C->reduction_ops().begin(); 881 for (auto IRef : C->varlists()) { 882 auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl()); 883 auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl()); 884 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl()); 885 auto *DRD = getReductionInit(*IRed); 886 if (auto *OASE = dyn_cast<OMPArraySectionExpr>(IRef)) { 887 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 888 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 889 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 890 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 891 Base = TempASE->getBase()->IgnoreParenImpCasts(); 892 auto *DE = cast<DeclRefExpr>(Base); 893 auto *OrigVD = cast<VarDecl>(DE->getDecl()); 894 auto OASELValueLB = EmitOMPArraySectionExpr(OASE); 895 auto OASELValueUB = 896 EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false); 897 auto OriginalBaseLValue = EmitLValue(DE); 898 LValue BaseLValue = 899 loadToBegin(*this, OrigVD->getType(), OASELValueLB.getType(), 900 OriginalBaseLValue); 901 // Store the address of the original variable associated with the LHS 902 // implicit variable. 903 PrivateScope.addPrivate(LHSVD, [this, OASELValueLB]() -> Address { 904 return OASELValueLB.getAddress(); 905 }); 906 // Emit reduction copy. 907 bool IsRegistered = PrivateScope.addPrivate( 908 OrigVD, [this, OrigVD, PrivateVD, BaseLValue, OASELValueLB, 909 OASELValueUB, OriginalBaseLValue, DRD, IRed]() -> Address { 910 // Emit VarDecl with copy init for arrays. 911 // Get the address of the original variable captured in current 912 // captured region. 913 auto *Size = Builder.CreatePtrDiff(OASELValueUB.getPointer(), 914 OASELValueLB.getPointer()); 915 Size = Builder.CreateNUWAdd( 916 Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1)); 917 CodeGenFunction::OpaqueValueMapping OpaqueMap( 918 *this, cast<OpaqueValueExpr>( 919 getContext() 920 .getAsVariableArrayType(PrivateVD->getType()) 921 ->getSizeExpr()), 922 RValue::get(Size)); 923 EmitVariablyModifiedType(PrivateVD->getType()); 924 auto Emission = EmitAutoVarAlloca(*PrivateVD); 925 auto Addr = Emission.getAllocatedAddress(); 926 auto *Init = PrivateVD->getInit(); 927 EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(), 928 DRD ? *IRed : Init, 929 OASELValueLB.getAddress()); 930 EmitAutoVarCleanups(Emission); 931 // Emit private VarDecl with reduction init. 932 auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(), 933 OASELValueLB.getPointer()); 934 auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset); 935 return castToBase(*this, OrigVD->getType(), 936 OASELValueLB.getType(), OriginalBaseLValue, 937 Ptr); 938 }); 939 assert(IsRegistered && "private var already registered as private"); 940 // Silence the warning about unused variable. 941 (void)IsRegistered; 942 PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address { 943 return GetAddrOfLocalVar(PrivateVD); 944 }); 945 } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(IRef)) { 946 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 947 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 948 Base = TempASE->getBase()->IgnoreParenImpCasts(); 949 auto *DE = cast<DeclRefExpr>(Base); 950 auto *OrigVD = cast<VarDecl>(DE->getDecl()); 951 auto ASELValue = EmitLValue(ASE); 952 auto OriginalBaseLValue = EmitLValue(DE); 953 LValue BaseLValue = loadToBegin( 954 *this, OrigVD->getType(), ASELValue.getType(), OriginalBaseLValue); 955 // Store the address of the original variable associated with the LHS 956 // implicit variable. 957 PrivateScope.addPrivate(LHSVD, [this, ASELValue]() -> Address { 958 return ASELValue.getAddress(); 959 }); 960 // Emit reduction copy. 961 bool IsRegistered = PrivateScope.addPrivate( 962 OrigVD, [this, OrigVD, PrivateVD, BaseLValue, ASELValue, 963 OriginalBaseLValue, DRD, IRed]() -> Address { 964 // Emit private VarDecl with reduction init. 965 AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD); 966 auto Addr = Emission.getAllocatedAddress(); 967 if (DRD) { 968 emitInitWithReductionInitializer(*this, DRD, *IRed, Addr, 969 ASELValue.getAddress(), 970 ASELValue.getType()); 971 } else 972 EmitAutoVarInit(Emission); 973 EmitAutoVarCleanups(Emission); 974 auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(), 975 ASELValue.getPointer()); 976 auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset); 977 return castToBase(*this, OrigVD->getType(), ASELValue.getType(), 978 OriginalBaseLValue, Ptr); 979 }); 980 assert(IsRegistered && "private var already registered as private"); 981 // Silence the warning about unused variable. 982 (void)IsRegistered; 983 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address { 984 return Builder.CreateElementBitCast( 985 GetAddrOfLocalVar(PrivateVD), ConvertTypeForMem(RHSVD->getType()), 986 "rhs.begin"); 987 }); 988 } else { 989 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl()); 990 QualType Type = PrivateVD->getType(); 991 if (getContext().getAsArrayType(Type)) { 992 // Store the address of the original variable associated with the LHS 993 // implicit variable. 994 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), 995 CapturedStmtInfo->lookup(OrigVD) != nullptr, 996 IRef->getType(), VK_LValue, IRef->getExprLoc()); 997 Address OriginalAddr = EmitLValue(&DRE).getAddress(); 998 PrivateScope.addPrivate(LHSVD, [this, &OriginalAddr, 999 LHSVD]() -> Address { 1000 OriginalAddr = Builder.CreateElementBitCast( 1001 OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin"); 1002 return OriginalAddr; 1003 }); 1004 bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address { 1005 if (Type->isVariablyModifiedType()) { 1006 CodeGenFunction::OpaqueValueMapping OpaqueMap( 1007 *this, cast<OpaqueValueExpr>( 1008 getContext() 1009 .getAsVariableArrayType(PrivateVD->getType()) 1010 ->getSizeExpr()), 1011 RValue::get( 1012 getTypeSize(OrigVD->getType().getNonReferenceType()))); 1013 EmitVariablyModifiedType(Type); 1014 } 1015 auto Emission = EmitAutoVarAlloca(*PrivateVD); 1016 auto Addr = Emission.getAllocatedAddress(); 1017 auto *Init = PrivateVD->getInit(); 1018 EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(), 1019 DRD ? *IRed : Init, OriginalAddr); 1020 EmitAutoVarCleanups(Emission); 1021 return Emission.getAllocatedAddress(); 1022 }); 1023 assert(IsRegistered && "private var already registered as private"); 1024 // Silence the warning about unused variable. 1025 (void)IsRegistered; 1026 PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address { 1027 return Builder.CreateElementBitCast( 1028 GetAddrOfLocalVar(PrivateVD), 1029 ConvertTypeForMem(RHSVD->getType()), "rhs.begin"); 1030 }); 1031 } else { 1032 // Store the address of the original variable associated with the LHS 1033 // implicit variable. 1034 Address OriginalAddr = Address::invalid(); 1035 PrivateScope.addPrivate(LHSVD, [this, OrigVD, IRef, 1036 &OriginalAddr]() -> Address { 1037 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), 1038 CapturedStmtInfo->lookup(OrigVD) != nullptr, 1039 IRef->getType(), VK_LValue, IRef->getExprLoc()); 1040 OriginalAddr = EmitLValue(&DRE).getAddress(); 1041 return OriginalAddr; 1042 }); 1043 // Emit reduction copy. 1044 bool IsRegistered = PrivateScope.addPrivate( 1045 OrigVD, [this, PrivateVD, OriginalAddr, DRD, IRed]() -> Address { 1046 // Emit private VarDecl with reduction init. 1047 AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD); 1048 auto Addr = Emission.getAllocatedAddress(); 1049 if (DRD) { 1050 emitInitWithReductionInitializer(*this, DRD, *IRed, Addr, 1051 OriginalAddr, 1052 PrivateVD->getType()); 1053 } else 1054 EmitAutoVarInit(Emission); 1055 EmitAutoVarCleanups(Emission); 1056 return Addr; 1057 }); 1058 assert(IsRegistered && "private var already registered as private"); 1059 // Silence the warning about unused variable. 1060 (void)IsRegistered; 1061 PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address { 1062 return GetAddrOfLocalVar(PrivateVD); 1063 }); 1064 } 1065 } 1066 ++ILHS; 1067 ++IRHS; 1068 ++IPriv; 1069 ++IRed; 1070 } 1071 } 1072 } 1073 1074 void CodeGenFunction::EmitOMPReductionClauseFinal( 1075 const OMPExecutableDirective &D) { 1076 if (!HaveInsertPoint()) 1077 return; 1078 llvm::SmallVector<const Expr *, 8> Privates; 1079 llvm::SmallVector<const Expr *, 8> LHSExprs; 1080 llvm::SmallVector<const Expr *, 8> RHSExprs; 1081 llvm::SmallVector<const Expr *, 8> ReductionOps; 1082 bool HasAtLeastOneReduction = false; 1083 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { 1084 HasAtLeastOneReduction = true; 1085 Privates.append(C->privates().begin(), C->privates().end()); 1086 LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); 1087 RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); 1088 ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end()); 1089 } 1090 if (HasAtLeastOneReduction) { 1091 // Emit nowait reduction if nowait clause is present or directive is a 1092 // parallel directive (it always has implicit barrier). 1093 CGM.getOpenMPRuntime().emitReduction( 1094 *this, D.getLocEnd(), Privates, LHSExprs, RHSExprs, ReductionOps, 1095 D.getSingleClause<OMPNowaitClause>() || 1096 isOpenMPParallelDirective(D.getDirectiveKind()) || 1097 D.getDirectiveKind() == OMPD_simd, 1098 D.getDirectiveKind() == OMPD_simd); 1099 } 1100 } 1101 1102 static void emitPostUpdateForReductionClause( 1103 CodeGenFunction &CGF, const OMPExecutableDirective &D, 1104 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) { 1105 if (!CGF.HaveInsertPoint()) 1106 return; 1107 llvm::BasicBlock *DoneBB = nullptr; 1108 for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { 1109 if (auto *PostUpdate = C->getPostUpdateExpr()) { 1110 if (!DoneBB) { 1111 if (auto *Cond = CondGen(CGF)) { 1112 // If the first post-update expression is found, emit conditional 1113 // block if it was requested. 1114 auto *ThenBB = CGF.createBasicBlock(".omp.reduction.pu"); 1115 DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done"); 1116 CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB); 1117 CGF.EmitBlock(ThenBB); 1118 } 1119 } 1120 CGF.EmitIgnoredExpr(PostUpdate); 1121 } 1122 } 1123 if (DoneBB) 1124 CGF.EmitBlock(DoneBB, /*IsFinished=*/true); 1125 } 1126 1127 static void emitCommonOMPParallelDirective(CodeGenFunction &CGF, 1128 const OMPExecutableDirective &S, 1129 OpenMPDirectiveKind InnermostKind, 1130 const RegionCodeGenTy &CodeGen) { 1131 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 1132 auto OutlinedFn = CGF.CGM.getOpenMPRuntime(). 1133 emitParallelOrTeamsOutlinedFunction(S, 1134 *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); 1135 if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) { 1136 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); 1137 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(), 1138 /*IgnoreResultAssign*/ true); 1139 CGF.CGM.getOpenMPRuntime().emitNumThreadsClause( 1140 CGF, NumThreads, NumThreadsClause->getLocStart()); 1141 } 1142 if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) { 1143 CodeGenFunction::RunCleanupsScope ProcBindScope(CGF); 1144 CGF.CGM.getOpenMPRuntime().emitProcBindClause( 1145 CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart()); 1146 } 1147 const Expr *IfCond = nullptr; 1148 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 1149 if (C->getNameModifier() == OMPD_unknown || 1150 C->getNameModifier() == OMPD_parallel) { 1151 IfCond = C->getCondition(); 1152 break; 1153 } 1154 } 1155 1156 OMPLexicalScope Scope(CGF, S); 1157 llvm::SmallVector<llvm::Value *, 16> CapturedVars; 1158 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); 1159 CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn, 1160 CapturedVars, IfCond); 1161 } 1162 1163 void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { 1164 // Emit parallel region as a standalone region. 1165 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 1166 OMPPrivateScope PrivateScope(CGF); 1167 bool Copyins = CGF.EmitOMPCopyinClause(S); 1168 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); 1169 if (Copyins) { 1170 // Emit implicit barrier to synchronize threads and avoid data races on 1171 // propagation master's thread values of threadprivate variables to local 1172 // instances of that variables of all other implicit threads. 1173 CGF.CGM.getOpenMPRuntime().emitBarrierCall( 1174 CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, 1175 /*ForceSimpleCall=*/true); 1176 } 1177 CGF.EmitOMPPrivateClause(S, PrivateScope); 1178 CGF.EmitOMPReductionClauseInit(S, PrivateScope); 1179 (void)PrivateScope.Privatize(); 1180 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 1181 CGF.EmitOMPReductionClauseFinal(S); 1182 }; 1183 emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen); 1184 emitPostUpdateForReductionClause( 1185 *this, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 1186 } 1187 1188 void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, 1189 JumpDest LoopExit) { 1190 RunCleanupsScope BodyScope(*this); 1191 // Update counters values on current iteration. 1192 for (auto I : D.updates()) { 1193 EmitIgnoredExpr(I); 1194 } 1195 // Update the linear variables. 1196 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { 1197 for (auto *U : C->updates()) 1198 EmitIgnoredExpr(U); 1199 } 1200 1201 // On a continue in the body, jump to the end. 1202 auto Continue = getJumpDestInCurrentScope("omp.body.continue"); 1203 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 1204 // Emit loop body. 1205 EmitStmt(D.getBody()); 1206 // The end (updates/cleanups). 1207 EmitBlock(Continue.getBlock()); 1208 BreakContinueStack.pop_back(); 1209 } 1210 1211 void CodeGenFunction::EmitOMPInnerLoop( 1212 const Stmt &S, bool RequiresCleanup, const Expr *LoopCond, 1213 const Expr *IncExpr, 1214 const llvm::function_ref<void(CodeGenFunction &)> &BodyGen, 1215 const llvm::function_ref<void(CodeGenFunction &)> &PostIncGen) { 1216 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end"); 1217 1218 // Start the loop with a block that tests the condition. 1219 auto CondBlock = createBasicBlock("omp.inner.for.cond"); 1220 EmitBlock(CondBlock); 1221 LoopStack.push(CondBlock); 1222 1223 // If there are any cleanups between here and the loop-exit scope, 1224 // create a block to stage a loop exit along. 1225 auto ExitBlock = LoopExit.getBlock(); 1226 if (RequiresCleanup) 1227 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup"); 1228 1229 auto LoopBody = createBasicBlock("omp.inner.for.body"); 1230 1231 // Emit condition. 1232 EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S)); 1233 if (ExitBlock != LoopExit.getBlock()) { 1234 EmitBlock(ExitBlock); 1235 EmitBranchThroughCleanup(LoopExit); 1236 } 1237 1238 EmitBlock(LoopBody); 1239 incrementProfileCounter(&S); 1240 1241 // Create a block for the increment. 1242 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc"); 1243 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 1244 1245 BodyGen(*this); 1246 1247 // Emit "IV = IV + 1" and a back-edge to the condition block. 1248 EmitBlock(Continue.getBlock()); 1249 EmitIgnoredExpr(IncExpr); 1250 PostIncGen(*this); 1251 BreakContinueStack.pop_back(); 1252 EmitBranch(CondBlock); 1253 LoopStack.pop(); 1254 // Emit the fall-through block. 1255 EmitBlock(LoopExit.getBlock()); 1256 } 1257 1258 void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { 1259 if (!HaveInsertPoint()) 1260 return; 1261 // Emit inits for the linear variables. 1262 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { 1263 for (auto *Init : C->inits()) { 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 } 1289 1290 void CodeGenFunction::EmitOMPLinearClauseFinal( 1291 const OMPLoopDirective &D, 1292 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) { 1293 if (!HaveInsertPoint()) 1294 return; 1295 llvm::BasicBlock *DoneBB = nullptr; 1296 // Emit the final values of the linear variables. 1297 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { 1298 auto IC = C->varlist_begin(); 1299 for (auto *F : C->finals()) { 1300 if (!DoneBB) { 1301 if (auto *Cond = CondGen(*this)) { 1302 // If the first post-update expression is found, emit conditional 1303 // block if it was requested. 1304 auto *ThenBB = createBasicBlock(".omp.linear.pu"); 1305 DoneBB = createBasicBlock(".omp.linear.pu.done"); 1306 Builder.CreateCondBr(Cond, ThenBB, DoneBB); 1307 EmitBlock(ThenBB); 1308 } 1309 } 1310 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl()); 1311 DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), 1312 CapturedStmtInfo->lookup(OrigVD) != nullptr, 1313 (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); 1314 Address OrigAddr = EmitLValue(&DRE).getAddress(); 1315 CodeGenFunction::OMPPrivateScope VarScope(*this); 1316 VarScope.addPrivate(OrigVD, [OrigAddr]() -> Address { return OrigAddr; }); 1317 (void)VarScope.Privatize(); 1318 EmitIgnoredExpr(F); 1319 ++IC; 1320 } 1321 if (auto *PostUpdate = C->getPostUpdateExpr()) 1322 EmitIgnoredExpr(PostUpdate); 1323 } 1324 if (DoneBB) 1325 EmitBlock(DoneBB, /*IsFinished=*/true); 1326 } 1327 1328 static void emitAlignedClause(CodeGenFunction &CGF, 1329 const OMPExecutableDirective &D) { 1330 if (!CGF.HaveInsertPoint()) 1331 return; 1332 for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) { 1333 unsigned ClauseAlignment = 0; 1334 if (auto AlignmentExpr = Clause->getAlignment()) { 1335 auto AlignmentCI = 1336 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr)); 1337 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue()); 1338 } 1339 for (auto E : Clause->varlists()) { 1340 unsigned Alignment = ClauseAlignment; 1341 if (Alignment == 0) { 1342 // OpenMP [2.8.1, Description] 1343 // If no optional parameter is specified, implementation-defined default 1344 // alignments for SIMD instructions on the target platforms are assumed. 1345 Alignment = 1346 CGF.getContext() 1347 .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign( 1348 E->getType()->getPointeeType())) 1349 .getQuantity(); 1350 } 1351 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && 1352 "alignment is not power of 2"); 1353 if (Alignment != 0) { 1354 llvm::Value *PtrValue = CGF.EmitScalarExpr(E); 1355 CGF.EmitAlignmentAssumption(PtrValue, Alignment); 1356 } 1357 } 1358 } 1359 } 1360 1361 void CodeGenFunction::EmitOMPPrivateLoopCounters( 1362 const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) { 1363 if (!HaveInsertPoint()) 1364 return; 1365 auto I = S.private_counters().begin(); 1366 for (auto *E : S.counters()) { 1367 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 1368 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()); 1369 (void)LoopScope.addPrivate(VD, [&]() -> Address { 1370 // Emit var without initialization. 1371 if (!LocalDeclMap.count(PrivateVD)) { 1372 auto VarEmission = EmitAutoVarAlloca(*PrivateVD); 1373 EmitAutoVarCleanups(VarEmission); 1374 } 1375 DeclRefExpr DRE(const_cast<VarDecl *>(PrivateVD), 1376 /*RefersToEnclosingVariableOrCapture=*/false, 1377 (*I)->getType(), VK_LValue, (*I)->getExprLoc()); 1378 return EmitLValue(&DRE).getAddress(); 1379 }); 1380 if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) || 1381 VD->hasGlobalStorage()) { 1382 (void)LoopScope.addPrivate(PrivateVD, [&]() -> Address { 1383 DeclRefExpr DRE(const_cast<VarDecl *>(VD), 1384 LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD), 1385 E->getType(), VK_LValue, E->getExprLoc()); 1386 return EmitLValue(&DRE).getAddress(); 1387 }); 1388 } 1389 ++I; 1390 } 1391 } 1392 1393 static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, 1394 const Expr *Cond, llvm::BasicBlock *TrueBlock, 1395 llvm::BasicBlock *FalseBlock, uint64_t TrueCount) { 1396 if (!CGF.HaveInsertPoint()) 1397 return; 1398 { 1399 CodeGenFunction::OMPPrivateScope PreCondScope(CGF); 1400 CGF.EmitOMPPrivateLoopCounters(S, PreCondScope); 1401 (void)PreCondScope.Privatize(); 1402 // Get initial values of real counters. 1403 for (auto I : S.inits()) { 1404 CGF.EmitIgnoredExpr(I); 1405 } 1406 } 1407 // Check that loop is executed at least one time. 1408 CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount); 1409 } 1410 1411 void CodeGenFunction::EmitOMPLinearClause( 1412 const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { 1413 if (!HaveInsertPoint()) 1414 return; 1415 llvm::DenseSet<const VarDecl *> SIMDLCVs; 1416 if (isOpenMPSimdDirective(D.getDirectiveKind())) { 1417 auto *LoopDirective = cast<OMPLoopDirective>(&D); 1418 for (auto *C : LoopDirective->counters()) { 1419 SIMDLCVs.insert( 1420 cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl()); 1421 } 1422 } 1423 for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { 1424 auto CurPrivate = C->privates().begin(); 1425 for (auto *E : C->varlists()) { 1426 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 1427 auto *PrivateVD = 1428 cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl()); 1429 if (!SIMDLCVs.count(VD->getCanonicalDecl())) { 1430 bool IsRegistered = PrivateScope.addPrivate(VD, [&]() -> Address { 1431 // Emit private VarDecl with copy init. 1432 EmitVarDecl(*PrivateVD); 1433 return GetAddrOfLocalVar(PrivateVD); 1434 }); 1435 assert(IsRegistered && "linear var already registered as private"); 1436 // Silence the warning about unused variable. 1437 (void)IsRegistered; 1438 } else 1439 EmitVarDecl(*PrivateVD); 1440 ++CurPrivate; 1441 } 1442 } 1443 } 1444 1445 static void emitSimdlenSafelenClause(CodeGenFunction &CGF, 1446 const OMPExecutableDirective &D, 1447 bool IsMonotonic) { 1448 if (!CGF.HaveInsertPoint()) 1449 return; 1450 if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) { 1451 RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(), 1452 /*ignoreResult=*/true); 1453 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); 1454 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue()); 1455 // In presence of finite 'safelen', it may be unsafe to mark all 1456 // the memory instructions parallel, because loop-carried 1457 // dependences of 'safelen' iterations are possible. 1458 if (!IsMonotonic) 1459 CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>()); 1460 } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) { 1461 RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(), 1462 /*ignoreResult=*/true); 1463 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); 1464 CGF.LoopStack.setVectorizeWidth(Val->getZExtValue()); 1465 // In presence of finite 'safelen', it may be unsafe to mark all 1466 // the memory instructions parallel, because loop-carried 1467 // dependences of 'safelen' iterations are possible. 1468 CGF.LoopStack.setParallel(false); 1469 } 1470 } 1471 1472 void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D, 1473 bool IsMonotonic) { 1474 // Walk clauses and process safelen/lastprivate. 1475 LoopStack.setParallel(!IsMonotonic); 1476 LoopStack.setVectorizeEnable(true); 1477 emitSimdlenSafelenClause(*this, D, IsMonotonic); 1478 } 1479 1480 void CodeGenFunction::EmitOMPSimdFinal( 1481 const OMPLoopDirective &D, 1482 const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) { 1483 if (!HaveInsertPoint()) 1484 return; 1485 llvm::BasicBlock *DoneBB = nullptr; 1486 auto IC = D.counters().begin(); 1487 auto IPC = D.private_counters().begin(); 1488 for (auto F : D.finals()) { 1489 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl()); 1490 auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl()); 1491 auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD); 1492 if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) || 1493 OrigVD->hasGlobalStorage() || CED) { 1494 if (!DoneBB) { 1495 if (auto *Cond = CondGen(*this)) { 1496 // If the first post-update expression is found, emit conditional 1497 // block if it was requested. 1498 auto *ThenBB = createBasicBlock(".omp.final.then"); 1499 DoneBB = createBasicBlock(".omp.final.done"); 1500 Builder.CreateCondBr(Cond, ThenBB, DoneBB); 1501 EmitBlock(ThenBB); 1502 } 1503 } 1504 Address OrigAddr = Address::invalid(); 1505 if (CED) 1506 OrigAddr = EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress(); 1507 else { 1508 DeclRefExpr DRE(const_cast<VarDecl *>(PrivateVD), 1509 /*RefersToEnclosingVariableOrCapture=*/false, 1510 (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc()); 1511 OrigAddr = EmitLValue(&DRE).getAddress(); 1512 } 1513 OMPPrivateScope VarScope(*this); 1514 VarScope.addPrivate(OrigVD, 1515 [OrigAddr]() -> Address { return OrigAddr; }); 1516 (void)VarScope.Privatize(); 1517 EmitIgnoredExpr(F); 1518 } 1519 ++IC; 1520 ++IPC; 1521 } 1522 if (DoneBB) 1523 EmitBlock(DoneBB, /*IsFinished=*/true); 1524 } 1525 1526 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { 1527 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 1528 OMPLoopScope PreInitScope(CGF, S); 1529 // if (PreCond) { 1530 // for (IV in 0..LastIteration) BODY; 1531 // <Final counter/linear vars updates>; 1532 // } 1533 // 1534 1535 // Emit: if (PreCond) - begin. 1536 // If the condition constant folds and can be elided, avoid emitting the 1537 // whole loop. 1538 bool CondConstant; 1539 llvm::BasicBlock *ContBlock = nullptr; 1540 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { 1541 if (!CondConstant) 1542 return; 1543 } else { 1544 auto *ThenBlock = CGF.createBasicBlock("simd.if.then"); 1545 ContBlock = CGF.createBasicBlock("simd.if.end"); 1546 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock, 1547 CGF.getProfileCount(&S)); 1548 CGF.EmitBlock(ThenBlock); 1549 CGF.incrementProfileCounter(&S); 1550 } 1551 1552 // Emit the loop iteration variable. 1553 const Expr *IVExpr = S.getIterationVariable(); 1554 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); 1555 CGF.EmitVarDecl(*IVDecl); 1556 CGF.EmitIgnoredExpr(S.getInit()); 1557 1558 // Emit the iterations count variable. 1559 // If it is not a variable, Sema decided to calculate iterations count on 1560 // each iteration (e.g., it is foldable into a constant). 1561 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 1562 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 1563 // Emit calculation of the iterations count. 1564 CGF.EmitIgnoredExpr(S.getCalcLastIteration()); 1565 } 1566 1567 CGF.EmitOMPSimdInit(S); 1568 1569 emitAlignedClause(CGF, S); 1570 CGF.EmitOMPLinearClauseInit(S); 1571 { 1572 OMPPrivateScope LoopScope(CGF); 1573 CGF.EmitOMPPrivateLoopCounters(S, LoopScope); 1574 CGF.EmitOMPLinearClause(S, LoopScope); 1575 CGF.EmitOMPPrivateClause(S, LoopScope); 1576 CGF.EmitOMPReductionClauseInit(S, LoopScope); 1577 bool HasLastprivateClause = 1578 CGF.EmitOMPLastprivateClauseInit(S, LoopScope); 1579 (void)LoopScope.Privatize(); 1580 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), 1581 S.getInc(), 1582 [&S](CodeGenFunction &CGF) { 1583 CGF.EmitOMPLoopBody(S, JumpDest()); 1584 CGF.EmitStopPoint(&S); 1585 }, 1586 [](CodeGenFunction &) {}); 1587 CGF.EmitOMPSimdFinal( 1588 S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 1589 // Emit final copy of the lastprivate variables at the end of loops. 1590 if (HasLastprivateClause) 1591 CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true); 1592 CGF.EmitOMPReductionClauseFinal(S); 1593 emitPostUpdateForReductionClause( 1594 CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 1595 } 1596 CGF.EmitOMPLinearClauseFinal( 1597 S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); 1598 // Emit: if (PreCond) - end. 1599 if (ContBlock) { 1600 CGF.EmitBranch(ContBlock); 1601 CGF.EmitBlock(ContBlock, true); 1602 } 1603 }; 1604 OMPLexicalScope Scope(*this, S); 1605 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); 1606 } 1607 1608 void CodeGenFunction::EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic, 1609 const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, 1610 Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk) { 1611 auto &RT = CGM.getOpenMPRuntime(); 1612 1613 const Expr *IVExpr = S.getIterationVariable(); 1614 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 1615 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 1616 1617 auto LoopExit = getJumpDestInCurrentScope("omp.dispatch.end"); 1618 1619 // Start the loop with a block that tests the condition. 1620 auto CondBlock = createBasicBlock("omp.dispatch.cond"); 1621 EmitBlock(CondBlock); 1622 LoopStack.push(CondBlock); 1623 1624 llvm::Value *BoolCondVal = nullptr; 1625 if (!DynamicOrOrdered) { 1626 // UB = min(UB, GlobalUB) 1627 EmitIgnoredExpr(S.getEnsureUpperBound()); 1628 // IV = LB 1629 EmitIgnoredExpr(S.getInit()); 1630 // IV < UB 1631 BoolCondVal = EvaluateExprAsBool(S.getCond()); 1632 } else { 1633 BoolCondVal = RT.emitForNext(*this, S.getLocStart(), IVSize, IVSigned, IL, 1634 LB, UB, ST); 1635 } 1636 1637 // If there are any cleanups between here and the loop-exit scope, 1638 // create a block to stage a loop exit along. 1639 auto ExitBlock = LoopExit.getBlock(); 1640 if (LoopScope.requiresCleanups()) 1641 ExitBlock = createBasicBlock("omp.dispatch.cleanup"); 1642 1643 auto LoopBody = createBasicBlock("omp.dispatch.body"); 1644 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); 1645 if (ExitBlock != LoopExit.getBlock()) { 1646 EmitBlock(ExitBlock); 1647 EmitBranchThroughCleanup(LoopExit); 1648 } 1649 EmitBlock(LoopBody); 1650 1651 // Emit "IV = LB" (in case of static schedule, we have already calculated new 1652 // LB for loop condition and emitted it above). 1653 if (DynamicOrOrdered) 1654 EmitIgnoredExpr(S.getInit()); 1655 1656 // Create a block for the increment. 1657 auto Continue = getJumpDestInCurrentScope("omp.dispatch.inc"); 1658 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 1659 1660 // Generate !llvm.loop.parallel metadata for loads and stores for loops 1661 // with dynamic/guided scheduling and without ordered clause. 1662 if (!isOpenMPSimdDirective(S.getDirectiveKind())) 1663 LoopStack.setParallel(!IsMonotonic); 1664 else 1665 EmitOMPSimdInit(S, IsMonotonic); 1666 1667 SourceLocation Loc = S.getLocStart(); 1668 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(), 1669 [&S, LoopExit](CodeGenFunction &CGF) { 1670 CGF.EmitOMPLoopBody(S, LoopExit); 1671 CGF.EmitStopPoint(&S); 1672 }, 1673 [Ordered, IVSize, IVSigned, Loc](CodeGenFunction &CGF) { 1674 if (Ordered) { 1675 CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd( 1676 CGF, Loc, IVSize, IVSigned); 1677 } 1678 }); 1679 1680 EmitBlock(Continue.getBlock()); 1681 BreakContinueStack.pop_back(); 1682 if (!DynamicOrOrdered) { 1683 // Emit "LB = LB + Stride", "UB = UB + Stride". 1684 EmitIgnoredExpr(S.getNextLowerBound()); 1685 EmitIgnoredExpr(S.getNextUpperBound()); 1686 } 1687 1688 EmitBranch(CondBlock); 1689 LoopStack.pop(); 1690 // Emit the fall-through block. 1691 EmitBlock(LoopExit.getBlock()); 1692 1693 // Tell the runtime we are done. 1694 if (!DynamicOrOrdered) 1695 RT.emitForStaticFinish(*this, S.getLocEnd()); 1696 1697 } 1698 1699 void CodeGenFunction::EmitOMPForOuterLoop( 1700 OpenMPScheduleClauseKind ScheduleKind, bool IsMonotonic, 1701 const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered, 1702 Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk) { 1703 auto &RT = CGM.getOpenMPRuntime(); 1704 1705 // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime). 1706 const bool DynamicOrOrdered = Ordered || RT.isDynamic(ScheduleKind); 1707 1708 assert((Ordered || 1709 !RT.isStaticNonchunked(ScheduleKind, /*Chunked=*/Chunk != nullptr)) && 1710 "static non-chunked schedule does not need outer loop"); 1711 1712 // Emit outer loop. 1713 // 1714 // OpenMP [2.7.1, Loop Construct, Description, table 2-1] 1715 // When schedule(dynamic,chunk_size) is specified, the iterations are 1716 // distributed to threads in the team in chunks as the threads request them. 1717 // Each thread executes a chunk of iterations, then requests another chunk, 1718 // until no chunks remain to be distributed. Each chunk contains chunk_size 1719 // iterations, except for the last chunk to be distributed, which may have 1720 // fewer iterations. When no chunk_size is specified, it defaults to 1. 1721 // 1722 // When schedule(guided,chunk_size) is specified, the iterations are assigned 1723 // to threads in the team in chunks as the executing threads request them. 1724 // Each thread executes a chunk of iterations, then requests another chunk, 1725 // until no chunks remain to be assigned. For a chunk_size of 1, the size of 1726 // each chunk is proportional to the number of unassigned iterations divided 1727 // by the number of threads in the team, decreasing to 1. For a chunk_size 1728 // with value k (greater than 1), the size of each chunk is determined in the 1729 // same way, with the restriction that the chunks do not contain fewer than k 1730 // iterations (except for the last chunk to be assigned, which may have fewer 1731 // than k iterations). 1732 // 1733 // When schedule(auto) is specified, the decision regarding scheduling is 1734 // delegated to the compiler and/or runtime system. The programmer gives the 1735 // implementation the freedom to choose any possible mapping of iterations to 1736 // threads in the team. 1737 // 1738 // When schedule(runtime) is specified, the decision regarding scheduling is 1739 // deferred until run time, and the schedule and chunk size are taken from the 1740 // run-sched-var ICV. If the ICV is set to auto, the schedule is 1741 // implementation defined 1742 // 1743 // while(__kmpc_dispatch_next(&LB, &UB)) { 1744 // idx = LB; 1745 // while (idx <= UB) { BODY; ++idx; 1746 // __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only. 1747 // } // inner loop 1748 // } 1749 // 1750 // OpenMP [2.7.1, Loop Construct, Description, table 2-1] 1751 // When schedule(static, chunk_size) is specified, iterations are divided into 1752 // chunks of size chunk_size, and the chunks are assigned to the threads in 1753 // the team in a round-robin fashion in the order of the thread number. 1754 // 1755 // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) { 1756 // while (idx <= UB) { BODY; ++idx; } // inner loop 1757 // LB = LB + ST; 1758 // UB = UB + ST; 1759 // } 1760 // 1761 1762 const Expr *IVExpr = S.getIterationVariable(); 1763 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 1764 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 1765 1766 if (DynamicOrOrdered) { 1767 llvm::Value *UBVal = EmitScalarExpr(S.getLastIteration()); 1768 RT.emitForDispatchInit(*this, S.getLocStart(), ScheduleKind, 1769 IVSize, IVSigned, Ordered, UBVal, Chunk); 1770 } else { 1771 RT.emitForStaticInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned, 1772 Ordered, IL, LB, UB, ST, Chunk); 1773 } 1774 1775 EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, Ordered, LB, UB, 1776 ST, IL, Chunk); 1777 } 1778 1779 void CodeGenFunction::EmitOMPDistributeOuterLoop( 1780 OpenMPDistScheduleClauseKind ScheduleKind, 1781 const OMPDistributeDirective &S, OMPPrivateScope &LoopScope, 1782 Address LB, Address UB, Address ST, Address IL, llvm::Value *Chunk) { 1783 1784 auto &RT = CGM.getOpenMPRuntime(); 1785 1786 // Emit outer loop. 1787 // Same behavior as a OMPForOuterLoop, except that schedule cannot be 1788 // dynamic 1789 // 1790 1791 const Expr *IVExpr = S.getIterationVariable(); 1792 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 1793 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 1794 1795 RT.emitDistributeStaticInit(*this, S.getLocStart(), ScheduleKind, 1796 IVSize, IVSigned, /* Ordered = */ false, 1797 IL, LB, UB, ST, Chunk); 1798 1799 EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, 1800 S, LoopScope, /* Ordered = */ false, LB, UB, ST, IL, Chunk); 1801 } 1802 1803 /// \brief Emit a helper variable and return corresponding lvalue. 1804 static LValue EmitOMPHelperVar(CodeGenFunction &CGF, 1805 const DeclRefExpr *Helper) { 1806 auto VDecl = cast<VarDecl>(Helper->getDecl()); 1807 CGF.EmitVarDecl(*VDecl); 1808 return CGF.EmitLValue(Helper); 1809 } 1810 1811 namespace { 1812 struct ScheduleKindModifiersTy { 1813 OpenMPScheduleClauseKind Kind; 1814 OpenMPScheduleClauseModifier M1; 1815 OpenMPScheduleClauseModifier M2; 1816 ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind, 1817 OpenMPScheduleClauseModifier M1, 1818 OpenMPScheduleClauseModifier M2) 1819 : Kind(Kind), M1(M1), M2(M2) {} 1820 }; 1821 } // namespace 1822 1823 bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { 1824 // Emit the loop iteration variable. 1825 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable()); 1826 auto IVDecl = cast<VarDecl>(IVExpr->getDecl()); 1827 EmitVarDecl(*IVDecl); 1828 1829 // Emit the iterations count variable. 1830 // If it is not a variable, Sema decided to calculate iterations count on each 1831 // iteration (e.g., it is foldable into a constant). 1832 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 1833 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 1834 // Emit calculation of the iterations count. 1835 EmitIgnoredExpr(S.getCalcLastIteration()); 1836 } 1837 1838 auto &RT = CGM.getOpenMPRuntime(); 1839 1840 bool HasLastprivateClause; 1841 // Check pre-condition. 1842 { 1843 OMPLoopScope PreInitScope(*this, S); 1844 // Skip the entire loop if we don't meet the precondition. 1845 // If the condition constant folds and can be elided, avoid emitting the 1846 // whole loop. 1847 bool CondConstant; 1848 llvm::BasicBlock *ContBlock = nullptr; 1849 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { 1850 if (!CondConstant) 1851 return false; 1852 } else { 1853 auto *ThenBlock = createBasicBlock("omp.precond.then"); 1854 ContBlock = createBasicBlock("omp.precond.end"); 1855 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock, 1856 getProfileCount(&S)); 1857 EmitBlock(ThenBlock); 1858 incrementProfileCounter(&S); 1859 } 1860 1861 llvm::DenseSet<const Expr *> EmittedFinals; 1862 emitAlignedClause(*this, S); 1863 EmitOMPLinearClauseInit(S); 1864 // Emit helper vars inits. 1865 LValue LB = 1866 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable())); 1867 LValue UB = 1868 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable())); 1869 LValue ST = 1870 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); 1871 LValue IL = 1872 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); 1873 1874 // Emit 'then' code. 1875 { 1876 OMPPrivateScope LoopScope(*this); 1877 if (EmitOMPFirstprivateClause(S, LoopScope)) { 1878 // Emit implicit barrier to synchronize threads and avoid data races on 1879 // initialization of firstprivate variables and post-update of 1880 // lastprivate variables. 1881 CGM.getOpenMPRuntime().emitBarrierCall( 1882 *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, 1883 /*ForceSimpleCall=*/true); 1884 } 1885 EmitOMPPrivateClause(S, LoopScope); 1886 HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope); 1887 EmitOMPReductionClauseInit(S, LoopScope); 1888 EmitOMPPrivateLoopCounters(S, LoopScope); 1889 EmitOMPLinearClause(S, LoopScope); 1890 (void)LoopScope.Privatize(); 1891 1892 // Detect the loop schedule kind and chunk. 1893 llvm::Value *Chunk = nullptr; 1894 OpenMPScheduleClauseKind ScheduleKind = OMPC_SCHEDULE_unknown; 1895 OpenMPScheduleClauseModifier M1 = OMPC_SCHEDULE_MODIFIER_unknown; 1896 OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown; 1897 if (auto *C = S.getSingleClause<OMPScheduleClause>()) { 1898 ScheduleKind = C->getScheduleKind(); 1899 M1 = C->getFirstScheduleModifier(); 1900 M2 = C->getSecondScheduleModifier(); 1901 if (const auto *Ch = C->getChunkSize()) { 1902 Chunk = EmitScalarExpr(Ch); 1903 Chunk = EmitScalarConversion(Chunk, Ch->getType(), 1904 S.getIterationVariable()->getType(), 1905 S.getLocStart()); 1906 } 1907 } 1908 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 1909 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 1910 const bool Ordered = S.getSingleClause<OMPOrderedClause>() != nullptr; 1911 // OpenMP 4.5, 2.7.1 Loop Construct, Description. 1912 // If the static schedule kind is specified or if the ordered clause is 1913 // specified, and if no monotonic modifier is specified, the effect will 1914 // be as if the monotonic modifier was specified. 1915 if (RT.isStaticNonchunked(ScheduleKind, 1916 /* Chunked */ Chunk != nullptr) && 1917 !Ordered) { 1918 if (isOpenMPSimdDirective(S.getDirectiveKind())) 1919 EmitOMPSimdInit(S, /*IsMonotonic=*/true); 1920 // OpenMP [2.7.1, Loop Construct, Description, table 2-1] 1921 // When no chunk_size is specified, the iteration space is divided into 1922 // chunks that are approximately equal in size, and at most one chunk is 1923 // distributed to each thread. Note that the size of the chunks is 1924 // unspecified in this case. 1925 RT.emitForStaticInit(*this, S.getLocStart(), ScheduleKind, 1926 IVSize, IVSigned, Ordered, 1927 IL.getAddress(), LB.getAddress(), 1928 UB.getAddress(), ST.getAddress()); 1929 auto LoopExit = 1930 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit")); 1931 // UB = min(UB, GlobalUB); 1932 EmitIgnoredExpr(S.getEnsureUpperBound()); 1933 // IV = LB; 1934 EmitIgnoredExpr(S.getInit()); 1935 // while (idx <= UB) { BODY; ++idx; } 1936 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), 1937 S.getInc(), 1938 [&S, LoopExit](CodeGenFunction &CGF) { 1939 CGF.EmitOMPLoopBody(S, LoopExit); 1940 CGF.EmitStopPoint(&S); 1941 }, 1942 [](CodeGenFunction &) {}); 1943 EmitBlock(LoopExit.getBlock()); 1944 // Tell the runtime we are done. 1945 RT.emitForStaticFinish(*this, S.getLocStart()); 1946 } else { 1947 const bool IsMonotonic = Ordered || 1948 ScheduleKind == OMPC_SCHEDULE_static || 1949 ScheduleKind == OMPC_SCHEDULE_unknown || 1950 M1 == OMPC_SCHEDULE_MODIFIER_monotonic || 1951 M2 == OMPC_SCHEDULE_MODIFIER_monotonic; 1952 // Emit the outer loop, which requests its work chunk [LB..UB] from 1953 // runtime and runs the inner loop to process it. 1954 EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered, 1955 LB.getAddress(), UB.getAddress(), ST.getAddress(), 1956 IL.getAddress(), Chunk); 1957 } 1958 if (isOpenMPSimdDirective(S.getDirectiveKind())) { 1959 EmitOMPSimdFinal(S, 1960 [&](CodeGenFunction &CGF) -> llvm::Value * { 1961 return CGF.Builder.CreateIsNotNull( 1962 CGF.EmitLoadOfScalar(IL, S.getLocStart())); 1963 }); 1964 } 1965 EmitOMPReductionClauseFinal(S); 1966 // Emit post-update of the reduction variables if IsLastIter != 0. 1967 emitPostUpdateForReductionClause( 1968 *this, S, [&](CodeGenFunction &CGF) -> llvm::Value * { 1969 return CGF.Builder.CreateIsNotNull( 1970 CGF.EmitLoadOfScalar(IL, S.getLocStart())); 1971 }); 1972 // Emit final copy of the lastprivate variables if IsLastIter != 0. 1973 if (HasLastprivateClause) 1974 EmitOMPLastprivateClauseFinal( 1975 S, isOpenMPSimdDirective(S.getDirectiveKind()), 1976 Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getLocStart()))); 1977 } 1978 EmitOMPLinearClauseFinal(S, [&](CodeGenFunction &CGF) -> llvm::Value * { 1979 return CGF.Builder.CreateIsNotNull( 1980 CGF.EmitLoadOfScalar(IL, S.getLocStart())); 1981 }); 1982 // We're now done with the loop, so jump to the continuation block. 1983 if (ContBlock) { 1984 EmitBranch(ContBlock); 1985 EmitBlock(ContBlock, true); 1986 } 1987 } 1988 return HasLastprivateClause; 1989 } 1990 1991 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { 1992 bool HasLastprivates = false; 1993 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF, 1994 PrePostActionTy &) { 1995 HasLastprivates = CGF.EmitOMPWorksharingLoop(S); 1996 }; 1997 { 1998 OMPLexicalScope Scope(*this, S); 1999 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, 2000 S.hasCancel()); 2001 } 2002 2003 // Emit an implicit barrier at the end. 2004 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { 2005 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for); 2006 } 2007 } 2008 2009 void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) { 2010 bool HasLastprivates = false; 2011 auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF, 2012 PrePostActionTy &) { 2013 HasLastprivates = CGF.EmitOMPWorksharingLoop(S); 2014 }; 2015 { 2016 OMPLexicalScope Scope(*this, S); 2017 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen); 2018 } 2019 2020 // Emit an implicit barrier at the end. 2021 if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { 2022 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for); 2023 } 2024 } 2025 2026 static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty, 2027 const Twine &Name, 2028 llvm::Value *Init = nullptr) { 2029 auto LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty); 2030 if (Init) 2031 CGF.EmitScalarInit(Init, LVal); 2032 return LVal; 2033 } 2034 2035 void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { 2036 auto *Stmt = cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt(); 2037 auto *CS = dyn_cast<CompoundStmt>(Stmt); 2038 bool HasLastprivates = false; 2039 auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF, 2040 PrePostActionTy &) { 2041 auto &C = CGF.CGM.getContext(); 2042 auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 2043 // Emit helper vars inits. 2044 LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.", 2045 CGF.Builder.getInt32(0)); 2046 auto *GlobalUBVal = CS != nullptr ? CGF.Builder.getInt32(CS->size() - 1) 2047 : CGF.Builder.getInt32(0); 2048 LValue UB = 2049 createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal); 2050 LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.", 2051 CGF.Builder.getInt32(1)); 2052 LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.", 2053 CGF.Builder.getInt32(0)); 2054 // Loop counter. 2055 LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv."); 2056 OpaqueValueExpr IVRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue); 2057 CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV); 2058 OpaqueValueExpr UBRefExpr(S.getLocStart(), KmpInt32Ty, VK_LValue); 2059 CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB); 2060 // Generate condition for loop. 2061 BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue, 2062 OK_Ordinary, S.getLocStart(), 2063 /*fpContractable=*/false); 2064 // Increment for loop counter. 2065 UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary, 2066 S.getLocStart()); 2067 auto BodyGen = [Stmt, CS, &S, &IV](CodeGenFunction &CGF) { 2068 // Iterate through all sections and emit a switch construct: 2069 // switch (IV) { 2070 // case 0: 2071 // <SectionStmt[0]>; 2072 // break; 2073 // ... 2074 // case <NumSection> - 1: 2075 // <SectionStmt[<NumSection> - 1]>; 2076 // break; 2077 // } 2078 // .omp.sections.exit: 2079 auto *ExitBB = CGF.createBasicBlock(".omp.sections.exit"); 2080 auto *SwitchStmt = CGF.Builder.CreateSwitch( 2081 CGF.EmitLoadOfLValue(IV, S.getLocStart()).getScalarVal(), ExitBB, 2082 CS == nullptr ? 1 : CS->size()); 2083 if (CS) { 2084 unsigned CaseNumber = 0; 2085 for (auto *SubStmt : CS->children()) { 2086 auto CaseBB = CGF.createBasicBlock(".omp.sections.case"); 2087 CGF.EmitBlock(CaseBB); 2088 SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB); 2089 CGF.EmitStmt(SubStmt); 2090 CGF.EmitBranch(ExitBB); 2091 ++CaseNumber; 2092 } 2093 } else { 2094 auto CaseBB = CGF.createBasicBlock(".omp.sections.case"); 2095 CGF.EmitBlock(CaseBB); 2096 SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB); 2097 CGF.EmitStmt(Stmt); 2098 CGF.EmitBranch(ExitBB); 2099 } 2100 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 2101 }; 2102 2103 CodeGenFunction::OMPPrivateScope LoopScope(CGF); 2104 if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) { 2105 // Emit implicit barrier to synchronize threads and avoid data races on 2106 // initialization of firstprivate variables and post-update of lastprivate 2107 // variables. 2108 CGF.CGM.getOpenMPRuntime().emitBarrierCall( 2109 CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, 2110 /*ForceSimpleCall=*/true); 2111 } 2112 CGF.EmitOMPPrivateClause(S, LoopScope); 2113 HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); 2114 CGF.EmitOMPReductionClauseInit(S, LoopScope); 2115 (void)LoopScope.Privatize(); 2116 2117 // Emit static non-chunked loop. 2118 CGF.CGM.getOpenMPRuntime().emitForStaticInit( 2119 CGF, S.getLocStart(), OMPC_SCHEDULE_static, /*IVSize=*/32, 2120 /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(), LB.getAddress(), 2121 UB.getAddress(), ST.getAddress()); 2122 // UB = min(UB, GlobalUB); 2123 auto *UBVal = CGF.EmitLoadOfScalar(UB, S.getLocStart()); 2124 auto *MinUBGlobalUB = CGF.Builder.CreateSelect( 2125 CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal); 2126 CGF.EmitStoreOfScalar(MinUBGlobalUB, UB); 2127 // IV = LB; 2128 CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getLocStart()), IV); 2129 // while (idx <= UB) { BODY; ++idx; } 2130 CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen, 2131 [](CodeGenFunction &) {}); 2132 // Tell the runtime we are done. 2133 CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart()); 2134 CGF.EmitOMPReductionClauseFinal(S); 2135 // Emit post-update of the reduction variables if IsLastIter != 0. 2136 emitPostUpdateForReductionClause( 2137 CGF, S, [&](CodeGenFunction &CGF) -> llvm::Value * { 2138 return CGF.Builder.CreateIsNotNull( 2139 CGF.EmitLoadOfScalar(IL, S.getLocStart())); 2140 }); 2141 2142 // Emit final copy of the lastprivate variables if IsLastIter != 0. 2143 if (HasLastprivates) 2144 CGF.EmitOMPLastprivateClauseFinal( 2145 S, /*NoFinals=*/false, 2146 CGF.Builder.CreateIsNotNull( 2147 CGF.EmitLoadOfScalar(IL, S.getLocStart()))); 2148 }; 2149 2150 bool HasCancel = false; 2151 if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S)) 2152 HasCancel = OSD->hasCancel(); 2153 else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S)) 2154 HasCancel = OPSD->hasCancel(); 2155 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen, 2156 HasCancel); 2157 // Emit barrier for lastprivates only if 'sections' directive has 'nowait' 2158 // clause. Otherwise the barrier will be generated by the codegen for the 2159 // directive. 2160 if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) { 2161 // Emit implicit barrier to synchronize threads and avoid data races on 2162 // initialization of firstprivate variables. 2163 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), 2164 OMPD_unknown); 2165 } 2166 } 2167 2168 void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) { 2169 { 2170 OMPLexicalScope Scope(*this, S); 2171 EmitSections(S); 2172 } 2173 // Emit an implicit barrier at the end. 2174 if (!S.getSingleClause<OMPNowaitClause>()) { 2175 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), 2176 OMPD_sections); 2177 } 2178 } 2179 2180 void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) { 2181 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2182 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2183 }; 2184 OMPLexicalScope Scope(*this, S); 2185 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen, 2186 S.hasCancel()); 2187 } 2188 2189 void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { 2190 llvm::SmallVector<const Expr *, 8> CopyprivateVars; 2191 llvm::SmallVector<const Expr *, 8> DestExprs; 2192 llvm::SmallVector<const Expr *, 8> SrcExprs; 2193 llvm::SmallVector<const Expr *, 8> AssignmentOps; 2194 // Check if there are any 'copyprivate' clauses associated with this 2195 // 'single' construct. 2196 // Build a list of copyprivate variables along with helper expressions 2197 // (<source>, <destination>, <destination>=<source> expressions) 2198 for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) { 2199 CopyprivateVars.append(C->varlists().begin(), C->varlists().end()); 2200 DestExprs.append(C->destination_exprs().begin(), 2201 C->destination_exprs().end()); 2202 SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end()); 2203 AssignmentOps.append(C->assignment_ops().begin(), 2204 C->assignment_ops().end()); 2205 } 2206 // Emit code for 'single' region along with 'copyprivate' clauses 2207 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 2208 Action.Enter(CGF); 2209 OMPPrivateScope SingleScope(CGF); 2210 (void)CGF.EmitOMPFirstprivateClause(S, SingleScope); 2211 CGF.EmitOMPPrivateClause(S, SingleScope); 2212 (void)SingleScope.Privatize(); 2213 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2214 }; 2215 { 2216 OMPLexicalScope Scope(*this, S); 2217 CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getLocStart(), 2218 CopyprivateVars, DestExprs, 2219 SrcExprs, AssignmentOps); 2220 } 2221 // Emit an implicit barrier at the end (to avoid data race on firstprivate 2222 // init or if no 'nowait' clause was specified and no 'copyprivate' clause). 2223 if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) { 2224 CGM.getOpenMPRuntime().emitBarrierCall( 2225 *this, S.getLocStart(), 2226 S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single); 2227 } 2228 } 2229 2230 void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { 2231 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 2232 Action.Enter(CGF); 2233 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2234 }; 2235 OMPLexicalScope Scope(*this, S); 2236 CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getLocStart()); 2237 } 2238 2239 void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { 2240 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 2241 Action.Enter(CGF); 2242 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2243 }; 2244 Expr *Hint = nullptr; 2245 if (auto *HintClause = S.getSingleClause<OMPHintClause>()) 2246 Hint = HintClause->getHint(); 2247 OMPLexicalScope Scope(*this, S); 2248 CGM.getOpenMPRuntime().emitCriticalRegion(*this, 2249 S.getDirectiveName().getAsString(), 2250 CodeGen, S.getLocStart(), Hint); 2251 } 2252 2253 void CodeGenFunction::EmitOMPParallelForDirective( 2254 const OMPParallelForDirective &S) { 2255 // Emit directive as a combined directive that consists of two implicit 2256 // directives: 'parallel' with 'for' directive. 2257 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2258 CGF.EmitOMPWorksharingLoop(S); 2259 }; 2260 emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen); 2261 } 2262 2263 void CodeGenFunction::EmitOMPParallelForSimdDirective( 2264 const OMPParallelForSimdDirective &S) { 2265 // Emit directive as a combined directive that consists of two implicit 2266 // directives: 'parallel' with 'for' directive. 2267 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2268 CGF.EmitOMPWorksharingLoop(S); 2269 }; 2270 emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen); 2271 } 2272 2273 void CodeGenFunction::EmitOMPParallelSectionsDirective( 2274 const OMPParallelSectionsDirective &S) { 2275 // Emit directive as a combined directive that consists of two implicit 2276 // directives: 'parallel' with 'sections' directive. 2277 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2278 CGF.EmitSections(S); 2279 }; 2280 emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen); 2281 } 2282 2283 void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, 2284 const RegionCodeGenTy &BodyGen, 2285 const TaskGenTy &TaskGen, 2286 bool Tied) { 2287 // Emit outlined function for task construct. 2288 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 2289 auto *I = CS->getCapturedDecl()->param_begin(); 2290 auto *PartId = std::next(I); 2291 auto *TaskT = std::next(I, 4); 2292 // The first function argument for tasks is a thread id, the second one is a 2293 // part id (0 for tied tasks, >=0 for untied task). 2294 llvm::DenseSet<const VarDecl *> EmittedAsPrivate; 2295 // Get list of private variables. 2296 OMPPrivateDataTy Data; 2297 Data.Tied = Tied; 2298 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) { 2299 auto IRef = C->varlist_begin(); 2300 for (auto *IInit : C->private_copies()) { 2301 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 2302 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { 2303 Data.PrivateVars.push_back(*IRef); 2304 Data.PrivateCopies.push_back(IInit); 2305 } 2306 ++IRef; 2307 } 2308 } 2309 EmittedAsPrivate.clear(); 2310 // Get list of firstprivate variables. 2311 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) { 2312 auto IRef = C->varlist_begin(); 2313 auto IElemInitRef = C->inits().begin(); 2314 for (auto *IInit : C->private_copies()) { 2315 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 2316 if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) { 2317 Data.FirstprivateVars.push_back(*IRef); 2318 Data.FirstprivateCopies.push_back(IInit); 2319 Data.FirstprivateInits.push_back(*IElemInitRef); 2320 } 2321 ++IRef; 2322 ++IElemInitRef; 2323 } 2324 } 2325 // Build list of dependences. 2326 for (const auto *C : S.getClausesOfKind<OMPDependClause>()) 2327 for (auto *IRef : C->varlists()) 2328 Data.Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef)); 2329 auto &&CodeGen = [PartId, &S, &Data, CS, &BodyGen](CodeGenFunction &CGF, 2330 PrePostActionTy &Action) { 2331 // Set proper addresses for generated private copies. 2332 OMPPrivateScope Scope(CGF); 2333 if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty()) { 2334 auto *CopyFn = CGF.Builder.CreateLoad( 2335 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3))); 2336 auto *PrivatesPtr = CGF.Builder.CreateLoad( 2337 CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(2))); 2338 // Map privates. 2339 llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs; 2340 llvm::SmallVector<llvm::Value *, 16> CallArgs; 2341 CallArgs.push_back(PrivatesPtr); 2342 for (auto *E : Data.PrivateVars) { 2343 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 2344 Address PrivatePtr = CGF.CreateMemTemp( 2345 CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr"); 2346 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr)); 2347 CallArgs.push_back(PrivatePtr.getPointer()); 2348 } 2349 for (auto *E : Data.FirstprivateVars) { 2350 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 2351 Address PrivatePtr = 2352 CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()), 2353 ".firstpriv.ptr.addr"); 2354 PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr)); 2355 CallArgs.push_back(PrivatePtr.getPointer()); 2356 } 2357 CGF.EmitRuntimeCall(CopyFn, CallArgs); 2358 for (auto &&Pair : PrivatePtrs) { 2359 Address Replacement(CGF.Builder.CreateLoad(Pair.second), 2360 CGF.getContext().getDeclAlign(Pair.first)); 2361 Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; }); 2362 } 2363 } 2364 (void)Scope.Privatize(); 2365 2366 Action.Enter(CGF); 2367 BodyGen(CGF); 2368 }; 2369 auto *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( 2370 S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied, 2371 Data.NumberOfParts); 2372 OMPLexicalScope Scope(*this, S); 2373 TaskGen(*this, OutlinedFn, Data); 2374 } 2375 2376 void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { 2377 // Emit outlined function for task construct. 2378 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 2379 auto CapturedStruct = GenerateCapturedStmtArgument(*CS); 2380 // Check if we should emit tied or untied task. 2381 bool Tied = !S.getSingleClause<OMPUntiedClause>(); 2382 // Check if the task is final 2383 llvm::PointerIntPair<llvm::Value *, 1, bool> Final; 2384 if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) { 2385 // If the condition constant folds and can be elided, try to avoid emitting 2386 // the condition and the dead arm of the if/else. 2387 auto *Cond = Clause->getCondition(); 2388 bool CondConstant; 2389 if (ConstantFoldsToSimpleInteger(Cond, CondConstant)) 2390 Final.setInt(CondConstant); 2391 else 2392 Final.setPointer(EvaluateExprAsBool(Cond)); 2393 } else { 2394 // By default the task is not final. 2395 Final.setInt(/*IntVal=*/false); 2396 } 2397 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); 2398 const Expr *IfCond = nullptr; 2399 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 2400 if (C->getNameModifier() == OMPD_unknown || 2401 C->getNameModifier() == OMPD_task) { 2402 IfCond = C->getCondition(); 2403 break; 2404 } 2405 } 2406 2407 auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) { 2408 CGF.EmitStmt(CS->getCapturedStmt()); 2409 }; 2410 auto &&TaskGen = [&S, &Final, SharedsTy, CapturedStruct, 2411 IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn, 2412 const OMPPrivateDataTy &Data) { 2413 CGF.CGM.getOpenMPRuntime().emitTaskCall( 2414 CGF, S.getLocStart(), S, Data.Tied, Final, Data.NumberOfParts, 2415 OutlinedFn, SharedsTy, CapturedStruct, IfCond, Data.PrivateVars, 2416 Data.PrivateCopies, Data.FirstprivateVars, Data.FirstprivateCopies, 2417 Data.FirstprivateInits, Data.Dependences); 2418 }; 2419 EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Tied); 2420 } 2421 2422 void CodeGenFunction::EmitOMPTaskyieldDirective( 2423 const OMPTaskyieldDirective &S) { 2424 CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getLocStart()); 2425 } 2426 2427 void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) { 2428 CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_barrier); 2429 } 2430 2431 void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) { 2432 CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getLocStart()); 2433 } 2434 2435 void CodeGenFunction::EmitOMPTaskgroupDirective( 2436 const OMPTaskgroupDirective &S) { 2437 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 2438 Action.Enter(CGF); 2439 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2440 }; 2441 OMPLexicalScope Scope(*this, S); 2442 CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getLocStart()); 2443 } 2444 2445 void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) { 2446 CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> { 2447 if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>()) { 2448 return llvm::makeArrayRef(FlushClause->varlist_begin(), 2449 FlushClause->varlist_end()); 2450 } 2451 return llvm::None; 2452 }(), S.getLocStart()); 2453 } 2454 2455 void CodeGenFunction::EmitOMPDistributeLoop(const OMPDistributeDirective &S) { 2456 // Emit the loop iteration variable. 2457 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable()); 2458 auto IVDecl = cast<VarDecl>(IVExpr->getDecl()); 2459 EmitVarDecl(*IVDecl); 2460 2461 // Emit the iterations count variable. 2462 // If it is not a variable, Sema decided to calculate iterations count on each 2463 // iteration (e.g., it is foldable into a constant). 2464 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 2465 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 2466 // Emit calculation of the iterations count. 2467 EmitIgnoredExpr(S.getCalcLastIteration()); 2468 } 2469 2470 auto &RT = CGM.getOpenMPRuntime(); 2471 2472 // Check pre-condition. 2473 { 2474 OMPLoopScope PreInitScope(*this, S); 2475 // Skip the entire loop if we don't meet the precondition. 2476 // If the condition constant folds and can be elided, avoid emitting the 2477 // whole loop. 2478 bool CondConstant; 2479 llvm::BasicBlock *ContBlock = nullptr; 2480 if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { 2481 if (!CondConstant) 2482 return; 2483 } else { 2484 auto *ThenBlock = createBasicBlock("omp.precond.then"); 2485 ContBlock = createBasicBlock("omp.precond.end"); 2486 emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock, 2487 getProfileCount(&S)); 2488 EmitBlock(ThenBlock); 2489 incrementProfileCounter(&S); 2490 } 2491 2492 // Emit 'then' code. 2493 { 2494 // Emit helper vars inits. 2495 LValue LB = 2496 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable())); 2497 LValue UB = 2498 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable())); 2499 LValue ST = 2500 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); 2501 LValue IL = 2502 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); 2503 2504 OMPPrivateScope LoopScope(*this); 2505 EmitOMPPrivateLoopCounters(S, LoopScope); 2506 (void)LoopScope.Privatize(); 2507 2508 // Detect the distribute schedule kind and chunk. 2509 llvm::Value *Chunk = nullptr; 2510 OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown; 2511 if (auto *C = S.getSingleClause<OMPDistScheduleClause>()) { 2512 ScheduleKind = C->getDistScheduleKind(); 2513 if (const auto *Ch = C->getChunkSize()) { 2514 Chunk = EmitScalarExpr(Ch); 2515 Chunk = EmitScalarConversion(Chunk, Ch->getType(), 2516 S.getIterationVariable()->getType(), 2517 S.getLocStart()); 2518 } 2519 } 2520 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 2521 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 2522 2523 // OpenMP [2.10.8, distribute Construct, Description] 2524 // If dist_schedule is specified, kind must be static. If specified, 2525 // iterations are divided into chunks of size chunk_size, chunks are 2526 // assigned to the teams of the league in a round-robin fashion in the 2527 // order of the team number. When no chunk_size is specified, the 2528 // iteration space is divided into chunks that are approximately equal 2529 // in size, and at most one chunk is distributed to each team of the 2530 // league. The size of the chunks is unspecified in this case. 2531 if (RT.isStaticNonchunked(ScheduleKind, 2532 /* Chunked */ Chunk != nullptr)) { 2533 RT.emitDistributeStaticInit(*this, S.getLocStart(), ScheduleKind, 2534 IVSize, IVSigned, /* Ordered = */ false, 2535 IL.getAddress(), LB.getAddress(), 2536 UB.getAddress(), ST.getAddress()); 2537 auto LoopExit = 2538 getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit")); 2539 // UB = min(UB, GlobalUB); 2540 EmitIgnoredExpr(S.getEnsureUpperBound()); 2541 // IV = LB; 2542 EmitIgnoredExpr(S.getInit()); 2543 // while (idx <= UB) { BODY; ++idx; } 2544 EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), 2545 S.getInc(), 2546 [&S, LoopExit](CodeGenFunction &CGF) { 2547 CGF.EmitOMPLoopBody(S, LoopExit); 2548 CGF.EmitStopPoint(&S); 2549 }, 2550 [](CodeGenFunction &) {}); 2551 EmitBlock(LoopExit.getBlock()); 2552 // Tell the runtime we are done. 2553 RT.emitForStaticFinish(*this, S.getLocStart()); 2554 } else { 2555 // Emit the outer loop, which requests its work chunk [LB..UB] from 2556 // runtime and runs the inner loop to process it. 2557 EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, 2558 LB.getAddress(), UB.getAddress(), ST.getAddress(), 2559 IL.getAddress(), Chunk); 2560 } 2561 } 2562 2563 // We're now done with the loop, so jump to the continuation block. 2564 if (ContBlock) { 2565 EmitBranch(ContBlock); 2566 EmitBlock(ContBlock, true); 2567 } 2568 } 2569 } 2570 2571 void CodeGenFunction::EmitOMPDistributeDirective( 2572 const OMPDistributeDirective &S) { 2573 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 2574 CGF.EmitOMPDistributeLoop(S); 2575 }; 2576 OMPLexicalScope Scope(*this, S); 2577 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen, 2578 false); 2579 } 2580 2581 static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM, 2582 const CapturedStmt *S) { 2583 CodeGenFunction CGF(CGM, /*suppressNewContext=*/true); 2584 CodeGenFunction::CGCapturedStmtInfo CapStmtInfo; 2585 CGF.CapturedStmtInfo = &CapStmtInfo; 2586 auto *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S); 2587 Fn->addFnAttr(llvm::Attribute::NoInline); 2588 return Fn; 2589 } 2590 2591 void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) { 2592 if (!S.getAssociatedStmt()) 2593 return; 2594 auto *C = S.getSingleClause<OMPSIMDClause>(); 2595 auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF, 2596 PrePostActionTy &Action) { 2597 if (C) { 2598 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 2599 llvm::SmallVector<llvm::Value *, 16> CapturedVars; 2600 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); 2601 auto *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS); 2602 CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars); 2603 } else { 2604 Action.Enter(CGF); 2605 CGF.EmitStmt( 2606 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 2607 } 2608 }; 2609 OMPLexicalScope Scope(*this, S); 2610 CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getLocStart(), !C); 2611 } 2612 2613 static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val, 2614 QualType SrcType, QualType DestType, 2615 SourceLocation Loc) { 2616 assert(CGF.hasScalarEvaluationKind(DestType) && 2617 "DestType must have scalar evaluation kind."); 2618 assert(!Val.isAggregate() && "Must be a scalar or complex."); 2619 return Val.isScalar() 2620 ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, DestType, 2621 Loc) 2622 : CGF.EmitComplexToScalarConversion(Val.getComplexVal(), SrcType, 2623 DestType, Loc); 2624 } 2625 2626 static CodeGenFunction::ComplexPairTy 2627 convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType, 2628 QualType DestType, SourceLocation Loc) { 2629 assert(CGF.getEvaluationKind(DestType) == TEK_Complex && 2630 "DestType must have complex evaluation kind."); 2631 CodeGenFunction::ComplexPairTy ComplexVal; 2632 if (Val.isScalar()) { 2633 // Convert the input element to the element type of the complex. 2634 auto DestElementType = DestType->castAs<ComplexType>()->getElementType(); 2635 auto ScalarVal = CGF.EmitScalarConversion(Val.getScalarVal(), SrcType, 2636 DestElementType, Loc); 2637 ComplexVal = CodeGenFunction::ComplexPairTy( 2638 ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType())); 2639 } else { 2640 assert(Val.isComplex() && "Must be a scalar or complex."); 2641 auto SrcElementType = SrcType->castAs<ComplexType>()->getElementType(); 2642 auto DestElementType = DestType->castAs<ComplexType>()->getElementType(); 2643 ComplexVal.first = CGF.EmitScalarConversion( 2644 Val.getComplexVal().first, SrcElementType, DestElementType, Loc); 2645 ComplexVal.second = CGF.EmitScalarConversion( 2646 Val.getComplexVal().second, SrcElementType, DestElementType, Loc); 2647 } 2648 return ComplexVal; 2649 } 2650 2651 static void emitSimpleAtomicStore(CodeGenFunction &CGF, bool IsSeqCst, 2652 LValue LVal, RValue RVal) { 2653 if (LVal.isGlobalReg()) { 2654 CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal); 2655 } else { 2656 CGF.EmitAtomicStore(RVal, LVal, 2657 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent 2658 : llvm::AtomicOrdering::Monotonic, 2659 LVal.isVolatile(), /*IsInit=*/false); 2660 } 2661 } 2662 2663 void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal, 2664 QualType RValTy, SourceLocation Loc) { 2665 switch (getEvaluationKind(LVal.getType())) { 2666 case TEK_Scalar: 2667 EmitStoreThroughLValue(RValue::get(convertToScalarValue( 2668 *this, RVal, RValTy, LVal.getType(), Loc)), 2669 LVal); 2670 break; 2671 case TEK_Complex: 2672 EmitStoreOfComplex( 2673 convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal, 2674 /*isInit=*/false); 2675 break; 2676 case TEK_Aggregate: 2677 llvm_unreachable("Must be a scalar or complex."); 2678 } 2679 } 2680 2681 static void EmitOMPAtomicReadExpr(CodeGenFunction &CGF, bool IsSeqCst, 2682 const Expr *X, const Expr *V, 2683 SourceLocation Loc) { 2684 // v = x; 2685 assert(V->isLValue() && "V of 'omp atomic read' is not lvalue"); 2686 assert(X->isLValue() && "X of 'omp atomic read' is not lvalue"); 2687 LValue XLValue = CGF.EmitLValue(X); 2688 LValue VLValue = CGF.EmitLValue(V); 2689 RValue Res = XLValue.isGlobalReg() 2690 ? CGF.EmitLoadOfLValue(XLValue, Loc) 2691 : CGF.EmitAtomicLoad( 2692 XLValue, Loc, 2693 IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent 2694 : llvm::AtomicOrdering::Monotonic, 2695 XLValue.isVolatile()); 2696 // OpenMP, 2.12.6, atomic Construct 2697 // Any atomic construct with a seq_cst clause forces the atomically 2698 // performed operation to include an implicit flush operation without a 2699 // list. 2700 if (IsSeqCst) 2701 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); 2702 CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc); 2703 } 2704 2705 static void EmitOMPAtomicWriteExpr(CodeGenFunction &CGF, bool IsSeqCst, 2706 const Expr *X, const Expr *E, 2707 SourceLocation Loc) { 2708 // x = expr; 2709 assert(X->isLValue() && "X of 'omp atomic write' is not lvalue"); 2710 emitSimpleAtomicStore(CGF, IsSeqCst, CGF.EmitLValue(X), CGF.EmitAnyExpr(E)); 2711 // OpenMP, 2.12.6, atomic Construct 2712 // Any atomic construct with a seq_cst clause forces the atomically 2713 // performed operation to include an implicit flush operation without a 2714 // list. 2715 if (IsSeqCst) 2716 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); 2717 } 2718 2719 static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X, 2720 RValue Update, 2721 BinaryOperatorKind BO, 2722 llvm::AtomicOrdering AO, 2723 bool IsXLHSInRHSPart) { 2724 auto &Context = CGF.CGM.getContext(); 2725 // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x' 2726 // expression is simple and atomic is allowed for the given type for the 2727 // target platform. 2728 if (BO == BO_Comma || !Update.isScalar() || 2729 !Update.getScalarVal()->getType()->isIntegerTy() || 2730 !X.isSimple() || (!isa<llvm::ConstantInt>(Update.getScalarVal()) && 2731 (Update.getScalarVal()->getType() != 2732 X.getAddress().getElementType())) || 2733 !X.getAddress().getElementType()->isIntegerTy() || 2734 !Context.getTargetInfo().hasBuiltinAtomic( 2735 Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment()))) 2736 return std::make_pair(false, RValue::get(nullptr)); 2737 2738 llvm::AtomicRMWInst::BinOp RMWOp; 2739 switch (BO) { 2740 case BO_Add: 2741 RMWOp = llvm::AtomicRMWInst::Add; 2742 break; 2743 case BO_Sub: 2744 if (!IsXLHSInRHSPart) 2745 return std::make_pair(false, RValue::get(nullptr)); 2746 RMWOp = llvm::AtomicRMWInst::Sub; 2747 break; 2748 case BO_And: 2749 RMWOp = llvm::AtomicRMWInst::And; 2750 break; 2751 case BO_Or: 2752 RMWOp = llvm::AtomicRMWInst::Or; 2753 break; 2754 case BO_Xor: 2755 RMWOp = llvm::AtomicRMWInst::Xor; 2756 break; 2757 case BO_LT: 2758 RMWOp = X.getType()->hasSignedIntegerRepresentation() 2759 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min 2760 : llvm::AtomicRMWInst::Max) 2761 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin 2762 : llvm::AtomicRMWInst::UMax); 2763 break; 2764 case BO_GT: 2765 RMWOp = X.getType()->hasSignedIntegerRepresentation() 2766 ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max 2767 : llvm::AtomicRMWInst::Min) 2768 : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax 2769 : llvm::AtomicRMWInst::UMin); 2770 break; 2771 case BO_Assign: 2772 RMWOp = llvm::AtomicRMWInst::Xchg; 2773 break; 2774 case BO_Mul: 2775 case BO_Div: 2776 case BO_Rem: 2777 case BO_Shl: 2778 case BO_Shr: 2779 case BO_LAnd: 2780 case BO_LOr: 2781 return std::make_pair(false, RValue::get(nullptr)); 2782 case BO_PtrMemD: 2783 case BO_PtrMemI: 2784 case BO_LE: 2785 case BO_GE: 2786 case BO_EQ: 2787 case BO_NE: 2788 case BO_AddAssign: 2789 case BO_SubAssign: 2790 case BO_AndAssign: 2791 case BO_OrAssign: 2792 case BO_XorAssign: 2793 case BO_MulAssign: 2794 case BO_DivAssign: 2795 case BO_RemAssign: 2796 case BO_ShlAssign: 2797 case BO_ShrAssign: 2798 case BO_Comma: 2799 llvm_unreachable("Unsupported atomic update operation"); 2800 } 2801 auto *UpdateVal = Update.getScalarVal(); 2802 if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) { 2803 UpdateVal = CGF.Builder.CreateIntCast( 2804 IC, X.getAddress().getElementType(), 2805 X.getType()->hasSignedIntegerRepresentation()); 2806 } 2807 auto *Res = CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(), UpdateVal, AO); 2808 return std::make_pair(true, RValue::get(Res)); 2809 } 2810 2811 std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr( 2812 LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart, 2813 llvm::AtomicOrdering AO, SourceLocation Loc, 2814 const llvm::function_ref<RValue(RValue)> &CommonGen) { 2815 // Update expressions are allowed to have the following forms: 2816 // x binop= expr; -> xrval + expr; 2817 // x++, ++x -> xrval + 1; 2818 // x--, --x -> xrval - 1; 2819 // x = x binop expr; -> xrval binop expr 2820 // x = expr Op x; - > expr binop xrval; 2821 auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart); 2822 if (!Res.first) { 2823 if (X.isGlobalReg()) { 2824 // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop 2825 // 'xrval'. 2826 EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X); 2827 } else { 2828 // Perform compare-and-swap procedure. 2829 EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified()); 2830 } 2831 } 2832 return Res; 2833 } 2834 2835 static void EmitOMPAtomicUpdateExpr(CodeGenFunction &CGF, bool IsSeqCst, 2836 const Expr *X, const Expr *E, 2837 const Expr *UE, bool IsXLHSInRHSPart, 2838 SourceLocation Loc) { 2839 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) && 2840 "Update expr in 'atomic update' must be a binary operator."); 2841 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts()); 2842 // Update expressions are allowed to have the following forms: 2843 // x binop= expr; -> xrval + expr; 2844 // x++, ++x -> xrval + 1; 2845 // x--, --x -> xrval - 1; 2846 // x = x binop expr; -> xrval binop expr 2847 // x = expr Op x; - > expr binop xrval; 2848 assert(X->isLValue() && "X of 'omp atomic update' is not lvalue"); 2849 LValue XLValue = CGF.EmitLValue(X); 2850 RValue ExprRValue = CGF.EmitAnyExpr(E); 2851 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent 2852 : llvm::AtomicOrdering::Monotonic; 2853 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts()); 2854 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts()); 2855 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS; 2856 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS; 2857 auto Gen = 2858 [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) -> RValue { 2859 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); 2860 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue); 2861 return CGF.EmitAnyExpr(UE); 2862 }; 2863 (void)CGF.EmitOMPAtomicSimpleUpdateExpr( 2864 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen); 2865 // OpenMP, 2.12.6, atomic Construct 2866 // Any atomic construct with a seq_cst clause forces the atomically 2867 // performed operation to include an implicit flush operation without a 2868 // list. 2869 if (IsSeqCst) 2870 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); 2871 } 2872 2873 static RValue convertToType(CodeGenFunction &CGF, RValue Value, 2874 QualType SourceType, QualType ResType, 2875 SourceLocation Loc) { 2876 switch (CGF.getEvaluationKind(ResType)) { 2877 case TEK_Scalar: 2878 return RValue::get( 2879 convertToScalarValue(CGF, Value, SourceType, ResType, Loc)); 2880 case TEK_Complex: { 2881 auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc); 2882 return RValue::getComplex(Res.first, Res.second); 2883 } 2884 case TEK_Aggregate: 2885 break; 2886 } 2887 llvm_unreachable("Must be a scalar or complex."); 2888 } 2889 2890 static void EmitOMPAtomicCaptureExpr(CodeGenFunction &CGF, bool IsSeqCst, 2891 bool IsPostfixUpdate, const Expr *V, 2892 const Expr *X, const Expr *E, 2893 const Expr *UE, bool IsXLHSInRHSPart, 2894 SourceLocation Loc) { 2895 assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue"); 2896 assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue"); 2897 RValue NewVVal; 2898 LValue VLValue = CGF.EmitLValue(V); 2899 LValue XLValue = CGF.EmitLValue(X); 2900 RValue ExprRValue = CGF.EmitAnyExpr(E); 2901 auto AO = IsSeqCst ? llvm::AtomicOrdering::SequentiallyConsistent 2902 : llvm::AtomicOrdering::Monotonic; 2903 QualType NewVValType; 2904 if (UE) { 2905 // 'x' is updated with some additional value. 2906 assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) && 2907 "Update expr in 'atomic capture' must be a binary operator."); 2908 auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts()); 2909 // Update expressions are allowed to have the following forms: 2910 // x binop= expr; -> xrval + expr; 2911 // x++, ++x -> xrval + 1; 2912 // x--, --x -> xrval - 1; 2913 // x = x binop expr; -> xrval binop expr 2914 // x = expr Op x; - > expr binop xrval; 2915 auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts()); 2916 auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts()); 2917 auto *XRValExpr = IsXLHSInRHSPart ? LHS : RHS; 2918 NewVValType = XRValExpr->getType(); 2919 auto *ERValExpr = IsXLHSInRHSPart ? RHS : LHS; 2920 auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr, 2921 IsSeqCst, IsPostfixUpdate](RValue XRValue) -> RValue { 2922 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); 2923 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue); 2924 RValue Res = CGF.EmitAnyExpr(UE); 2925 NewVVal = IsPostfixUpdate ? XRValue : Res; 2926 return Res; 2927 }; 2928 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr( 2929 XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen); 2930 if (Res.first) { 2931 // 'atomicrmw' instruction was generated. 2932 if (IsPostfixUpdate) { 2933 // Use old value from 'atomicrmw'. 2934 NewVVal = Res.second; 2935 } else { 2936 // 'atomicrmw' does not provide new value, so evaluate it using old 2937 // value of 'x'. 2938 CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue); 2939 CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second); 2940 NewVVal = CGF.EmitAnyExpr(UE); 2941 } 2942 } 2943 } else { 2944 // 'x' is simply rewritten with some 'expr'. 2945 NewVValType = X->getType().getNonReferenceType(); 2946 ExprRValue = convertToType(CGF, ExprRValue, E->getType(), 2947 X->getType().getNonReferenceType(), Loc); 2948 auto &&Gen = [&CGF, &NewVVal, ExprRValue](RValue XRValue) -> RValue { 2949 NewVVal = XRValue; 2950 return ExprRValue; 2951 }; 2952 // Try to perform atomicrmw xchg, otherwise simple exchange. 2953 auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr( 2954 XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO, 2955 Loc, Gen); 2956 if (Res.first) { 2957 // 'atomicrmw' instruction was generated. 2958 NewVVal = IsPostfixUpdate ? Res.second : ExprRValue; 2959 } 2960 } 2961 // Emit post-update store to 'v' of old/new 'x' value. 2962 CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc); 2963 // OpenMP, 2.12.6, atomic Construct 2964 // Any atomic construct with a seq_cst clause forces the atomically 2965 // performed operation to include an implicit flush operation without a 2966 // list. 2967 if (IsSeqCst) 2968 CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc); 2969 } 2970 2971 static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, 2972 bool IsSeqCst, bool IsPostfixUpdate, 2973 const Expr *X, const Expr *V, const Expr *E, 2974 const Expr *UE, bool IsXLHSInRHSPart, 2975 SourceLocation Loc) { 2976 switch (Kind) { 2977 case OMPC_read: 2978 EmitOMPAtomicReadExpr(CGF, IsSeqCst, X, V, Loc); 2979 break; 2980 case OMPC_write: 2981 EmitOMPAtomicWriteExpr(CGF, IsSeqCst, X, E, Loc); 2982 break; 2983 case OMPC_unknown: 2984 case OMPC_update: 2985 EmitOMPAtomicUpdateExpr(CGF, IsSeqCst, X, E, UE, IsXLHSInRHSPart, Loc); 2986 break; 2987 case OMPC_capture: 2988 EmitOMPAtomicCaptureExpr(CGF, IsSeqCst, IsPostfixUpdate, V, X, E, UE, 2989 IsXLHSInRHSPart, Loc); 2990 break; 2991 case OMPC_if: 2992 case OMPC_final: 2993 case OMPC_num_threads: 2994 case OMPC_private: 2995 case OMPC_firstprivate: 2996 case OMPC_lastprivate: 2997 case OMPC_reduction: 2998 case OMPC_safelen: 2999 case OMPC_simdlen: 3000 case OMPC_collapse: 3001 case OMPC_default: 3002 case OMPC_seq_cst: 3003 case OMPC_shared: 3004 case OMPC_linear: 3005 case OMPC_aligned: 3006 case OMPC_copyin: 3007 case OMPC_copyprivate: 3008 case OMPC_flush: 3009 case OMPC_proc_bind: 3010 case OMPC_schedule: 3011 case OMPC_ordered: 3012 case OMPC_nowait: 3013 case OMPC_untied: 3014 case OMPC_threadprivate: 3015 case OMPC_depend: 3016 case OMPC_mergeable: 3017 case OMPC_device: 3018 case OMPC_threads: 3019 case OMPC_simd: 3020 case OMPC_map: 3021 case OMPC_num_teams: 3022 case OMPC_thread_limit: 3023 case OMPC_priority: 3024 case OMPC_grainsize: 3025 case OMPC_nogroup: 3026 case OMPC_num_tasks: 3027 case OMPC_hint: 3028 case OMPC_dist_schedule: 3029 case OMPC_defaultmap: 3030 case OMPC_uniform: 3031 llvm_unreachable("Clause is not allowed in 'omp atomic'."); 3032 } 3033 } 3034 3035 void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) { 3036 bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>(); 3037 OpenMPClauseKind Kind = OMPC_unknown; 3038 for (auto *C : S.clauses()) { 3039 // Find first clause (skip seq_cst clause, if it is first). 3040 if (C->getClauseKind() != OMPC_seq_cst) { 3041 Kind = C->getClauseKind(); 3042 break; 3043 } 3044 } 3045 3046 const auto *CS = 3047 S.getAssociatedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true); 3048 if (const auto *EWC = dyn_cast<ExprWithCleanups>(CS)) { 3049 enterFullExpression(EWC); 3050 } 3051 // Processing for statements under 'atomic capture'. 3052 if (const auto *Compound = dyn_cast<CompoundStmt>(CS)) { 3053 for (const auto *C : Compound->body()) { 3054 if (const auto *EWC = dyn_cast<ExprWithCleanups>(C)) { 3055 enterFullExpression(EWC); 3056 } 3057 } 3058 } 3059 3060 auto &&CodeGen = [&S, Kind, IsSeqCst, CS](CodeGenFunction &CGF, 3061 PrePostActionTy &) { 3062 CGF.EmitStopPoint(CS); 3063 EmitOMPAtomicExpr(CGF, Kind, IsSeqCst, S.isPostfixUpdate(), S.getX(), 3064 S.getV(), S.getExpr(), S.getUpdateExpr(), 3065 S.isXLHSInRHSPart(), S.getLocStart()); 3066 }; 3067 OMPLexicalScope Scope(*this, S); 3068 CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_atomic, CodeGen); 3069 } 3070 3071 std::pair<llvm::Function * /*OutlinedFn*/, llvm::Constant * /*OutlinedFnID*/> 3072 CodeGenFunction::EmitOMPTargetDirectiveOutlinedFunction( 3073 CodeGenModule &CGM, const OMPTargetDirective &S, StringRef ParentName, 3074 bool IsOffloadEntry) { 3075 llvm::Function *OutlinedFn = nullptr; 3076 llvm::Constant *OutlinedFnID = nullptr; 3077 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) { 3078 OMPPrivateScope PrivateScope(CGF); 3079 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); 3080 CGF.EmitOMPPrivateClause(S, PrivateScope); 3081 (void)PrivateScope.Privatize(); 3082 3083 Action.Enter(CGF); 3084 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 3085 }; 3086 // Emit target region as a standalone region. 3087 CGM.getOpenMPRuntime().emitTargetOutlinedFunction( 3088 S, ParentName, OutlinedFn, OutlinedFnID, IsOffloadEntry, CodeGen); 3089 return std::make_pair(OutlinedFn, OutlinedFnID); 3090 } 3091 3092 void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) { 3093 const CapturedStmt &CS = *cast<CapturedStmt>(S.getAssociatedStmt()); 3094 3095 llvm::SmallVector<llvm::Value *, 16> CapturedVars; 3096 GenerateOpenMPCapturedVars(CS, CapturedVars); 3097 3098 llvm::Function *Fn = nullptr; 3099 llvm::Constant *FnID = nullptr; 3100 3101 // Check if we have any if clause associated with the directive. 3102 const Expr *IfCond = nullptr; 3103 3104 if (auto *C = S.getSingleClause<OMPIfClause>()) { 3105 IfCond = C->getCondition(); 3106 } 3107 3108 // Check if we have any device clause associated with the directive. 3109 const Expr *Device = nullptr; 3110 if (auto *C = S.getSingleClause<OMPDeviceClause>()) { 3111 Device = C->getDevice(); 3112 } 3113 3114 // Check if we have an if clause whose conditional always evaluates to false 3115 // or if we do not have any targets specified. If so the target region is not 3116 // an offload entry point. 3117 bool IsOffloadEntry = true; 3118 if (IfCond) { 3119 bool Val; 3120 if (ConstantFoldsToSimpleInteger(IfCond, Val) && !Val) 3121 IsOffloadEntry = false; 3122 } 3123 if (CGM.getLangOpts().OMPTargetTriples.empty()) 3124 IsOffloadEntry = false; 3125 3126 assert(CurFuncDecl && "No parent declaration for target region!"); 3127 StringRef ParentName; 3128 // In case we have Ctors/Dtors we use the complete type variant to produce 3129 // the mangling of the device outlined kernel. 3130 if (auto *D = dyn_cast<CXXConstructorDecl>(CurFuncDecl)) 3131 ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete)); 3132 else if (auto *D = dyn_cast<CXXDestructorDecl>(CurFuncDecl)) 3133 ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete)); 3134 else 3135 ParentName = 3136 CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CurFuncDecl))); 3137 3138 std::tie(Fn, FnID) = EmitOMPTargetDirectiveOutlinedFunction( 3139 CGM, S, ParentName, IsOffloadEntry); 3140 OMPLexicalScope Scope(*this, S); 3141 CGM.getOpenMPRuntime().emitTargetCall(*this, S, Fn, FnID, IfCond, Device, 3142 CapturedVars); 3143 } 3144 3145 static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF, 3146 const OMPExecutableDirective &S, 3147 OpenMPDirectiveKind InnermostKind, 3148 const RegionCodeGenTy &CodeGen) { 3149 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 3150 auto OutlinedFn = CGF.CGM.getOpenMPRuntime(). 3151 emitParallelOrTeamsOutlinedFunction(S, 3152 *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); 3153 3154 const OMPTeamsDirective &TD = *dyn_cast<OMPTeamsDirective>(&S); 3155 const OMPNumTeamsClause *NT = TD.getSingleClause<OMPNumTeamsClause>(); 3156 const OMPThreadLimitClause *TL = TD.getSingleClause<OMPThreadLimitClause>(); 3157 if (NT || TL) { 3158 Expr *NumTeams = (NT) ? NT->getNumTeams() : nullptr; 3159 Expr *ThreadLimit = (TL) ? TL->getThreadLimit() : nullptr; 3160 3161 CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit, 3162 S.getLocStart()); 3163 } 3164 3165 OMPLexicalScope Scope(CGF, S); 3166 llvm::SmallVector<llvm::Value *, 16> CapturedVars; 3167 CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); 3168 CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getLocStart(), OutlinedFn, 3169 CapturedVars); 3170 } 3171 3172 void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) { 3173 // Emit parallel region as a standalone region. 3174 auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) { 3175 OMPPrivateScope PrivateScope(CGF); 3176 (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope); 3177 CGF.EmitOMPPrivateClause(S, PrivateScope); 3178 (void)PrivateScope.Privatize(); 3179 CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 3180 }; 3181 emitCommonOMPTeamsDirective(*this, S, OMPD_teams, CodeGen); 3182 } 3183 3184 void CodeGenFunction::EmitOMPCancellationPointDirective( 3185 const OMPCancellationPointDirective &S) { 3186 CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getLocStart(), 3187 S.getCancelRegion()); 3188 } 3189 3190 void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) { 3191 const Expr *IfCond = nullptr; 3192 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 3193 if (C->getNameModifier() == OMPD_unknown || 3194 C->getNameModifier() == OMPD_cancel) { 3195 IfCond = C->getCondition(); 3196 break; 3197 } 3198 } 3199 CGM.getOpenMPRuntime().emitCancelCall(*this, S.getLocStart(), IfCond, 3200 S.getCancelRegion()); 3201 } 3202 3203 CodeGenFunction::JumpDest 3204 CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) { 3205 if (Kind == OMPD_parallel || Kind == OMPD_task) 3206 return ReturnBlock; 3207 assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections || 3208 Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for); 3209 return BreakContinueStack.back().BreakBlock; 3210 } 3211 3212 // Generate the instructions for '#pragma omp target data' directive. 3213 void CodeGenFunction::EmitOMPTargetDataDirective( 3214 const OMPTargetDataDirective &S) { 3215 // emit the code inside the construct for now 3216 OMPLexicalScope Scope(*this, S); 3217 CGM.getOpenMPRuntime().emitInlinedDirective( 3218 *this, OMPD_target_data, [&S](CodeGenFunction &CGF, PrePostActionTy &) { 3219 CGF.EmitStmt( 3220 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 3221 }); 3222 } 3223 3224 void CodeGenFunction::EmitOMPTargetEnterDataDirective( 3225 const OMPTargetEnterDataDirective &S) { 3226 // TODO: codegen for target enter data. 3227 } 3228 3229 void CodeGenFunction::EmitOMPTargetExitDataDirective( 3230 const OMPTargetExitDataDirective &S) { 3231 // TODO: codegen for target exit data. 3232 } 3233 3234 void CodeGenFunction::EmitOMPTargetParallelDirective( 3235 const OMPTargetParallelDirective &S) { 3236 // TODO: codegen for target parallel. 3237 } 3238 3239 void CodeGenFunction::EmitOMPTargetParallelForDirective( 3240 const OMPTargetParallelForDirective &S) { 3241 // TODO: codegen for target parallel for. 3242 } 3243 3244 /// Emit a helper variable and return corresponding lvalue. 3245 static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper, 3246 const ImplicitParamDecl *PVD, 3247 CodeGenFunction::OMPPrivateScope &Privates) { 3248 auto *VDecl = cast<VarDecl>(Helper->getDecl()); 3249 Privates.addPrivate( 3250 VDecl, [&CGF, PVD]() -> Address { return CGF.GetAddrOfLocalVar(PVD); }); 3251 } 3252 3253 void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) { 3254 assert(isOpenMPTaskLoopDirective(S.getDirectiveKind())); 3255 // Emit outlined function for task construct. 3256 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 3257 auto CapturedStruct = GenerateCapturedStmtArgument(*CS); 3258 auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl()); 3259 const Expr *IfCond = nullptr; 3260 for (const auto *C : S.getClausesOfKind<OMPIfClause>()) { 3261 if (C->getNameModifier() == OMPD_unknown || 3262 C->getNameModifier() == OMPD_taskloop) { 3263 IfCond = C->getCondition(); 3264 break; 3265 } 3266 } 3267 bool Nogroup = S.getSingleClause<OMPNogroupClause>(); 3268 // TODO: Check if we should emit tied or untied task. 3269 // Check if the task is final 3270 llvm::PointerIntPair<llvm::Value *, 1, bool> Final; 3271 if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) { 3272 // If the condition constant folds and can be elided, try to avoid emitting 3273 // the condition and the dead arm of the if/else. 3274 auto *Cond = Clause->getCondition(); 3275 bool CondConstant; 3276 if (ConstantFoldsToSimpleInteger(Cond, CondConstant)) 3277 Final.setInt(CondConstant); 3278 else 3279 Final.setPointer(EvaluateExprAsBool(Cond)); 3280 } else { 3281 // By default the task is not final. 3282 Final.setInt(/*IntVal=*/false); 3283 } 3284 3285 auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) { 3286 // if (PreCond) { 3287 // for (IV in 0..LastIteration) BODY; 3288 // <Final counter/linear vars updates>; 3289 // } 3290 // 3291 3292 // Emit: if (PreCond) - begin. 3293 // If the condition constant folds and can be elided, avoid emitting the 3294 // whole loop. 3295 bool CondConstant; 3296 llvm::BasicBlock *ContBlock = nullptr; 3297 OMPLoopScope PreInitScope(CGF, S); 3298 if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) { 3299 if (!CondConstant) 3300 return; 3301 } else { 3302 auto *ThenBlock = CGF.createBasicBlock("taskloop.if.then"); 3303 ContBlock = CGF.createBasicBlock("taskloop.if.end"); 3304 emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock, 3305 CGF.getProfileCount(&S)); 3306 CGF.EmitBlock(ThenBlock); 3307 CGF.incrementProfileCounter(&S); 3308 } 3309 3310 OMPPrivateScope LoopScope(CGF); 3311 // Emit helper vars inits. 3312 enum { LowerBound = 5, UpperBound, Stride, LastIter }; 3313 auto *I = CS->getCapturedDecl()->param_begin(); 3314 auto *LBP = std::next(I, LowerBound); 3315 auto *UBP = std::next(I, UpperBound); 3316 auto *STP = std::next(I, Stride); 3317 auto *LIP = std::next(I, LastIter); 3318 mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP, 3319 LoopScope); 3320 mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP, 3321 LoopScope); 3322 mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope); 3323 mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP, 3324 LoopScope); 3325 CGF.EmitOMPPrivateLoopCounters(S, LoopScope); 3326 (void)LoopScope.Privatize(); 3327 // Emit the loop iteration variable. 3328 const Expr *IVExpr = S.getIterationVariable(); 3329 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); 3330 CGF.EmitVarDecl(*IVDecl); 3331 CGF.EmitIgnoredExpr(S.getInit()); 3332 3333 // Emit the iterations count variable. 3334 // If it is not a variable, Sema decided to calculate iterations count on 3335 // each iteration (e.g., it is foldable into a constant). 3336 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 3337 CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 3338 // Emit calculation of the iterations count. 3339 CGF.EmitIgnoredExpr(S.getCalcLastIteration()); 3340 } 3341 3342 CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(), 3343 S.getInc(), 3344 [&S](CodeGenFunction &CGF) { 3345 CGF.EmitOMPLoopBody(S, JumpDest()); 3346 CGF.EmitStopPoint(&S); 3347 }, 3348 [](CodeGenFunction &) {}); 3349 // Emit: if (PreCond) - end. 3350 if (ContBlock) { 3351 CGF.EmitBranch(ContBlock); 3352 CGF.EmitBlock(ContBlock, true); 3353 } 3354 }; 3355 auto &&TaskGen = [&S, SharedsTy, CapturedStruct, IfCond, &Final, 3356 Nogroup](CodeGenFunction &CGF, llvm::Value *OutlinedFn, 3357 const OMPPrivateDataTy &Data) { 3358 auto &&CodeGen = [&](CodeGenFunction &CGF, PrePostActionTy &) { 3359 OMPLoopScope PreInitScope(CGF, S); 3360 CGF.CGM.getOpenMPRuntime().emitTaskLoopCall( 3361 CGF, S.getLocStart(), S, Data.Tied, Final, Nogroup, 3362 Data.NumberOfParts, OutlinedFn, SharedsTy, CapturedStruct, IfCond, 3363 Data.PrivateVars, Data.PrivateCopies, Data.FirstprivateVars, 3364 Data.FirstprivateCopies, Data.FirstprivateInits); 3365 }; 3366 CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop, 3367 CodeGen); 3368 }; 3369 EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, /*Tied=*/true); 3370 } 3371 3372 void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) { 3373 EmitOMPTaskLoopBasedDirective(S); 3374 } 3375 3376 void CodeGenFunction::EmitOMPTaskLoopSimdDirective( 3377 const OMPTaskLoopSimdDirective &S) { 3378 // emit the code inside the construct for now 3379 OMPLexicalScope Scope(*this, S); 3380 CGM.getOpenMPRuntime().emitInlinedDirective( 3381 *this, OMPD_taskloop_simd, [&S](CodeGenFunction &CGF, PrePostActionTy &) { 3382 OMPLoopScope PreInitScope(CGF, S); 3383 CGF.EmitStmt( 3384 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 3385 }); 3386 } 3387