From 8992979c9f883945fbf1778f16e7d979dd6a2840 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 14 Aug 2019 19:30:06 +0000 Subject: [PATCH 01/22] [OPENMP]Support for non-rectangular loops. Added basic support for non-rectangular loops. It requires an additional analysis of min/max boundaries for non-rectangular loops. Since only linear dependency is allowed, we can do this analysis. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368903 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/StmtOpenMP.h | 77 +++- lib/AST/StmtOpenMP.cpp | 85 +++++ lib/CodeGen/CGStmtOpenMP.cpp | 30 ++ lib/Sema/SemaOpenMP.cpp | 531 +++++++++++++++++++++++----- lib/Serialization/ASTReaderStmt.cpp | 12 + lib/Serialization/ASTWriterStmt.cpp | 6 + test/OpenMP/for_codegen.cpp | 182 +++++++++- test/OpenMP/for_loop_messages.cpp | 3 +- test/OpenMP/parallel_messages.cpp | 2 +- 9 files changed, 828 insertions(+), 100 deletions(-) diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index e37f5b1e000..c9efe323871 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -448,7 +448,8 @@ class OMPLoopDirective : public OMPExecutableDirective { PreInitsOffset = 8, // The '...End' enumerators do not correspond to child expressions - they // specify the offset to the end (and start of the following counters/ - // updates/finals arrays). + // updates/finals/dependent_counters/dependent_inits/finals_conditions + // arrays). DefaultEnd = 9, // The following 8 exprs are used by worksharing and distribute loops only. IsLastIterVariableOffset = 9, @@ -474,7 +475,8 @@ class OMPLoopDirective : public OMPExecutableDirective { CombinedNextUpperBoundOffset = 27, CombinedDistConditionOffset = 28, CombinedParForInDistConditionOffset = 29, - // Offset to the end (and start of the following counters/updates/finals + // Offset to the end (and start of the following + // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions // arrays) for combined distribute loop directives. CombinedDistributeEnd = 30, }; @@ -517,6 +519,30 @@ class OMPLoopDirective : public OMPExecutableDirective { return MutableArrayRef(Storage, CollapsedNum); } + /// Get the dependent counters storage. + MutableArrayRef getDependentCounters() { + Expr **Storage = reinterpret_cast( + &*std::next(child_begin(), + getArraysOffset(getDirectiveKind()) + 5 * CollapsedNum)); + return MutableArrayRef(Storage, CollapsedNum); + } + + /// Get the dependent inits storage. + MutableArrayRef getDependentInits() { + Expr **Storage = reinterpret_cast( + &*std::next(child_begin(), + getArraysOffset(getDirectiveKind()) + 6 * CollapsedNum)); + return MutableArrayRef(Storage, CollapsedNum); + } + + /// Get the finals conditions storage. + MutableArrayRef getFinalsConditions() { + Expr **Storage = reinterpret_cast( + &*std::next(child_begin(), + getArraysOffset(getDirectiveKind()) + 7 * CollapsedNum)); + return MutableArrayRef(Storage, CollapsedNum); + } + protected: /// Build instance of loop directive of class \a Kind. /// @@ -551,9 +577,10 @@ class OMPLoopDirective : public OMPExecutableDirective { /// Children number. static unsigned numLoopChildren(unsigned CollapsedNum, OpenMPDirectiveKind Kind) { - return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters, - // PrivateCounters, Inits, - // Updates and Finals + return getArraysOffset(Kind) + + 8 * CollapsedNum; // Counters, PrivateCounters, Inits, + // Updates, Finals, DependentCounters, + // DependentInits, FinalsConditions. } void setIterationVariable(Expr *IV) { @@ -703,6 +730,9 @@ class OMPLoopDirective : public OMPExecutableDirective { void setInits(ArrayRef A); void setUpdates(ArrayRef A); void setFinals(ArrayRef A); + void setDependentCounters(ArrayRef A); + void setDependentInits(ArrayRef A); + void setFinalsConditions(ArrayRef A); public: /// The expressions built to support OpenMP loops in combined/composite @@ -798,6 +828,15 @@ class OMPLoopDirective : public OMPExecutableDirective { SmallVector Updates; /// Final loop counter values for GodeGen. SmallVector Finals; + /// List of counters required for the generation of the non-rectangular + /// loops. + SmallVector DependentCounters; + /// List of initializers required for the generation of the non-rectangular + /// loops. + SmallVector DependentInits; + /// List of final conditions required for the generation of the + /// non-rectangular loops. + SmallVector FinalsConditions; /// Init statement for all captured expressions. Stmt *PreInits; @@ -813,7 +852,9 @@ class OMPLoopDirective : public OMPExecutableDirective { } /// Initialize all the fields to null. - /// \param Size Number of elements in the counters/finals/updates arrays. + /// \param Size Number of elements in the + /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions + /// arrays. void clear(unsigned Size) { IterationVarRef = nullptr; LastIteration = nullptr; @@ -839,12 +880,18 @@ class OMPLoopDirective : public OMPExecutableDirective { Inits.resize(Size); Updates.resize(Size); Finals.resize(Size); + DependentCounters.resize(Size); + DependentInits.resize(Size); + FinalsConditions.resize(Size); for (unsigned i = 0; i < Size; ++i) { Counters[i] = nullptr; PrivateCounters[i] = nullptr; Inits[i] = nullptr; Updates[i] = nullptr; Finals[i] = nullptr; + DependentCounters[i] = nullptr; + DependentInits[i] = nullptr; + FinalsConditions[i] = nullptr; } PreInits = nullptr; DistCombinedFields.LB = nullptr; @@ -1078,6 +1125,24 @@ class OMPLoopDirective : public OMPExecutableDirective { return const_cast(this)->getFinals(); } + ArrayRef dependent_counters() { return getDependentCounters(); } + + ArrayRef dependent_counters() const { + return const_cast(this)->getDependentCounters(); + } + + ArrayRef dependent_inits() { return getDependentInits(); } + + ArrayRef dependent_inits() const { + return const_cast(this)->getDependentInits(); + } + + ArrayRef finals_conditions() { return getFinalsConditions(); } + + ArrayRef finals_conditions() const { + return const_cast(this)->getFinalsConditions(); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPSimdDirectiveClass || T->getStmtClass() == OMPForDirectiveClass || diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp index 4e829897ceb..7fda574bae0 100644 --- a/lib/AST/StmtOpenMP.cpp +++ b/lib/AST/StmtOpenMP.cpp @@ -72,6 +72,25 @@ void OMPLoopDirective::setFinals(ArrayRef A) { std::copy(A.begin(), A.end(), getFinals().begin()); } +void OMPLoopDirective::setDependentCounters(ArrayRef A) { + assert( + A.size() == getCollapsedNumber() && + "Number of dependent counters is not the same as the collapsed number"); + llvm::copy(A, getDependentCounters().begin()); +} + +void OMPLoopDirective::setDependentInits(ArrayRef A) { + assert(A.size() == getCollapsedNumber() && + "Number of dependent inits is not the same as the collapsed number"); + llvm::copy(A, getDependentInits().begin()); +} + +void OMPLoopDirective::setFinalsConditions(ArrayRef A) { + assert(A.size() == getCollapsedNumber() && + "Number of finals conditions is not the same as the collapsed number"); + llvm::copy(A, getFinalsConditions().begin()); +} + OMPParallelDirective *OMPParallelDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef Clauses, Stmt *AssociatedStmt, bool HasCancel) { @@ -122,6 +141,9 @@ OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -170,6 +192,9 @@ OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setHasCancel(HasCancel); return Dir; @@ -220,6 +245,9 @@ OMPForSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -383,6 +411,9 @@ OMPParallelForDirective *OMPParallelForDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setHasCancel(HasCancel); return Dir; @@ -432,6 +463,9 @@ OMPParallelForSimdDirective *OMPParallelForSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -772,6 +806,9 @@ OMPTargetParallelForDirective *OMPTargetParallelForDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setHasCancel(HasCancel); return Dir; @@ -914,6 +951,9 @@ OMPTaskLoopDirective *OMPTaskLoopDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -963,6 +1003,9 @@ OMPTaskLoopSimdDirective *OMPTaskLoopSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -1011,6 +1054,9 @@ OMPDistributeDirective *OMPDistributeDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -1089,6 +1135,9 @@ OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB); Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB); @@ -1157,6 +1206,9 @@ OMPDistributeParallelForSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB); Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB); @@ -1219,6 +1271,9 @@ OMPDistributeSimdDirective *OMPDistributeSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -1271,6 +1326,9 @@ OMPTargetParallelForSimdDirective *OMPTargetParallelForSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -1315,6 +1373,9 @@ OMPTargetSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc, Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -1363,6 +1424,9 @@ OMPTeamsDistributeDirective *OMPTeamsDistributeDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -1414,6 +1478,9 @@ OMPTeamsDistributeSimdDirective *OMPTeamsDistributeSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -1471,6 +1538,9 @@ OMPTeamsDistributeParallelForSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB); Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB); @@ -1540,6 +1610,9 @@ OMPTeamsDistributeParallelForDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB); Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB); @@ -1628,6 +1701,9 @@ OMPTargetTeamsDistributeDirective *OMPTargetTeamsDistributeDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } @@ -1688,6 +1764,9 @@ OMPTargetTeamsDistributeParallelForDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB); Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB); @@ -1761,6 +1840,9 @@ OMPTargetTeamsDistributeParallelForSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); Dir->setCombinedLowerBoundVariable(Exprs.DistCombinedFields.LB); Dir->setCombinedUpperBoundVariable(Exprs.DistCombinedFields.UB); @@ -1826,6 +1908,9 @@ OMPTargetTeamsDistributeSimdDirective::Create( Dir->setInits(Exprs.Inits); Dir->setUpdates(Exprs.Updates); Dir->setFinals(Exprs.Finals); + Dir->setDependentCounters(Exprs.DependentCounters); + Dir->setDependentInits(Exprs.DependentInits); + Dir->setFinalsConditions(Exprs.FinalsConditions); Dir->setPreInits(Exprs.PreInits); return Dir; } diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index e8fbca5108a..2ca7ebc6b0d 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -1324,6 +1324,16 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D, // On a continue in the body, jump to the end. JumpDest Continue = getJumpDestInCurrentScope("omp.body.continue"); BreakContinueStack.push_back(BreakContinue(LoopExit, Continue)); + for (const Expr *E : D.finals_conditions()) { + if (!E) + continue; + // Check that loop counter in non-rectangular nest fits into the iteration + // space. + llvm::BasicBlock *NextBB = createBasicBlock("omp.body.next"); + EmitBranchOnBoolExpr(E, NextBB, Continue.getBlock(), + getProfileCount(D.getBody())); + EmitBlock(NextBB); + } // Emit loop body. EmitStmt(D.getBody()); // The end (updates/cleanups). @@ -1553,8 +1563,28 @@ static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, CGF.EmitIgnoredExpr(I); } } + // Create temp loop control variables with their init values to support + // non-rectangular loops. + CodeGenFunction::OMPMapVars PreCondVars; + for (const Expr * E: S.dependent_counters()) { + if (!E) + continue; + assert(!E->getType().getNonReferenceType()->isRecordType() && + "dependent counter must not be an iterator."); + const auto *VD = cast(cast(E)->getDecl()); + Address CounterAddr = + CGF.CreateMemTemp(VD->getType().getNonReferenceType()); + (void)PreCondVars.setVarAddr(CGF, VD, CounterAddr); + } + (void)PreCondVars.apply(CGF); + for (const Expr *E : S.dependent_inits()) { + if (!E) + continue; + CGF.EmitIgnoredExpr(E); + } // Check that loop is executed at least one time. CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount); + PreCondVars.restore(CGF); } void CodeGenFunction::EmitOMPLinearClause( diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 49c7c3aca14..3c23e43a20a 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -4709,6 +4709,54 @@ StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef Clauses, } namespace { +/// Iteration space of a single for loop. +struct LoopIterationSpace final { + /// True if the condition operator is the strict compare operator (<, > or + /// !=). + bool IsStrictCompare = false; + /// Condition of the loop. + Expr *PreCond = nullptr; + /// This expression calculates the number of iterations in the loop. + /// It is always possible to calculate it before starting the loop. + Expr *NumIterations = nullptr; + /// The loop counter variable. + Expr *CounterVar = nullptr; + /// Private loop counter variable. + Expr *PrivateCounterVar = nullptr; + /// This is initializer for the initial value of #CounterVar. + Expr *CounterInit = nullptr; + /// This is step for the #CounterVar used to generate its update: + /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. + Expr *CounterStep = nullptr; + /// Should step be subtracted? + bool Subtract = false; + /// Source range of the loop init. + SourceRange InitSrcRange; + /// Source range of the loop condition. + SourceRange CondSrcRange; + /// Source range of the loop increment. + SourceRange IncSrcRange; + /// Minimum value that can have the loop control variable. Used to support + /// non-rectangular loops. Applied only for LCV with the non-iterator types, + /// since only such variables can be used in non-loop invariant expressions. + Expr *MinValue = nullptr; + /// Maximum value that can have the loop control variable. Used to support + /// non-rectangular loops. Applied only for LCV with the non-iterator type, + /// since only such variables can be used in non-loop invariant expressions. + Expr *MaxValue = nullptr; + /// true, if the lower bound depends on the outer loop control var. + bool IsNonRectangularLB = false; + /// true, if the upper bound depends on the outer loop control var. + bool IsNonRectangularUB = false; + /// Index of the loop this loop depends on and forms non-rectangular loop + /// nest. + unsigned LoopDependentIdx = 0; + /// Final condition for the non-rectangular loop nest support. It is used to + /// check that the number of iterations for this particular counter must be + /// finished. + Expr *FinalCondition = nullptr; +}; + /// Helper class for checking canonical form of the OpenMP loops and /// extracting iteration space of each loop in the loop nest, that will be used /// for IR generation. @@ -4758,6 +4806,9 @@ class OpenMPIterationSpaceChecker { Optional CondDependOnLC; /// Checks if the provide statement depends on the loop counter. Optional doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); + /// Original condition required for checking of the exit condition for + /// non-rectangular loop. + Expr *Condition = nullptr; public: OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, @@ -4789,7 +4840,7 @@ class OpenMPIterationSpaceChecker { bool isStrictTestOp() const { return TestIsStrictOp; } /// Build the expression to calculate the number of iterations. Expr *buildNumIterations( - Scope *S, const bool LimitedType, + Scope *S, ArrayRef ResultIterSpaces, bool LimitedType, llvm::MapVector &Captures) const; /// Build the precondition expression for the loops. Expr * @@ -4813,8 +4864,21 @@ class OpenMPIterationSpaceChecker { llvm::MapVector &Captures, SourceLocation Loc, Expr *Inc = nullptr, OverloadedOperatorKind OOK = OO_Amp); + /// Builds the minimum value for the loop counter. + std::pair buildMinMaxValues( + Scope *S, llvm::MapVector &Captures) const; + /// Builds final condition for the non-rectangular loops. + Expr *buildFinalCondition(Scope *S) const; /// Return true if any expression is dependent. bool dependent() const; + /// Returns true if the initializer forms non-rectangular loop. + bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } + /// Returns true if the condition forms non-rectangular loop. + bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } + /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. + unsigned getLoopDependentIdx() const { + return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); + } private: /// Check the right-hand side of an assignment in the increment @@ -5013,9 +5077,9 @@ class LoopCounterRefChecker final return false; } bool VisitStmt(const Stmt *S) { - bool Res = true; + bool Res = false; for (const Stmt *Child : S->children()) - Res = Child && Visit(Child) && Res; + Res = (Child && Visit(Child)) || Res; return Res; } explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, @@ -5165,6 +5229,7 @@ bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; return true; } + Condition = S; S = getExprAsWritten(S); SourceLocation CondLoc = S->getBeginLoc(); if (auto *BO = dyn_cast(S)) { @@ -5351,15 +5416,177 @@ tryBuildCapture(Sema &SemaRef, Expr *Capture, /// Build the expression to calculate the number of iterations. Expr *OpenMPIterationSpaceChecker::buildNumIterations( - Scope *S, const bool LimitedType, + Scope *S, ArrayRef ResultIterSpaces, bool LimitedType, llvm::MapVector &Captures) const { ExprResult Diff; QualType VarType = LCDecl->getType().getNonReferenceType(); if (VarType->isIntegerType() || VarType->isPointerType() || SemaRef.getLangOpts().CPlusPlus) { + Expr *LBVal = LB; + Expr *UBVal = UB; + // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : + // max(LB(MinVal), LB(MaxVal)) + if (InitDependOnLC) { + const LoopIterationSpace &IS = + ResultIterSpaces[ResultIterSpaces.size() - 1 - + InitDependOnLC.getValueOr( + CondDependOnLC.getValueOr(0))]; + if (!IS.MinValue || !IS.MaxValue) + return nullptr; + // OuterVar = Min + ExprResult MinValue = + SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); + if (!MinValue.isUsable()) + return nullptr; + + ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, + IS.CounterVar, MinValue.get()); + if (!LBMinVal.isUsable()) + return nullptr; + // OuterVar = Min, LBVal + LBMinVal = + SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); + if (!LBMinVal.isUsable()) + return nullptr; + // (OuterVar = Min, LBVal) + LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); + if (!LBMinVal.isUsable()) + return nullptr; + + // OuterVar = Max + ExprResult MaxValue = + SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); + if (!MaxValue.isUsable()) + return nullptr; + + ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, + IS.CounterVar, MaxValue.get()); + if (!LBMaxVal.isUsable()) + return nullptr; + // OuterVar = Max, LBVal + LBMaxVal = + SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); + if (!LBMaxVal.isUsable()) + return nullptr; + // (OuterVar = Max, LBVal) + LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); + if (!LBMaxVal.isUsable()) + return nullptr; + + Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); + Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); + if (!LBMin || !LBMax) + return nullptr; + // LB(MinVal) < LB(MaxVal) + ExprResult MinLessMaxRes = + SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); + if (!MinLessMaxRes.isUsable()) + return nullptr; + Expr *MinLessMax = + tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); + if (!MinLessMax) + return nullptr; + if (TestIsLessOp.getValue()) { + // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), + // LB(MaxVal)) + ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, + MinLessMax, LBMin, LBMax); + if (!MinLB.isUsable()) + return nullptr; + LBVal = MinLB.get(); + } else { + // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), + // LB(MaxVal)) + ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, + MinLessMax, LBMax, LBMin); + if (!MaxLB.isUsable()) + return nullptr; + LBVal = MaxLB.get(); + } + } + // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : + // min(UB(MinVal), UB(MaxVal)) + if (CondDependOnLC) { + const LoopIterationSpace &IS = + ResultIterSpaces[ResultIterSpaces.size() - 1 - + InitDependOnLC.getValueOr( + CondDependOnLC.getValueOr(0))]; + if (!IS.MinValue || !IS.MaxValue) + return nullptr; + // OuterVar = Min + ExprResult MinValue = + SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); + if (!MinValue.isUsable()) + return nullptr; + + ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, + IS.CounterVar, MinValue.get()); + if (!UBMinVal.isUsable()) + return nullptr; + // OuterVar = Min, UBVal + UBMinVal = + SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); + if (!UBMinVal.isUsable()) + return nullptr; + // (OuterVar = Min, UBVal) + UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); + if (!UBMinVal.isUsable()) + return nullptr; + + // OuterVar = Max + ExprResult MaxValue = + SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); + if (!MaxValue.isUsable()) + return nullptr; + + ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, + IS.CounterVar, MaxValue.get()); + if (!UBMaxVal.isUsable()) + return nullptr; + // OuterVar = Max, UBVal + UBMaxVal = + SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); + if (!UBMaxVal.isUsable()) + return nullptr; + // (OuterVar = Max, UBVal) + UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); + if (!UBMaxVal.isUsable()) + return nullptr; + + Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); + Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); + if (!UBMin || !UBMax) + return nullptr; + // UB(MinVal) > UB(MaxVal) + ExprResult MinGreaterMaxRes = + SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); + if (!MinGreaterMaxRes.isUsable()) + return nullptr; + Expr *MinGreaterMax = + tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); + if (!MinGreaterMax) + return nullptr; + if (TestIsLessOp.getValue()) { + // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), + // UB(MaxVal)) + ExprResult MaxUB = SemaRef.ActOnConditionalOp( + DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); + if (!MaxUB.isUsable()) + return nullptr; + UBVal = MaxUB.get(); + } else { + // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), + // UB(MaxVal)) + ExprResult MinUB = SemaRef.ActOnConditionalOp( + DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); + if (!MinUB.isUsable()) + return nullptr; + UBVal = MinUB.get(); + } + } // Upper - Lower - Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; - Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; + Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; + Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); if (!Upper || !Lower) @@ -5446,6 +5673,127 @@ Expr *OpenMPIterationSpaceChecker::buildNumIterations( return Diff.get(); } +std::pair OpenMPIterationSpaceChecker::buildMinMaxValues( + Scope *S, llvm::MapVector &Captures) const { + // Do not build for iterators, they cannot be used in non-rectangular loop + // nests. + if (LCDecl->getType()->isRecordType()) + return std::make_pair(nullptr, nullptr); + // If we subtract, the min is in the condition, otherwise the min is in the + // init value. + Expr *MinExpr = nullptr; + Expr *MaxExpr = nullptr; + Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; + Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; + bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() + : CondDependOnLC.hasValue(); + bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() + : InitDependOnLC.hasValue(); + Expr *Lower = + LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); + Expr *Upper = + UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); + if (!Upper || !Lower) + return std::make_pair(nullptr, nullptr); + + if (TestIsLessOp.getValue()) + MinExpr = Lower; + else + MaxExpr = Upper; + + // Build minimum/maximum value based on number of iterations. + ExprResult Diff; + QualType VarType = LCDecl->getType().getNonReferenceType(); + + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + + // Upper - Lower [- 1] + if (TestIsStrictOp) + Diff = SemaRef.BuildBinOp( + S, DefaultLoc, BO_Sub, Diff.get(), + SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + + // Upper - Lower [- 1] + Step + ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); + if (!NewStep.isUsable()) + return std::make_pair(nullptr, nullptr); + + // Parentheses (for dumping/debugging purposes only). + Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + + // (Upper - Lower [- 1]) / Step + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + + // ((Upper - Lower [- 1]) / Step) * Step + // Parentheses (for dumping/debugging purposes only). + Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + + // Convert to the original type or ptrdiff_t, if original type is pointer. + if (!VarType->isAnyPointerType() && + !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { + Diff = SemaRef.PerformImplicitConversion( + Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); + } else if (VarType->isAnyPointerType() && + !SemaRef.Context.hasSameType( + Diff.get()->getType(), + SemaRef.Context.getUnsignedPointerDiffType())) { + Diff = SemaRef.PerformImplicitConversion( + Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), + Sema::AA_Converting, /*AllowExplicit=*/true); + } + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + + // Parentheses (for dumping/debugging purposes only). + Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + + if (TestIsLessOp.getValue()) { + // MinExpr = Lower; + // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + MaxExpr = Diff.get(); + } else { + // MaxExpr = Upper; + // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); + if (!Diff.isUsable()) + return std::make_pair(nullptr, nullptr); + MinExpr = Diff.get(); + } + + return std::make_pair(MinExpr, MaxExpr); +} + +Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { + if (InitDependOnLC || CondDependOnLC) + return Condition; + return nullptr; +} + Expr *OpenMPIterationSpaceChecker::buildPreCond( Scope *S, Expr *Cond, llvm::MapVector &Captures) const { @@ -5453,8 +5801,10 @@ Expr *OpenMPIterationSpaceChecker::buildPreCond( bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); - ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); - ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); + ExprResult NewLB = + InitDependOnLC ? LB : tryBuildCapture(SemaRef, LB, Captures); + ExprResult NewUB = + CondDependOnLC ? UB : tryBuildCapture(SemaRef, UB, Captures); if (!NewLB.isUsable() || !NewUB.isUsable()) return nullptr; @@ -5576,36 +5926,6 @@ Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( return Diff.get(); } - -/// Iteration space of a single for loop. -struct LoopIterationSpace final { - /// True if the condition operator is the strict compare operator (<, > or - /// !=). - bool IsStrictCompare = false; - /// Condition of the loop. - Expr *PreCond = nullptr; - /// This expression calculates the number of iterations in the loop. - /// It is always possible to calculate it before starting the loop. - Expr *NumIterations = nullptr; - /// The loop counter variable. - Expr *CounterVar = nullptr; - /// Private loop counter variable. - Expr *PrivateCounterVar = nullptr; - /// This is initializer for the initial value of #CounterVar. - Expr *CounterInit = nullptr; - /// This is step for the #CounterVar used to generate its update: - /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. - Expr *CounterStep = nullptr; - /// Should step be subtracted? - bool Subtract = false; - /// Source range of the loop init. - SourceRange InitSrcRange; - /// Source range of the loop condition. - SourceRange CondSrcRange; - /// Source range of the loop increment. - SourceRange IncSrcRange; -}; - } // namespace void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { @@ -5696,7 +6016,7 @@ static bool checkOpenMPIterationSpace( unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, - LoopIterationSpace &ResultIterSpace, + llvm::MutableArrayRef ResultIterSpaces, llvm::MapVector &Captures) { // OpenMP [2.6, Canonical Loop Form] // for (init-expr; test-expr; incr-expr) structured-block @@ -5774,37 +6094,57 @@ static bool checkOpenMPIterationSpace( return HasErrors; // Build the loop's iteration space representation. - ResultIterSpace.PreCond = + ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); - ResultIterSpace.NumIterations = ISC.buildNumIterations( - DSA.getCurScope(), - (isOpenMPWorksharingDirective(DKind) || - isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), - Captures); - ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); - ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); - ResultIterSpace.CounterInit = ISC.buildCounterInit(); - ResultIterSpace.CounterStep = ISC.buildCounterStep(); - ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); - ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); - ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); - ResultIterSpace.Subtract = ISC.shouldSubtractStep(); - ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); - - HasErrors |= (ResultIterSpace.PreCond == nullptr || - ResultIterSpace.NumIterations == nullptr || - ResultIterSpace.CounterVar == nullptr || - ResultIterSpace.PrivateCounterVar == nullptr || - ResultIterSpace.CounterInit == nullptr || - ResultIterSpace.CounterStep == nullptr); + ResultIterSpaces[CurrentNestedLoopCount].NumIterations = + ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, + (isOpenMPWorksharingDirective(DKind) || + isOpenMPTaskLoopDirective(DKind) || + isOpenMPDistributeDirective(DKind)), + Captures); + ResultIterSpaces[CurrentNestedLoopCount].CounterVar = + ISC.buildCounterVar(Captures, DSA); + ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = + ISC.buildPrivateCounterVar(); + ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); + ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); + ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); + ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = + ISC.getConditionSrcRange(); + ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = + ISC.getIncrementSrcRange(); + ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); + ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = + ISC.isStrictTestOp(); + std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, + ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = + ISC.buildMinMaxValues(DSA.getCurScope(), Captures); + ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = + ISC.buildFinalCondition(DSA.getCurScope()); + ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = + ISC.doesInitDependOnLC(); + ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = + ISC.doesCondDependOnLC(); + ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = + ISC.getLoopDependentIdx(); + + HasErrors |= + (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || + ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || + ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || + ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || + ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || + ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); if (!HasErrors && DSA.isOrderedRegion()) { if (DSA.getOrderedRegionParam().second->getNumForLoops()) { if (CurrentNestedLoopCount < DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { DSA.getOrderedRegionParam().second->setLoopNumIterations( - CurrentNestedLoopCount, ResultIterSpace.NumIterations); + CurrentNestedLoopCount, + ResultIterSpaces[CurrentNestedLoopCount].NumIterations); DSA.getOrderedRegionParam().second->setLoopCounter( - CurrentNestedLoopCount, ResultIterSpace.CounterVar); + CurrentNestedLoopCount, + ResultIterSpaces[CurrentNestedLoopCount].CounterVar); } } for (auto &Pair : DSA.getDoacrossDependClauses()) { @@ -5821,11 +6161,13 @@ static bool checkOpenMPIterationSpace( Expr *CntValue; if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) CntValue = ISC.buildOrderedLoopData( - DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, + DSA.getCurScope(), + ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, Pair.first->getDependencyLoc()); else CntValue = ISC.buildOrderedLoopData( - DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, + DSA.getCurScope(), + ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, Pair.first->getDependencyLoc(), Pair.second[CurrentNestedLoopCount].first, Pair.second[CurrentNestedLoopCount].second); @@ -5839,10 +6181,12 @@ static bool checkOpenMPIterationSpace( /// Build 'VarRef = Start. static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, - ExprResult Start, + ExprResult Start, bool IsNonRectangularLB, llvm::MapVector &Captures) { // Build 'VarRef = Start. - ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); + ExprResult NewStart = IsNonRectangularLB + ? Start.get() + : tryBuildCapture(SemaRef, Start.get(), Captures); if (!NewStart.isUsable()) return ExprError(); if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), @@ -5863,6 +6207,7 @@ buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, static ExprResult buildCounterUpdate( Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, + bool IsNonRectangularLB, llvm::MapVector *Captures = nullptr) { // Add parentheses (for debugging purposes only). Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); @@ -5882,8 +6227,12 @@ static ExprResult buildCounterUpdate( // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or // 'VarRef = Start (+|-) Iter * Step'. - ExprResult NewStart = Start; - if (Captures) + if (!Start.isUsable()) + return ExprError(); + ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); + if (!NewStart.isUsable()) + return ExprError(); + if (Captures && !IsNonRectangularLB) NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); if (NewStart.isInvalid()) return ExprError(); @@ -6054,8 +6403,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, if (checkOpenMPIterationSpace( DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, - OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], - Captures)) + OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) return 0; // Move on to the next nested for loop, or to the loop body. // OpenMP [2.8.1, simd construct, Restrictions] @@ -6068,8 +6416,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, if (checkOpenMPIterationSpace( DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, - OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], - Captures)) + OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) return 0; if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { // Handle initialization of captured loop iterator variables. @@ -6530,6 +6877,9 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.Inits.resize(NestedLoopCount); Built.Updates.resize(NestedLoopCount); Built.Finals.resize(NestedLoopCount); + Built.DependentCounters.resize(NestedLoopCount); + Built.DependentInits.resize(NestedLoopCount); + Built.FinalsConditions.resize(NestedLoopCount); { // We implement the following algorithm for obtaining the // original loop iteration variable values based on the @@ -6589,24 +6939,26 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, DeclRefExpr *CounterVar = buildDeclRefExpr( SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), /*RefersToCapture=*/true); - ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, - IS.CounterInit, Captures); + ExprResult Init = + buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, + IS.CounterInit, IS.IsNonRectangularLB, Captures); if (!Init.isUsable()) { HasErrors = true; break; } ExprResult Update = buildCounterUpdate( SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, - IS.CounterStep, IS.Subtract, &Captures); + IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); if (!Update.isUsable()) { HasErrors = true; break; } // 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, &Captures); + ExprResult Final = + buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, + IS.CounterInit, IS.NumIterations, IS.CounterStep, + IS.Subtract, IS.IsNonRectangularLB, &Captures); if (!Final.isUsable()) { HasErrors = true; break; @@ -6622,6 +6974,16 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.Inits[Cnt] = Init.get(); Built.Updates[Cnt] = Update.get(); Built.Finals[Cnt] = Final.get(); + Built.DependentCounters[Cnt] = nullptr; + Built.DependentInits[Cnt] = nullptr; + Built.FinalsConditions[Cnt] = nullptr; + if (IS.IsNonRectangularLB) { + Built.DependentCounters[Cnt] = + Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; + Built.DependentInits[Cnt] = + Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; + Built.FinalsConditions[Cnt] = IS.FinalCondition; + } } } @@ -6634,7 +6996,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.NumIterations = NumIterations.get(); Built.CalcLastIteration = SemaRef .ActOnFinishFullExpr(CalcLastIteration.get(), - /*DiscardedValue*/ false) + /*DiscardedValue=*/false) .get(); Built.PreCond = PreCond.get(); Built.PreInits = buildPreInits(C, Captures); @@ -12778,9 +13140,9 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, // Build update: Var = InitExpr + IV * Step ExprResult Update; if (!Info.first) - Update = - buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, - InitExpr, IV, Step, /* Subtract */ false); + Update = buildCounterUpdate( + SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, + /*Subtract=*/false, /*IsNonRectangularLB=*/false); else Update = *CurPrivate; Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), @@ -12791,7 +13153,8 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, if (!Info.first) Final = buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, - InitExpr, NumIterations, Step, /*Subtract=*/false); + InitExpr, NumIterations, Step, /*Subtract=*/false, + /*IsNonRectangularLB=*/false); else Final = *CurPrivate; Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index afaaa543bb2..8ab0845d151 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -2060,6 +2060,18 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) { for (unsigned i = 0; i < CollapsedNum; ++i) Sub.push_back(Record.readSubExpr()); D->setFinals(Sub); + Sub.clear(); + for (unsigned i = 0; i < CollapsedNum; ++i) + Sub.push_back(Record.readSubExpr()); + D->setDependentCounters(Sub); + Sub.clear(); + for (unsigned i = 0; i < CollapsedNum; ++i) + Sub.push_back(Record.readSubExpr()); + D->setDependentInits(Sub); + Sub.clear(); + for (unsigned i = 0; i < CollapsedNum; ++i) + Sub.push_back(Record.readSubExpr()); + D->setFinalsConditions(Sub); } void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) { diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 4fbcbaabe74..a6927f32c0e 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1995,6 +1995,12 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) { for (auto I : D->finals()) { Record.AddStmt(I); } + for (Stmt *S : D->dependent_counters()) + Record.AddStmt(S); + for (Stmt *S : D->dependent_inits()) + Record.AddStmt(S); + for (Stmt *S : D->finals_conditions()) + Record.AddStmt(S); } void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) { diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp index 47c5be9becf..80afa1c9452 100644 --- a/test/OpenMP/for_codegen.cpp +++ b/test/OpenMP/for_codegen.cpp @@ -25,10 +25,176 @@ // CHECK-LABEL: loop_with_counter_collapse void loop_with_counter_collapse() { + // Captured initializations. + // CHECK: store i32 0, i32* [[I_TMP:%.+]], + // CHECK: [[VAL:%.+]] = load i32, i32* [[I_TMP]], + // CHECK: store i32 [[VAL]], i32* [[J_LB_MIN:%.+]], + // CHECK: store i32 3, i32* [[I_TMP]], + // CHECK: [[VAL:%.+]] = load i32, i32* [[I_TMP]], + // CHECK: store i32 [[VAL]], i32* [[J_LB_MAX:%.+]], + // CHECK: [[J_LB_MIN_VAL:%.+]] = load i32, i32* [[J_LB_MIN]], + // CHECK: [[J_LB_MAX_VAL:%.+]] = load i32, i32* [[J_LB_MAX]], + // CHECK: [[CMP:%.+]] = icmp slt i32 [[J_LB_MIN_VAL]], [[J_LB_MAX_VAL]] + // CHECK: [[BOOL:%.+]] = zext i1 [[CMP]] to i8 + // CHECK: store i8 [[BOOL]], i8* [[J_LB_CMP:%.+]], + // CHECK: store i32 0, i32* [[I_TMP]], + // CHECK: [[VAL:%.+]] = load i32, i32* [[I_TMP]], + // CHECK: [[J_UB_MIN_VAL:%.+]] = add nsw i32 4, [[VAL]] + // CHECK: store i32 [[J_UB_MIN_VAL]], i32* [[J_UB_MIN:%.+]], + // CHECK: store i32 3, i32* [[I_TMP]], + // CHECK: [[VAL:%.+]] = load i32, i32* [[I_TMP]], + // CHECK: [[J_UB_MAX_VAL:%.+]] = add nsw i32 4, [[VAL]] + // CHECK: store i32 [[J_UB_MAX_VAL]], i32* [[J_UB_MAX:%.+]], + // CHECK: [[J_UB_MIN_VAL:%.+]] = load i32, i32* [[J_UB_MIN]], + // CHECK: [[J_UB_MAX_VAL:%.+]] = load i32, i32* [[J_UB_MAX]], + // CHECK: [[CMP:%.+]] = icmp sgt i32 [[J_UB_MIN_VAL]], [[J_UB_MAX_VAL]] + // CHECK: [[BOOL:%.+]] = zext i1 [[CMP]] to i8 + // CHECK: store i8 [[BOOL]], i8* [[J_UB_CMP:%.+]], + // CHECK: [[J_UB_CMP_VAL:%.+]] = load i8, i8* [[J_UB_CMP]], + // CHECK: [[BOOL:%.+]] = trunc i8 [[J_UB_CMP_VAL]] to i1 + // CHECK: br i1 [[BOOL]], label %[[TRUE:[^,]+]], label %[[FALSE:[^,]+]] + // CHECK: [[TRUE]]: + // CHECK: [[J_UB_MIN_VAL:%.+]] = load i32, i32* [[J_UB_MIN]], + // CHECK: br label %[[EXIT:[^,]+]] + // CHECK: [[FALSE]]: + // CHECK: [[J_UB_MAX_VAL:%.+]] = load i32, i32* [[J_UB_MAX]], + // CHECK: br label %[[EXIT]] + // CHECK: [[EXIT]]: + // CHECK: [[J_UB_VAL:%.+]] = phi i32 [ [[J_UB_MIN_VAL]], %[[TRUE]] ], [ [[J_UB_MAX_VAL]], %[[FALSE]] ] + // CHECK: store i32 [[J_UB_VAL]], i32* [[J_UB:%.+]], + // CHECK: [[J_LB_CMP_VAL:%.+]] = load i8, i8* [[J_LB_CMP]], + // CHECK: [[BOOL:%.+]] = trunc i8 [[J_LB_CMP_VAL]] to i1 + // CHECK: br i1 [[BOOL]], label %[[TRUE:[^,]+]], label %[[FALSE:[^,]+]] + // CHECK: [[TRUE]]: + // CHECK: [[J_LB_MIN_VAL:%.+]] = load i32, i32* [[J_LB_MIN]], + // CHECK: br label %[[EXIT:[^,]+]] + // CHECK: [[FALSE]]: + // CHECK: [[J_LB_MAX_VAL:%.+]] = load i32, i32* [[J_LB_MAX]], + // CHECK: br label %[[EXIT]] + // CHECK: [[EXIT]]: + // CHECK: [[J_LB_VAL:%.+]] = phi i32 [ [[J_LB_MIN_VAL]], %[[TRUE]] ], [ [[J_LB_MAX_VAL]], %[[FALSE]] ] + // CHECK: store i32 [[J_LB_VAL]], i32* [[J_LB:%.+]], + // CHECK: [[J_UB_VAL:%.+]] = load i32, i32* [[J_UB]], + // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[J_LB]], + // CHECK: [[SUB:%.+]] = sub nsw i32 [[J_UB_VAL]], [[J_LB_VAL]] + // CHECK: [[SUB_ST:%.+]] = sub nsw i32 [[SUB]], 1 + // CHECK: [[ADD_ST:%.+]] = add nsw i32 [[SUB_ST]], 1 + // CHECK: [[DIV_ST:%.+]] = sdiv i32 [[ADD_ST]], 1 + // CHECK: [[CAST:%.+]] = sext i32 [[DIV_ST]] to i64 + // CHECK: [[MUL:%.+]] = mul nsw i64 4, [[CAST]] + // CHECK: [[NUM_ITERS_VAL:%.+]] = sub nsw i64 [[MUL]], 1 + // CHECK: store i64 [[NUM_ITERS_VAL]], i64* [[NUM_ITERS:%.+]], + + // Initialization + // CHECK: store i32 0, i32* [[I:%.+]], + // CHECK: [[I_INIT:%.+]] = load i32, i32* [[I]], + // CHECK: store i32 [[I_INIT]], i32* [[J:%.+]], + // LIFETIME: call void @llvm.lifetime.end // LIFETIME: call void @llvm.lifetime.end - // CHECK: call void @__kmpc_for_static_init_8(%struct.ident_t* @ - // CHECK: call void @__kmpc_for_static_fini(%struct.ident_t* @ + + // Precondition for j counter + // CHECK: store i32 0, i32* [[TMP_I:%.+]], + // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[TMP_I]], + // CHECK: [[I_VAL:%.+]] = load i32, i32* [[TMP_I]], + // CHECK: [[J_UB_VAL:%.+]] = add nsw i32 4, [[I_VAL]] + // CHECK: [[CMP:%.+]] = icmp slt i32 [[J_LB_VAL]], [[J_UB_VAL]] + // CHECK: br i1 [[CMP]], label %[[THEN:[^,]+]], label %[[ELSE:[^,]+]] + + // CHECK: [[THEN]]: + // CHECK: store i64 0, i64* [[LB:%.+]], + // CHECK: [[NUM_ITERS_VAL:%.+]] = load i64, i64* [[NUM_ITERS]], + // CHECK: store i64 [[NUM_ITERS_VAL]], i64* [[UB:%.+]], + // CHECK: store i64 1, i64* [[STRIDE:%.+]], + // CHECK: store i32 0, i32* [[IS_LAST:%.+]], + // CHECK: call void @__kmpc_for_static_init_8(%struct.ident_t* @{{.+}}, i32 %{{.+}}, i32 34, i32* [[IS_LAST]], i64* [[LB]], i64* [[UB]], i64* [[STRIDE]], i64 1, i64 1) + // CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]], + // CHECK: [[NUM_ITERS_VAL:%.+]] = load i64, i64* [[NUM_ITERS]], + // CHECK: [[CMP:%.+]] = icmp sgt i64 [[UB_VAL]], [[NUM_ITERS_VAL]] + // CHECK: br i1 [[CMP]], label %[[TRUE:[^,]+]], label %[[FALSE:[^,]+]] + // CHECK: [[TRUE]]: + // CHECK: [[NUM_ITERS_VAL:%.+]] = load i64, i64* [[NUM_ITERS]], + // CHECK: br label %[[DONE:[^,]+]] + // CHECK: [[FALSE]]: + // CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]], + // CHECK: br label %[[DONE]] + // CHECK: [[DONE]]: + // CHECK: [[TOP:%.+]] = phi i64 [ [[NUM_ITERS_VAL]], %[[TRUE]] ], [ [[UB_VAL]], %[[FALSE]] ] + // CHECK: store i64 [[TOP]], i64* [[UB]], + // CHECK: [[LB_VAL:%.+]] = load i64, i64* [[LB]], + // CHECK: store i64 [[LB_VAL]], i64* [[IV:%.+]], + // CHECK: br label %[[COND:[^,]+]] + // CHECK: [[COND]]: + // CHECK: [[IV_VAL:%.+]] = load i64, i64* [[IV]], + // CHECK: [[UB_VAL:%.+]] = load i64, i64* [[UB]], + // CHECK: [[CMP:%.+]] = icmp sle i64 [[IV_VAL]], [[UB_VAL]] + // CHECK: br i1 [[CMP]], label %[[BODY:[^,]+]], label %[[CLEANUP:[^,]+]] + // LIFETIME: [[CLEANUP]]: + // LIFETIME: br label %[[CLEANUP:[^,]+]] + // CHECK: [[BODY]]: + // CHECK: [[IV_VAL:%.+]] = load i64, i64* [[IV]], + // CHECK: [[J_UB_VAL:%.+]] = load i32, i32* [[J_UB]], + // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[J_LB]], + // CHECK: [[SUB:%.+]] = sub nsw i32 [[J_UB_VAL]], [[J_LB_VAL]] + // CHECK: [[SUB_ST:%.+]] = sub nsw i32 [[SUB]], 1 + // CHECK: [[ADD_ST:%.+]] = add nsw i32 [[SUB_ST]], 1 + // CHECK: [[DIV_ST:%.+]] = sdiv i32 [[ADD_ST]], 1 + // CHECK: [[MUL:%.+]] = mul nsw i32 1, [[DIV_ST]] + // CHECK: [[CAST:%.+]] = sext i32 [[MUL]] to i64 + // CHECK: [[DIV:%.+]] = sdiv i64 [[IV_VAL]], [[CAST]] + // CHECK: [[MUL:%.+]] = mul nsw i64 [[DIV]], 1 + // CHECK: [[ADD:%.+]] = add nsw i64 0, [[MUL]] + // CHECK: [[CAST:%.+]] = trunc i64 [[ADD]] to i32 + // CHECK: store i32 [[CAST]], i32* [[I_PRIV:%.+]], + // CHECK: [[I_VAL:%.+]] = load i32, i32* [[I_PRIV]], + // CHECK: [[CONV:%.+]] = sext i32 [[I_VAL]] to i64 + // CHECK: [[IV_VAL:%.+]] = load i64, i64* [[IV]], + // CHECK: [[IV_VAL1:%.+]] = load i64, i64* [[IV]], + // CHECK: [[J_UB_VAL:%.+]] = load i32, i32* [[J_UB]], + // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[J_LB]], + // CHECK: [[SUB:%.+]] = sub nsw i32 [[J_UB_VAL]], [[J_LB_VAL]] + // CHECK: [[SUB_ST:%.+]] = sub nsw i32 [[SUB]], 1 + // CHECK: [[ADD_ST:%.+]] = add nsw i32 [[SUB_ST]], 1 + // CHECK: [[DIV_ST:%.+]] = sdiv i32 [[ADD_ST]], 1 + // CHECK: [[MUL:%.+]] = mul nsw i32 1, [[DIV_ST]] + // CHECK: [[CAST:%.+]] = sext i32 [[MUL]] to i64 + // CHECK: [[DIV:%.+]] = sdiv i64 [[IV_VAL1]], [[CAST]] + // CHECK: [[J_UB_VAL:%.+]] = load i32, i32* [[J_UB]], + // CHECK: [[J_LB_VAL:%.+]] = load i32, i32* [[J_LB]], + // CHECK: [[SUB:%.+]] = sub nsw i32 [[J_UB_VAL]], [[J_LB_VAL]] + // CHECK: [[SUB_ST:%.+]] = sub nsw i32 [[SUB]], 1 + // CHECK: [[ADD_ST:%.+]] = add nsw i32 [[SUB_ST]], 1 + // CHECK: [[DIV_ST:%.+]] = sdiv i32 [[ADD_ST]], 1 + // CHECK: [[MUL:%.+]] = mul nsw i32 1, [[DIV_ST]] + // CHECK: [[CAST:%.+]] = sext i32 [[MUL]] to i64 + // CHECK: [[MUL:%.+]] = mul nsw i64 [[DIV]], [[CAST]] + // CHECK: [[SUB:%.+]] = sub nsw i64 [[IV_VAL]], [[MUL]] + // CHECK: [[MUL:%.+]] = mul nsw i64 [[SUB:%.+]], 1 + // CHECK: [[ADD:%.+]] = add nsw i64 [[CONV]], [[MUL]] + // CHECK: [[CAST:%.+]] = trunc i64 [[ADD]] to i32 + // CHECK: store i32 [[CAST]], i32* [[J_PRIV:%.+]], + + // Check that the loop variable is not out of its boundaries. + // CHECK: [[J_VAL:%.+]] = load i32, i32* [[J_PRIV]], + // CHECK: [[I_VAL:%.+]] = load i32, i32* [[I_PRIV]], + // CHECK: [[J_COND:%.+]] = add nsw i32 4, [[I_VAL]] + // CHECK: [[CMP:%.+]] = icmp slt i32 [[J_VAL]], [[J_COND]] + // CHECK: br i1 [[CMP]], label %[[NEXT:[^,]+]], label %[[BODY_CONT:[^,]+]] + // CHECK: [[NEXT]]: + + // Main body is empty. + // CHECK: br label %[[BODY_CONT]] + // CHECK: [[BODY_CONT]]: + // CHECK: br label %[[INC:[^,]+]] + // CHECK: [[INC]]: + // CHECK: [[IV_VAL:%.+]] = load i64, i64* [[IV]], + // CHECK: [[ADD:%.+]] = add nsw i64 [[IV_VAL]], 1 + // CHECK: store i64 [[ADD]], i64* [[IV]], + // CHECK: br label %[[COND]] + // CHECK: [[CLEANUP]]: + // CHECK: br label %[[EXIT:[^,]+]] + // CHECK: [[EXIT]]: + // CHECK: call void @__kmpc_for_static_fini(%struct.ident_t* @{{.+}}, i32 %{{.+}}) // LIFETIME: call void @llvm.lifetime.end // LIFETIME: call void @llvm.lifetime.end // LIFETIME: call void @llvm.lifetime.end @@ -40,7 +206,7 @@ void loop_with_counter_collapse() { // LIFETIME: call void @llvm.lifetime.end #pragma omp for collapse(2) for (int i = 0; i < 4; i++) { - for (int j = i; j < 4; j++) { + for (int j = i; j < 4 + i; j++) { } } } @@ -449,13 +615,14 @@ void for_with_references() { // CHECK: [[I:%.+]] = alloca i8, // CHECK: [[CNT:%.+]] = alloca i8*, // CHECK: [[CNT_PRIV:%.+]] = alloca i8, -// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: call void @__kmpc_for_static_init_8( // CHECK-NOT: load i8, i8* [[CNT]], // CHECK: call void @__kmpc_for_static_fini( char i = 0; char &cnt = i; -#pragma omp for +#pragma omp for collapse(2) for (cnt = 0; cnt < 2; ++cnt) + for (int j = cnt; j < 4 + cnt; j++) k = cnt; } @@ -528,13 +695,14 @@ void loop_with_It_plus(It begin, It end) { // CHECK: call void @__kmpc_for_static_fini( void loop_with_stmt_expr() { -#pragma omp for +#pragma omp for collapse(2) for (int i = __extension__({float b = 0;b; }); i < __extension__({double c = 1;c; }); i += __extension__({char d = 1; d; })) + for (int j = i; j < 4 + i; j++) ; } // CHECK-LABEL: loop_with_stmt_expr // CHECK: call i32 @__kmpc_global_thread_num( -// CHECK: call void @__kmpc_for_static_init_4( +// CHECK: call void @__kmpc_for_static_init_8( // CHECK: call void @__kmpc_for_static_fini( diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp index f5f6d0b7031..37c81123e43 100644 --- a/test/OpenMP/for_loop_messages.cpp +++ b/test/OpenMP/for_loop_messages.cpp @@ -651,10 +651,9 @@ class TC { ; #pragma omp parallel -// expected-error@+6 2 {{expected loop invariant expression or ' * ii + ' kind of expression}} -// expected-error@+5 {{expected loop invariant expression or ' * TC::ii + ' kind of expression}} // expected-error@+5 2 {{expected loop invariant expression or ' * ii + ' kind of expression}} // expected-error@+4 {{expected loop invariant expression or ' * TC::ii + ' kind of expression}} +// expected-error@+4 {{expected loop invariant expression or ' * TC::ii + ' kind of expression}} #pragma omp for collapse(3) for (ii = 10 + 25; ii < 1000; ii += 1) for (iii = ii * 10 + 25; iii < ii / ii - 23; iii += 1) diff --git a/test/OpenMP/parallel_messages.cpp b/test/OpenMP/parallel_messages.cpp index ac8869fff9d..c9b6dbc98f0 100644 --- a/test/OpenMP/parallel_messages.cpp +++ b/test/OpenMP/parallel_messages.cpp @@ -102,6 +102,6 @@ struct h { h operator<(h, h); void g::j() { #pragma omp parallel for default(none) if(a::b) - for (auto a = blocks.cbegin; a < blocks; ++a) // expected-error {{invalid operands to binary expression ('f' and 'int')}} + for (auto a = blocks.cbegin; a < blocks; ++a) // expected-error 2 {{invalid operands to binary expression ('f' and 'int')}} ; } From a16001b1bd2c421174838df17f629807c62e7d1b Mon Sep 17 00:00:00 2001 From: Stanislav Mekhanoshin Date: Wed, 14 Aug 2019 20:55:15 +0000 Subject: [PATCH 02/22] [AMDGPU] Do not assume a default GCN target Differential Revision: https://reviews.llvm.org/D66246 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368917 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Basic/Targets/AMDGPU.cpp | 5 +---- test/Driver/amdgpu-mcpu.cl | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/Basic/Targets/AMDGPU.cpp b/lib/Basic/Targets/AMDGPU.cpp index b5c82e28857..ebc9b9d60c2 100644 --- a/lib/Basic/Targets/AMDGPU.cpp +++ b/lib/Basic/Targets/AMDGPU.cpp @@ -131,9 +131,6 @@ bool AMDGPUTargetInfo::initFeatureMap( // XXX - What does the member GPU mean if device name string passed here? if (isAMDGCN(getTriple())) { - if (CPU.empty()) - CPU = "gfx600"; - switch (llvm::AMDGPU::parseArchAMDGCN(CPU)) { case GK_GFX1012: case GK_GFX1011: @@ -189,7 +186,7 @@ bool AMDGPUTargetInfo::initFeatureMap( case GK_GFX600: break; case GK_NONE: - return false; + break; default: llvm_unreachable("Unhandled GPU!"); } diff --git a/test/Driver/amdgpu-mcpu.cl b/test/Driver/amdgpu-mcpu.cl index 1559c7fafc7..3aa507618bf 100644 --- a/test/Driver/amdgpu-mcpu.cl +++ b/test/Driver/amdgpu-mcpu.cl @@ -52,6 +52,7 @@ // AMDGCN-based processors. // +// RUN: %clang -### -target amdgcn %s 2>&1 | FileCheck --check-prefix=GCNDEFAULT %s // RUN: %clang -### -target amdgcn -mcpu=gfx600 %s 2>&1 | FileCheck --check-prefix=GFX600 %s // RUN: %clang -### -target amdgcn -mcpu=tahiti %s 2>&1 | FileCheck --check-prefix=TAHITI %s // RUN: %clang -### -target amdgcn -mcpu=gfx601 %s 2>&1 | FileCheck --check-prefix=GFX601 %s @@ -90,6 +91,7 @@ // RUN: %clang -### -target amdgcn -mcpu=gfx1011 %s 2>&1 | FileCheck --check-prefix=GFX1011 %s // RUN: %clang -### -target amdgcn -mcpu=gfx1012 %s 2>&1 | FileCheck --check-prefix=GFX1012 %s +// GCNDEFAULT-NOT: -target-cpu // GFX600: "-target-cpu" "gfx600" // TAHITI: "-target-cpu" "tahiti" // GFX601: "-target-cpu" "gfx601" From 30684d096269a615b16a1e5310f5dba1e06d64bf Mon Sep 17 00:00:00 2001 From: Matthias Gehre Date: Wed, 14 Aug 2019 21:55:57 +0000 Subject: [PATCH 03/22] [LifetimeAnalysis] Support std::stack::top() and std::optional::value() Summary: Diagnose dangling pointers that come from std::stack::top() and std::optional::value(). Reviewers: gribozavr Subscribers: cfe-commits, xazax.hun Tags: #clang Differential Revision: https://reviews.llvm.org/D66164 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368929 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaInit.cpp | 2 +- test/Sema/warn-lifetime-analysis-nocfg.cpp | 27 ++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 0811d3fd14e..e11cc92e1bb 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -6610,7 +6610,7 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) { OO == OverloadedOperatorKind::OO_Star; } return llvm::StringSwitch(Callee->getName()) - .Cases("front", "back", "at", true) + .Cases("front", "back", "at", "top", "value", true) .Default(false); } return false; diff --git a/test/Sema/warn-lifetime-analysis-nocfg.cpp b/test/Sema/warn-lifetime-analysis-nocfg.cpp index ba3cc1fc969..c8016bf55cb 100644 --- a/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -170,7 +170,15 @@ template struct optional { optional(); optional(const T&); - T &operator*(); + T &operator*() &; + T &&operator*() &&; + T &value() &; + T &&value() &&; +}; + +template +struct stack { + T &top(); }; } @@ -188,6 +196,16 @@ const char *danglingRawPtrFromLocal() { return s.c_str(); // expected-warning {{address of stack memory associated with local variable 's' returned}} } +int &danglingRawPtrFromLocal2() { + std::optional o; + return o.value(); // expected-warning {{reference to stack memory associated with local variable 'o' returned}} +} + +int &danglingRawPtrFromLocal3() { + std::optional o; + return *o; // expected-warning {{reference to stack memory associated with local variable 'o' returned}} +} + const char *danglingRawPtrFromTemp() { return std::basic_string().c_str(); // expected-warning {{returning address of local temporary object}} } @@ -203,9 +221,10 @@ int *danglingUniquePtrFromTemp2() { } void danglingReferenceFromTempOwner() { - int &r = *std::optional(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} - int &r2 = *std::optional(5); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} - int &r3 = std::vector().at(3); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + int &&r = *std::optional(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + int &&r2 = *std::optional(5); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + int &&r3 = std::optional(5).value(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + int &r4 = std::vector().at(3); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} } std::vector getTempVec(); From 68afe3d5dccef33e028c8a1f9609852396e7217a Mon Sep 17 00:00:00 2001 From: JF Bastien Date: Wed, 14 Aug 2019 22:48:12 +0000 Subject: [PATCH 04/22] Remove LVALUE / RVALUE workarounds Summary: LLVM_HAS_RVALUE_REFERENCE_THIS and LLVM_LVALUE_FUNCTION shouldn't be needed anymore because the minimum compiler versions support them. Subscribers: jkorous, dexonsmith, cfe-commits, llvm-commits, hans, thakis, chandlerc, rnk Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D66240 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368939 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index 864266e77ee..bccdcf2d922 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -167,7 +167,7 @@ class ExplodedNode : public llvm::FoldingSetNode { const ProgramStateRef &getState() const { return State; } template - Optional getLocationAs() const LLVM_LVALUE_FUNCTION { + Optional getLocationAs() const & { return Location.getAs(); } From e88444ece6df0a3685bd7b8e80a7a9ab43fa17e8 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 14 Aug 2019 22:57:50 +0000 Subject: [PATCH 05/22] Fix handling of class member access into a vector type. When handling a member access into a non-class, non-ObjC-object type, we would perform a lookup into the surrounding scope as if for an unqualified lookup. If the member access was followed by a '<' and this lookup (or the typo-correction for it) found a template name, we'd treat the member access as naming that template. Now we treat such accesses as never naming a template if the type of the object expression is of vector type, so that vector component accesses are never misinterpreted as naming something else. This is not entirely correct, since it is in fact valid to name a template from the enclosing scope in this context, when invoking a pseudo-destructor for the vector type via an alias template, but that's very much a corner case, and this change leaves that case only as broken as the corresponding case for Objective-C types is. This incidentally adds support for dr2292, which permits a 'template' keyword at the start of a member access naming a pseudo-destructor. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368940 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprCXX.cpp | 6 +----- lib/Sema/SemaTemplate.cpp | 20 +++++++++++++++++--- test/CXX/drs/dr22xx.cpp | 9 +++++++++ test/CXX/drs/dr4xx.cpp | 4 ++-- test/SemaCXX/cxx2a-adl-only-template-id.cpp | 8 ++++++++ test/SemaCXX/pseudo-destructors.cpp | 4 ++-- test/SemaCXX/vector.cpp | 16 ++++++++++++++++ 7 files changed, 55 insertions(+), 12 deletions(-) diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 8f882e4ca32..7c68e4d9145 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -6794,14 +6794,10 @@ ExprResult Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, // it's legal for the type to be incomplete if this is a pseudo-destructor // call. We'll do more incomplete-type checks later in the lookup process, // so just skip this check for ObjC types. - if (BaseType->isObjCObjectOrInterfaceType()) { + if (!BaseType->isRecordType()) { ObjectType = ParsedType::make(BaseType); MayBePseudoDestructor = true; return Base; - } else if (!BaseType->isRecordType()) { - ObjectType = nullptr; - MayBePseudoDestructor = true; - return Base; } // The object type must be complete (or dependent), or diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 3df74edf2f9..ce0c2ef4022 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -362,13 +362,27 @@ bool Sema::LookupTemplateName(LookupResult &Found, // x->B::f, and we are looking into the type of the object. assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist"); LookupCtx = computeDeclContext(ObjectType); - IsDependent = !LookupCtx; + IsDependent = !LookupCtx && ObjectType->isDependentType(); assert((IsDependent || !ObjectType->isIncompleteType() || ObjectType->castAs()->isBeingDefined()) && "Caller should have completed object type"); - // Template names cannot appear inside an Objective-C class or object type. - if (ObjectType->isObjCObjectOrInterfaceType()) { + // Template names cannot appear inside an Objective-C class or object type + // or a vector type. + // + // FIXME: This is wrong. For example: + // + // template using Vec = T __attribute__((ext_vector_type(4))); + // Vec vi; + // vi.Vec::~Vec(); + // + // ... should be accepted but we will not treat 'Vec' as a template name + // here. The right thing to do would be to check if the name is a valid + // vector component name, and look up a template name if not. And similarly + // for lookups into Objective-C class and object types, where the same + // problem can arise. + if (ObjectType->isObjCObjectOrInterfaceType() || + ObjectType->isVectorType()) { Found.clear(); return false; } diff --git a/test/CXX/drs/dr22xx.cpp b/test/CXX/drs/dr22xx.cpp index 70a26db757c..8896281e9ca 100644 --- a/test/CXX/drs/dr22xx.cpp +++ b/test/CXX/drs/dr22xx.cpp @@ -26,3 +26,12 @@ void f() { } } #endif + +namespace dr2292 { // dr2292: 9 +#if __cplusplus >= 201103L + template using id = T; + void test(int *p) { + p->template id::~id(); + } +#endif +} diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp index 00393cc2e4c..8eeb7715cad 100644 --- a/test/CXX/drs/dr4xx.cpp +++ b/test/CXX/drs/dr4xx.cpp @@ -318,8 +318,8 @@ namespace dr420 { // dr420: yes q->~id(); p->id::~id(); q->id::~id(); - p->template id::~id(); // expected-error {{'template' keyword not permitted here}} expected-error {{base type 'int' is not a struct}} - q->template id::~id(); // expected-error {{'template' keyword not permitted here}} expected-error {{base type 'int' is not a struct}} + p->template id::~id(); // OK since dr2292 + q->template id::~id(); // OK since dr2292 p->A::template id::~id(); q->A::template id::~id(); } diff --git a/test/SemaCXX/cxx2a-adl-only-template-id.cpp b/test/SemaCXX/cxx2a-adl-only-template-id.cpp index 4bd9a22f5f4..28ecbade1b1 100644 --- a/test/SemaCXX/cxx2a-adl-only-template-id.cpp +++ b/test/SemaCXX/cxx2a-adl-only-template-id.cpp @@ -65,3 +65,11 @@ void xf(g x); // expected-error {{variable has incomplete type 'void'}} exp struct B : g { // expected-error {{expected class name}} B() : g() {} // expected-error {{expected class member or base class name}} }; + +namespace vector_components { + typedef __attribute__((__ext_vector_type__(2))) float vector_float2; + bool foo123(vector_float2 &A, vector_float2 &B) + { + return A.x < B.x && B.y > A.y; + } +} diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp index 08938bf34a7..fb2d0afdc3f 100644 --- a/test/SemaCXX/pseudo-destructors.cpp +++ b/test/SemaCXX/pseudo-destructors.cpp @@ -34,7 +34,7 @@ void f(A* a, Foo *f, int *i, double *d, int ii) { g().~Bar(); // expected-error{{non-scalar}} f->::~Bar(); - f->N::~Wibble(); // FIXME: technically, Wibble isn't a class-name + f->N::~Wibble(); // expected-error{{'N' does not refer to a type}} expected-error{{'Wibble' does not refer to a type}} f->::~Bar(17, 42); // expected-error{{cannot have any arguments}} @@ -79,7 +79,7 @@ namespace PR11339 { template void destroy(T* p) { p->~T(); // ok - p->~oops(); // expected-error{{expected the class name after '~' to name a destructor}} + p->~oops(); // expected-error{{identifier 'oops' in object destruction expression does not name a type}} } template void destroy(int*); // expected-note{{in instantiation of function template specialization}} diff --git a/test/SemaCXX/vector.cpp b/test/SemaCXX/vector.cpp index 40dcd35c1bb..295e1e17323 100644 --- a/test/SemaCXX/vector.cpp +++ b/test/SemaCXX/vector.cpp @@ -342,3 +342,19 @@ void test_vector_literal(inte4 res) { inte4 b = (inte4)(a, a); //expected-error{{C-style cast from vector 'inte2' (vector of 2 'int' values) to vector 'inte4' (vector of 4 'int' values) of different size}} //expected-warning{{expression result unused}} } +typedef __attribute__((__ext_vector_type__(4))) float vector_float4; +typedef __attribute__((__ext_vector_type__(4))) int vector_int4; + +namespace swizzle_template_confusion { + template struct xyzw {}; + vector_int4 foo123(vector_float4 &A, vector_float4 &B) { + return A.xyzw < B.x && B.y > A.y; // OK, not a template-id + } +} + +namespace swizzle_typo_correction { + template struct xyzv {}; + vector_int4 foo123(vector_float4 &A, vector_float4 &B) { + return A.xyzw < B.x && B.y > A.y; // OK, not a typo for 'xyzv' + } +} From 7410a82389827d6c4f3e9a209445a60f26c8be54 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 14 Aug 2019 22:57:51 +0000 Subject: [PATCH 06/22] [www] Update DR status page to match latest version of CWG issues list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368941 91177308-0d34-0410-b5e6-96231b3b80d8 --- www/cxx_dr_status.html | 166 +++++++++++++++++++++++++++++++++-------- 1 file changed, 134 insertions(+), 32 deletions(-) diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html index f36db8aae96..a8172eb43d4 100755 --- a/www/cxx_dr_status.html +++ b/www/cxx_dr_status.html @@ -4131,11 +4131,11 @@

C++ defect report implementation status

Restrictions on declarators with late-specified return types Partial - + 682 - drafting + tentatively ready Missing description of lookup of template aliases - Not resolved + Unknown 683 @@ -10847,7 +10847,7 @@

C++ defect report implementation status

1839 - drafting + review Lookup of block-scope extern declarations Not resolved @@ -13053,11 +13053,11 @@

C++ defect report implementation status

Composite type of object and function pointers Unknown - + 2207 - drafting + tentatively ready Alignment of allocation function return value - Not resolved + Unknown 2208 @@ -13567,7 +13567,7 @@

C++ defect report implementation status

2292 DRWP simple-template-id is ambiguous between class-name and type-name - Unknown + SVN 2293 @@ -13611,11 +13611,11 @@

C++ defect report implementation status

constexpr vararg functions Unknown - + 2300 - drafting + tentatively ready Lambdas in multiple definitions - Not resolved + Unknown 2301 @@ -13797,11 +13797,11 @@

C++ defect report implementation status

Missing references to variable templates Unknown - + 2331 - DR + drafting Redundancy in description of class scope - Unknown + Not resolved 2332 @@ -13895,7 +13895,7 @@

C++ defect report implementation status

2347 - drafting + review Passing short scoped enumerations to ellipsis Not resolved @@ -14007,11 +14007,11 @@

C++ defect report implementation status

Confusing specification for dynamic_cast Unknown - + 2366 - drafting + tentatively ready Can default initialization be constant initialization? - Not resolved + Unknown 2367 @@ -14057,7 +14057,7 @@

C++ defect report implementation status

2374 - drafting + review Overly permissive specification of enum direct-list-initialization Not resolved @@ -14067,11 +14067,11 @@

C++ defect report implementation status

Multiple redeclarations of constexpr static data members Unknown - + 2376 - drafting + tentatively ready Class template argument deduction with array declarator - Not resolved + Unknown 2377 @@ -14139,11 +14139,11 @@

C++ defect report implementation status

Linkage of const-qualified variable template SVN - + 2388 - drafting + NAD Applicability of contract-attribute-specifiers - Not resolved + Unknown 2389 @@ -14151,11 +14151,11 @@

C++ defect report implementation status

Agreement of deduced and explicitly-specified variable types Not resolved - + 2390 - drafting + tentatively ready Is the argument of __has_cpp_attribute macro-expanded? - Not resolved + Unknown 2391 @@ -14207,15 +14207,15 @@

C++ defect report implementation status

2399 - drafting + review Unclear referent of “expression” in assignment-expression Not resolved - + 2400 - drafting + tentatively ready Constexpr virtual functions and temporary objects - Not resolved + Unknown 2401 @@ -14229,6 +14229,108 @@

C++ defect report implementation status

When is the restriction to a single c-char in a Unicode literal enforced? Not resolved + + 2403 + open + Temporary materialization and base/member initialization + Not resolved + + + 2404 + tentatively ready + [[no_unique_address]] and allocation order + Unknown + + + 2405 + drafting + Additional type-dependent expressions + Not resolved + + + 2406 + tentatively ready + [[fallthrough]] attribute and iteration statements + Unknown + + + 2407 + review + Missing entry in Annex C for defaulted comparison operators + Not resolved + + + 2408 + open + Temporaries and previously-initialized elements in aggregate initialization + Not resolved + + + 2409 + drafting + Explicit specializations of constexpr static data members + Not resolved + + + 2410 + review + Implicit calls of immediate functions + Not resolved + + + 2411 + open + Comparison of pointers to members in template non-type arguments + Not resolved + + + 2412 + open + SFINAE vs undeduced placeholder type + Not resolved + + + 2413 + drafting + typename in conversion-function-ids + Not resolved + + + 2414 + drafting + Unclear results if both member and friend operator<=> are declared + Not resolved + + + 2415 + NAD + using-declarations vs copy assignment operators + Unknown + + + 2416 + open + Explicit specializations vs constexpr and consteval + Not resolved + + + 2417 + open + Explicit instantiation and exception specifications + Not resolved + + + 2418 + tentatively ready + Missing cases in definition of “usable in constant expressions” + Unknown + + + 2419 + open + Loss of generality treating pointers to objects as one-element arrays + Not resolved + From 49a6b091014f0033829e099ea7ac50bc7b6e9c32 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 14 Aug 2019 23:04:18 +0000 Subject: [PATCH 07/22] [Clang] Migrate llvm::make_unique to std::make_unique Now that we've moved to C++14, we no longer need the llvm::make_unique implementation from STLExtras.h. This patch is a mechanical replacement of (hopefully) all the llvm::make_unique instances across the monorepo. Differential revision: https://reviews.llvm.org/D66259 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368942 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AnnotateFunctions/AnnotateFunctions.cpp | 2 +- .../PrintFunctionNames/PrintFunctionNames.cpp | 2 +- examples/clang-interpreter/main.cpp | 2 +- include/clang/AST/ASTImporterSharedState.h | 2 +- include/clang/Basic/SyncScope.h | 2 +- include/clang/Frontend/ASTUnit.h | 2 +- include/clang/Lex/Preprocessor.h | 4 +- include/clang/Sema/SemaInternal.h | 2 +- include/clang/Sema/TypoCorrection.h | 8 +- include/clang/Serialization/ASTReader.h | 4 +- .../Core/BugReporter/BugReporter.h | 2 +- .../Core/PathSensitive/ExplodedGraph.h | 2 +- include/clang/Tooling/ASTDiff/ASTDiff.h | 2 +- .../RefactoringActionRulesInternal.h | 2 +- lib/ARCMigrate/ARCMT.cpp | 4 +- lib/ARCMigrate/ObjCMT.cpp | 6 +- lib/AST/ASTContext.cpp | 2 +- lib/AST/CXXInheritance.cpp | 2 +- lib/AST/ExternalASTMerger.cpp | 2 +- lib/AST/ItaniumCXXABI.cpp | 2 +- lib/AST/Mangle.cpp | 2 +- lib/AST/MicrosoftCXXABI.cpp | 2 +- lib/AST/VTableBuilder.cpp | 12 +- lib/ASTMatchers/ASTMatchFinder.cpp | 2 +- lib/ASTMatchers/Dynamic/Marshallers.h | 14 +- lib/ASTMatchers/Dynamic/Registry.cpp | 2 +- lib/Analysis/AnalysisDeclContext.cpp | 2 +- lib/Analysis/CallGraph.cpp | 2 +- lib/Analysis/Consumed.cpp | 6 +- lib/Analysis/ThreadSafety.cpp | 30 ++-- .../SampleAnalyzer/MainCallChecker.cpp | 2 +- lib/Basic/FileManager.cpp | 4 +- lib/Basic/SourceManager.cpp | 10 +- lib/CodeGen/BackendUtil.cpp | 6 +- lib/CodeGen/CGCall.cpp | 8 +- lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp | 4 +- lib/CodeGen/CodeGenAction.cpp | 6 +- lib/CodeGen/CodeGenModule.cpp | 2 +- lib/CodeGen/CodeGenPGO.cpp | 2 +- .../ObjectFilePCHContainerOperations.cpp | 4 +- .../linux/DirectoryWatcher-linux.cpp | 4 +- .../mac/DirectoryWatcher-mac.cpp | 2 +- lib/Driver/Driver.cpp | 96 ++++++------- lib/Driver/DriverOptions.cpp | 2 +- lib/Driver/ToolChains/AMDGPU.cpp | 2 +- lib/Driver/ToolChains/AVR.cpp | 2 +- lib/Driver/ToolChains/Ananas.cpp | 4 +- lib/Driver/ToolChains/BareMetal.cpp | 2 +- lib/Driver/ToolChains/Clang.cpp | 16 +-- lib/Driver/ToolChains/CloudABI.cpp | 2 +- lib/Driver/ToolChains/CommonArgs.cpp | 4 +- lib/Driver/ToolChains/CrossWindows.cpp | 4 +- lib/Driver/ToolChains/Cuda.cpp | 6 +- lib/Driver/ToolChains/Darwin.cpp | 12 +- lib/Driver/ToolChains/DragonFly.cpp | 4 +- lib/Driver/ToolChains/FreeBSD.cpp | 4 +- lib/Driver/ToolChains/Fuchsia.cpp | 2 +- lib/Driver/ToolChains/Gnu.cpp | 6 +- lib/Driver/ToolChains/HIP.cpp | 10 +- lib/Driver/ToolChains/Hexagon.cpp | 4 +- lib/Driver/ToolChains/MSP430.cpp | 2 +- lib/Driver/ToolChains/MSVC.cpp | 4 +- lib/Driver/ToolChains/MinGW.cpp | 4 +- lib/Driver/ToolChains/Minix.cpp | 4 +- lib/Driver/ToolChains/Myriad.cpp | 6 +- lib/Driver/ToolChains/NaCl.cpp | 2 +- lib/Driver/ToolChains/NetBSD.cpp | 4 +- lib/Driver/ToolChains/OpenBSD.cpp | 4 +- lib/Driver/ToolChains/PS4CPU.cpp | 6 +- lib/Driver/ToolChains/RISCVToolchain.cpp | 2 +- lib/Driver/ToolChains/Solaris.cpp | 4 +- lib/Driver/ToolChains/WebAssembly.cpp | 2 +- lib/Driver/ToolChains/XCore.cpp | 4 +- lib/Format/ContinuationIndenter.cpp | 6 +- lib/Format/Format.cpp | 4 +- lib/Format/UnwrappedLineParser.cpp | 2 +- lib/Frontend/ASTConsumers.cpp | 8 +- lib/Frontend/ASTUnit.cpp | 14 +- lib/Frontend/ChainedIncludesSource.cpp | 2 +- lib/Frontend/CompilerInstance.cpp | 14 +- .../CreateInvocationFromCommandLine.cpp | 2 +- lib/Frontend/DependencyFile.cpp | 6 +- lib/Frontend/DependencyGraph.cpp | 2 +- lib/Frontend/FrontendAction.cpp | 2 +- lib/Frontend/FrontendActions.cpp | 20 +-- lib/Frontend/HeaderIncludeGen.cpp | 2 +- .../InterfaceStubFunctionsConsumer.cpp | 4 +- lib/Frontend/ModuleDependencyCollector.cpp | 6 +- lib/Frontend/MultiplexConsumer.cpp | 4 +- lib/Frontend/PrecompiledPreamble.cpp | 4 +- lib/Frontend/PrintPreprocessedOutput.cpp | 2 +- lib/Frontend/Rewrite/FrontendActions.cpp | 4 +- lib/Frontend/Rewrite/HTMLPrint.cpp | 2 +- lib/Frontend/Rewrite/RewriteModernObjC.cpp | 2 +- lib/Frontend/Rewrite/RewriteObjC.cpp | 2 +- lib/Frontend/SerializedDiagnosticPrinter.cpp | 6 +- lib/Frontend/VerifyDiagnosticConsumer.cpp | 6 +- .../ExecuteCompilerInvocation.cpp | 86 ++++++------ lib/Index/IndexingAction.cpp | 12 +- lib/Lex/PPDirectives.cpp | 4 +- lib/Lex/PPLexerChange.cpp | 4 +- lib/Lex/PPMacroExpansion.cpp | 2 +- lib/Lex/Pragma.cpp | 2 +- lib/Lex/Preprocessor.cpp | 4 +- lib/Parse/ParseCXXInlineMethods.cpp | 2 +- lib/Parse/ParseExpr.cpp | 2 +- lib/Parse/ParsePragma.cpp | 90 ++++++------ lib/Parse/ParseStmt.cpp | 2 +- lib/Parse/ParseTentative.cpp | 2 +- lib/Sema/Sema.cpp | 2 +- lib/Sema/SemaCXXScopeSpec.cpp | 2 +- lib/Sema/SemaDecl.cpp | 6 +- lib/Sema/SemaDeclCXX.cpp | 6 +- lib/Sema/SemaDeclObjC.cpp | 4 +- lib/Sema/SemaExpr.cpp | 2 +- lib/Sema/SemaExprMember.cpp | 2 +- lib/Sema/SemaExprObjC.cpp | 2 +- lib/Sema/SemaInit.cpp | 2 +- lib/Sema/SemaLookup.cpp | 2 +- lib/Sema/SemaOpenMP.cpp | 4 +- lib/Sema/SemaTemplate.cpp | 6 +- lib/Sema/SemaTemplateVariadic.cpp | 2 +- lib/Serialization/ASTReader.cpp | 2 +- lib/Serialization/ModuleManager.cpp | 2 +- lib/Serialization/PCHContainerOperations.cpp | 6 +- .../Checkers/ArrayBoundChecker.cpp | 2 +- .../Checkers/ArrayBoundCheckerV2.cpp | 4 +- .../Checkers/BasicObjCFoundationChecks.cpp | 10 +- .../BlockInCriticalSectionChecker.cpp | 2 +- .../Checkers/BoolAssignmentChecker.cpp | 2 +- .../Checkers/CStringChecker.cpp | 10 +- .../Checkers/CallAndMessageChecker.cpp | 16 +-- .../Checkers/CastSizeChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/ChrootChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/CloneChecker.cpp | 4 +- .../Checkers/ConversionChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/DebugCheckers.cpp | 2 +- .../DeleteWithNonVirtualDtorChecker.cpp | 4 +- .../Checkers/DereferenceChecker.cpp | 4 +- .../Checkers/DivZeroChecker.cpp | 4 +- .../Checkers/DynamicTypeChecker.cpp | 2 +- .../Checkers/DynamicTypePropagation.cpp | 2 +- .../Checkers/EnumCastOutOfRangeChecker.cpp | 2 +- .../Checkers/ExprInspectionChecker.cpp | 2 +- .../Checkers/FixedAddressChecker.cpp | 2 +- .../Checkers/GenericTaintChecker.cpp | 4 +- .../Checkers/InnerPointerChecker.cpp | 2 +- .../Checkers/IteratorChecker.cpp | 8 +- .../Checkers/LocalizationChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/MIGChecker.cpp | 2 +- .../Checkers/MPI-Checker/MPIBugReporter.cpp | 10 +- .../Checkers/MacOSKeychainAPIChecker.cpp | 14 +- .../Checkers/MacOSXAPIChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 32 ++--- .../Checkers/MmapWriteExecChecker.cpp | 2 +- lib/StaticAnalyzer/Checkers/MoveChecker.cpp | 4 +- .../Checkers/NSAutoreleasePoolChecker.cpp | 2 +- .../Checkers/NSErrorChecker.cpp | 2 +- .../Checkers/NonNullParamChecker.cpp | 4 +- .../Checkers/NullabilityChecker.cpp | 4 +- .../Checkers/ObjCAtSyncChecker.cpp | 4 +- .../Checkers/ObjCContainersChecker.cpp | 2 +- .../Checkers/ObjCSelfInitChecker.cpp | 2 +- .../Checkers/ObjCSuperDeallocChecker.cpp | 2 +- .../Checkers/PaddingChecker.cpp | 4 +- .../Checkers/PointerArithChecker.cpp | 4 +- .../Checkers/PointerSubChecker.cpp | 2 +- .../Checkers/PthreadLockChecker.cpp | 12 +- .../RetainCountChecker/RetainCountChecker.cpp | 10 +- .../RetainCountDiagnostics.cpp | 6 +- .../Checkers/ReturnPointerRangeChecker.cpp | 2 +- .../Checkers/ReturnUndefChecker.cpp | 2 +- .../Checkers/SimpleStreamChecker.cpp | 4 +- .../Checkers/StackAddrEscapeChecker.cpp | 16 +-- lib/StaticAnalyzer/Checkers/StreamChecker.cpp | 8 +- .../Checkers/TaintTesterChecker.cpp | 2 +- .../Checkers/TestAfterDivZeroChecker.cpp | 4 +- .../Checkers/UndefBranchChecker.cpp | 2 +- .../Checkers/UndefCapturedBlockVarChecker.cpp | 4 +- .../Checkers/UndefResultChecker.cpp | 2 +- .../UndefinedArraySubscriptChecker.cpp | 2 +- .../Checkers/UndefinedAssignmentChecker.cpp | 2 +- .../UninitializedObjectChecker.cpp | 4 +- .../Checkers/UnixAPIChecker.cpp | 6 +- .../Checkers/VLASizeChecker.cpp | 4 +- lib/StaticAnalyzer/Checkers/ValistChecker.cpp | 8 +- lib/StaticAnalyzer/Checkers/VforkChecker.cpp | 2 +- .../Checkers/VirtualCallChecker.cpp | 4 +- lib/StaticAnalyzer/Core/BugReporter.cpp | 26 ++-- .../Core/BugReporterVisitors.cpp | 28 ++-- .../Core/RangeConstraintManager.cpp | 2 +- lib/StaticAnalyzer/Core/RegionStore.cpp | 4 +- .../Core/SMTConstraintManager.cpp | 2 +- lib/StaticAnalyzer/Core/WorkList.cpp | 12 +- .../Frontend/AnalysisConsumer.cpp | 12 +- .../Frontend/CheckerRegistration.cpp | 2 +- .../Frontend/FrontendActions.cpp | 2 +- lib/Tooling/ASTDiff/ASTDiff.cpp | 16 +-- lib/Tooling/AllTUsExecution.cpp | 2 +- lib/Tooling/CommonOptionsParser.cpp | 2 +- lib/Tooling/CompilationDatabase.cpp | 4 +- .../DependencyScanningFilesystem.cpp | 4 +- .../DependencyScanningWorker.cpp | 4 +- .../GuessTargetAndModeCompilationDatabase.cpp | 2 +- .../InterpolatingCompilationDatabase.cpp | 2 +- .../Refactoring/ASTSelectionRequirements.cpp | 2 +- .../Refactoring/RefactoringActions.cpp | 4 +- .../Refactoring/Rename/RenamingAction.cpp | 4 +- .../Refactoring/Rename/SymbolOccurrences.cpp | 2 +- .../Refactoring/Rename/USRFindingAction.cpp | 2 +- lib/Tooling/RefactoringCallbacks.cpp | 2 +- lib/Tooling/StandaloneExecution.cpp | 2 +- lib/Tooling/Syntax/Tokens.cpp | 2 +- tools/c-index-test/core_main.cpp | 2 +- tools/clang-check/ClangCheck.cpp | 2 +- tools/clang-diff/ClangDiff.cpp | 4 +- .../ClangExtDefMapGen.cpp | 2 +- .../clang-fuzzer/handle-llvm/handle_llvm.cpp | 2 +- tools/clang-import-test/clang-import-test.cpp | 22 +-- tools/clang-refactor/ClangRefactor.cpp | 12 +- tools/clang-refactor/TestSupport.cpp | 2 +- tools/clang-scan-deps/ClangScanDeps.cpp | 4 +- tools/driver/cc1_main.cpp | 4 +- tools/driver/cc1as_main.cpp | 8 +- tools/libclang/CIndex.cpp | 2 +- tools/libclang/CIndexDiagnostic.cpp | 6 +- tools/libclang/CIndexer.cpp | 2 +- tools/libclang/CXLoadedDiagnostic.cpp | 4 +- tools/libclang/Indexing.cpp | 8 +- unittests/AST/EvaluateAsRValueTest.cpp | 2 +- unittests/AST/ExternalASTSourceTest.cpp | 2 +- unittests/AST/RecursiveASTVisitorTest.cpp | 2 +- .../ASTMatchers/ASTMatchersInternalTest.cpp | 12 +- .../ASTMatchers/ASTMatchersNarrowingTest.cpp | 26 ++-- unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 10 +- .../ASTMatchers/ASTMatchersTraversalTest.cpp | 130 +++++++++--------- unittests/ASTMatchers/Dynamic/ParserTest.cpp | 8 +- unittests/Basic/FileManagerTest.cpp | 22 +-- unittests/Basic/SourceManagerTest.cpp | 2 +- .../CrossTU/CrossTranslationUnitTest.cpp | 2 +- unittests/Frontend/ASTUnitTest.cpp | 2 +- unittests/Frontend/CompilerInstanceTest.cpp | 2 +- unittests/Frontend/FrontendActionTest.cpp | 2 +- unittests/Index/IndexTests.cpp | 2 +- unittests/Lex/LexerTest.cpp | 2 +- unittests/Sema/CodeCompleteTest.cpp | 2 +- unittests/Sema/ExternalSemaSourceTest.cpp | 2 +- .../StaticAnalyzer/CallDescriptionTest.cpp | 2 +- unittests/StaticAnalyzer/StoreTest.cpp | 2 +- unittests/StaticAnalyzer/SymbolReaperTest.cpp | 2 +- unittests/Tooling/CompilationDatabaseTest.cpp | 6 +- unittests/Tooling/ExecutionTest.cpp | 2 +- unittests/Tooling/RefactoringTest.cpp | 2 +- unittests/Tooling/Syntax/TokensTest.cpp | 2 +- unittests/Tooling/Syntax/TreeTest.cpp | 6 +- unittests/Tooling/TestVisitor.h | 2 +- unittests/Tooling/ToolingTest.cpp | 16 +-- utils/TableGen/ClangAttrEmitter.cpp | 44 +++--- utils/TableGen/NeonEmitter.cpp | 8 +- 259 files changed, 831 insertions(+), 831 deletions(-) diff --git a/examples/AnnotateFunctions/AnnotateFunctions.cpp b/examples/AnnotateFunctions/AnnotateFunctions.cpp index 96eb78eb17d..d201bf3df89 100644 --- a/examples/AnnotateFunctions/AnnotateFunctions.cpp +++ b/examples/AnnotateFunctions/AnnotateFunctions.cpp @@ -41,7 +41,7 @@ class AnnotateFunctionsAction : public PluginASTAction { public: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) override { - return llvm::make_unique(); + return std::make_unique(); } bool ParseArgs(const CompilerInstance &CI, diff --git a/examples/PrintFunctionNames/PrintFunctionNames.cpp b/examples/PrintFunctionNames/PrintFunctionNames.cpp index e573ac93eb3..6509a6440e1 100644 --- a/examples/PrintFunctionNames/PrintFunctionNames.cpp +++ b/examples/PrintFunctionNames/PrintFunctionNames.cpp @@ -81,7 +81,7 @@ class PrintFunctionNamesAction : public PluginASTAction { protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) override { - return llvm::make_unique(CI, ParsedTemplates); + return std::make_unique(CI, ParsedTemplates); } bool ParseArgs(const CompilerInstance &CI, diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp index b81b7ebbb61..134d70774f8 100644 --- a/examples/clang-interpreter/main.cpp +++ b/examples/clang-interpreter/main.cpp @@ -58,7 +58,7 @@ class SimpleJIT { IRCompileLayer CompileLayer{ES, ObjectLayer, SimpleCompiler(*TM)}; static std::unique_ptr createMemMgr() { - return llvm::make_unique(); + return std::make_unique(); } SimpleJIT( diff --git a/include/clang/AST/ASTImporterSharedState.h b/include/clang/AST/ASTImporterSharedState.h index 3635a62deef..829eb1c611c 100644 --- a/include/clang/AST/ASTImporterSharedState.h +++ b/include/clang/AST/ASTImporterSharedState.h @@ -47,7 +47,7 @@ class ASTImporterSharedState { ASTImporterSharedState() = default; ASTImporterSharedState(TranslationUnitDecl &ToTU) { - LookupTable = llvm::make_unique(ToTU); + LookupTable = std::make_unique(ToTU); } ASTImporterLookupTable *getLookupTable() { return LookupTable.get(); } diff --git a/include/clang/Basic/SyncScope.h b/include/clang/Basic/SyncScope.h index 15af02d83cd..ce8fb9cbed1 100644 --- a/include/clang/Basic/SyncScope.h +++ b/include/clang/Basic/SyncScope.h @@ -144,7 +144,7 @@ AtomicScopeModel::create(AtomicScopeModelKind K) { case AtomicScopeModelKind::None: return std::unique_ptr{}; case AtomicScopeModelKind::OpenCL: - return llvm::make_unique(); + return std::make_unique(); } llvm_unreachable("Invalid atomic scope model kind"); } diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 4491bf298c1..08cc91946eb 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -315,7 +315,7 @@ class ASTUnit { CodeCompletionTUInfo &getCodeCompletionTUInfo() { if (!CCTUInfo) - CCTUInfo = llvm::make_unique( + CCTUInfo = std::make_unique( std::make_shared()); return *CCTUInfo; } diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index f65b0cda462..fdf4bebd87f 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -994,7 +994,7 @@ class Preprocessor { PPCallbacks *getPPCallbacks() const { return Callbacks.get(); } void addPPCallbacks(std::unique_ptr C) { if (Callbacks) - C = llvm::make_unique(std::move(C), + C = std::make_unique(std::move(C), std::move(Callbacks)); Callbacks = std::move(C); } @@ -1471,7 +1471,7 @@ class Preprocessor { if (LexLevel) { // It's not correct in general to enter caching lex mode while in the // middle of a nested lexing action. - auto TokCopy = llvm::make_unique(1); + auto TokCopy = std::make_unique(1); TokCopy[0] = Tok; EnterTokenStream(std::move(TokCopy), 1, true, IsReinject); } else { diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index dfb34daa14d..cdaf7b70a92 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -97,7 +97,7 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer { bool EnteringContext) : Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0), SavedTCIndex(0), SemaRef(SemaRef), S(S), - SS(SS ? llvm::make_unique(*SS) : nullptr), + SS(SS ? std::make_unique(*SS) : nullptr), CorrectionValidator(std::move(CCC)), MemberContext(MemberContext), Result(SemaRef, TypoName, LookupKind), Namespaces(SemaRef.Context, SemaRef.CurContext, SS), diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h index b49a96c0b93..e0f8d152dbe 100644 --- a/include/clang/Sema/TypoCorrection.h +++ b/include/clang/Sema/TypoCorrection.h @@ -356,7 +356,7 @@ class DefaultFilterCCC final : public CorrectionCandidateCallback { : CorrectionCandidateCallback(Typo, TypoNNS) {} std::unique_ptr clone() override { - return llvm::make_unique(*this); + return std::make_unique(*this); } }; @@ -369,7 +369,7 @@ class DeclFilterCCC final : public CorrectionCandidateCallback { return candidate.getCorrectionDeclAs(); } std::unique_ptr clone() override { - return llvm::make_unique(*this); + return std::make_unique(*this); } }; @@ -384,7 +384,7 @@ class FunctionCallFilterCCC : public CorrectionCandidateCallback { bool ValidateCandidate(const TypoCorrection &candidate) override; std::unique_ptr clone() override { - return llvm::make_unique(*this); + return std::make_unique(*this); } private: @@ -409,7 +409,7 @@ class NoTypoCorrectionCCC final : public CorrectionCandidateCallback { return false; } std::unique_ptr clone() override { - return llvm::make_unique(*this); + return std::make_unique(*this); } }; diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 37bea48d884..13d16539cc5 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1578,7 +1578,7 @@ class ASTReader /// Takes ownership of \p L. void addListener(std::unique_ptr L) { if (Listener) - L = llvm::make_unique(std::move(L), + L = std::make_unique(std::move(L), std::move(Listener)); Listener = std::move(L); } @@ -1594,7 +1594,7 @@ class ASTReader auto Old = Reader.takeListener(); if (Old) { Chained = true; - L = llvm::make_unique(std::move(L), + L = std::make_unique(std::move(L), std::move(Old)); } Reader.setListener(std::move(L)); diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index c3d7ba3120f..f68e231a1f0 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -646,7 +646,7 @@ class NoteTag : public ProgramPointTag { public: const NoteTag *makeNoteTag(Callback &&Cb, bool IsPrunable = false) { - // We cannot use make_unique because we cannot access the private + // We cannot use std::make_unique because we cannot access the private // constructor from inside it. std::unique_ptr T(new NoteTag(std::move(Cb), IsPrunable)); Tags.push_back(std::move(T)); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index bccdcf2d922..07fb937e393 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -337,7 +337,7 @@ class ExplodedGraph { bool IsSink = false); std::unique_ptr MakeEmptyGraph() const { - return llvm::make_unique(); + return std::make_unique(); } /// addRoot - Add an untyped node to the set of roots. diff --git a/include/clang/Tooling/ASTDiff/ASTDiff.h b/include/clang/Tooling/ASTDiff/ASTDiff.h index d6cbc09dced..c1cc124e1e9 100644 --- a/include/clang/Tooling/ASTDiff/ASTDiff.h +++ b/include/clang/Tooling/ASTDiff/ASTDiff.h @@ -71,7 +71,7 @@ class SyntaxTree { /// Constructs a tree from any AST node. template SyntaxTree(T *Node, ASTContext &AST) - : TreeImpl(llvm::make_unique(this, Node, AST)) {} + : TreeImpl(std::make_unique(this, Node, AST)) {} SyntaxTree(SyntaxTree &&Other) = default; ~SyntaxTree(); diff --git a/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h b/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h index cc6ae83202f..aaa9e50faa9 100644 --- a/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h +++ b/include/clang/Tooling/Refactoring/RefactoringActionRulesInternal.h @@ -148,7 +148,7 @@ createRefactoringActionRule(const RequirementTypes &... Requirements) { std::tuple Requirements; }; - return llvm::make_unique(std::make_tuple(Requirements...)); + return std::make_unique(std::make_tuple(Requirements...)); } } // end namespace tooling diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp index 568e06f21fb..27e2d584e9e 100644 --- a/lib/ARCMigrate/ARCMT.cpp +++ b/lib/ARCMigrate/ARCMT.cpp @@ -453,8 +453,8 @@ class ARCMTMacroTrackerAction : public ASTFrontendAction { std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override { CI.getPreprocessor().addPPCallbacks( - llvm::make_unique(ARCMTMacroLocs)); - return llvm::make_unique(); + std::make_unique(ARCMTMacroLocs)); + return std::make_unique(); } }; diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index b0ffdda8b2f..4abb04fef5b 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -208,10 +208,10 @@ ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { CI.getPreprocessor().addPPCallbacks(std::unique_ptr(PPRec)); std::vector> Consumers; Consumers.push_back(WrapperFrontendAction::CreateASTConsumer(CI, InFile)); - Consumers.push_back(llvm::make_unique( + Consumers.push_back(std::make_unique( MigrateDir, ObjCMigAction, Remapper, CompInst->getFileManager(), PPRec, CompInst->getPreprocessor(), false, None)); - return llvm::make_unique(std::move(Consumers)); + return std::make_unique(std::move(Consumers)); } bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) { @@ -2034,7 +2034,7 @@ MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { CI.getPreprocessor().addPPCallbacks(std::unique_ptr(PPRec)); std::vector WhiteList = getWhiteListFilenames(CI.getFrontendOpts().ObjCMTWhiteListPath); - return llvm::make_unique( + return std::make_unique( CI.getFrontendOpts().OutputFile, ObjCMTAction, Remapper, CI.getFileManager(), PPRec, CI.getPreprocessor(), /*isOutputFile=*/true, WhiteList); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 24392321f95..03683ced0f3 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -10472,7 +10472,7 @@ ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) { if (!Parents) // We build the parent map for the traversal scope (usually whole TU), as // hasAncestor can escape any subtree. - Parents = llvm::make_unique(*this); + Parents = std::make_unique(*this); return Parents->getParents(Node); } diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp index ecf451b175a..a3a3794b2ed 100644 --- a/lib/AST/CXXInheritance.cpp +++ b/lib/AST/CXXInheritance.cpp @@ -44,7 +44,7 @@ void CXXBasePaths::ComputeDeclsFound() { Decls.insert(Path->Decls.front()); NumDeclsFound = Decls.size(); - DeclsFound = llvm::make_unique(NumDeclsFound); + DeclsFound = std::make_unique(NumDeclsFound); std::copy(Decls.begin(), Decls.end(), DeclsFound.get()); } diff --git a/lib/AST/ExternalASTMerger.cpp b/lib/AST/ExternalASTMerger.cpp index 61e657da7c9..4dc89f0f31a 100644 --- a/lib/AST/ExternalASTMerger.cpp +++ b/lib/AST/ExternalASTMerger.cpp @@ -320,7 +320,7 @@ ExternalASTMerger::ExternalASTMerger(const ImporterTarget &Target, void ExternalASTMerger::AddSources(llvm::ArrayRef Sources) { for (const ImporterSource &S : Sources) { assert(&S.AST != &Target.AST); - Importers.push_back(llvm::make_unique( + Importers.push_back(std::make_unique( *this, Target.AST, Target.FM, S.AST, S.FM, S.OM)); } } diff --git a/lib/AST/ItaniumCXXABI.cpp b/lib/AST/ItaniumCXXABI.cpp index 77fb5a1d33b..67f874b7b9f 100644 --- a/lib/AST/ItaniumCXXABI.cpp +++ b/lib/AST/ItaniumCXXABI.cpp @@ -218,7 +218,7 @@ class ItaniumCXXABI : public CXXABI { std::unique_ptr createMangleNumberingContext() const override { - return llvm::make_unique(); + return std::make_unique(); } }; } diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp index 625282368a4..28de87fde9e 100644 --- a/lib/AST/Mangle.cpp +++ b/lib/AST/Mangle.cpp @@ -470,7 +470,7 @@ class ASTNameGenerator::Implementation { }; ASTNameGenerator::ASTNameGenerator(ASTContext &Ctx) - : Impl(llvm::make_unique(Ctx)) {} + : Impl(std::make_unique(Ctx)) {} ASTNameGenerator::~ASTNameGenerator() {} diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp index 444e55f777f..074abba3d45 100644 --- a/lib/AST/MicrosoftCXXABI.cpp +++ b/lib/AST/MicrosoftCXXABI.cpp @@ -132,7 +132,7 @@ class MicrosoftCXXABI : public CXXABI { std::unique_ptr createMangleNumberingContext() const override { - return llvm::make_unique(); + return std::make_unique(); } }; } diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp index 0c699571555..5688042dadd 100644 --- a/lib/AST/VTableBuilder.cpp +++ b/lib/AST/VTableBuilder.cpp @@ -2268,7 +2268,7 @@ CreateVTableLayout(const ItaniumVTableBuilder &Builder) { SmallVector VTableThunks(Builder.vtable_thunks_begin(), Builder.vtable_thunks_end()); - return llvm::make_unique( + return std::make_unique( Builder.VTableIndices, Builder.vtable_components(), VTableThunks, Builder.getAddressPoints()); } @@ -3253,7 +3253,7 @@ void MicrosoftVTableContext::computeVTablePaths(bool ForVBTables, // Base case: this subobject has its own vptr. if (ForVBTables ? Layout.hasOwnVBPtr() : Layout.hasOwnVFPtr()) - Paths.push_back(llvm::make_unique(RD)); + Paths.push_back(std::make_unique(RD)); // Recursive case: get all the vbtables from our bases and remove anything // that shares a virtual base. @@ -3276,7 +3276,7 @@ void MicrosoftVTableContext::computeVTablePaths(bool ForVBTables, continue; // Copy the path and adjust it as necessary. - auto P = llvm::make_unique(*BaseInfo); + auto P = std::make_unique(*BaseInfo); // We mangle Base into the path if the path would've been ambiguous and it // wasn't already extended with Base. @@ -3562,7 +3562,7 @@ void MicrosoftVTableContext::computeVTableRelatedInformation( const VTableLayout::AddressPointsMapTy EmptyAddressPointsMap; { - auto VFPtrs = llvm::make_unique(); + auto VFPtrs = std::make_unique(); computeVTablePaths(/*ForVBTables=*/false, RD, *VFPtrs); computeFullPathsForVFTables(Context, RD, *VFPtrs); VFPtrLocations[RD] = std::move(VFPtrs); @@ -3576,7 +3576,7 @@ void MicrosoftVTableContext::computeVTableRelatedInformation( assert(VFTableLayouts.count(id) == 0); SmallVector VTableThunks( Builder.vtable_thunks_begin(), Builder.vtable_thunks_end()); - VFTableLayouts[id] = llvm::make_unique( + VFTableLayouts[id] = std::make_unique( ArrayRef{0}, Builder.vtable_components(), VTableThunks, EmptyAddressPointsMap); Thunks.insert(Builder.thunks_begin(), Builder.thunks_end()); @@ -3668,7 +3668,7 @@ const VirtualBaseInfo &MicrosoftVTableContext::computeVBTableRelatedInformation( std::unique_ptr &Entry = VBaseInfo[RD]; if (Entry) return *Entry; - Entry = llvm::make_unique(); + Entry = std::make_unique(); VBI = Entry.get(); } diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp index 6eb4a2c4268..c51fd630e64 100644 --- a/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/lib/ASTMatchers/ASTMatchFinder.cpp @@ -1078,7 +1078,7 @@ bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, } std::unique_ptr MatchFinder::newASTConsumer() { - return llvm::make_unique(this, ParsingDone); + return std::make_unique(this, ParsingDone); } void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node, diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h index fac2fc98e09..9f46108d184 100644 --- a/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/lib/ASTMatchers/Dynamic/Marshallers.h @@ -729,7 +729,7 @@ std::unique_ptr makeMatcherAutoMarshall(ReturnType (*Func)(), StringRef MatcherName) { std::vector RetTypes; BuildReturnTypeVector::build(RetTypes); - return llvm::make_unique( + return std::make_unique( matcherMarshall0, reinterpret_cast(Func), MatcherName, RetTypes, None); } @@ -741,7 +741,7 @@ makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1), StringRef MatcherName) { std::vector RetTypes; BuildReturnTypeVector::build(RetTypes); ArgKind AK = ArgTypeTraits::getKind(); - return llvm::make_unique( + return std::make_unique( matcherMarshall1, reinterpret_cast(Func), MatcherName, RetTypes, AK); } @@ -755,7 +755,7 @@ makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2), BuildReturnTypeVector::build(RetTypes); ArgKind AKs[] = { ArgTypeTraits::getKind(), ArgTypeTraits::getKind() }; - return llvm::make_unique( + return std::make_unique( matcherMarshall2, reinterpret_cast(Func), MatcherName, RetTypes, AKs); } @@ -766,7 +766,7 @@ template makeMatcherAutoMarshall( ast_matchers::internal::VariadicFunction VarFunc, StringRef MatcherName) { - return llvm::make_unique(VarFunc, MatcherName); + return std::make_unique(VarFunc, MatcherName); } /// Overload for VariadicDynCastAllOfMatchers. @@ -778,7 +778,7 @@ std::unique_ptr makeMatcherAutoMarshall( ast_matchers::internal::VariadicDynCastAllOfMatcher VarFunc, StringRef MatcherName) { - return llvm::make_unique(VarFunc, MatcherName); + return std::make_unique(VarFunc, MatcherName); } /// Argument adaptative overload. @@ -791,7 +791,7 @@ std::unique_ptr makeMatcherAutoMarshall( std::vector> Overloads; AdaptativeOverloadCollector(MatcherName, Overloads); - return llvm::make_unique(Overloads); + return std::make_unique(Overloads); } template