diff options
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 466 |
1 files changed, 184 insertions, 282 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index d58f91104fe..c1233d8278f 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1028,9 +1028,9 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { PopExpressionEvaluationContext(); } -static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, - Expr *NumIterations, Sema &SemaRef, - Scope *S); +static bool +FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, + Expr *NumIterations, Sema &SemaRef, Scope *S); namespace { @@ -1708,10 +1708,11 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { } static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, - Expr *CaptureExpr, bool WithInit) { + Expr *CaptureExpr, bool WithInit, + bool AsExpression) { assert(CaptureExpr); ASTContext &C = S.getASTContext(); - Expr *Init = CaptureExpr->IgnoreImpCasts(); + Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); QualType Ty = Init->getType(); if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { if (S.getLangOpts().CPlusPlus) @@ -1741,17 +1742,28 @@ static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, if (auto *VD = S.IsOpenMPCapturedDecl(D)) CD = cast<OMPCapturedExprDecl>(VD); else - CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit); + CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, + /*AsExpression=*/false); return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), SourceLocation()); } -static DeclRefExpr *buildCapture(Sema &S, Expr *CaptureExpr) { - auto *CD = - buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), - CaptureExpr, /*WithInit=*/true); - return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), - SourceLocation()); +static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { + if (!Ref) { + auto *CD = + buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), + CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); + Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), + CaptureExpr->getExprLoc()); + } + ExprResult Res = Ref; + if (!S.getLangOpts().CPlusPlus && + CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && + Ref->getType()->isPointerType()) + Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); + if (!Res.isUsable()) + return ExprError(); + return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); } StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, @@ -3251,9 +3263,12 @@ public: /// \brief True if the step should be subtracted. bool ShouldSubtractStep() const { return SubtractStep; } /// \brief Build the expression to calculate the number of iterations. - Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; + Expr * + BuildNumIterations(Scope *S, const bool LimitedType, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; /// \brief Build the precondition expression for the loops. - Expr *BuildPreCond(Scope *S, Expr *Cond) const; + Expr *BuildPreCond(Scope *S, Expr *Cond, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; /// \brief Build reference expression to the counter be used for codegen. Expr *BuildCounterVar() const; /// \brief Build reference expression to the private counter be used for @@ -3613,62 +3628,26 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { return true; } -namespace { -// Transform variables declared in GNU statement expressions to new ones to -// avoid crash on codegen. -class TransformToNewDefs : public TreeTransform<TransformToNewDefs> { - typedef TreeTransform<TransformToNewDefs> BaseTransform; - -public: - TransformToNewDefs(Sema &SemaRef) : BaseTransform(SemaRef) {} - - Decl *TransformDefinition(SourceLocation Loc, Decl *D) { - if (auto *VD = cast<VarDecl>(D)) - if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) && - !isa<ImplicitParamDecl>(D)) { - auto *NewVD = VarDecl::Create( - SemaRef.Context, VD->getDeclContext(), VD->getLocStart(), - VD->getLocation(), VD->getIdentifier(), VD->getType(), - VD->getTypeSourceInfo(), VD->getStorageClass()); - NewVD->setTSCSpec(VD->getTSCSpec()); - NewVD->setInit(VD->getInit()); - NewVD->setInitStyle(VD->getInitStyle()); - NewVD->setExceptionVariable(VD->isExceptionVariable()); - NewVD->setNRVOVariable(VD->isNRVOVariable()); - NewVD->setCXXForRangeDecl(VD->isCXXForRangeDecl()); - NewVD->setConstexpr(VD->isConstexpr()); - NewVD->setInitCapture(VD->isInitCapture()); - NewVD->setPreviousDeclInSameBlockScope( - VD->isPreviousDeclInSameBlockScope()); - VD->getDeclContext()->addHiddenDecl(NewVD); - if (VD->hasAttrs()) - NewVD->setAttrs(VD->getAttrs()); - transformedLocalDecl(VD, NewVD); - return NewVD; - } - return BaseTransform::TransformDefinition(Loc, D); - } - - ExprResult TransformDeclRefExpr(DeclRefExpr *E) { - if (auto *NewD = TransformDecl(E->getExprLoc(), E->getDecl())) - if (E->getDecl() != NewD) { - NewD->setReferenced(); - NewD->markUsed(SemaRef.Context); - return DeclRefExpr::Create( - SemaRef.Context, E->getQualifierLoc(), E->getTemplateKeywordLoc(), - cast<ValueDecl>(NewD), E->refersToEnclosingVariableOrCapture(), - E->getNameInfo(), E->getType(), E->getValueKind()); - } - return BaseTransform::TransformDeclRefExpr(E); - } -}; +static ExprResult +tryBuildCapture(Sema &SemaRef, Expr *Capture, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { + if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) + return SemaRef.PerformImplicitConversion( + Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, + /*AllowExplicit=*/true); + auto I = Captures.find(Capture); + if (I != Captures.end()) + return buildCapture(SemaRef, Capture, I->second); + DeclRefExpr *Ref = nullptr; + ExprResult Res = buildCapture(SemaRef, Capture, Ref); + Captures[Capture] = Ref; + return Res; } /// \brief Build the expression to calculate the number of iterations. -Expr * -OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, - const bool LimitedType) const { - TransformToNewDefs Transform(SemaRef); +Expr *OpenMPIterationSpaceChecker::BuildNumIterations( + Scope *S, const bool LimitedType, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { ExprResult Diff; auto VarType = Var->getType().getNonReferenceType(); if (VarType->isIntegerType() || VarType->isPointerType() || @@ -3676,24 +3655,8 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, // Upper - Lower auto *UBExpr = TestIsLessOp ? UB : LB; auto *LBExpr = TestIsLessOp ? LB : UB; - Expr *Upper = Transform.TransformExpr(UBExpr).get(); - Expr *Lower = Transform.TransformExpr(LBExpr).get(); - if (!Upper || !Lower) - return nullptr; - if (!SemaRef.Context.hasSameType(Upper->getType(), UBExpr->getType())) { - Upper = SemaRef - .PerformImplicitConversion(Upper, UBExpr->getType(), - Sema::AA_Converting, - /*AllowExplicit=*/true) - .get(); - } - if (!SemaRef.Context.hasSameType(Lower->getType(), LBExpr->getType())) { - Lower = SemaRef - .PerformImplicitConversion(Lower, LBExpr->getType(), - Sema::AA_Converting, - /*AllowExplicit=*/true) - .get(); - } + Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); + Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); if (!Upper || !Lower) return nullptr; @@ -3720,18 +3683,9 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, return nullptr; // Upper - Lower [- 1] + Step - auto *StepNoImp = Step->IgnoreImplicit(); - auto NewStep = Transform.TransformExpr(StepNoImp); - if (NewStep.isInvalid()) + auto NewStep = tryBuildCapture(SemaRef, Step, Captures); + if (!NewStep.isUsable()) return nullptr; - if (!SemaRef.Context.hasSameType(NewStep.get()->getType(), - StepNoImp->getType())) { - NewStep = SemaRef.PerformImplicitConversion( - NewStep.get(), StepNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStep.isInvalid()) - return nullptr; - } Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); if (!Diff.isUsable()) return nullptr; @@ -3742,17 +3696,6 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, return nullptr; // (Upper - Lower [- 1] + Step) / Step - NewStep = Transform.TransformExpr(StepNoImp); - if (NewStep.isInvalid()) - return nullptr; - if (!SemaRef.Context.hasSameType(NewStep.get()->getType(), - StepNoImp->getType())) { - NewStep = SemaRef.PerformImplicitConversion( - NewStep.get(), StepNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStep.isInvalid()) - return nullptr; - } Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); if (!Diff.isUsable()) return nullptr; @@ -3798,35 +3741,25 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, return Diff.get(); } -Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { +Expr *OpenMPIterationSpaceChecker::BuildPreCond( + Scope *S, Expr *Cond, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { // Try to build LB <op> UB, where <op> is <, >, <=, or >=. bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); - TransformToNewDefs Transform(SemaRef); - - auto NewLB = Transform.TransformExpr(LB); - auto NewUB = Transform.TransformExpr(UB); - if (NewLB.isInvalid() || NewUB.isInvalid()) - return Cond; - if (!SemaRef.Context.hasSameType(NewLB.get()->getType(), LB->getType())) { - NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(), - Sema::AA_Converting, - /*AllowExplicit=*/true); - } - if (!SemaRef.Context.hasSameType(NewUB.get()->getType(), UB->getType())) { - NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(), - Sema::AA_Converting, - /*AllowExplicit=*/true); - } - if (NewLB.isInvalid() || NewUB.isInvalid()) - return Cond; + + auto NewLB = tryBuildCapture(SemaRef, LB, Captures); + auto NewUB = tryBuildCapture(SemaRef, UB, Captures); + if (!NewLB.isUsable() || !NewUB.isUsable()) + return nullptr; + auto CondExpr = SemaRef.BuildBinOp( S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) : (TestIsStrictOp ? BO_GT : BO_GE), NewLB.get(), NewUB.get()); if (CondExpr.isUsable()) { - if (!SemaRef.Context.hasSameType(CondExpr.get()->getType(), - SemaRef.Context.BoolTy)) + if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), + SemaRef.Context.BoolTy)) CondExpr = SemaRef.PerformImplicitConversion( CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, /*AllowExplicit=*/true); @@ -3909,7 +3842,8 @@ static bool CheckOpenMPIterationSpace( unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, - LoopIterationSpace &ResultIterSpace) { + LoopIterationSpace &ResultIterSpace, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { // OpenMP [2.6, Canonical Loop Form] // for (init-expr; test-expr; incr-expr) structured-block auto For = dyn_cast_or_null<ForStmt>(S); @@ -4027,11 +3961,13 @@ static bool CheckOpenMPIterationSpace( return HasErrors; // Build the loop's iteration space representation. - ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond()); + ResultIterSpace.PreCond = + ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); ResultIterSpace.NumIterations = ISC.BuildNumIterations( - DSA.getCurScope(), (isOpenMPWorksharingDirective(DKind) || - isOpenMPTaskLoopDirective(DKind) || - isOpenMPDistributeDirective(DKind))); + DSA.getCurScope(), + (isOpenMPWorksharingDirective(DKind) || + isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), + Captures); ResultIterSpace.CounterVar = ISC.BuildCounterVar(); ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); ResultIterSpace.CounterInit = ISC.BuildCounterInit(); @@ -4052,23 +3988,15 @@ static bool CheckOpenMPIterationSpace( } /// \brief Build 'VarRef = Start. -static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, - ExprResult VarRef, ExprResult Start) { - TransformToNewDefs Transform(SemaRef); +static ExprResult +BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, + ExprResult Start, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { // Build 'VarRef = Start. - auto *StartNoImp = Start.get()->IgnoreImplicit(); - auto NewStart = Transform.TransformExpr(StartNoImp); - if (NewStart.isInvalid()) + auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); + if (!NewStart.isUsable()) return ExprError(); if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), - StartNoImp->getType())) { - NewStart = SemaRef.PerformImplicitConversion( - NewStart.get(), StartNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStart.isInvalid()) - return ExprError(); - } - if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), VarRef.get()->getType())) { NewStart = SemaRef.PerformImplicitConversion( NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, @@ -4083,29 +4011,22 @@ static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, } /// \brief Build 'VarRef = Start + Iter * Step'. -static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, - SourceLocation Loc, ExprResult VarRef, - ExprResult Start, ExprResult Iter, - ExprResult Step, bool Subtract) { +static ExprResult +BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, + ExprResult VarRef, ExprResult Start, ExprResult Iter, + ExprResult Step, bool Subtract, + llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { // Add parentheses (for debugging purposes only). Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || !Step.isUsable()) return ExprError(); - auto *StepNoImp = Step.get()->IgnoreImplicit(); - TransformToNewDefs Transform(SemaRef); - auto NewStep = Transform.TransformExpr(StepNoImp); + ExprResult NewStep = Step; + if (Captures) + NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); if (NewStep.isInvalid()) return ExprError(); - if (!SemaRef.Context.hasSameType(NewStep.get()->getType(), - StepNoImp->getType())) { - NewStep = SemaRef.PerformImplicitConversion( - NewStep.get(), StepNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStep.isInvalid()) - return ExprError(); - } ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); if (!Update.isUsable()) @@ -4113,18 +4034,11 @@ static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or // 'VarRef = Start (+|-) Iter * Step'. - auto *StartNoImp = Start.get()->IgnoreImplicit(); - auto NewStart = Transform.TransformExpr(StartNoImp); + ExprResult NewStart = Start; + if (Captures) + NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); if (NewStart.isInvalid()) return ExprError(); - if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), - StartNoImp->getType())) { - NewStart = SemaRef.PerformImplicitConversion( - NewStart.get(), StartNoImp->getType(), Sema::AA_Converting, - /*AllowExplicit=*/true); - if (NewStart.isInvalid()) - return ExprError(); - } // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. ExprResult SavedUpdate = Update; @@ -4196,6 +4110,49 @@ static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { return false; } +/// Build preinits statement for the given declarations. +static Stmt *buildPreInits(ASTContext &Context, + SmallVectorImpl<Decl *> &PreInits) { + if (!PreInits.empty()) { + return new (Context) DeclStmt( + DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), + SourceLocation(), SourceLocation()); + } + return nullptr; +} + +/// Build preinits statement for the given declarations. +static Stmt *buildPreInits(ASTContext &Context, + llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { + if (!Captures.empty()) { + SmallVector<Decl *, 16> PreInits; + for (auto &Pair : Captures) + PreInits.push_back(Pair.second->getDecl()); + return buildPreInits(Context, PreInits); + } + return nullptr; +} + +/// Build postupdate expression for the given list of postupdates expressions. +static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { + Expr *PostUpdate = nullptr; + if (!PostUpdates.empty()) { + for (auto *E : PostUpdates) { + Expr *ConvE = S.BuildCStyleCastExpr( + E->getExprLoc(), + S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), + E->getExprLoc(), E) + .get(); + PostUpdate = PostUpdate + ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, + PostUpdate, ConvE) + .get() + : ConvE; + } + } + return PostUpdate; +} + /// \brief Called on a for stmt to check itself and nested loops (if any). /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, /// number of collapsed loops otherwise. @@ -4229,6 +4186,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, } // This is helper routine for loop directives (e.g., 'for', 'simd', // 'for simd', etc.). + llvm::MapVector<Expr *, DeclRefExpr *> Captures; SmallVector<LoopIterationSpace, 4> IterSpaces; IterSpaces.resize(NestedLoopCount); Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); @@ -4236,7 +4194,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, CollapseLoopCountExpr, OrderedLoopCountExpr, VarsWithImplicitDSA, - IterSpaces[Cnt])) + IterSpaces[Cnt], Captures)) return 0; // Move on to the next nested for loop, or to the loop body. // OpenMP [2.8.1, simd construct, Restrictions] @@ -4358,19 +4316,13 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); ExprResult CalcLastIteration; if (!IsConstant) { - SourceLocation SaveLoc; - VarDecl *SaveVar = - buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), - ".omp.last.iteration"); - ExprResult SaveRef = buildDeclRefExpr( - SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc); - CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign, - SaveRef.get(), LastIteration.get()); + ExprResult SaveRef = + tryBuildCapture(SemaRef, LastIteration.get(), Captures); LastIteration = SaveRef; // Prepare SaveRef + 1. NumIterations = SemaRef.BuildBinOp( - CurScope, SaveLoc, BO_Add, SaveRef.get(), + CurScope, SourceLocation(), BO_Add, SaveRef.get(), SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); if (!NumIterations.isUsable()) return 0; @@ -4525,14 +4477,14 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), /*RefersToCapture=*/true); ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, - IS.CounterInit); + IS.CounterInit, Captures); if (!Init.isUsable()) { HasErrors = true; break; } - ExprResult Update = - BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, - IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); + ExprResult Update = BuildCounterUpdate( + SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, + IS.CounterStep, IS.Subtract, &Captures); if (!Update.isUsable()) { HasErrors = true; break; @@ -4541,7 +4493,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step ExprResult Final = BuildCounterUpdate( SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, - IS.NumIterations, IS.CounterStep, IS.Subtract); + IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); if (!Final.isUsable()) { HasErrors = true; break; @@ -4586,6 +4538,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.CalcLastIteration = SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); Built.PreCond = PreCond.get(); + Built.PreInits = buildPreInits(C, Captures); Built.Cond = Cond.get(); Built.Init = Init.get(); Built.Inc = Inc.get(); @@ -6201,6 +6154,16 @@ StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( assert((CurContext->isDependentContext() || B.builtAll()) && "omp for loop exprs were not built"); + if (!CurContext->isDependentContext()) { + // Finalize the clauses that need pre-built expressions for CodeGen. + for (auto C : Clauses) { + if (auto LC = dyn_cast<OMPLinearClause>(C)) + if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), + B.NumIterations, *this, CurScope)) + return StmtError(); + } + } + // OpenMP, [2.9.2 taskloop Construct, Restrictions] // The grainsize clause and num_tasks clause are mutually exclusive and may // not appear on the same taskloop directive. @@ -6847,13 +6810,9 @@ OMPClause *Sema::ActOnOpenMPScheduleClause( return nullptr; } } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { - ValExpr = buildCapture(*this, ValExpr); - Decl *D = cast<DeclRefExpr>(ValExpr)->getDecl(); - HelperValStmt = - new (Context) DeclStmt(DeclGroupRef::Create(Context, &D, - /*NumDecls=*/1), - SourceLocation(), SourceLocation()); - ValExpr = DefaultLvalueConversion(ValExpr).get(); + llvm::MapVector<Expr *, DeclRefExpr *> Captures; + ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); + HelperValStmt = buildPreInits(Context, Captures); } } } @@ -7569,16 +7528,10 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, if (Vars.empty()) return nullptr; - Stmt *PreInit = nullptr; - if (!ExprCaptures.empty()) { - PreInit = new (Context) - DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), - ExprCaptures.size()), - SourceLocation(), SourceLocation()); - } return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, - Vars, PrivateCopies, Inits, PreInit); + Vars, PrivateCopies, Inits, + buildPreInits(Context, ExprCaptures)); } OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, @@ -7730,27 +7683,11 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, if (Vars.empty()) return nullptr; - Stmt *PreInit = nullptr; - if (!ExprCaptures.empty()) { - PreInit = new (Context) - DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), - ExprCaptures.size()), - SourceLocation(), SourceLocation()); - } - Expr *PostUpdate = nullptr; - if (!ExprPostUpdates.empty()) { - for (auto *E : ExprPostUpdates) { - ExprResult PostUpdateRes = - PostUpdate - ? CreateBuiltinBinOp(SourceLocation(), BO_Comma, PostUpdate, E) - : E; - PostUpdate = PostUpdateRes.get(); - } - } return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, SrcExprs, DstExprs, AssignmentOps, - PreInit, PostUpdate); + buildPreInits(Context, ExprCaptures), + buildPostUpdate(*this, ExprPostUpdates)); } OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, @@ -8482,20 +8419,20 @@ OMPClause *Sema::ActOnOpenMPReductionClause( } else { VarsExpr = Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); - if (!IsOpenMPCapturedDecl(D)) { - ExprCaptures.push_back(Ref->getDecl()); - if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { - ExprResult RefRes = DefaultLvalueConversion(Ref); - if (!RefRes.isUsable()) - continue; - ExprResult PostUpdateRes = - BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, - SimpleRefExpr, RefRes.get()); - if (!PostUpdateRes.isUsable()) - continue; - ExprPostUpdates.push_back( - IgnoredValueConversions(PostUpdateRes.get()).get()); - } + } + if (!IsOpenMPCapturedDecl(D)) { + ExprCaptures.push_back(Ref->getDecl()); + if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { + ExprResult RefRes = DefaultLvalueConversion(Ref); + if (!RefRes.isUsable()) + continue; + ExprResult PostUpdateRes = + BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, + SimpleRefExpr, RefRes.get()); + if (!PostUpdateRes.isUsable()) + continue; + ExprPostUpdates.push_back( + IgnoredValueConversions(PostUpdateRes.get()).get()); } } } @@ -8509,28 +8446,12 @@ OMPClause *Sema::ActOnOpenMPReductionClause( if (Vars.empty()) return nullptr; - Stmt *PreInit = nullptr; - if (!ExprCaptures.empty()) { - PreInit = new (Context) - DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), - ExprCaptures.size()), - SourceLocation(), SourceLocation()); - } - Expr *PostUpdate = nullptr; - if (!ExprPostUpdates.empty()) { - for (auto *E : ExprPostUpdates) { - ExprResult PostUpdateRes = - PostUpdate - ? CreateBuiltinBinOp(SourceLocation(), BO_Comma, PostUpdate, E) - : E; - PostUpdate = PostUpdateRes.get(); - } - } return OMPReductionClause::Create( Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, - LHSs, RHSs, ReductionOps, PreInit, PostUpdate); + LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), + buildPostUpdate(*this, ExprPostUpdates)); } OMPClause *Sema::ActOnOpenMPLinearClause( @@ -8696,32 +8617,16 @@ OMPClause *Sema::ActOnOpenMPLinearClause( } } - Stmt *PreInit = nullptr; - if (!ExprCaptures.empty()) { - PreInit = new (Context) - DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(), - ExprCaptures.size()), - SourceLocation(), SourceLocation()); - } - Expr *PostUpdate = nullptr; - if (!ExprPostUpdates.empty()) { - for (auto *E : ExprPostUpdates) { - ExprResult PostUpdateRes = - PostUpdate - ? CreateBuiltinBinOp(SourceLocation(), BO_Comma, PostUpdate, E) - : E; - PostUpdate = PostUpdateRes.get(); - } - } - return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, ColonLoc, EndLoc, Vars, Privates, Inits, - StepExpr, CalcStepExpr, PreInit, PostUpdate); + StepExpr, CalcStepExpr, + buildPreInits(Context, ExprCaptures), + buildPostUpdate(*this, ExprPostUpdates)); } -static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, - Expr *NumIterations, Sema &SemaRef, - Scope *S) { +static bool +FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, + Expr *NumIterations, Sema &SemaRef, Scope *S) { // Walk the vars and build update/final expressions for the CodeGen. SmallVector<Expr *, 8> Updates; SmallVector<Expr *, 8> Finals; @@ -8731,8 +8636,9 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, // If linear-step is not specified it is assumed to be 1. if (Step == nullptr) Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); - else if (CalcStep) + else if (CalcStep) { Step = cast<BinaryOperator>(CalcStep)->getLHS(); + } bool HasErrors = false; auto CurInit = Clause.inits().begin(); auto CurPrivate = Clause.privates().begin(); @@ -10315,13 +10221,9 @@ OMPClause *Sema::ActOnOpenMPDistScheduleClause( return nullptr; } } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { - ValExpr = buildCapture(*this, ValExpr); - Decl *D = cast<DeclRefExpr>(ValExpr)->getDecl(); - HelperValStmt = - new (Context) DeclStmt(DeclGroupRef::Create(Context, &D, - /*NumDecls=*/1), - SourceLocation(), SourceLocation()); - ValExpr = DefaultLvalueConversion(ValExpr).get(); + llvm::MapVector<Expr *, DeclRefExpr *> Captures; + ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); + HelperValStmt = buildPreInits(Context, Captures); } } } |