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