Hans, thanks a lot. Best regards, Alexey Bataev
> 16 авг. 2018 г., в 5:36, Hans Wennborg <h...@chromium.org> написал(а): > > I've gone ahead and merged it in r339851. > >> On Wed, Aug 15, 2018 at 3:23 PM, Alexey Bataev <a.bat...@outlook.com> wrote: >> I think it would be good to backport it. Could you do that, Jonas? >> >> ------------- >> Best regards, >> Alexey Bataev >> >> 15.08.2018 5:02, Jonas Hahnfeld via cfe-commits пишет: >> >> Alexey, Hans, >> >> does it make sense to backport for 7.0 as it fixes PR37580? >> >> Thanks, >> Jonas >> >> On 2018-08-13 21:04, Alexey Bataev via cfe-commits wrote: >> >> Author: abataev >> Date: Mon Aug 13 12:04:24 2018 >> New Revision: 339603 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=339603&view=rev >> Log: >> [OPENMP] Fix emission of the loop doacross constructs. >> >> The number of loops associated with the OpenMP loop constructs should >> not be considered as the number loops to collapse. >> >> Modified: >> cfe/trunk/include/clang/AST/OpenMPClause.h >> cfe/trunk/lib/AST/OpenMPClause.cpp >> cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp >> cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h >> cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp >> cfe/trunk/lib/Sema/SemaOpenMP.cpp >> cfe/trunk/lib/Serialization/ASTReaderStmt.cpp >> cfe/trunk/lib/Serialization/ASTWriterStmt.cpp >> cfe/trunk/test/OpenMP/ordered_doacross_codegen.c >> cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp >> cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp >> >> Modified: cfe/trunk/include/clang/AST/OpenMPClause.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/OpenMPClause.h (original) >> +++ cfe/trunk/include/clang/AST/OpenMPClause.h Mon Aug 13 12:04:24 2018 >> @@ -930,8 +930,11 @@ public: >> /// \endcode >> /// In this example directive '#pragma omp for' has 'ordered' clause with >> /// parameter 2. >> -class OMPOrderedClause : public OMPClause { >> +class OMPOrderedClause final >> + : public OMPClause, >> + private llvm::TrailingObjects<OMPOrderedClause, Expr *> { >> friend class OMPClauseReader; >> + friend TrailingObjects; >> >> /// Location of '('. >> SourceLocation LParenLoc; >> @@ -939,6 +942,26 @@ class OMPOrderedClause : public OMPClaus >> /// Number of for-loops. >> Stmt *NumForLoops = nullptr; >> >> + /// Real number of loops. >> + unsigned NumberOfLoops = 0; >> + >> + /// Build 'ordered' clause. >> + /// >> + /// \param Num Expression, possibly associated with this clause. >> + /// \param NumLoops Number of loops, associated with this clause. >> + /// \param StartLoc Starting location of the clause. >> + /// \param LParenLoc Location of '('. >> + /// \param EndLoc Ending location of the clause. >> + OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc, >> + SourceLocation LParenLoc, SourceLocation EndLoc) >> + : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), >> + NumForLoops(Num), NumberOfLoops(NumLoops) {} >> + >> + /// Build an empty clause. >> + explicit OMPOrderedClause(unsigned NumLoops) >> + : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()), >> + NumberOfLoops(NumLoops) {} >> + >> /// Set the number of associated for-loops. >> void setNumForLoops(Expr *Num) { NumForLoops = Num; } >> >> @@ -946,17 +969,17 @@ public: >> /// Build 'ordered' clause. >> /// >> /// \param Num Expression, possibly associated with this clause. >> + /// \param NumLoops Number of loops, associated with this clause. >> /// \param StartLoc Starting location of the clause. >> /// \param LParenLoc Location of '('. >> /// \param EndLoc Ending location of the clause. >> - OMPOrderedClause(Expr *Num, SourceLocation StartLoc, >> - SourceLocation LParenLoc, SourceLocation EndLoc) >> - : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), >> - NumForLoops(Num) {} >> + static OMPOrderedClause *Create(const ASTContext &C, Expr *Num, >> + unsigned NumLoops, SourceLocation >> StartLoc, >> + SourceLocation LParenLoc, >> + SourceLocation EndLoc); >> >> /// Build an empty clause. >> - explicit OMPOrderedClause() >> - : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {} >> + static OMPOrderedClause* CreateEmpty(const ASTContext &C, unsigned >> NumLoops); >> >> /// Sets the location of '('. >> void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } >> @@ -967,6 +990,17 @@ public: >> /// Return the number of associated for-loops. >> Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); } >> >> + /// Set number of iterations for the specified loop. >> + void setLoopNumIterations(unsigned NumLoop, Expr *NumIterations); >> + /// Get number of iterations for all the loops. >> + ArrayRef<Expr *> getLoopNumIterations() const; >> + >> + /// Set loop counter for the specified loop. >> + void setLoopCounter(unsigned NumLoop, Expr *Counter); >> + /// Get loops counter for the specified loop. >> + Expr *getLoopCunter(unsigned NumLoop); >> + const Expr *getLoopCunter(unsigned NumLoop) const; >> + >> child_range children() { return child_range(&NumForLoops, >> &NumForLoops + 1); } >> >> static bool classof(const OMPClause *T) { >> @@ -3095,24 +3129,32 @@ class OMPDependClause final >> /// Colon location. >> SourceLocation ColonLoc; >> >> + /// Number of loops, associated with the depend clause. >> + unsigned NumLoops = 0; >> + >> /// Build clause with number of variables \a N. >> /// >> /// \param StartLoc Starting location of the clause. >> /// \param LParenLoc Location of '('. >> /// \param EndLoc Ending location of the clause. >> /// \param N Number of the variables in the clause. >> + /// \param NumLoops Number of loops that is associated with this depend >> + /// clause. >> OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc, >> - SourceLocation EndLoc, unsigned N) >> + SourceLocation EndLoc, unsigned N, unsigned NumLoops) >> : OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc, >> - EndLoc, N) {} >> + EndLoc, N), NumLoops(NumLoops) {} >> >> /// Build an empty clause. >> /// >> /// \param N Number of variables. >> - explicit OMPDependClause(unsigned N) >> + /// \param NumLoops Number of loops that is associated with this depend >> + /// clause. >> + explicit OMPDependClause(unsigned N, unsigned NumLoops) >> : OMPVarListClause<OMPDependClause>(OMPC_depend, SourceLocation(), >> SourceLocation(), >> SourceLocation(), >> - N) {} >> + N), >> + NumLoops(NumLoops) {} >> >> /// Set dependency kind. >> void setDependencyKind(OpenMPDependClauseKind K) { DepKind = K; } >> @@ -3134,16 +3176,23 @@ public: >> /// \param DepLoc Location of the dependency type. >> /// \param ColonLoc Colon location. >> /// \param VL List of references to the variables. >> - static OMPDependClause * >> - Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation >> LParenLoc, >> - SourceLocation EndLoc, OpenMPDependClauseKind DepKind, >> - SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> >> VL); >> + /// \param NumLoops Number of loops that is associated with this depend >> + /// clause. >> + static OMPDependClause *Create(const ASTContext &C, SourceLocation >> StartLoc, >> + SourceLocation LParenLoc, >> + SourceLocation EndLoc, >> + OpenMPDependClauseKind DepKind, >> + SourceLocation DepLoc, >> SourceLocation ColonLoc, >> + ArrayRef<Expr *> VL, unsigned NumLoops); >> >> /// Creates an empty clause with \a N variables. >> /// >> /// \param C AST context. >> /// \param N The number of variables. >> - static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N); >> + /// \param NumLoops Number of loops that is associated with this depend >> + /// clause. >> + static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N, >> + unsigned NumLoops); >> >> /// Get dependency type. >> OpenMPDependClauseKind getDependencyKind() const { return DepKind; } >> @@ -3154,15 +3203,16 @@ public: >> /// Get colon location. >> SourceLocation getColonLoc() const { return ColonLoc; } >> >> - /// Set the loop counter value for the depend clauses with 'sink|source' >> kind >> - /// of dependency. Required for codegen. >> - void setCounterValue(Expr *V); >> - >> - /// Get the loop counter value. >> - Expr *getCounterValue(); >> + /// Get number of loops associated with the clause. >> + unsigned getNumLoops() const { return NumLoops; } >> >> - /// Get the loop counter value. >> - const Expr *getCounterValue() const; >> + /// Set the loop data for the depend clauses with 'sink|source' kind of >> + /// dependency. >> + void setLoopData(unsigned NumLoop, Expr *Cnt); >> + >> + /// Get the loop data. >> + Expr *getLoopData(unsigned NumLoop); >> + const Expr *getLoopData(unsigned NumLoop) const; >> >> child_range children() { >> return child_range(reinterpret_cast<Stmt **>(varlist_begin()), >> >> Modified: cfe/trunk/lib/AST/OpenMPClause.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/OpenMPClause.cpp?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/lib/AST/OpenMPClause.cpp (original) >> +++ cfe/trunk/lib/AST/OpenMPClause.cpp Mon Aug 13 12:04:24 2018 >> @@ -181,6 +181,57 @@ const OMPClauseWithPostUpdate *OMPClause >> return nullptr; >> } >> >> +OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num, >> + unsigned NumLoops, >> + SourceLocation StartLoc, >> + SourceLocation LParenLoc, >> + SourceLocation EndLoc) { >> + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops)); >> + auto *Clause = >> + new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, >> EndLoc); >> + for (unsigned I = 0; I < NumLoops; ++I) { >> + Clause->setLoopNumIterations(I, nullptr); >> + Clause->setLoopCounter(I, nullptr); >> + } >> + return Clause; >> +} >> + >> +OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C, >> + unsigned NumLoops) { >> + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops)); >> + auto *Clause = new (Mem) OMPOrderedClause(NumLoops); >> + for (unsigned I = 0; I < NumLoops; ++I) { >> + Clause->setLoopNumIterations(I, nullptr); >> + Clause->setLoopCounter(I, nullptr); >> + } >> + return Clause; >> +} >> + >> +void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop, >> + Expr *NumIterations) { >> + assert(NumLoop < NumberOfLoops && "out of loops number."); >> + getTrailingObjects<Expr *>()[NumLoop] = NumIterations; >> +} >> + >> +ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations() const { >> + return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumberOfLoops); >> +} >> + >> +void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) { >> + assert(NumLoop < NumberOfLoops && "out of loops number."); >> + getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop] = Counter; >> +} >> + >> +Expr *OMPOrderedClause::getLoopCunter(unsigned NumLoop) { >> + assert(NumLoop < NumberOfLoops && "out of loops number."); >> + return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop]; >> +} >> + >> +const Expr *OMPOrderedClause::getLoopCunter(unsigned NumLoop) const { >> + assert(NumLoop < NumberOfLoops && "out of loops number."); >> + return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop]; >> +} >> + >> void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) { >> assert(VL.size() == varlist_size() && >> "Number of private copies is not the same as the >> preallocated buffer"); >> @@ -653,44 +704,58 @@ OMPFlushClause *OMPFlushClause::CreateEm >> return new (Mem) OMPFlushClause(N); >> } >> >> -OMPDependClause *OMPDependClause::Create( >> - const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, >> - SourceLocation EndLoc, OpenMPDependClauseKind DepKind, >> - SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL) { >> - void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1)); >> - OMPDependClause *Clause = >> - new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size()); >> +OMPDependClause * >> +OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, >> + SourceLocation LParenLoc, SourceLocation EndLoc, >> + OpenMPDependClauseKind DepKind, SourceLocation >> DepLoc, >> + SourceLocation ColonLoc, ArrayRef<Expr *> VL, >> + unsigned NumLoops) { >> + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + NumLoops)); >> + OMPDependClause *Clause = new (Mem) >> + OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops); >> Clause->setVarRefs(VL); >> Clause->setDependencyKind(DepKind); >> Clause->setDependencyLoc(DepLoc); >> Clause->setColonLoc(ColonLoc); >> - Clause->setCounterValue(nullptr); >> + for (unsigned I = 0 ; I < NumLoops; ++I) >> + Clause->setLoopData(I, nullptr); >> return Clause; >> } >> >> -OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, >> unsigned N) { >> - void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1)); >> - return new (Mem) OMPDependClause(N); >> -} >> - >> -void OMPDependClause::setCounterValue(Expr *V) { >> - assert(getDependencyKind() == OMPC_DEPEND_sink || >> - getDependencyKind() == OMPC_DEPEND_source || V == nullptr); >> - *getVarRefs().end() = V; >> -} >> - >> -const Expr *OMPDependClause::getCounterValue() const { >> - auto *V = *getVarRefs().end(); >> - assert(getDependencyKind() == OMPC_DEPEND_sink || >> - getDependencyKind() == OMPC_DEPEND_source || V == nullptr); >> - return V; >> -} >> - >> -Expr *OMPDependClause::getCounterValue() { >> - auto *V = *getVarRefs().end(); >> - assert(getDependencyKind() == OMPC_DEPEND_sink || >> - getDependencyKind() == OMPC_DEPEND_source || V == nullptr); >> - return V; >> +OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned >> N, >> + unsigned NumLoops) { >> + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + NumLoops)); >> + return new (Mem) OMPDependClause(N, NumLoops); >> +} >> + >> +void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) { >> + assert((getDependencyKind() == OMPC_DEPEND_sink || >> + getDependencyKind() == OMPC_DEPEND_source) && >> + NumLoop < NumLoops && >> + "Expected sink or source depend + loop index must be less number >> of " >> + "loops."); >> + auto It = std::next(getVarRefs().end(), NumLoop); >> + *It = Cnt; >> +} >> + >> +Expr *OMPDependClause::getLoopData(unsigned NumLoop) { >> + assert((getDependencyKind() == OMPC_DEPEND_sink || >> + getDependencyKind() == OMPC_DEPEND_source) && >> + NumLoop < NumLoops && >> + "Expected sink or source depend + loop index must be less number >> of " >> + "loops."); >> + auto It = std::next(getVarRefs().end(), NumLoop); >> + return *It; >> +} >> + >> +const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const { >> + assert((getDependencyKind() == OMPC_DEPEND_sink || >> + getDependencyKind() == OMPC_DEPEND_source) && >> + NumLoop < NumLoops && >> + "Expected sink or source depend + loop index must be less number >> of " >> + "loops."); >> + auto It = std::next(getVarRefs().end(), NumLoop); >> + return *It; >> } >> >> unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber( >> >> Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp Mon Aug 13 12:04:24 2018 >> @@ -8811,7 +8811,8 @@ public: >> } // namespace >> >> void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF, >> - const OMPLoopDirective &D) { >> + const OMPLoopDirective &D, >> + ArrayRef<Expr *> NumIterations) { >> if (!CGF.HaveInsertPoint()) >> return; >> >> @@ -8834,32 +8835,45 @@ void CGOpenMPRuntime::emitDoacrossInit(C >> } else { >> RD = cast<RecordDecl>(KmpDimTy->getAsTagDecl()); >> } >> + llvm::APInt Size(/*numBits=*/32, NumIterations.size()); >> + QualType ArrayTy = >> + C.getConstantArrayType(KmpDimTy, Size, ArrayType::Normal, 0); >> >> - Address DimsAddr = CGF.CreateMemTemp(KmpDimTy, "dims"); >> - CGF.EmitNullInitialization(DimsAddr, KmpDimTy); >> + Address DimsAddr = CGF.CreateMemTemp(ArrayTy, "dims"); >> + CGF.EmitNullInitialization(DimsAddr, ArrayTy); >> enum { LowerFD = 0, UpperFD, StrideFD }; >> // Fill dims with data. >> - LValue DimsLVal = CGF.MakeAddrLValue(DimsAddr, KmpDimTy); >> - // dims.upper = num_iterations; >> - LValue UpperLVal = >> - CGF.EmitLValueForField(DimsLVal, *std::next(RD->field_begin(), >> UpperFD)); >> - llvm::Value *NumIterVal = CGF.EmitScalarConversion( >> - CGF.EmitScalarExpr(D.getNumIterations()), >> D.getNumIterations()->getType(), >> - Int64Ty, D.getNumIterations()->getExprLoc()); >> - CGF.EmitStoreOfScalar(NumIterVal, UpperLVal); >> - // dims.stride = 1; >> - LValue StrideLVal = >> - CGF.EmitLValueForField(DimsLVal, *std::next(RD->field_begin(), >> StrideFD)); >> - CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty, /*V=*/1), >> - StrideLVal); >> + for (unsigned I = 0, E = NumIterations.size(); I < E; ++I) { >> + LValue DimsLVal = >> + CGF.MakeAddrLValue(CGF.Builder.CreateConstArrayGEP( >> + DimsAddr, I, >> C.getTypeSizeInChars(KmpDimTy)), >> + KmpDimTy); >> + // dims.upper = num_iterations; >> + LValue UpperLVal = CGF.EmitLValueForField( >> + DimsLVal, *std::next(RD->field_begin(), UpperFD)); >> + llvm::Value *NumIterVal = >> + CGF.EmitScalarConversion(CGF.EmitScalarExpr(NumIterations[I]), >> + D.getNumIterations()->getType(), Int64Ty, >> + D.getNumIterations()->getExprLoc()); >> + CGF.EmitStoreOfScalar(NumIterVal, UpperLVal); >> + // dims.stride = 1; >> + LValue StrideLVal = CGF.EmitLValueForField( >> + DimsLVal, *std::next(RD->field_begin(), StrideFD)); >> + CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty, >> /*V=*/1), >> + StrideLVal); >> + } >> >> // Build call void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, >> // kmp_int32 num_dims, struct kmp_dim * dims); >> - llvm::Value *Args[] = {emitUpdateLocation(CGF, D.getBeginLoc()), >> - getThreadID(CGF, D.getBeginLoc()), >> - llvm::ConstantInt::getSigned(CGM.Int32Ty, 1), >> - CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( >> - DimsAddr.getPointer(), CGM.VoidPtrTy)}; >> + llvm::Value *Args[] = { >> + emitUpdateLocation(CGF, D.getBeginLoc()), >> + getThreadID(CGF, D.getBeginLoc()), >> + llvm::ConstantInt::getSigned(CGM.Int32Ty, NumIterations.size()), >> + CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( >> + CGF.Builder >> + .CreateConstArrayGEP(DimsAddr, 0, >> C.getTypeSizeInChars(KmpDimTy)) >> + .getPointer(), >> + CGM.VoidPtrTy)}; >> >> llvm::Value *RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_init); >> CGF.EmitRuntimeCall(RTLFn, Args); >> @@ -8874,16 +8888,29 @@ void CGOpenMPRuntime::emitDoacrossOrdere >> const OMPDependClause *C) { >> QualType Int64Ty = >> CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, >> /*Signed=*/1); >> - const Expr *CounterVal = C->getCounterValue(); >> - assert(CounterVal); >> - llvm::Value *CntVal = >> CGF.EmitScalarConversion(CGF.EmitScalarExpr(CounterVal), >> - >> CounterVal->getType(), Int64Ty, >> - CounterVal->getExprLoc()); >> - Address CntAddr = CGF.CreateMemTemp(Int64Ty, ".cnt.addr"); >> - CGF.EmitStoreOfScalar(CntVal, CntAddr, /*Volatile=*/false, Int64Ty); >> - llvm::Value *Args[] = {emitUpdateLocation(CGF, C->getBeginLoc()), >> - getThreadID(CGF, C->getBeginLoc()), >> - CntAddr.getPointer()}; >> + llvm::APInt Size(/*numBits=*/32, C->getNumLoops()); >> + QualType ArrayTy = CGM.getContext().getConstantArrayType( >> + Int64Ty, Size, ArrayType::Normal, 0); >> + Address CntAddr = CGF.CreateMemTemp(ArrayTy, ".cnt.addr"); >> + for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) { >> + const Expr *CounterVal = C->getLoopData(I); >> + assert(CounterVal); >> + llvm::Value *CntVal = CGF.EmitScalarConversion( >> + CGF.EmitScalarExpr(CounterVal), CounterVal->getType(), Int64Ty, >> + CounterVal->getExprLoc()); >> + CGF.EmitStoreOfScalar( >> + CntVal, >> + CGF.Builder.CreateConstArrayGEP( >> + CntAddr, I, CGM.getContext().getTypeSizeInChars(Int64Ty)), >> + /*Volatile=*/false, Int64Ty); >> + } >> + llvm::Value *Args[] = { >> + emitUpdateLocation(CGF, C->getBeginLoc()), >> + getThreadID(CGF, C->getBeginLoc()), >> + CGF.Builder >> + .CreateConstArrayGEP(CntAddr, 0, >> + >> CGM.getContext().getTypeSizeInChars(Int64Ty)) >> + .getPointer()}; >> llvm::Value *RTLFn; >> if (C->getDependencyKind() == OMPC_DEPEND_source) { >> RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_post); >> @@ -9198,7 +9225,8 @@ void CGOpenMPSIMDRuntime::emitTargetData >> } >> >> void CGOpenMPSIMDRuntime::emitDoacrossInit(CodeGenFunction &CGF, >> - const OMPLoopDirective &D) { >> + const OMPLoopDirective &D, >> + ArrayRef<Expr *> NumIterations) >> { >> llvm_unreachable("Not supported in SIMD-only mode"); >> } >> >> >> Modified: cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h (original) >> +++ cfe/trunk/lib/CodeGen/CGOpenMPRuntime.h Mon Aug 13 12:04:24 2018 >> @@ -1469,8 +1469,8 @@ public: >> >> /// Emit initialization for doacross loop nesting support. >> /// \param D Loop-based construct used in doacross nesting construct. >> - virtual void emitDoacrossInit(CodeGenFunction &CGF, >> - const OMPLoopDirective &D); >> + virtual void emitDoacrossInit(CodeGenFunction &CGF, const >> OMPLoopDirective &D, >> + ArrayRef<Expr *> NumIterations); >> >> /// Emit code for doacross ordered directive with 'depend' clause. >> /// \param C 'depend' clause with 'sink|source' dependency kind. >> @@ -2057,8 +2057,8 @@ public: >> >> /// Emit initialization for doacross loop nesting support. >> /// \param D Loop-based construct used in doacross nesting construct. >> - void emitDoacrossInit(CodeGenFunction &CGF, >> - const OMPLoopDirective &D) override; >> + void emitDoacrossInit(CodeGenFunction &CGF, const OMPLoopDirective &D, >> + ArrayRef<Expr *> NumIterations) override; >> >> /// Emit code for doacross ordered directive with 'depend' clause. >> /// \param C 'depend' clause with 'sink|source' dependency kind. >> >> Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original) >> +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Mon Aug 13 12:04:24 2018 >> @@ -1509,6 +1509,23 @@ void CodeGenFunction::EmitOMPPrivateLoop >> } >> ++I; >> } >> + // Privatize extra loop counters used in loops for ordered(n) clauses. >> + for (const auto *C : S.getClausesOfKind<OMPOrderedClause>()) { >> + if (!C->getNumForLoops()) >> + continue; >> + for (unsigned I = S.getCollapsedNumber(), >> + E = C->getLoopNumIterations().size(); >> + I < E; ++I) { >> + const auto *DRE = cast<DeclRefExpr>(C->getLoopCunter(I)); >> + const auto *VD = cast<VarDecl>(DRE->getDecl()); >> + // Override only those variables that are really emitted already. >> + if (LocalDeclMap.count(VD)) { >> + (void)LoopScope.addPrivate(VD, [this, DRE, VD]() { >> + return CreateMemTemp(DRE->getType(), VD->getName()); >> + }); >> + } >> + } >> + } >> } >> >> static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, >> @@ -2244,7 +2261,7 @@ bool CodeGenFunction::EmitOMPWorksharing >> bool Ordered = false; >> if (const auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) >> { >> if (OrderedClause->getNumForLoops()) >> - RT.emitDoacrossInit(*this, S); >> + RT.emitDoacrossInit(*this, S, >> OrderedClause->getLoopNumIterations()); >> else >> Ordered = true; >> } >> @@ -4942,6 +4959,20 @@ void CodeGenFunction::EmitSimpleOMPExecu >> CGF.EmitVarDecl(*VD); >> } >> } >> + for (const auto *C : D.getClausesOfKind<OMPOrderedClause>()) { >> + if (!C->getNumForLoops()) >> + continue; >> + for (unsigned I = LD->getCollapsedNumber(), >> + E = C->getLoopNumIterations().size(); >> + I < E; ++I) { >> + if (const auto *VD = dyn_cast<OMPCapturedExprDecl>( >> + cast<DeclRefExpr>(C->getLoopCunter(I))->getDecl())) { >> + // Emit only those that were not explicitly referenced >> in clauses. >> + if (!CGF.LocalDeclMap.count(VD)) >> + CGF.EmitVarDecl(*VD); >> + } >> + } >> + } >> } >> CGF.EmitStmt(D.getInnermostCapturedStmt()->getCapturedStmt()); >> } >> >> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Aug 13 12:04:24 2018 >> @@ -73,6 +73,8 @@ public: >> }; >> using OperatorOffsetTy = >> llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; >> + using DoacrossDependMapTy = >> + llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; >> >> private: >> struct DSAInfo { >> @@ -97,8 +99,6 @@ private: >> llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; >> using CriticalsWithHintsTy = >> llvm::StringMap<std::pair<const OMPCriticalDirective *, >> llvm::APSInt>>; >> - using DoacrossDependMapTy = >> - llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; >> struct ReductionData { >> using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; >> SourceRange ReductionRange; >> @@ -137,7 +137,7 @@ private: >> /// first argument (Expr *) contains optional argument of the >> /// 'ordered' clause, the second one is true if the regions has >> 'ordered' >> /// clause, false otherwise. >> - llvm::PointerIntPair<const Expr *, 1, bool> OrderedRegion; >> + llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> >> OrderedRegion; >> bool NowaitRegion = false; >> bool CancelRegion = false; >> unsigned AssociatedLoops = 1; >> @@ -398,23 +398,42 @@ public: >> } >> >> /// Marks current region as ordered (it has an 'ordered' clause). >> - void setOrderedRegion(bool IsOrdered, const Expr *Param) { >> + void setOrderedRegion(bool IsOrdered, const Expr *Param, >> + OMPOrderedClause *Clause) { >> assert(!isStackEmpty()); >> - Stack.back().first.back().OrderedRegion.setInt(IsOrdered); >> - Stack.back().first.back().OrderedRegion.setPointer(Param); >> + if (IsOrdered) >> + Stack.back().first.back().OrderedRegion.emplace(Param, Clause); >> + else >> + Stack.back().first.back().OrderedRegion.reset(); >> + } >> + /// Returns true, if region is ordered (has associated 'ordered' clause), >> + /// false - otherwise. >> + bool isOrderedRegion() const { >> + if (isStackEmpty()) >> + return false; >> + return Stack.back().first.rbegin()->OrderedRegion.hasValue(); >> + } >> + /// Returns optional parameter for the ordered region. >> + std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const >> { >> + if (isStackEmpty() || >> + !Stack.back().first.rbegin()->OrderedRegion.hasValue()) >> + return std::make_pair(nullptr, nullptr); >> + return Stack.back().first.rbegin()->OrderedRegion.getValue(); >> } >> /// Returns true, if parent region is ordered (has associated >> /// 'ordered' clause), false - otherwise. >> bool isParentOrderedRegion() const { >> if (isStackEmpty() || Stack.back().first.size() == 1) >> return false; >> - return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt(); >> + return >> std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); >> } >> /// Returns optional parameter for the ordered region. >> - const Expr *getParentOrderedRegionParam() const { >> - if (isStackEmpty() || Stack.back().first.size() == 1) >> - return nullptr; >> - return >> std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer(); >> + std::pair<const Expr *, OMPOrderedClause *> >> + getParentOrderedRegionParam() const { >> + if (isStackEmpty() || Stack.back().first.size() == 1 || >> + !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) >> + return std::make_pair(nullptr, nullptr); >> + return >> std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); >> } >> /// Marks current region as nowait (it has a 'nowait' clause). >> void setNowaitRegion(bool IsNowait = true) { >> @@ -3745,6 +3764,13 @@ public: >> Expr *buildCounterInit() const; >> /// Build step of the counter be used for codegen. >> Expr *buildCounterStep() const; >> + /// Build loop data with counter value for depend clauses in ordered >> + /// directives. >> + Expr * >> + buildOrderedLoopData(Scope *S, Expr *Counter, >> + llvm::MapVector<const Expr *, DeclRefExpr *> >> &Captures, >> + SourceLocation Loc, Expr *Inc = nullptr, >> + OverloadedOperatorKind OOK = OO_Amp); >> /// Return true if any expression is dependent. >> bool dependent() const; >> >> @@ -3909,7 +3935,12 @@ bool OpenMPIterationSpaceChecker::checkA >> SemaRef.Diag(S->getBeginLoc(), >> diag::ext_omp_loop_not_canonical_init) >> << S->getSourceRange(); >> - return setLCDeclAndLB(Var, nullptr, Var->getInit()); >> + return setLCDeclAndLB( >> + Var, >> + buildDeclRefExpr(SemaRef, Var, >> + Var->getType().getNonReferenceType(), >> + DS->getBeginLoc()), >> + Var->getInit()); >> } >> } >> } >> @@ -4271,7 +4302,8 @@ Expr *OpenMPIterationSpaceChecker::build >> >> /// Build reference expression to the counter be used for codegen. >> DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( >> - llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, >> DSAStackTy &DSA) const { >> + llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, >> + DSAStackTy &DSA) const { >> auto *VD = dyn_cast<VarDecl>(LCDecl); >> if (!VD) { >> VD = SemaRef.isOpenMPCapturedDecl(LCDecl); >> @@ -4311,6 +4343,63 @@ Expr *OpenMPIterationSpaceChecker::build >> /// Build step of the counter be used for codegen. >> Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; >> } >> >> +Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( >> + Scope *S, Expr *Counter, >> + llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation >> Loc, >> + Expr *Inc, OverloadedOperatorKind OOK) { >> + Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); >> + if (!Cnt) >> + return nullptr; >> + if (Inc) { >> + assert((OOK == OO_Plus || OOK == OO_Minus) && >> + "Expected only + or - operations for depend clauses."); >> + BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; >> + Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); >> + if (!Cnt) >> + return nullptr; >> + } >> + ExprResult Diff; >> + QualType VarType = LCDecl->getType().getNonReferenceType(); >> + if (VarType->isIntegerType() || VarType->isPointerType() || >> + SemaRef.getLangOpts().CPlusPlus) { >> + // Upper - Lower >> + Expr *Upper = >> + TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get(); >> + Expr *Lower = >> + TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt; >> + if (!Upper || !Lower) >> + return nullptr; >> + >> + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); >> + >> + if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { >> + // BuildBinOp already emitted error, this one is to point user to >> upper >> + // and lower bound, and to tell what is passed to 'operator-'. >> + SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) >> + << Upper->getSourceRange() << Lower->getSourceRange(); >> + return nullptr; >> + } >> + } >> + >> + if (!Diff.isUsable()) >> + return nullptr; >> + >> + // Parentheses (for dumping/debugging purposes only). >> + Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); >> + if (!Diff.isUsable()) >> + return nullptr; >> + >> + ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); >> + if (!NewStep.isUsable()) >> + return nullptr; >> + // (Upper - Lower) / Step >> + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), >> NewStep.get()); >> + if (!Diff.isUsable()) >> + return nullptr; >> + >> + return Diff.get(); >> +} >> + >> /// Iteration space of a single for loop. >> struct LoopIterationSpace final { >> /// Condition of the loop. >> @@ -4370,7 +4459,8 @@ void Sema::ActOnOpenMPLoopInitialization >> static bool checkOpenMPIterationSpace( >> OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, >> unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, >> - Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, >> + unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, >> + Expr *OrderedLoopCountExpr, >> Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, >> LoopIterationSpace &ResultIterSpace, >> llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { >> @@ -4380,9 +4470,9 @@ static bool checkOpenMPIterationSpace( >> if (!For) { >> SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) >> << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr >> != nullptr) >> - << getOpenMPDirectiveName(DKind) << NestedLoopCount >> + << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount >> << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; >> - if (NestedLoopCount > 1) { >> + if (TotalNestedLoopCount > 1) { >> if (CollapseLoopCountExpr && OrderedLoopCountExpr) >> SemaRef.Diag(DSA.getConstructLoc(), >> diag::note_omp_collapse_ordered_expr) >> @@ -4515,6 +4605,41 @@ static bool checkOpenMPIterationSpace( >> ResultIterSpace.PrivateCounterVar == nullptr || >> ResultIterSpace.CounterInit == nullptr || >> ResultIterSpace.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); >> + DSA.getOrderedRegionParam().second->setLoopCounter( >> + CurrentNestedLoopCount, ResultIterSpace.CounterVar); >> + } >> + } >> + for (auto &Pair : DSA.getDoacrossDependClauses()) { >> + if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { >> + // Erroneous case - clause has some problems. >> + continue; >> + } >> + if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && >> + Pair.second.size() <= CurrentNestedLoopCount) { >> + // Erroneous case - clause has some problems. >> + Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); >> + continue; >> + } >> + Expr *CntValue; >> + if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) >> + CntValue = ISC.buildOrderedLoopData( >> + DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, >> + Pair.first->getDependencyLoc()); >> + else >> + CntValue = ISC.buildOrderedLoopData( >> + DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, >> + Pair.first->getDependencyLoc(), >> + Pair.second[CurrentNestedLoopCount].first, >> + Pair.second[CurrentNestedLoopCount].second); >> + Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); >> + } >> + } >> >> return HasErrors; >> } >> @@ -4700,6 +4825,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin >> if (CollapseLoopCountExpr->EvaluateAsInt(Result, >> SemaRef.getASTContext())) >> NestedLoopCount = Result.getLimitedValue(); >> } >> + unsigned OrderedLoopCount = 1; >> if (OrderedLoopCountExpr) { >> // Found 'ordered' clause - calculate collapse number. >> llvm::APSInt Result; >> @@ -4712,21 +4838,43 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin >> diag::note_collapse_loop_count) >> << CollapseLoopCountExpr->getSourceRange(); >> } >> - NestedLoopCount = Result.getLimitedValue(); >> + OrderedLoopCount = Result.getLimitedValue(); >> } >> } >> // This is helper routine for loop directives (e.g., 'for', 'simd', >> // 'for simd', etc.). >> llvm::MapVector<const Expr *, DeclRefExpr *> Captures; >> SmallVector<LoopIterationSpace, 4> IterSpaces; >> - IterSpaces.resize(NestedLoopCount); >> + IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount)); >> Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); >> for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { >> - if (checkOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, >> - NestedLoopCount, CollapseLoopCountExpr, >> - OrderedLoopCountExpr, >> VarsWithImplicitDSA, >> - IterSpaces[Cnt], Captures)) >> + if (checkOpenMPIterationSpace( >> + DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, >> + std::max(OrderedLoopCount, NestedLoopCount), >> CollapseLoopCountExpr, >> + OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], >> + Captures)) >> + return 0; >> + // Move on to the next nested for loop, or to the loop body. >> + // OpenMP [2.8.1, simd construct, Restrictions] >> + // All loops associated with the construct must be perfectly nested; >> that >> + // is, there must be no intervening code nor any OpenMP directive >> between >> + // any two loops. >> + CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); >> + } >> + for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { >> + if (checkOpenMPIterationSpace( >> + DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, >> + std::max(OrderedLoopCount, NestedLoopCount), >> CollapseLoopCountExpr, >> + OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], >> + Captures)) >> return 0; >> + if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { >> + // Handle initialization of captured loop iterator variables. >> + auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); >> + if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { >> + Captures[DRE] = DRE; >> + } >> + } >> // Move on to the next nested for loop, or to the loop body. >> // OpenMP [2.8.1, simd construct, Restrictions] >> // All loops associated with the construct must be perfectly nested; >> that >> @@ -5113,7 +5261,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin >> Built.Inits.resize(NestedLoopCount); >> Built.Updates.resize(NestedLoopCount); >> Built.Finals.resize(NestedLoopCount); >> - SmallVector<Expr *, 4> LoopMultipliers; >> { >> ExprResult Div; >> // Go from inner nested loop to outer. >> @@ -5183,7 +5330,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin >> HasErrors = true; >> break; >> } >> - LoopMultipliers.push_back(Div.get()); >> } >> if (!Update.isUsable() || !Final.isUsable()) { >> HasErrors = true; >> @@ -5231,55 +5377,6 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin >> Built.DistCombinedFields.NLB = CombNextLB.get(); >> Built.DistCombinedFields.NUB = CombNextUB.get(); >> >> - Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); >> - // Fill data for doacross depend clauses. >> - for (const auto &Pair : DSA.getDoacrossDependClauses()) { >> - if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) { >> - Pair.first->setCounterValue(CounterVal); >> - } else { >> - if (NestedLoopCount != Pair.second.size() || >> - NestedLoopCount != LoopMultipliers.size() + 1) { >> - // Erroneous case - clause has some problems. >> - Pair.first->setCounterValue(CounterVal); >> - continue; >> - } >> - assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); >> - auto I = Pair.second.rbegin(); >> - auto IS = IterSpaces.rbegin(); >> - auto ILM = LoopMultipliers.rbegin(); >> - Expr *UpCounterVal = CounterVal; >> - Expr *Multiplier = nullptr; >> - for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { >> - if (I->first) { >> - assert(IS->CounterStep); >> - Expr *NormalizedOffset = >> - SemaRef >> - .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, >> - I->first, IS->CounterStep) >> - .get(); >> - if (Multiplier) { >> - NormalizedOffset = >> - SemaRef >> - .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, >> - NormalizedOffset, Multiplier) >> - .get(); >> - } >> - assert(I->second == OO_Plus || I->second == OO_Minus); >> - BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : >> BO_Sub; >> - UpCounterVal = SemaRef >> - .BuildBinOp(CurScope, I->first->getExprLoc(), >> BOK, >> - UpCounterVal, NormalizedOffset) >> - .get(); >> - } >> - Multiplier = *ILM; >> - ++I; >> - ++IS; >> - ++ILM; >> - } >> - Pair.first->setCounterValue(UpCounterVal); >> - } >> - } >> - >> return NestedLoopCount; >> } >> >> @@ -5847,12 +5944,12 @@ StmtResult Sema::ActOnOpenMPOrderedDirec >> Diag(DependFound->getBeginLoc(), >> diag::err_omp_depend_clause_thread_simd) >> << getOpenMPClauseName(TC ? TC->getClauseKind() : >> SC->getClauseKind()); >> ErrorFound = true; >> - } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { >> + } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) >> { >> Diag(DependFound->getBeginLoc(), >> diag::err_omp_ordered_directive_without_param); >> ErrorFound = true; >> } else if (TC || Clauses.empty()) { >> - if (const Expr *Param = DSAStack->getParentOrderedRegionParam()) { >> + if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) >> { >> SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; >> Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) >> << (TC != nullptr); >> @@ -8628,9 +8725,11 @@ OMPClause *Sema::ActOnOpenMPOrderedClaus >> } else { >> NumForLoops = nullptr; >> } >> - DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); >> - return new (Context) >> - OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); >> + auto *Clause = OMPOrderedClause::Create( >> + Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : >> 0, >> + StartLoc, LParenLoc, EndLoc); >> + DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); >> + return Clause; >> } >> >> OMPClause *Sema::ActOnOpenMPSimpleClause( >> @@ -11486,8 +11585,9 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe >> DSAStackTy::OperatorOffsetTy OpsOffs; >> llvm::APSInt DepCounter(/*BitWidth=*/32); >> llvm::APSInt TotalDepCount(/*BitWidth=*/32); >> - if (DepKind == OMPC_DEPEND_sink) { >> - if (const Expr *OrderedCountExpr = >> DSAStack->getParentOrderedRegionParam()) { >> + if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { >> + if (const Expr *OrderedCountExpr = >> + DSAStack->getParentOrderedRegionParam().first) { >> TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); >> TotalDepCount.setIsUnsigned(/*Val=*/true); >> } >> @@ -11503,7 +11603,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe >> SourceLocation ELoc = RefExpr->getExprLoc(); >> Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); >> if (DepKind == OMPC_DEPEND_sink) { >> - if (DSAStack->getParentOrderedRegionParam() && >> + if (DSAStack->getParentOrderedRegionParam().first && >> DepCounter >= TotalDepCount) { >> Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); >> continue; >> @@ -11569,7 +11669,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe >> continue; >> } >> if (!CurContext->isDependentContext() && >> - DSAStack->getParentOrderedRegionParam() && >> + DSAStack->getParentOrderedRegionParam().first && >> DepCounter != DSAStack->isParentLoopControlVariable(D).first) { >> const ValueDecl *VD = >> >> DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); >> @@ -11607,7 +11707,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe >> >> if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && >> TotalDepCount > VarList.size() && >> - DSAStack->getParentOrderedRegionParam() && >> + DSAStack->getParentOrderedRegionParam().first && >> DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { >> Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) >> << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); >> @@ -11617,7 +11717,8 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe >> return nullptr; >> >> auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, >> - DepKind, DepLoc, ColonLoc, Vars); >> + DepKind, DepLoc, ColonLoc, Vars, >> + TotalDepCount.getZExtValue()); >> if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && >> DSAStack->isParentOrderedRegion()) >> DSAStack->addDoacrossDependClause(C, OpsOffs); >> >> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Aug 13 12:04:24 2018 >> @@ -1856,7 +1856,7 @@ OMPClause *OMPClauseReader::readClause() >> C = new (Context) OMPScheduleClause(); >> break; >> case OMPC_ordered: >> - C = new (Context) OMPOrderedClause(); >> + C = OMPOrderedClause::CreateEmpty(Context, Reader->Record.readInt()); >> break; >> case OMPC_nowait: >> C = new (Context) OMPNowaitClause(); >> @@ -1927,9 +1927,12 @@ OMPClause *OMPClauseReader::readClause() >> case OMPC_flush: >> C = OMPFlushClause::CreateEmpty(Context, Reader->Record.readInt()); >> break; >> - case OMPC_depend: >> - C = OMPDependClause::CreateEmpty(Context, Reader->Record.readInt()); >> + case OMPC_depend: { >> + unsigned NumVars = Reader->Record.readInt(); >> + unsigned NumLoops = Reader->Record.readInt(); >> + C = OMPDependClause::CreateEmpty(Context, NumVars, NumLoops); >> break; >> + } >> case OMPC_device: >> C = new (Context) OMPDeviceClause(); >> break; >> @@ -2087,6 +2090,10 @@ void OMPClauseReader::VisitOMPScheduleCl >> >> void OMPClauseReader::VisitOMPOrderedClause(OMPOrderedClause *C) { >> C->setNumForLoops(Reader->Record.readSubExpr()); >> + for (unsigned I = 0, E = C->NumberOfLoops; I < E; ++I) >> + C->setLoopNumIterations(I, Reader->Record.readSubExpr()); >> + for (unsigned I = 0, E = C->NumberOfLoops; I < E; ++I) >> + C->setLoopCounter(I, Reader->Record.readSubExpr()); >> C->setLParenLoc(Reader->ReadSourceLocation()); >> } >> >> @@ -2395,10 +2402,11 @@ void OMPClauseReader::VisitOMPDependClau >> unsigned NumVars = C->varlist_size(); >> SmallVector<Expr *, 16> Vars; >> Vars.reserve(NumVars); >> - for (unsigned i = 0; i != NumVars; ++i) >> + for (unsigned I = 0; I != NumVars; ++I) >> Vars.push_back(Reader->Record.readSubExpr()); >> C->setVarRefs(Vars); >> - C->setCounterValue(Reader->Record.readSubExpr()); >> + for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) >> + C->setLoopData(I, Reader->Record.readSubExpr()); >> } >> >> void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) { >> >> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Aug 13 12:04:24 2018 >> @@ -1898,7 +1898,12 @@ void OMPClauseWriter::VisitOMPScheduleCl >> } >> >> void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *C) { >> + Record.push_back(C->getLoopNumIterations().size()); >> Record.AddStmt(C->getNumForLoops()); >> + for (Expr *NumIter : C->getLoopNumIterations()) >> + Record.AddStmt(NumIter); >> + for (unsigned I = 0, E = C->getLoopNumIterations().size(); I <E; ++I) >> + Record.AddStmt(C->getLoopCunter(I)); >> Record.AddSourceLocation(C->getLParenLoc()); >> } >> >> @@ -2102,13 +2107,15 @@ void OMPClauseWriter::VisitOMPFlushClaus >> >> void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) { >> Record.push_back(C->varlist_size()); >> + Record.push_back(C->getNumLoops()); >> Record.AddSourceLocation(C->getLParenLoc()); >> Record.push_back(C->getDependencyKind()); >> Record.AddSourceLocation(C->getDependencyLoc()); >> Record.AddSourceLocation(C->getColonLoc()); >> for (auto *VE : C->varlists()) >> Record.AddStmt(VE); >> - Record.AddStmt(C->getCounterValue()); >> + for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) >> + Record.AddStmt(C->getLoopData(I)); >> } >> >> void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) { >> >> >> Modified: cfe/trunk/test/OpenMP/ordered_doacross_codegen.c >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_doacross_codegen.c?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/test/OpenMP/ordered_doacross_codegen.c (original) >> +++ cfe/trunk/test/OpenMP/ordered_doacross_codegen.c Mon Aug 13 12:04:24 >> 2018 >> @@ -19,17 +19,19 @@ void foo(); >> // CHECK-LABEL: @main() >> int main() { >> int i; >> -// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]], >> +// CHECK: [[DIMS:%.+]] = alloca [1 x [[KMP_DIM]]], >> // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]]) >> // CHECK: icmp >> // CHECK-NEXT: br i1 % >> -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* >> +// CHECK: [[CAST:%.+]] = bitcast [1 x [[KMP_DIM]]]* [[DIMS]] to i8* >> // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]], i8 0, >> i64 24, i1 false) >> -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], >> i32 0, i32 1 >> +// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], [1 >> x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0 >> +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], >> i32 0, i32 1 >> // CHECK: store i64 %{{.+}}, i64* % >> -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], >> i32 0, i32 2 >> +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], >> i32 0, i32 2 >> // CHECK: store i64 1, i64* % >> -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* >> +// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], [1 >> x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0 >> +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8* >> // CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], >> i32 1, i8* [[CAST]]) >> // CHECK: call void @__kmpc_for_static_init_4( >> #pragma omp for ordered(1) >> @@ -37,18 +39,26 @@ int main() { >> a[i] = b[i] + 1; >> foo(); >> // CHECK: call void [[FOO:.+]]( >> -// CHECK: load i32, i32* [[CNT:%.+]], >> +// CHECK: load i32, i32* [[I:%.+]], >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 >> // CHECK-NEXT: sext i32 %{{.+}} to i64 >> -// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x >> i64]* [[CNT:%.+]], i64 0, i64 0 >> +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x >> i64]* [[CNT]], i64 0, i64 0 >> // CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 >> [[GTID]], i64* [[TMP]]) >> #pragma omp ordered depend(source) >> c[i] = c[i] + 1; >> foo(); >> // CHECK: call void [[FOO]] >> -// CHECK: load i32, i32* [[CNT]], >> +// CHECK: load i32, i32* [[I]], >> // CHECK-NEXT: sub nsw i32 %{{.+}}, 2 >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 >> // CHECK-NEXT: sext i32 %{{.+}} to i64 >> -// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x >> i64]* [[CNT:%.+]], i64 0, i64 0 >> +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x >> i64]* [[CNT]], i64 0, i64 0 >> // CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 >> [[GTID]], i64* [[TMP]]) >> #pragma omp ordered depend(sink : i - 2) >> d[i] = a[i - 2]; >> >> Modified: cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp (original) >> +++ cfe/trunk/test/OpenMP/ordered_doacross_codegen.cpp Mon Aug 13 12:04:24 >> 2018 >> @@ -19,17 +19,19 @@ void foo(); >> // CHECK-LABEL: @main() >> int main() { >> int i; >> -// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]], >> +// CHECK: [[DIMS:%.+]] = alloca [1 x [[KMP_DIM]]], >> // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]]) >> // CHECK: icmp >> // CHECK-NEXT: br i1 % >> -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* >> +// CHECK: [[CAST:%.+]] = bitcast [1 x [[KMP_DIM]]]* [[DIMS]] to i8* >> // CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]], i8 0, >> i64 24, i1 false) >> -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], >> i32 0, i32 1 >> +// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], [1 >> x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0 >> +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], >> i32 0, i32 1 >> // CHECK: store i64 %{{.+}}, i64* % >> -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], >> i32 0, i32 2 >> +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], >> i32 0, i32 2 >> // CHECK: store i64 1, i64* % >> -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* >> +// CHECK: [[DIM:%.+]] = getelementptr inbounds [1 x [[KMP_DIM]]], [1 >> x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0 >> +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8* >> // CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], >> i32 1, i8* [[CAST]]) >> // CHECK: call void @__kmpc_for_static_init_4( >> #pragma omp for ordered(1) >> @@ -37,18 +39,26 @@ int main() { >> a[i] = b[i] + 1; >> foo(); >> // CHECK: invoke void [[FOO:.+]]( >> -// CHECK: load i32, i32* [[CNT:%.+]], >> +// CHECK: load i32, i32* [[I:%.+]], >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 >> // CHECK-NEXT: sext i32 %{{.+}} to i64 >> -// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x >> i64]* [[CNT:%.+]], i64 0, i64 0 >> +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x >> i64]* [[CNT]], i64 0, i64 0 >> // CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 >> [[GTID]], i64* [[TMP]]) >> #pragma omp ordered depend(source) >> c[i] = c[i] + 1; >> foo(); >> // CHECK: invoke void [[FOO]] >> -// CHECK: load i32, i32* [[CNT]], >> +// CHECK: load i32, i32* [[I]], >> // CHECK-NEXT: sub nsw i32 %{{.+}}, 2 >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 >> // CHECK-NEXT: sext i32 %{{.+}} to i64 >> -// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x >> i64]* [[CNT:%.+]], i64 0, i64 0 >> +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [1 x i64], [1 x >> i64]* [[CNT]], i64 0, i64 0 >> // CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 >> [[GTID]], i64* [[TMP]]) >> #pragma omp ordered depend(sink : i - 2) >> d[i] = a[i - 2]; >> @@ -75,41 +85,84 @@ struct TestStruct { >> T bar(T, T, T); >> void baz(T, T); >> TestStruct() { >> -// CHECK: [[CNT:%.+]] = alloca i64, >> -// CHECK: [[DIMS:%.+]] = alloca [[KMP_DIM]], >> +// CHECK: [[DIMS:%.+]] = alloca [2 x [[KMP_DIM]]], >> // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT:%.+]]) >> -// CHECK: icmp >> -// CHECK-NEXT: br i1 % >> -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* >> -// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]], i8 0, >> i64 24, i1 false) >> -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], >> i32 0, i32 1 >> +// CHECK: [[CAST:%.+]] = bitcast [2 x [[KMP_DIM]]]* [[DIMS]] to i8* >> +// CHECK: call void @llvm.memset.p0i8.i64(i8* align 8 [[CAST]], i8 0, >> i64 48, i1 false) >> +// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], [2 >> x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0 >> +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], >> i32 0, i32 1 >> +// CHECK: store i64 10, i64* % >> +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], >> i32 0, i32 2 >> +// CHECK: store i64 1, i64* % >> +// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], [2 >> x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 1 >> +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], >> i32 0, i32 1 >> // CHECK: store i64 %{{.+}}, i64* % >> -// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIMS]], >> i32 0, i32 2 >> +// CHECK: getelementptr inbounds [[KMP_DIM]], [[KMP_DIM]]* [[DIM]], >> i32 0, i32 2 >> // CHECK: store i64 1, i64* % >> -// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIMS]] to i8* >> -// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], >> i32 1, i8* [[CAST]]) >> -// CHECK: call void @__kmpc_for_static_init_8( >> +// CHECK: [[DIM:%.+]] = getelementptr inbounds [2 x [[KMP_DIM]]], [2 >> x [[KMP_DIM]]]* [[DIMS]], i64 0, i64 0 >> +// CHECK: [[CAST:%.+]] = bitcast [[KMP_DIM]]* [[DIM]] to i8* >> +// CHECK: call void @__kmpc_doacross_init([[IDENT]], i32 [[GTID]], >> i32 2, i8* [[CAST]]) >> +// CHECK: call void @__kmpc_for_static_init_4( >> #pragma omp for ordered(2) >> for (T j = 0; j < M; j++) >> for (i = 0; i < n; i += 2) { >> a[i][j] = foo(i, j); >> // CHECK: invoke {{.+TestStruct.+foo}} >> -// CHECK: load i64, i64* [[CNT]], >> -// CHECK-NEXT: sub nsw i64 %{{.+}}, 1 >> +// CHECK: load i32*, i32** % >> +// CHECK: load i32, i32* % >> +// CHECK: load i32, i32* % >> +// CHECK: load i32, i32* [[J:%.+]], >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 >> +// CHECK-NEXT: sext i32 %{{.+}} to i64 >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT:%.+]], i64 0, i64 0 >> // CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], >> +// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF:%.+]], >> +// CHECK-NEXT: load i32, i32* [[I]], >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 2 >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 2 >> +// CHECK-NEXT: sext i32 %{{.+}} to i64 >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT]], i64 0, i64 1 >> +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT]], i64 0, i64 0 >> // CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 >> [[GTID]], i64* [[TMP]]) >> -// CHECK-NEXT: load i64, i64* [[CNT]], >> -// CHECK-NEXT: load i32, i32* % >> -// CHECK-NEXT: mul nsw i32 1, % >> +// CHECK-NEXT: load i32, i32* [[J:%.+]], >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 1 >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 >> // CHECK-NEXT: sext i32 %{{.+}} to i64 >> -// CHECK-NEXT: sub nsw i64 % >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT:%.+]], i64 0, i64 0 >> // CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], >> +// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF]], >> +// CHECK-NEXT: load i32, i32* [[I]], >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 2 >> +// CHECK-NEXT: sext i32 %{{.+}} to i64 >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT]], i64 0, i64 1 >> +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT]], i64 0, i64 0 >> // CHECK-NEXT: call void @__kmpc_doacross_wait([[IDENT]], i32 >> [[GTID]], i64* [[TMP]]) >> #pragma omp ordered depend(sink : j, i - 2) depend(sink : j - 1, i) >> b[i][j] = bar(a[i][j], b[i - 1][j], b[i][j - 1]); >> // CHECK: invoke {{.+TestStruct.+bar}} >> -// CHECK: load i64, i64* [[CNT]], >> +// CHECK: load i32*, i32** % >> +// CHECK: load i32, i32* % >> +// CHECK: load i32, i32* % >> +// CHECK: load i32, i32* [[J]], >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 1 >> +// CHECK-NEXT: sext i32 %{{.+}} to i64 >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT:%.+]], i64 0, i64 0 >> // CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP:%.+]], >> +// CHECK-NEXT: [[I:%.+]] = load i32*, i32** [[I_REF]], >> +// CHECK-NEXT: load i32, i32* [[I]], >> +// CHECK-NEXT: sub nsw i32 %{{.+}}, 0 >> +// CHECK-NEXT: sdiv i32 %{{.+}}, 2 >> +// CHECK-NEXT: sext i32 %{{.+}} to i64 >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT]], i64 0, i64 1 >> +// CHECK-NEXT: store i64 %{{.+}}, i64* [[TMP]], >> +// CHECK-NEXT: [[TMP:%.+]] = getelementptr inbounds [2 x i64], [2 x >> i64]* [[CNT]], i64 0, i64 0 >> // CHECK-NEXT: call void @__kmpc_doacross_post([[IDENT]], i32 >> [[GTID]], i64* [[TMP]]) >> #pragma omp ordered depend(source) >> baz(a[i][j], b[i][j]); >> >> Modified: cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp?rev=339603&r1=339602&r2=339603&view=diff >> ============================================================================== >> --- cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp (original) >> +++ cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp Mon Aug 13 >> 12:04:24 2018 >> @@ -48,7 +48,7 @@ class S8 : public S7<S1> { >> >> public: >> S8(int v) : S7<S1>(v){ >> -#pragma omp parallel for simd private(a) private(this->a) >> private(S7<S1>::a) >> +#pragma omp parallel for simd private(a) private(this->a) private(S7 >> <S1>::a) >> for (int k = 0; k < a.a; ++k) >> ++this->a.a; >> } >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> >> >> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits