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 "CGOpenMPRuntime.h" 15 #include "CodeGenFunction.h" 16 #include "CodeGenModule.h" 17 #include "TargetInfo.h" 18 #include "clang/AST/Stmt.h" 19 #include "clang/AST/StmtOpenMP.h" 20 using namespace clang; 21 using namespace CodeGen; 22 23 namespace { 24 /// \brief RAII for emitting code of CapturedStmt without function outlining. 25 class InlinedOpenMPRegion { 26 CodeGenFunction &CGF; 27 CodeGenFunction::CGCapturedStmtInfo *PrevCapturedStmtInfo; 28 const Decl *StoredCurCodeDecl; 29 30 /// \brief A class to emit CapturedStmt construct as inlined statement without 31 /// generating a function for outlined code. 32 class CGInlinedOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo { 33 public: 34 CGInlinedOpenMPRegionInfo() : CGCapturedStmtInfo() {} 35 }; 36 37 public: 38 InlinedOpenMPRegion(CodeGenFunction &CGF, const Stmt *S) 39 : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo), 40 StoredCurCodeDecl(CGF.CurCodeDecl) { 41 CGF.CurCodeDecl = cast<CapturedStmt>(S)->getCapturedDecl(); 42 CGF.CapturedStmtInfo = new CGInlinedOpenMPRegionInfo(); 43 } 44 ~InlinedOpenMPRegion() { 45 delete CGF.CapturedStmtInfo; 46 CGF.CapturedStmtInfo = PrevCapturedStmtInfo; 47 CGF.CurCodeDecl = StoredCurCodeDecl; 48 } 49 }; 50 } // namespace 51 52 //===----------------------------------------------------------------------===// 53 // OpenMP Directive Emission 54 //===----------------------------------------------------------------------===// 55 56 /// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen 57 /// function. Here is the logic: 58 /// if (Cond) { 59 /// CodeGen(true); 60 /// } else { 61 /// CodeGen(false); 62 /// } 63 static void EmitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond, 64 const std::function<void(bool)> &CodeGen) { 65 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange()); 66 67 // If the condition constant folds and can be elided, try to avoid emitting 68 // the condition and the dead arm of the if/else. 69 bool CondConstant; 70 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) { 71 CodeGen(CondConstant); 72 return; 73 } 74 75 // Otherwise, the condition did not fold, or we couldn't elide it. Just 76 // emit the conditional branch. 77 auto ThenBlock = CGF.createBasicBlock(/*name*/ "omp_if.then"); 78 auto ElseBlock = CGF.createBasicBlock(/*name*/ "omp_if.else"); 79 auto ContBlock = CGF.createBasicBlock(/*name*/ "omp_if.end"); 80 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount*/ 0); 81 82 // Emit the 'then' code. 83 CGF.EmitBlock(ThenBlock); 84 CodeGen(/*ThenBlock*/ true); 85 CGF.EmitBranch(ContBlock); 86 // Emit the 'else' code if present. 87 { 88 // There is no need to emit line number for unconditional branch. 89 ApplyDebugLocation DL(CGF); 90 CGF.EmitBlock(ElseBlock); 91 } 92 CodeGen(/*ThenBlock*/ false); 93 { 94 // There is no need to emit line number for unconditional branch. 95 ApplyDebugLocation DL(CGF); 96 CGF.EmitBranch(ContBlock); 97 } 98 // Emit the continuation block for code after the if. 99 CGF.EmitBlock(ContBlock, /*IsFinished*/ true); 100 } 101 102 void CodeGenFunction::EmitOMPAggregateAssign(LValue OriginalAddr, 103 llvm::Value *PrivateAddr, 104 const Expr *AssignExpr, 105 QualType OriginalType, 106 const VarDecl *VDInit) { 107 EmitBlock(createBasicBlock(".omp.assign.begin.")); 108 if (!isa<CXXConstructExpr>(AssignExpr) || isTrivialInitializer(AssignExpr)) { 109 // Perform simple memcpy. 110 EmitAggregateAssign(PrivateAddr, OriginalAddr.getAddress(), 111 AssignExpr->getType()); 112 } else { 113 // Perform element-by-element initialization. 114 QualType ElementTy; 115 auto SrcBegin = OriginalAddr.getAddress(); 116 auto DestBegin = PrivateAddr; 117 auto ArrayTy = OriginalType->getAsArrayTypeUnsafe(); 118 auto SrcNumElements = emitArrayLength(ArrayTy, ElementTy, SrcBegin); 119 auto DestNumElements = emitArrayLength(ArrayTy, ElementTy, DestBegin); 120 auto SrcEnd = Builder.CreateGEP(SrcBegin, SrcNumElements); 121 auto DestEnd = Builder.CreateGEP(DestBegin, DestNumElements); 122 // The basic structure here is a do-while loop, because we don't 123 // need to check for the zero-element case. 124 auto BodyBB = createBasicBlock("omp.arraycpy.body"); 125 auto DoneBB = createBasicBlock("omp.arraycpy.done"); 126 auto IsEmpty = 127 Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty"); 128 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB); 129 130 // Enter the loop body, making that address the current address. 131 auto EntryBB = Builder.GetInsertBlock(); 132 EmitBlock(BodyBB); 133 auto SrcElementPast = Builder.CreatePHI(SrcBegin->getType(), 2, 134 "omp.arraycpy.srcElementPast"); 135 SrcElementPast->addIncoming(SrcEnd, EntryBB); 136 auto DestElementPast = Builder.CreatePHI(DestBegin->getType(), 2, 137 "omp.arraycpy.destElementPast"); 138 DestElementPast->addIncoming(DestEnd, EntryBB); 139 140 // Shift the address back by one element. 141 auto NegativeOne = llvm::ConstantInt::get(SizeTy, -1, true); 142 auto DestElement = Builder.CreateGEP(DestElementPast, NegativeOne, 143 "omp.arraycpy.dest.element"); 144 auto SrcElement = Builder.CreateGEP(SrcElementPast, NegativeOne, 145 "omp.arraycpy.src.element"); 146 { 147 // Create RunCleanScope to cleanup possible temps. 148 CodeGenFunction::RunCleanupsScope Init(*this); 149 // Emit initialization for single element. 150 LocalDeclMap[VDInit] = SrcElement; 151 EmitAnyExprToMem(AssignExpr, DestElement, 152 AssignExpr->getType().getQualifiers(), 153 /*IsInitializer*/ false); 154 LocalDeclMap.erase(VDInit); 155 } 156 157 // Check whether we've reached the end. 158 auto Done = 159 Builder.CreateICmpEQ(DestElement, DestBegin, "omp.arraycpy.done"); 160 Builder.CreateCondBr(Done, DoneBB, BodyBB); 161 DestElementPast->addIncoming(DestElement, Builder.GetInsertBlock()); 162 SrcElementPast->addIncoming(SrcElement, Builder.GetInsertBlock()); 163 164 // Done. 165 EmitBlock(DoneBB, true); 166 } 167 EmitBlock(createBasicBlock(".omp.assign.end.")); 168 } 169 170 void CodeGenFunction::EmitOMPFirstprivateClause( 171 const OMPExecutableDirective &D, 172 CodeGenFunction::OMPPrivateScope &PrivateScope) { 173 auto PrivateFilter = [](const OMPClause *C) -> bool { 174 return C->getClauseKind() == OMPC_firstprivate; 175 }; 176 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)> 177 I(D.clauses(), PrivateFilter); I; ++I) { 178 auto *C = cast<OMPFirstprivateClause>(*I); 179 auto IRef = C->varlist_begin(); 180 auto InitsRef = C->inits().begin(); 181 for (auto IInit : C->private_copies()) { 182 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 183 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); 184 bool IsRegistered; 185 if (*InitsRef != nullptr) { 186 // Emit VarDecl with copy init for arrays. 187 auto *FD = CapturedStmtInfo->lookup(OrigVD); 188 LValue Base = MakeNaturalAlignAddrLValue( 189 CapturedStmtInfo->getContextValue(), 190 getContext().getTagDeclType(FD->getParent())); 191 auto OriginalAddr = EmitLValueForField(Base, FD); 192 auto VDInit = cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl()); 193 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * { 194 auto Emission = EmitAutoVarAlloca(*VD); 195 // Emit initialization of aggregate firstprivate vars. 196 EmitOMPAggregateAssign(OriginalAddr, Emission.getAllocatedAddress(), 197 VD->getInit(), (*IRef)->getType(), VDInit); 198 EmitAutoVarCleanups(Emission); 199 return Emission.getAllocatedAddress(); 200 }); 201 } else 202 IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * { 203 // Emit private VarDecl with copy init. 204 EmitDecl(*VD); 205 return GetAddrOfLocalVar(VD); 206 }); 207 assert(IsRegistered && "counter already registered as private"); 208 // Silence the warning about unused variable. 209 (void)IsRegistered; 210 ++IRef, ++InitsRef; 211 } 212 } 213 } 214 215 void CodeGenFunction::EmitOMPPrivateClause( 216 const OMPExecutableDirective &D, 217 CodeGenFunction::OMPPrivateScope &PrivateScope) { 218 auto PrivateFilter = [](const OMPClause *C) -> bool { 219 return C->getClauseKind() == OMPC_private; 220 }; 221 for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)> 222 I(D.clauses(), PrivateFilter); I; ++I) { 223 auto *C = cast<OMPPrivateClause>(*I); 224 auto IRef = C->varlist_begin(); 225 for (auto IInit : C->private_copies()) { 226 auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); 227 auto VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl()); 228 bool IsRegistered = 229 PrivateScope.addPrivate(OrigVD, [&]() -> llvm::Value * { 230 // Emit private VarDecl with copy init. 231 EmitDecl(*VD); 232 return GetAddrOfLocalVar(VD); 233 }); 234 assert(IsRegistered && "counter already registered as private"); 235 // Silence the warning about unused variable. 236 (void)IsRegistered; 237 ++IRef; 238 } 239 } 240 } 241 242 /// \brief Emits code for OpenMP parallel directive in the parallel region. 243 static void EmitOMPParallelCall(CodeGenFunction &CGF, 244 const OMPParallelDirective &S, 245 llvm::Value *OutlinedFn, 246 llvm::Value *CapturedStruct) { 247 if (auto C = S.getSingleClause(/*K*/ OMPC_num_threads)) { 248 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); 249 auto NumThreadsClause = cast<OMPNumThreadsClause>(C); 250 auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(), 251 /*IgnoreResultAssign*/ true); 252 CGF.CGM.getOpenMPRuntime().EmitOMPNumThreadsClause( 253 CGF, NumThreads, NumThreadsClause->getLocStart()); 254 } 255 CGF.CGM.getOpenMPRuntime().EmitOMPParallelCall(CGF, S.getLocStart(), 256 OutlinedFn, CapturedStruct); 257 } 258 259 void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { 260 auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 261 auto CapturedStruct = GenerateCapturedStmtArgument(*CS); 262 auto OutlinedFn = CGM.getOpenMPRuntime().EmitOpenMPOutlinedFunction( 263 S, *CS->getCapturedDecl()->param_begin()); 264 if (auto C = S.getSingleClause(/*K*/ OMPC_if)) { 265 auto Cond = cast<OMPIfClause>(C)->getCondition(); 266 EmitOMPIfClause(*this, Cond, [&](bool ThenBlock) { 267 if (ThenBlock) 268 EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct); 269 else 270 CGM.getOpenMPRuntime().EmitOMPSerialCall(*this, S.getLocStart(), 271 OutlinedFn, CapturedStruct); 272 }); 273 } else 274 EmitOMPParallelCall(*this, S, OutlinedFn, CapturedStruct); 275 } 276 277 void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S, 278 bool SeparateIter) { 279 RunCleanupsScope BodyScope(*this); 280 // Update counters values on current iteration. 281 for (auto I : S.updates()) { 282 EmitIgnoredExpr(I); 283 } 284 // On a continue in the body, jump to the end. 285 auto Continue = getJumpDestInCurrentScope("omp.body.continue"); 286 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue)); 287 // Emit loop body. 288 EmitStmt(S.getBody()); 289 // The end (updates/cleanups). 290 EmitBlock(Continue.getBlock()); 291 BreakContinueStack.pop_back(); 292 if (SeparateIter) { 293 // TODO: Update lastprivates if the SeparateIter flag is true. 294 // This will be implemented in a follow-up OMPLastprivateClause patch, but 295 // result should be still correct without it, as we do not make these 296 // variables private yet. 297 } 298 } 299 300 void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S, 301 OMPPrivateScope &LoopScope, 302 bool SeparateIter) { 303 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end"); 304 auto Cnt = getPGORegionCounter(&S); 305 306 // Start the loop with a block that tests the condition. 307 auto CondBlock = createBasicBlock("omp.inner.for.cond"); 308 EmitBlock(CondBlock); 309 LoopStack.push(CondBlock); 310 311 // If there are any cleanups between here and the loop-exit scope, 312 // create a block to stage a loop exit along. 313 auto ExitBlock = LoopExit.getBlock(); 314 if (LoopScope.requiresCleanups()) 315 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup"); 316 317 auto LoopBody = createBasicBlock("omp.inner.for.body"); 318 319 // Emit condition: "IV < LastIteration + 1 [ - 1]" 320 // ("- 1" when lastprivate clause is present - separate one iteration). 321 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter)); 322 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, 323 PGO.createLoopWeights(S.getCond(SeparateIter), Cnt)); 324 325 if (ExitBlock != LoopExit.getBlock()) { 326 EmitBlock(ExitBlock); 327 EmitBranchThroughCleanup(LoopExit); 328 } 329 330 EmitBlock(LoopBody); 331 Cnt.beginRegion(Builder); 332 333 // Create a block for the increment. 334 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc"); 335 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 336 337 EmitOMPLoopBody(S); 338 EmitStopPoint(&S); 339 340 // Emit "IV = IV + 1" and a back-edge to the condition block. 341 EmitBlock(Continue.getBlock()); 342 EmitIgnoredExpr(S.getInc()); 343 BreakContinueStack.pop_back(); 344 EmitBranch(CondBlock); 345 LoopStack.pop(); 346 // Emit the fall-through block. 347 EmitBlock(LoopExit.getBlock()); 348 } 349 350 void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) { 351 auto IC = S.counters().begin(); 352 for (auto F : S.finals()) { 353 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) { 354 EmitIgnoredExpr(F); 355 } 356 ++IC; 357 } 358 } 359 360 static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM, 361 const OMPAlignedClause &Clause) { 362 unsigned ClauseAlignment = 0; 363 if (auto AlignmentExpr = Clause.getAlignment()) { 364 auto AlignmentCI = 365 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr)); 366 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue()); 367 } 368 for (auto E : Clause.varlists()) { 369 unsigned Alignment = ClauseAlignment; 370 if (Alignment == 0) { 371 // OpenMP [2.8.1, Description] 372 // If no optional parameter is specified, implementation-defined default 373 // alignments for SIMD instructions on the target platforms are assumed. 374 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment( 375 E->getType()); 376 } 377 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && 378 "alignment is not power of 2"); 379 if (Alignment != 0) { 380 llvm::Value *PtrValue = CGF.EmitScalarExpr(E); 381 CGF.EmitAlignmentAssumption(PtrValue, Alignment); 382 } 383 } 384 } 385 386 static void EmitPrivateLoopCounters(CodeGenFunction &CGF, 387 CodeGenFunction::OMPPrivateScope &LoopScope, 388 ArrayRef<Expr *> Counters) { 389 for (auto *E : Counters) { 390 auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); 391 bool IsRegistered = LoopScope.addPrivate(VD, [&]() -> llvm::Value * { 392 // Emit var without initialization. 393 auto VarEmission = CGF.EmitAutoVarAlloca(*VD); 394 CGF.EmitAutoVarCleanups(VarEmission); 395 return VarEmission.getAllocatedAddress(); 396 }); 397 assert(IsRegistered && "counter already registered as private"); 398 // Silence the warning about unused variable. 399 (void)IsRegistered; 400 } 401 (void)LoopScope.Privatize(); 402 } 403 404 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { 405 // Pragma 'simd' code depends on presence of 'lastprivate'. 406 // If present, we have to separate last iteration of the loop: 407 // 408 // if (LastIteration != 0) { 409 // for (IV in 0..LastIteration-1) BODY; 410 // BODY with updates of lastprivate vars; 411 // <Final counter/linear vars updates>; 412 // } 413 // 414 // otherwise (when there's no lastprivate): 415 // 416 // for (IV in 0..LastIteration) BODY; 417 // <Final counter/linear vars updates>; 418 // 419 420 // Walk clauses and process safelen/lastprivate. 421 bool SeparateIter = false; 422 LoopStack.setParallel(); 423 LoopStack.setVectorizerEnable(true); 424 for (auto C : S.clauses()) { 425 switch (C->getClauseKind()) { 426 case OMPC_safelen: { 427 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(), 428 AggValueSlot::ignored(), true); 429 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); 430 LoopStack.setVectorizerWidth(Val->getZExtValue()); 431 // In presence of finite 'safelen', it may be unsafe to mark all 432 // the memory instructions parallel, because loop-carried 433 // dependences of 'safelen' iterations are possible. 434 LoopStack.setParallel(false); 435 break; 436 } 437 case OMPC_aligned: 438 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C)); 439 break; 440 case OMPC_lastprivate: 441 SeparateIter = true; 442 break; 443 default: 444 // Not handled yet 445 ; 446 } 447 } 448 449 InlinedOpenMPRegion Region(*this, S.getAssociatedStmt()); 450 RunCleanupsScope DirectiveScope(*this); 451 452 CGDebugInfo *DI = getDebugInfo(); 453 if (DI) 454 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); 455 456 // Emit the loop iteration variable. 457 const Expr *IVExpr = S.getIterationVariable(); 458 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); 459 EmitVarDecl(*IVDecl); 460 EmitIgnoredExpr(S.getInit()); 461 462 // Emit the iterations count variable. 463 // If it is not a variable, Sema decided to calculate iterations count on each 464 // iteration (e.g., it is foldable into a constant). 465 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 466 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 467 // Emit calculation of the iterations count. 468 EmitIgnoredExpr(S.getCalcLastIteration()); 469 } 470 471 if (SeparateIter) { 472 // Emit: if (LastIteration > 0) - begin. 473 RegionCounter Cnt = getPGORegionCounter(&S); 474 auto ThenBlock = createBasicBlock("simd.if.then"); 475 auto ContBlock = createBasicBlock("simd.if.end"); 476 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount()); 477 EmitBlock(ThenBlock); 478 Cnt.beginRegion(Builder); 479 // Emit 'then' code. 480 { 481 OMPPrivateScope LoopScope(*this); 482 EmitPrivateLoopCounters(*this, LoopScope, S.counters()); 483 EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true); 484 EmitOMPLoopBody(S, /* SeparateIter */ true); 485 } 486 EmitOMPSimdFinal(S); 487 // Emit: if (LastIteration != 0) - end. 488 EmitBranch(ContBlock); 489 EmitBlock(ContBlock, true); 490 } else { 491 { 492 OMPPrivateScope LoopScope(*this); 493 EmitPrivateLoopCounters(*this, LoopScope, S.counters()); 494 EmitOMPInnerLoop(S, LoopScope); 495 } 496 EmitOMPSimdFinal(S); 497 } 498 499 if (DI) 500 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); 501 } 502 503 /// \brief Emit a helper variable and return corresponding lvalue. 504 static LValue EmitOMPHelperVar(CodeGenFunction &CGF, 505 const DeclRefExpr *Helper) { 506 auto VDecl = cast<VarDecl>(Helper->getDecl()); 507 CGF.EmitVarDecl(*VDecl); 508 return CGF.EmitLValue(Helper); 509 } 510 511 void CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { 512 // Emit the loop iteration variable. 513 auto IVExpr = cast<DeclRefExpr>(S.getIterationVariable()); 514 auto IVDecl = cast<VarDecl>(IVExpr->getDecl()); 515 EmitVarDecl(*IVDecl); 516 517 // Emit the iterations count variable. 518 // If it is not a variable, Sema decided to calculate iterations count on each 519 // iteration (e.g., it is foldable into a constant). 520 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 521 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 522 // Emit calculation of the iterations count. 523 EmitIgnoredExpr(S.getCalcLastIteration()); 524 } 525 526 auto &RT = CGM.getOpenMPRuntime(); 527 528 // Check pre-condition. 529 { 530 // Skip the entire loop if we don't meet the precondition. 531 RegionCounter Cnt = getPGORegionCounter(&S); 532 auto ThenBlock = createBasicBlock("omp.precond.then"); 533 auto ContBlock = createBasicBlock("omp.precond.end"); 534 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount()); 535 EmitBlock(ThenBlock); 536 Cnt.beginRegion(Builder); 537 // Emit 'then' code. 538 { 539 // Emit helper vars inits. 540 LValue LB = 541 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable())); 542 LValue UB = 543 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable())); 544 LValue ST = 545 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); 546 LValue IL = 547 EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); 548 549 OMPPrivateScope LoopScope(*this); 550 EmitPrivateLoopCounters(*this, LoopScope, S.counters()); 551 552 // Detect the loop schedule kind and chunk. 553 auto ScheduleKind = OMPC_SCHEDULE_unknown; 554 llvm::Value *Chunk = nullptr; 555 if (auto C = cast_or_null<OMPScheduleClause>( 556 S.getSingleClause(OMPC_schedule))) { 557 ScheduleKind = C->getScheduleKind(); 558 if (auto Ch = C->getChunkSize()) { 559 Chunk = EmitScalarExpr(Ch); 560 Chunk = EmitScalarConversion(Chunk, Ch->getType(), 561 S.getIterationVariable()->getType()); 562 } 563 } 564 const unsigned IVSize = getContext().getTypeSize(IVExpr->getType()); 565 const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation(); 566 if (RT.isStaticNonchunked(ScheduleKind, 567 /* Chunked */ Chunk != nullptr)) { 568 // OpenMP [2.7.1, Loop Construct, Description, table 2-1] 569 // When no chunk_size is specified, the iteration space is divided into 570 // chunks that are approximately equal in size, and at most one chunk is 571 // distributed to each thread. Note that the size of the chunks is 572 // unspecified in this case. 573 RT.EmitOMPForInit(*this, S.getLocStart(), ScheduleKind, IVSize, IVSigned, 574 IL.getAddress(), LB.getAddress(), UB.getAddress(), 575 ST.getAddress()); 576 // UB = min(UB, GlobalUB); 577 EmitIgnoredExpr(S.getEnsureUpperBound()); 578 // IV = LB; 579 EmitIgnoredExpr(S.getInit()); 580 // while (idx <= UB) { BODY; ++idx; } 581 EmitOMPInnerLoop(S, LoopScope); 582 // Tell the runtime we are done. 583 RT.EmitOMPForFinish(*this, S.getLocStart(), ScheduleKind); 584 } else 585 ErrorUnsupported(&S, "OpenMP loop with requested schedule"); 586 } 587 // We're now done with the loop, so jump to the continuation block. 588 EmitBranch(ContBlock); 589 EmitBlock(ContBlock, true); 590 } 591 } 592 593 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { 594 InlinedOpenMPRegion Region(*this, S.getAssociatedStmt()); 595 RunCleanupsScope DirectiveScope(*this); 596 597 CGDebugInfo *DI = getDebugInfo(); 598 if (DI) 599 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); 600 601 EmitOMPWorksharingLoop(S); 602 603 // Emit an implicit barrier at the end. 604 CGM.getOpenMPRuntime().EmitOMPBarrierCall(*this, S.getLocStart(), 605 /*IsExplicit*/ false); 606 if (DI) 607 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); 608 } 609 610 void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) { 611 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet."); 612 } 613 614 void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) { 615 llvm_unreachable("CodeGen for 'omp sections' is not supported yet."); 616 } 617 618 void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) { 619 llvm_unreachable("CodeGen for 'omp section' is not supported yet."); 620 } 621 622 void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) { 623 llvm_unreachable("CodeGen for 'omp single' is not supported yet."); 624 } 625 626 void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) { 627 CGM.getOpenMPRuntime().EmitOMPMasterRegion(*this, [&]() -> void { 628 InlinedOpenMPRegion Region(*this, S.getAssociatedStmt()); 629 RunCleanupsScope Scope(*this); 630 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 631 EnsureInsertPoint(); 632 }, S.getLocStart()); 633 } 634 635 void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { 636 CGM.getOpenMPRuntime().EmitOMPCriticalRegion( 637 *this, S.getDirectiveName().getAsString(), [&]() -> void { 638 InlinedOpenMPRegion Region(*this, S.getAssociatedStmt()); 639 RunCleanupsScope Scope(*this); 640 EmitStmt( 641 cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 642 EnsureInsertPoint(); 643 }, S.getLocStart()); 644 } 645 646 void 647 CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) { 648 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet."); 649 } 650 651 void CodeGenFunction::EmitOMPParallelForSimdDirective( 652 const OMPParallelForSimdDirective &) { 653 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet."); 654 } 655 656 void CodeGenFunction::EmitOMPParallelSectionsDirective( 657 const OMPParallelSectionsDirective &) { 658 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet."); 659 } 660 661 void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) { 662 llvm_unreachable("CodeGen for 'omp task' is not supported yet."); 663 } 664 665 void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) { 666 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet."); 667 } 668 669 void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) { 670 CGM.getOpenMPRuntime().EmitOMPBarrierCall(*this, S.getLocStart()); 671 } 672 673 void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) { 674 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet."); 675 } 676 677 void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) { 678 CGM.getOpenMPRuntime().EmitOMPFlush( 679 *this, [&]() -> ArrayRef<const Expr *> { 680 if (auto C = S.getSingleClause(/*K*/ OMPC_flush)) { 681 auto FlushClause = cast<OMPFlushClause>(C); 682 return llvm::makeArrayRef(FlushClause->varlist_begin(), 683 FlushClause->varlist_end()); 684 } 685 return llvm::None; 686 }(), 687 S.getLocStart()); 688 } 689 690 void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) { 691 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet."); 692 } 693 694 void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) { 695 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet."); 696 } 697 698 void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) { 699 llvm_unreachable("CodeGen for 'omp target' is not supported yet."); 700 } 701 702 void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &) { 703 llvm_unreachable("CodeGen for 'omp teams' is not supported yet."); 704 } 705 706