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 "clang/AST/Stmt.h" 18 #include "clang/AST/StmtOpenMP.h" 19 #include "TargetInfo.h" 20 using namespace clang; 21 using namespace CodeGen; 22 23 //===----------------------------------------------------------------------===// 24 // OpenMP Directive Emission 25 //===----------------------------------------------------------------------===// 26 27 void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { 28 const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt()); 29 llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS); 30 31 llvm::Value *OutlinedFn; 32 { 33 CodeGenFunction CGF(CGM, true); 34 CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind()); 35 CGF.CapturedStmtInfo = &CGInfo; 36 OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS); 37 } 38 39 // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/) 40 llvm::Value *Args[] = { 41 CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()), 42 Builder.getInt32(1), // Number of arguments after 'microtask' argument 43 // (there is only one additional argument - 'context') 44 Builder.CreateBitCast(OutlinedFn, 45 CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()), 46 EmitCastToVoidPtr(CapturedStruct)}; 47 llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction( 48 CGOpenMPRuntime::OMPRTL__kmpc_fork_call); 49 EmitRuntimeCall(RTLFn, Args); 50 } 51 52 void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S, 53 bool SeparateIter) { 54 RunCleanupsScope BodyScope(*this); 55 // Update counters values on current iteration. 56 for (auto I : S.updates()) { 57 EmitIgnoredExpr(I); 58 } 59 // On a continue in the body, jump to the end. 60 auto Continue = getJumpDestInCurrentScope("omp.body.continue"); 61 BreakContinueStack.push_back(BreakContinue(JumpDest(), Continue)); 62 // Emit loop body. 63 EmitStmt(S.getBody()); 64 // The end (updates/cleanups). 65 EmitBlock(Continue.getBlock()); 66 BreakContinueStack.pop_back(); 67 if (SeparateIter) { 68 // TODO: Update lastprivates if the SeparateIter flag is true. 69 // This will be implemented in a follow-up OMPLastprivateClause patch, but 70 // result should be still correct without it, as we do not make these 71 // variables private yet. 72 } 73 } 74 75 void CodeGenFunction::EmitOMPInnerLoop(const OMPLoopDirective &S, 76 OMPPrivateScope &LoopScope, 77 bool SeparateIter) { 78 auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end"); 79 auto Cnt = getPGORegionCounter(&S); 80 81 // Start the loop with a block that tests the condition. 82 auto CondBlock = createBasicBlock("omp.inner.for.cond"); 83 EmitBlock(CondBlock); 84 LoopStack.push(CondBlock); 85 86 // If there are any cleanups between here and the loop-exit scope, 87 // create a block to stage a loop exit along. 88 auto ExitBlock = LoopExit.getBlock(); 89 if (LoopScope.requiresCleanups()) 90 ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup"); 91 92 auto LoopBody = createBasicBlock("omp.inner.for.body"); 93 94 // Emit condition: "IV < LastIteration + 1 [ - 1]" 95 // ("- 1" when lastprivate clause is present - separate one iteration). 96 llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond(SeparateIter)); 97 Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock, 98 PGO.createLoopWeights(S.getCond(SeparateIter), Cnt)); 99 100 if (ExitBlock != LoopExit.getBlock()) { 101 EmitBlock(ExitBlock); 102 EmitBranchThroughCleanup(LoopExit); 103 } 104 105 EmitBlock(LoopBody); 106 Cnt.beginRegion(Builder); 107 108 // Create a block for the increment. 109 auto Continue = getJumpDestInCurrentScope("omp.inner.for.inc"); 110 BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); 111 112 EmitOMPLoopBody(S); 113 EmitStopPoint(&S); 114 115 // Emit "IV = IV + 1" and a back-edge to the condition block. 116 EmitBlock(Continue.getBlock()); 117 EmitIgnoredExpr(S.getInc()); 118 BreakContinueStack.pop_back(); 119 EmitBranch(CondBlock); 120 LoopStack.pop(); 121 // Emit the fall-through block. 122 EmitBlock(LoopExit.getBlock()); 123 } 124 125 void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) { 126 auto IC = S.counters().begin(); 127 for (auto F : S.finals()) { 128 if (LocalDeclMap.lookup(cast<DeclRefExpr>((*IC))->getDecl())) { 129 EmitIgnoredExpr(F); 130 } 131 ++IC; 132 } 133 } 134 135 static void EmitOMPAlignedClause(CodeGenFunction &CGF, CodeGenModule &CGM, 136 const OMPAlignedClause &Clause) { 137 unsigned ClauseAlignment = 0; 138 if (auto AlignmentExpr = Clause.getAlignment()) { 139 auto AlignmentCI = 140 cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr)); 141 ClauseAlignment = static_cast<unsigned>(AlignmentCI->getZExtValue()); 142 } 143 for (auto E : Clause.varlists()) { 144 unsigned Alignment = ClauseAlignment; 145 if (Alignment == 0) { 146 // OpenMP [2.8.1, Description] 147 // If no optional parameter isspecified, implementation-defined default 148 // alignments for SIMD instructions on the target platforms are assumed. 149 Alignment = CGM.getTargetCodeGenInfo().getOpenMPSimdDefaultAlignment( 150 E->getType()); 151 } 152 assert((Alignment == 0 || llvm::isPowerOf2_32(Alignment)) && 153 "alignment is not power of 2"); 154 if (Alignment != 0) { 155 llvm::Value *PtrValue = CGF.EmitScalarExpr(E); 156 CGF.EmitAlignmentAssumption(PtrValue, Alignment); 157 } 158 } 159 } 160 161 void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { 162 // Pragma 'simd' code depends on presence of 'lastprivate'. 163 // If present, we have to separate last iteration of the loop: 164 // 165 // if (LastIteration != 0) { 166 // for (IV in 0..LastIteration-1) BODY; 167 // BODY with updates of lastprivate vars; 168 // <Final counter/linear vars updates>; 169 // } 170 // 171 // otherwise (when there's no lastprivate): 172 // 173 // for (IV in 0..LastIteration) BODY; 174 // <Final counter/linear vars updates>; 175 // 176 177 // Walk clauses and process safelen/lastprivate. 178 bool SeparateIter = false; 179 LoopStack.setParallel(); 180 LoopStack.setVectorizerEnable(true); 181 for (auto C : S.clauses()) { 182 switch (C->getClauseKind()) { 183 case OMPC_safelen: { 184 RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(), 185 AggValueSlot::ignored(), true); 186 llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); 187 LoopStack.setVectorizerWidth(Val->getZExtValue()); 188 // In presence of finite 'safelen', it may be unsafe to mark all 189 // the memory instructions parallel, because loop-carried 190 // dependences of 'safelen' iterations are possible. 191 LoopStack.setParallel(false); 192 break; 193 } 194 case OMPC_aligned: 195 EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C)); 196 break; 197 case OMPC_lastprivate: 198 SeparateIter = true; 199 break; 200 default: 201 // Not handled yet 202 ; 203 } 204 } 205 206 RunCleanupsScope DirectiveScope(*this); 207 208 CGDebugInfo *DI = getDebugInfo(); 209 if (DI) 210 DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); 211 212 // Emit the loop iteration variable. 213 const Expr *IVExpr = S.getIterationVariable(); 214 const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); 215 EmitVarDecl(*IVDecl); 216 EmitIgnoredExpr(S.getInit()); 217 218 // Emit the iterations count variable. 219 // If it is not a variable, Sema decided to calculate iterations count on each 220 // iteration (e.g., it is foldable into a constant). 221 if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { 222 EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); 223 // Emit calculation of the iterations count. 224 EmitIgnoredExpr(S.getCalcLastIteration()); 225 } 226 227 if (SeparateIter) { 228 // Emit: if (LastIteration > 0) - begin. 229 RegionCounter Cnt = getPGORegionCounter(&S); 230 auto ThenBlock = createBasicBlock("simd.if.then"); 231 auto ContBlock = createBasicBlock("simd.if.end"); 232 EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount()); 233 EmitBlock(ThenBlock); 234 Cnt.beginRegion(Builder); 235 // Emit 'then' code. 236 { 237 OMPPrivateScope LoopScope(*this); 238 LoopScope.addPrivates(S.counters()); 239 EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true); 240 EmitOMPLoopBody(S, /* SeparateIter */ true); 241 } 242 EmitOMPSimdFinal(S); 243 // Emit: if (LastIteration != 0) - end. 244 EmitBranch(ContBlock); 245 EmitBlock(ContBlock, true); 246 } else { 247 { 248 OMPPrivateScope LoopScope(*this); 249 LoopScope.addPrivates(S.counters()); 250 EmitOMPInnerLoop(S, LoopScope); 251 } 252 EmitOMPSimdFinal(S); 253 } 254 255 if (DI) 256 DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); 257 } 258 259 void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) { 260 llvm_unreachable("CodeGen for 'omp for' is not supported yet."); 261 } 262 263 void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &) { 264 llvm_unreachable("CodeGen for 'omp for simd' is not supported yet."); 265 } 266 267 void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) { 268 llvm_unreachable("CodeGen for 'omp sections' is not supported yet."); 269 } 270 271 void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) { 272 llvm_unreachable("CodeGen for 'omp section' is not supported yet."); 273 } 274 275 void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) { 276 llvm_unreachable("CodeGen for 'omp single' is not supported yet."); 277 } 278 279 void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) { 280 llvm_unreachable("CodeGen for 'omp master' is not supported yet."); 281 } 282 283 void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) { 284 // __kmpc_critical(); 285 // <captured_body> 286 // __kmpc_end_critical(); 287 // 288 289 auto Lock = CGM.getOpenMPRuntime().GetCriticalRegionLock( 290 S.getDirectiveName().getAsString()); 291 CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock, 292 S.getLocStart()); 293 { 294 RunCleanupsScope Scope(*this); 295 EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); 296 EnsureInsertPoint(); 297 } 298 CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd()); 299 } 300 301 void 302 CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) { 303 llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet."); 304 } 305 306 void CodeGenFunction::EmitOMPParallelForSimdDirective( 307 const OMPParallelForSimdDirective &) { 308 llvm_unreachable("CodeGen for 'omp parallel for simd' is not supported yet."); 309 } 310 311 void CodeGenFunction::EmitOMPParallelSectionsDirective( 312 const OMPParallelSectionsDirective &) { 313 llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet."); 314 } 315 316 void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) { 317 llvm_unreachable("CodeGen for 'omp task' is not supported yet."); 318 } 319 320 void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) { 321 llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet."); 322 } 323 324 void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) { 325 llvm_unreachable("CodeGen for 'omp barrier' is not supported yet."); 326 } 327 328 void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) { 329 llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet."); 330 } 331 332 void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) { 333 llvm_unreachable("CodeGen for 'omp flush' is not supported yet."); 334 } 335 336 void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &) { 337 llvm_unreachable("CodeGen for 'omp ordered' is not supported yet."); 338 } 339 340 void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &) { 341 llvm_unreachable("CodeGen for 'omp atomic' is not supported yet."); 342 } 343 344 void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &) { 345 llvm_unreachable("CodeGen for 'omp target' is not supported yet."); 346 } 347 348