r339603 - [OPENMP] Fix emission of the loop doacross constructs.
Jonas Hahnfeld via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 15 02:02:19 PDT 2018
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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list