Skip to content

Commit 8c36665

Browse files
[OpenMP]Initial parsing/sema support for target_device selector set (llvm#118471)
This patch adds initial support for target_device selector set - Section 9.2 (Spec 6.0)
1 parent 7d669b7 commit 8c36665

16 files changed

+340
-136
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9451,7 +9451,8 @@ struct TargetOMPContext final : public llvm::omp::OMPContext {
94519451
TargetOMPContext(ASTContext &ASTCtx,
94529452
std::function<void(StringRef)> &&DiagUnknownTrait,
94539453
const FunctionDecl *CurrentFunctionDecl,
9454-
ArrayRef<llvm::omp::TraitProperty> ConstructTraits);
9454+
ArrayRef<llvm::omp::TraitProperty> ConstructTraits,
9455+
int DeviceNum);
94559456

94569457
virtual ~TargetOMPContext() = default;
94579458

clang/include/clang/Sema/SemaOpenMP.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,9 @@ class SemaOpenMP : public SemaBase {
849849
ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
850850
SourceLocation AppendArgsLoc, SourceRange SR);
851851

852+
/// Called on device_num selector in context selectors.
853+
void ActOnOpenMPDeviceNum(Expr *DeviceNumExpr);
854+
852855
OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
853856
SourceLocation StartLoc,
854857
SourceLocation LParenLoc,
@@ -1410,6 +1413,13 @@ class SemaOpenMP : public SemaBase {
14101413

14111414
void handleOMPAssumeAttr(Decl *D, const ParsedAttr &AL);
14121415

1416+
/// Setter and getter functions for device_num.
1417+
void setOpenMPDeviceNum(int Num);
1418+
1419+
int getOpenMPDeviceNum() const;
1420+
1421+
void setOpenMPDeviceNumID(StringRef ID);
1422+
14131423
private:
14141424
void *VarDataSharingAttributesStack;
14151425

@@ -1480,6 +1490,12 @@ class SemaOpenMP : public SemaBase {
14801490

14811491
/// All `omp assumes` we encountered so far.
14821492
SmallVector<OMPAssumeAttr *, 4> OMPAssumeGlobal;
1493+
1494+
/// Device number specified by the context selector.
1495+
int DeviceNum = -1;
1496+
1497+
/// Device number identifier specified by the context selector.
1498+
StringRef DeviceNumID;
14831499
};
14841500

14851501
} // namespace clang

clang/lib/AST/OpenMPClause.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,9 +2927,13 @@ llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
29272927
TargetOMPContext::TargetOMPContext(
29282928
ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
29292929
const FunctionDecl *CurrentFunctionDecl,
2930-
ArrayRef<llvm::omp::TraitProperty> ConstructTraits)
2930+
ArrayRef<llvm::omp::TraitProperty> ConstructTraits, int DeviceNum)
29312931
: OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
2932-
ASTCtx.getTargetInfo().getTriple()),
2932+
ASTCtx.getTargetInfo().getTriple(),
2933+
ASTCtx.getLangOpts().OMPTargetTriples.empty()
2934+
? llvm::Triple()
2935+
: ASTCtx.getLangOpts().OMPTargetTriples[0],
2936+
DeviceNum),
29332937
FeatureValidityCheck([&](StringRef FeatureName) {
29342938
return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);
29352939
}),

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,18 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
888888
TIProperty.Kind = TraitProperty::invalid;
889889

890890
SourceLocation NameLoc = Tok.getLocation();
891-
StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
891+
StringRef Name;
892+
if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
893+
Name = "number";
894+
TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Selector, Name);
895+
ExprResult DeviceNumExprResult = ParseExpression();
896+
if (DeviceNumExprResult.isUsable()) {
897+
Expr *DeviceNumExpr = DeviceNumExprResult.get();
898+
Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
899+
}
900+
return;
901+
}
902+
Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
892903
if (Name.empty()) {
893904
Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
894905
<< CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
@@ -918,7 +929,8 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
918929
<< "(<property-name>)";
919930
return;
920931
}
921-
TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
932+
TraitSelector SelectorForName =
933+
getOpenMPContextTraitSelectorKind(Name, SetForName);
922934
if (SelectorForName != TraitSelector::invalid) {
923935
Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
924936
<< Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
@@ -935,7 +947,7 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
935947
}
936948
for (const auto &PotentialSet :
937949
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
938-
TraitSet::device}) {
950+
TraitSet::device, TraitSet::target_device}) {
939951
TraitProperty PropertyForName =
940952
getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
941953
if (PropertyForName == TraitProperty::invalid)
@@ -1062,7 +1074,7 @@ void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
10621074
return;
10631075
}
10641076

1065-
TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
1077+
TISelector.Kind = getOpenMPContextTraitSelectorKind(Name, Set);
10661078
if (TISelector.Kind != TraitSelector::invalid) {
10671079
if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
10681080
TISelector.Kind = TraitSelector::invalid;
@@ -1084,7 +1096,7 @@ void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
10841096
}
10851097
for (const auto &PotentialSet :
10861098
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
1087-
TraitSet::device}) {
1099+
TraitSet::device, TraitSet::target_device}) {
10881100
TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
10891101
PotentialSet, TraitSelector::invalid, Name);
10901102
if (PropertyForName == TraitProperty::invalid)
@@ -1259,7 +1271,8 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
12591271
// It follows diagnosis and helping notes.
12601272
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
12611273

1262-
TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1274+
TraitSelector SelectorForName =
1275+
getOpenMPContextTraitSelectorKind(Name, TISet.Kind);
12631276
if (SelectorForName != TraitSelector::invalid) {
12641277
Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
12651278
<< Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
@@ -1276,7 +1289,7 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
12761289
}
12771290
for (const auto &PotentialSet :
12781291
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
1279-
TraitSet::device}) {
1292+
TraitSet::device, TraitSet::target_device}) {
12801293
TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
12811294
PotentialSet, TraitSelector::invalid, Name);
12821295
if (PropertyForName == TraitProperty::invalid)
@@ -2253,7 +2266,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
22532266
TargetOMPContext OMPCtx(
22542267
ASTCtx, std::move(DiagUnknownTrait),
22552268
/* CurrentFunctionDecl */ nullptr,
2256-
/* ConstructTraits */ ArrayRef<llvm::omp::TraitProperty>());
2269+
/* ConstructTraits */ ArrayRef<llvm::omp::TraitProperty>(),
2270+
Actions.OpenMP().getOpenMPDeviceNum());
22572271

22582272
if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
22592273
Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
@@ -2805,7 +2819,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
28052819
};
28062820
TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
28072821
/* CurrentFunctionDecl */ nullptr,
2808-
ArrayRef<llvm::omp::TraitProperty>());
2822+
ArrayRef<llvm::omp::TraitProperty>(),
2823+
Actions.OpenMP().getOpenMPDeviceNum());
28092824

28102825
// A single match is returned for OpenMP 5.0
28112826
int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7134,7 +7134,7 @@ ExprResult SemaOpenMP::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
71347134
};
71357135
TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
71367136
SemaRef.getCurFunctionDecl(),
7137-
DSAStack->getConstructTraits());
7137+
DSAStack->getConstructTraits(), getOpenMPDeviceNum());
71387138

71397139
QualType CalleeFnType = CalleeFnDecl->getType();
71407140

@@ -15631,6 +15631,38 @@ ExprResult SemaOpenMP::VerifyPositiveIntegerConstantInClause(
1563115631
return ICE;
1563215632
}
1563315633

15634+
void SemaOpenMP::setOpenMPDeviceNum(int Num) { DeviceNum = Num; }
15635+
15636+
void SemaOpenMP::setOpenMPDeviceNumID(StringRef ID) { DeviceNumID = ID; }
15637+
15638+
int SemaOpenMP::getOpenMPDeviceNum() const { return DeviceNum; }
15639+
15640+
void SemaOpenMP::ActOnOpenMPDeviceNum(Expr *DeviceNumExpr) {
15641+
llvm::APSInt Result;
15642+
Expr::EvalResult EvalResult;
15643+
// Evaluate the expression to an integer value
15644+
if (!DeviceNumExpr->isValueDependent() &&
15645+
DeviceNumExpr->EvaluateAsInt(EvalResult, SemaRef.Context)) {
15646+
// The device expression must evaluate to a non-negative integer value.
15647+
Result = EvalResult.Val.getInt();
15648+
if (Result.isNonNegative()) {
15649+
setOpenMPDeviceNum(Result.getZExtValue());
15650+
} else {
15651+
Diag(DeviceNumExpr->getExprLoc(),
15652+
diag::err_omp_negative_expression_in_clause)
15653+
<< "device_num" << 0 << DeviceNumExpr->getSourceRange();
15654+
}
15655+
} else if (auto *DeclRef = dyn_cast<DeclRefExpr>(DeviceNumExpr)) {
15656+
// Check if the expression is an identifier
15657+
IdentifierInfo *IdInfo = DeclRef->getDecl()->getIdentifier();
15658+
if (IdInfo) {
15659+
setOpenMPDeviceNumID(IdInfo->getName());
15660+
}
15661+
} else {
15662+
Diag(DeviceNumExpr->getExprLoc(), diag::err_expected_expression);
15663+
}
15664+
}
15665+
1563415666
OMPClause *SemaOpenMP::ActOnOpenMPSafelenClause(Expr *Len,
1563515667
SourceLocation StartLoc,
1563615668
SourceLocation LParenLoc,

clang/test/OpenMP/begin_declare_variant_messages.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,27 @@ const int var;
3232
#pragma omp end declare variant
3333
#pragma omp begin declare variant match // expected-error {{expected '(' after 'match'}}
3434
#pragma omp end declare variant
35-
#pragma omp begin declare variant match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
35+
#pragma omp begin declare variant match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
3636
#pragma omp end declare variant
37-
#pragma omp begin declare variant match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
37+
#pragma omp begin declare variant match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
3838
#pragma omp end declare variant
39-
#pragma omp begin declare variant match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
39+
#pragma omp begin declare variant match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
4040
#pragma omp end declare variant
41-
#pragma omp begin declare variant match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
41+
#pragma omp begin declare variant match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
4242
#pragma omp end declare variant
43-
#pragma omp begin declare variant match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
43+
#pragma omp begin declare variant match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
4444
#pragma omp end declare variant
45-
#pragma omp begin declare variant match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
45+
#pragma omp begin declare variant match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
4646
#pragma omp end declare variant
47-
#pragma omp begin declare variant match(xxx={) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
47+
#pragma omp begin declare variant match(xxx={) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}}
4848
#pragma omp end declare variant
49-
#pragma omp begin declare variant match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
49+
#pragma omp begin declare variant match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
5050
#pragma omp end declare variant
51-
#pragma omp begin declare variant match(xxx={vvv, vvv}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
51+
#pragma omp begin declare variant match(xxx={vvv, vvv}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
5252
#pragma omp end declare variant
53-
#pragma omp begin declare variant match(xxx={vvv} xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
53+
#pragma omp begin declare variant match(xxx={vvv} xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
5454
#pragma omp end declare variant
55-
#pragma omp begin declare variant match(xxx={vvv}) xxx // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
55+
#pragma omp begin declare variant match(xxx={vvv}) xxx // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}}
5656
#pragma omp end declare variant
5757
#pragma omp begin declare variant match(implementation={xxx}) // expected-warning {{'xxx' is not a valid context selector for the context set 'implementation'; selector ignored}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}}
5858
#pragma omp end declare variant

clang/test/OpenMP/declare_variant_ast_print.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ int foo(void);
2020
#pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm, xxx, ibm)}, device={kind(cpu, nohost)})
2121
#pragma omp declare variant(foo) match(device={kind(host)})
2222
#pragma omp declare variant(foo) match(device={kind(nohost), xxx})
23+
#pragma omp declare variant(foo) match(target_device={kind(host)})
24+
#pragma omp declare variant(foo) match(target_device={kind(nohost), xxx})
2325
#pragma omp declare variant(foo) match(implementation={extension(match_all)})
2426
#pragma omp declare variant(foo) match(implementation={extension(match_any)})
2527
#pragma omp declare variant(foo) match(implementation={extension(match_none)})
@@ -29,6 +31,8 @@ int bar(void);
2931
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_none)})
3032
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_any)})
3133
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_all)})
34+
// CHECK-NEXT: #pragma omp declare variant(foo) match(target_device={kind(nohost)})
35+
// CHECK-NEXT: #pragma omp declare variant(foo) match(target_device={kind(host)})
3236
// CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(nohost)})
3337
// CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(host)})
3438
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)}, device={kind(cpu, nohost)})

clang/test/OpenMP/declare_variant_bind_to_decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ int main() {
2929
// CHECK-LABEL: define {{[^@]+}}@main
3030
// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
3131
// CHECK-NEXT: entry:
32-
// CHECK-NEXT: call void @"_Z74foo$ompvariant$S2$s7$Pppc64le$Pppc64$S3$s9$Pmatch_any$Pbind_to_declarationv"()
32+
// CHECK-NEXT: call void @{{"_Z[0-9]+foo\$ompvariant\$.*"}}()
3333
// CHECK-NEXT: ret i32 0
3434
//

0 commit comments

Comments
 (0)