forked from OSchip/llvm-project
[OPENMP] Fix the restrictions for in_reduction clause.
This patch allows to use in_reduction clause even if the innermost directive is not taskgroup. llvm-svn: 308883
This commit is contained in:
parent
3e05105486
commit
f189cb79d4
|
@ -57,6 +57,10 @@ public:
|
|||
DeclRefExpr *PrivateCopy = nullptr;
|
||||
SourceLocation ImplicitDSALoc;
|
||||
DSAVarData() = default;
|
||||
DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr,
|
||||
DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc)
|
||||
: DKind(DKind), CKind(CKind), RefExpr(RefExpr),
|
||||
PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
|
||||
};
|
||||
typedef llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>
|
||||
OperatorOffsetTy;
|
||||
|
@ -246,11 +250,11 @@ public:
|
|||
void addReductionData(ValueDecl *D, SourceRange SR, const Expr *ReductionRef);
|
||||
/// Returns the location and reduction operation from the innermost parent
|
||||
/// region for the given \p D.
|
||||
bool getTopMostReductionData(ValueDecl *D, SourceRange &SR,
|
||||
DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
|
||||
BinaryOperatorKind &BOK);
|
||||
/// Returns the location and reduction operation from the innermost parent
|
||||
/// region for the given \p D.
|
||||
bool getTopMostReductionData(ValueDecl *D, SourceRange &SR,
|
||||
DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
|
||||
const Expr *&ReductionRef);
|
||||
|
||||
/// \brief Returns data sharing attributes from top of the stack for the
|
||||
|
@ -769,48 +773,54 @@ void DSAStackTy::addReductionData(ValueDecl *D, SourceRange SR,
|
|||
ReductionData.set(ReductionRef, SR);
|
||||
}
|
||||
|
||||
bool DSAStackTy::getTopMostReductionData(ValueDecl *D, SourceRange &SR,
|
||||
DSAStackTy::DSAVarData
|
||||
DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
|
||||
BinaryOperatorKind &BOK) {
|
||||
D = getCanonicalDecl(D);
|
||||
assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
|
||||
"Data-sharing attributes stack is empty or has only 1 region.");
|
||||
for (auto I = std::next(Stack.back().first.rbegin(), 0),
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
|
||||
if (Stack.back().first.empty())
|
||||
return DSAVarData();
|
||||
for (auto I = std::next(Stack.back().first.rbegin(), 1),
|
||||
E = Stack.back().first.rend();
|
||||
I != E; std::advance(I, 1)) {
|
||||
auto &Data = I->SharingMap[D];
|
||||
if (Data.Attributes != OMPC_reduction)
|
||||
if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
|
||||
continue;
|
||||
auto &ReductionData = I->ReductionMap[D];
|
||||
if (!ReductionData.ReductionOp ||
|
||||
ReductionData.ReductionOp.is<const Expr *>())
|
||||
return false;
|
||||
return DSAVarData();
|
||||
SR = ReductionData.ReductionRange;
|
||||
BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
|
||||
return true;
|
||||
return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
|
||||
Data.PrivateCopy, I->DefaultAttrLoc);
|
||||
}
|
||||
return false;
|
||||
return DSAVarData();
|
||||
}
|
||||
|
||||
bool DSAStackTy::getTopMostReductionData(ValueDecl *D, SourceRange &SR,
|
||||
DSAStackTy::DSAVarData
|
||||
DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
|
||||
const Expr *&ReductionRef) {
|
||||
D = getCanonicalDecl(D);
|
||||
assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
|
||||
"Data-sharing attributes stack is empty or has only 1 region.");
|
||||
for (auto I = std::next(Stack.back().first.rbegin(), 0),
|
||||
assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
|
||||
if (Stack.back().first.empty())
|
||||
return DSAVarData();
|
||||
for (auto I = std::next(Stack.back().first.rbegin(), 1),
|
||||
E = Stack.back().first.rend();
|
||||
I != E; std::advance(I, 1)) {
|
||||
auto &Data = I->SharingMap[D];
|
||||
if (Data.Attributes != OMPC_reduction)
|
||||
if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
|
||||
continue;
|
||||
auto &ReductionData = I->ReductionMap[D];
|
||||
if (!ReductionData.ReductionOp ||
|
||||
!ReductionData.ReductionOp.is<const Expr *>())
|
||||
return false;
|
||||
return DSAVarData();
|
||||
SR = ReductionData.ReductionRange;
|
||||
ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
|
||||
return true;
|
||||
return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
|
||||
Data.PrivateCopy, I->DefaultAttrLoc);
|
||||
}
|
||||
return false;
|
||||
return DSAVarData();
|
||||
}
|
||||
|
||||
bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
|
||||
|
@ -9550,20 +9560,20 @@ static bool ActOnOMPReductionKindClause(
|
|||
// condition must specify the same reduction-identifier as the in_reduction
|
||||
// clause.
|
||||
if (ClauseKind == OMPC_in_reduction) {
|
||||
DVar = Stack->hasDSA(
|
||||
D, [](OpenMPClauseKind K) { return K != OMPC_unknown; },
|
||||
[](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
|
||||
/*FromParent=*/true);
|
||||
if (DVar.CKind != OMPC_reduction || DVar.DKind != OMPD_taskgroup) {
|
||||
S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
|
||||
continue;
|
||||
}
|
||||
SourceRange ParentSR;
|
||||
BinaryOperatorKind ParentBOK;
|
||||
const Expr *ParentReductionOp;
|
||||
bool IsParentBOK = Stack->getTopMostReductionData(D, ParentSR, ParentBOK);
|
||||
bool IsParentReductionOp =
|
||||
Stack->getTopMostReductionData(D, ParentSR, ParentReductionOp);
|
||||
DSAStackTy::DSAVarData ParentBOKDSA =
|
||||
Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK);
|
||||
DSAStackTy::DSAVarData ParentReductionOpDSA =
|
||||
Stack->getTopMostTaskgroupReductionData(D, ParentSR,
|
||||
ParentReductionOp);
|
||||
bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
|
||||
bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
|
||||
if (!IsParentBOK && !IsParentReductionOp) {
|
||||
S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
|
||||
continue;
|
||||
}
|
||||
if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
|
||||
(DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
|
||||
IsParentReductionOp) {
|
||||
|
@ -9581,7 +9591,10 @@ static bool ActOnOMPReductionKindClause(
|
|||
<< ReductionIdRange << RefExpr->getSourceRange();
|
||||
S.Diag(ParentSR.getBegin(),
|
||||
diag::note_omp_previous_reduction_identifier)
|
||||
<< ParentSR << DVar.RefExpr->getSourceRange();
|
||||
<< ParentSR
|
||||
<< (IsParentBOK ? ParentBOKDSA.RefExpr
|
||||
: ParentReductionOpDSA.RefExpr)
|
||||
->getSourceRange();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -9624,10 +9637,12 @@ static bool ActOnOMPReductionKindClause(
|
|||
// All reduction items are still marked as reduction (to do not increase
|
||||
// code base size).
|
||||
Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
|
||||
if (CurrDir == OMPD_taskgroup) {
|
||||
if (DeclareReductionRef.isUsable())
|
||||
Stack->addReductionData(D, ReductionIdRange, DeclareReductionRef.get());
|
||||
else
|
||||
Stack->addReductionData(D, ReductionIdRange, BOK);
|
||||
}
|
||||
RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get());
|
||||
}
|
||||
return RD.Vars.empty();
|
||||
|
|
|
@ -155,6 +155,14 @@ int main(int argc, char **argv) {
|
|||
// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a]) priority(23) in_reduction(min: arr1)
|
||||
foo();
|
||||
// CHECK-NEXT: foo();
|
||||
#pragma omp taskgroup task_reduction(min: arr1)
|
||||
#pragma omp parallel reduction(+:arr1)
|
||||
#pragma omp task in_reduction(min: arr1)
|
||||
// CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1)
|
||||
// CHECK-NEXT: #pragma omp parallel reduction(+: arr1)
|
||||
// CHECK-NEXT: #pragma omp task in_reduction(min: arr1)
|
||||
foo();
|
||||
// CHECK-NEXT: foo();
|
||||
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue