void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt()); const Stmt *Body = CS->getCapturedStmt(); 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; } default: // Not handled yet ; } } EmitStmt(Body); }
OMPSimdDirective *OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *)); OMPSimdDirective *Dir = new (Mem) OMPSimdDirective(StartLoc, EndLoc, 1, Clauses.size()); Dir->setClauses(Clauses); Dir->setAssociatedStmt(AssociatedStmt); return Dir; }
OMPSimdDirective * OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs) { unsigned Size = llvm::alignTo(sizeof(OMPSimdDirective), llvm::alignOf<OMPClause *>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *) * numLoopChildren(CollapsedNum, OMPD_simd)); OMPSimdDirective *Dir = new (Mem) OMPSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size()); Dir->setClauses(Clauses); Dir->setAssociatedStmt(AssociatedStmt); Dir->setIterationVariable(Exprs.IterationVarRef); Dir->setLastIteration(Exprs.LastIteration); Dir->setCalcLastIteration(Exprs.CalcLastIteration); Dir->setPreCond(Exprs.PreCond); Dir->setCond(Exprs.Cond); Dir->setInit(Exprs.Init); Dir->setInc(Exprs.Inc); Dir->setCounters(Exprs.Counters); Dir->setPrivateCounters(Exprs.PrivateCounters); Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); return Dir; }
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()); }