r339603 - [OPENMP] Fix emission of the loop doacross constructs.
Jonas Hahnfeld via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 16 02:40:22 PDT 2018
Thanks Hans!
On 2018-08-16 11:35, Hans Wennborg wrote:
> I've gone ahead and merged it in r339851.
>
> On Wed, Aug 15, 2018 at 3:23 PM, Alexey Bataev <a.bataev at 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 at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>>
>>
More information about the cfe-commits
mailing list