forked from OSchip/llvm-project
[OPENMP50]Do not allow several scan directives in the same parent
region. According to OpenMP 5.0, exactly one scan directive must appear in the loop body of an enclosing worksharing-loop, worksharing-loop SIMD, or simd construct on which a reduction clause with the inscan modifier is present.
This commit is contained in:
parent
7ec2444880
commit
9b95929a26
|
@ -9833,6 +9833,10 @@ def err_omp_prohibited_region_critical_same_name : Error<
|
||||||
"cannot nest 'critical' regions having the same name %0">;
|
"cannot nest 'critical' regions having the same name %0">;
|
||||||
def note_omp_previous_critical_region : Note<
|
def note_omp_previous_critical_region : Note<
|
||||||
"previous 'critical' region starts here">;
|
"previous 'critical' region starts here">;
|
||||||
|
def err_omp_several_scan_directives_in_region : Error<
|
||||||
|
"exactly one 'scan' directive must appear in the loop body of an enclosing directive">;
|
||||||
|
def note_omp_previous_scan_directive : Note<
|
||||||
|
"previous 'scan' directive used here">;
|
||||||
def err_omp_sections_not_compound_stmt : Error<
|
def err_omp_sections_not_compound_stmt : Error<
|
||||||
"the statement for '#pragma omp sections' must be a compound statement">;
|
"the statement for '#pragma omp sections' must be a compound statement">;
|
||||||
def err_omp_parallel_sections_not_compound_stmt : Error<
|
def err_omp_parallel_sections_not_compound_stmt : Error<
|
||||||
|
|
|
@ -154,6 +154,7 @@ private:
|
||||||
bool CancelRegion = false;
|
bool CancelRegion = false;
|
||||||
bool LoopStart = false;
|
bool LoopStart = false;
|
||||||
bool BodyComplete = false;
|
bool BodyComplete = false;
|
||||||
|
SourceLocation PrevScanLocation;
|
||||||
SourceLocation InnerTeamsRegionLoc;
|
SourceLocation InnerTeamsRegionLoc;
|
||||||
/// Reference to the taskgroup task_reduction reference expression.
|
/// Reference to the taskgroup task_reduction reference expression.
|
||||||
Expr *TaskgroupReductionRef = nullptr;
|
Expr *TaskgroupReductionRef = nullptr;
|
||||||
|
@ -781,6 +782,22 @@ public:
|
||||||
return Top ? Top->CancelRegion : false;
|
return Top ? Top->CancelRegion : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark that parent region already has scan directive.
|
||||||
|
void setParentHasScanDirective(SourceLocation Loc) {
|
||||||
|
if (SharingMapTy *Parent = getSecondOnStackOrNull())
|
||||||
|
Parent->PrevScanLocation = Loc;
|
||||||
|
}
|
||||||
|
/// Return true if current region has inner cancel construct.
|
||||||
|
bool doesParentHasScanDirective() const {
|
||||||
|
const SharingMapTy *Top = getSecondOnStackOrNull();
|
||||||
|
return Top ? Top->PrevScanLocation.isValid() : false;
|
||||||
|
}
|
||||||
|
/// Return true if current region has inner cancel construct.
|
||||||
|
SourceLocation getParentScanDirectiveLoc() const {
|
||||||
|
const SharingMapTy *Top = getSecondOnStackOrNull();
|
||||||
|
return Top ? Top->PrevScanLocation : SourceLocation();
|
||||||
|
}
|
||||||
|
|
||||||
/// Set collapse value for the region.
|
/// Set collapse value for the region.
|
||||||
void setAssociatedLoops(unsigned Val) {
|
void setAssociatedLoops(unsigned Val) {
|
||||||
getTopOfStack().AssociatedLoops = Val;
|
getTopOfStack().AssociatedLoops = Val;
|
||||||
|
@ -8795,11 +8812,21 @@ StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
|
||||||
StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
|
StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
|
||||||
SourceLocation StartLoc,
|
SourceLocation StartLoc,
|
||||||
SourceLocation EndLoc) {
|
SourceLocation EndLoc) {
|
||||||
|
// Check that exactly one clause is specified.
|
||||||
if (Clauses.size() != 1) {
|
if (Clauses.size() != 1) {
|
||||||
Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
|
Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
|
||||||
diag::err_omp_scan_single_clause_expected);
|
diag::err_omp_scan_single_clause_expected);
|
||||||
return StmtError();
|
return StmtError();
|
||||||
}
|
}
|
||||||
|
// Check that only one instance of scan directives is used in the same outer
|
||||||
|
// region.
|
||||||
|
if (DSAStack->doesParentHasScanDirective()) {
|
||||||
|
Diag(StartLoc, diag::err_omp_several_scan_directives_in_region);
|
||||||
|
Diag(DSAStack->getParentScanDirectiveLoc(),
|
||||||
|
diag::note_omp_previous_scan_directive);
|
||||||
|
return StmtError();
|
||||||
|
}
|
||||||
|
DSAStack->setParentHasScanDirective(StartLoc);
|
||||||
return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
|
return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,12 +54,12 @@ T tmain(T argc) {
|
||||||
#pragma omp simd
|
#pragma omp simd
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
#pragma omp scan inclusive(argc)
|
#pragma omp scan inclusive(argc) // expected-note 2 {{previous 'scan' directive used here}}
|
||||||
case 1:
|
case 1:
|
||||||
#pragma omp scan inclusive(argc)
|
#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
#pragma omp scan inclusive(argc)
|
#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
#pragma omp simd
|
#pragma omp simd
|
||||||
|
@ -133,12 +133,12 @@ int main(int argc, char **argv) {
|
||||||
#pragma omp simd
|
#pragma omp simd
|
||||||
for (int i = 0; i < 10; ++i)
|
for (int i = 0; i < 10; ++i)
|
||||||
switch (argc) {
|
switch (argc) {
|
||||||
#pragma omp scan inclusive(argc)
|
#pragma omp scan inclusive(argc) // expected-note 2 {{previous 'scan' directive used here}}
|
||||||
case 1:
|
case 1:
|
||||||
#pragma omp scan inclusive(argc)
|
#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
#pragma omp scan inclusive(argc)
|
#pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
#pragma omp simd
|
#pragma omp simd
|
||||||
|
|
Loading…
Reference in New Issue