void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { InlinedOpenMPRegion Region(*this, S.getAssociatedStmt()); RunCleanupsScope DirectiveScope(*this); CGDebugInfo *DI = getDebugInfo(); if (DI) DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); EmitOMPWorksharingLoop(S); // Emit an implicit barrier at the end. CGM.getOpenMPRuntime().EmitOMPBarrierCall(*this, S.getLocStart(), /*IsExplicit*/ false); if (DI) DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); }
void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { // Pragma 'simd' code depends on presence of 'lastprivate'. // If present, we have to separate last iteration of the loop: // // if (LastIteration != 0) { // for (IV in 0..LastIteration-1) BODY; // BODY with updates of lastprivate vars; // <Final counter/linear vars updates>; // } // // otherwise (when there's no lastprivate): // // for (IV in 0..LastIteration) BODY; // <Final counter/linear vars updates>; // // Walk clauses and process safelen/lastprivate. bool SeparateIter = false; LoopStack.setParallel(); LoopStack.setVectorizerEnable(true); for (auto C : S.clauses()) { switch (C->getClauseKind()) { case OMPC_safelen: { RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(), AggValueSlot::ignored(), true); llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal()); LoopStack.setVectorizerWidth(Val->getZExtValue()); // In presence of finite 'safelen', it may be unsafe to mark all // the memory instructions parallel, because loop-carried // dependences of 'safelen' iterations are possible. LoopStack.setParallel(false); break; } case OMPC_aligned: EmitOMPAlignedClause(*this, CGM, cast<OMPAlignedClause>(*C)); break; case OMPC_lastprivate: SeparateIter = true; break; default: // Not handled yet ; } } RunCleanupsScope DirectiveScope(*this); CGDebugInfo *DI = getDebugInfo(); if (DI) DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); // Emit the loop iteration variable. const Expr *IVExpr = S.getIterationVariable(); const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl()); EmitVarDecl(*IVDecl); EmitIgnoredExpr(S.getInit()); // Emit the iterations count variable. // If it is not a variable, Sema decided to calculate iterations count on each // iteration (e.g., it is foldable into a constant). if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) { EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl())); // Emit calculation of the iterations count. EmitIgnoredExpr(S.getCalcLastIteration()); } if (SeparateIter) { // Emit: if (LastIteration > 0) - begin. RegionCounter Cnt = getPGORegionCounter(&S); auto ThenBlock = createBasicBlock("simd.if.then"); auto ContBlock = createBasicBlock("simd.if.end"); EmitBranchOnBoolExpr(S.getPreCond(), ThenBlock, ContBlock, Cnt.getCount()); EmitBlock(ThenBlock); Cnt.beginRegion(Builder); // Emit 'then' code. { OMPPrivateScope LoopScope(*this); EmitPrivateLoopCounters(*this, LoopScope, S.counters()); EmitOMPInnerLoop(S, LoopScope, /* SeparateIter */ true); EmitOMPLoopBody(S, /* SeparateIter */ true); } EmitOMPSimdFinal(S); // Emit: if (LastIteration != 0) - end. EmitBranch(ContBlock); EmitBlock(ContBlock, true); } else { { OMPPrivateScope LoopScope(*this); EmitPrivateLoopCounters(*this, LoopScope, S.counters()); EmitOMPInnerLoop(S, LoopScope); } EmitOMPSimdFinal(S); } if (DI) DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); }
void CodeGenFunction::EmitUPCForAllStmt(const UPCForAllStmt &S) { JumpDest LoopExit = getJumpDestInCurrentScope("upc_forall.end"); RunCleanupsScope ForScope(*this); llvm::Value *Depth = 0; if (S.getAfnty()) { Address DepthAddr = getUPCForAllDepth(CGM); Depth = Builder.CreateLoad(DepthAddr); Builder.CreateStore(Builder.CreateNUWAdd(Depth, llvm::ConstantInt::get(IntTy, 1), "upc_forall.inc_depth"), DepthAddr); EHStack.pushCleanup<UPCForAllCleanup>(NormalAndEHCleanup, Depth); } CGDebugInfo *DI = getDebugInfo(); if (DI) DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin()); // Evaluate the first part before the loop. if (S.getInit()) EmitStmt(S.getInit()); // Start the loop with a block that tests the condition. // If there's an increment, the continue scope will be overwritten // later. JumpDest Continue = getJumpDestInCurrentScope("upc_forall.cond"); llvm::BasicBlock *CondBlock = Continue.getBlock(); EmitBlock(CondBlock); // Create a cleanup scope for the condition variable cleanups. RunCleanupsScope ConditionScope(*this); llvm::Value *BoolCondVal = 0; if (S.getCond()) { // If the for statement has a condition scope, emit the local variable // declaration. llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); if (S.getConditionVariable()) { EmitAutoVarDecl(*S.getConditionVariable()); } // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. if (ForScope.requiresCleanups()) ExitBlock = createBasicBlock("upcforall.cond.cleanup"); // As long as the condition is true, iterate the loop. llvm::BasicBlock *ForBody = createBasicBlock("upc_forall.filter"); // C99 6.8.5p2/p4: The first substatement is executed if the expression // compares unequal to 0. The condition must be a scalar type. BoolCondVal = EvaluateExprAsBool(S.getCond()); Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock); if (ExitBlock != LoopExit.getBlock()) { EmitBlock(ExitBlock); EmitBranchThroughCleanup(LoopExit); } EmitBlock(ForBody); } else { // Treat it as a non-zero constant. Don't even create a new block for the // body, just fall into it. } // If the for loop doesn't have an increment we can just use the // condition as the continue block. Otherwise we'll need to create // a block for it (in the current scope, i.e. in the scope of the // condition), and that we will become our continue block. if (S.getInc()) Continue = getJumpDestInCurrentScope("upc_forall.inc"); // Store the blocks to use for break and continue. BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); if (const Expr *Afnty = S.getAfnty()) { llvm::Value *Affinity = EmitScalarExpr(Afnty); if (Afnty->getType()->hasPointerToSharedRepresentation()) { // get threadof Affinity = EmitUPCPointerGetThread(Affinity); } else { assert(Affinity->getType()->isIntegerTy()); llvm::Value *Threads = EmitUPCThreads(); if (cast<llvm::IntegerType>(Threads->getType())->getBitWidth() < cast<llvm::IntegerType>(Affinity->getType())->getBitWidth()) { Threads = Builder.CreateIntCast(Threads, Affinity->getType(), false); } else { Affinity = Builder.CreateIntCast(Affinity, Threads->getType(), Afnty->getType()->hasSignedIntegerRepresentation()); } if (Afnty->getType()->hasSignedIntegerRepresentation()) { Affinity = Builder.CreateSRem(Affinity, Threads); llvm::Value *Zero = llvm::ConstantInt::get(Affinity->getType(), 0); Affinity = Builder.CreateSelect(Builder.CreateICmpSLT(Affinity, Zero), Builder.CreateAdd(Affinity, Threads), Affinity); } else { Affinity = Builder.CreateURem(Affinity, Threads); } } Affinity = Builder.CreateIntCast(Affinity, IntTy, false); llvm::Value *MyThread = EmitUPCMyThread(); llvm::Value *Test = Builder.CreateOr(Builder.CreateICmpUGT(Depth, llvm::ConstantInt::get(IntTy, 0)), Builder.CreateICmpEQ(Affinity, MyThread)); llvm::BasicBlock *RealBody = createBasicBlock("upc_forall.body"); Builder.CreateCondBr(Test, RealBody, Continue.getBlock()); EmitBlock(RealBody); } { // Create a separate cleanup scope for the body, in case it is not // a compound statement. RunCleanupsScope BodyScope(*this); EmitStmt(S.getBody()); } // If there is an increment, emit it next. if (S.getInc()) { EmitBlock(Continue.getBlock()); EmitStmt(S.getInc()); } BreakContinueStack.pop_back(); ConditionScope.ForceCleanup(); EmitBranch(CondBlock); ForScope.ForceCleanup(); if (DI) DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd()); // Emit the fall-through block. EmitBlock(LoopExit.getBlock(), true); }