Skip to content

[OpenMP]Initial parsing/sema support for target_device selector set #118471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/include/clang/AST/OpenMPClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -9451,7 +9451,8 @@ struct TargetOMPContext final : public llvm::omp::OMPContext {
TargetOMPContext(ASTContext &ASTCtx,
std::function<void(StringRef)> &&DiagUnknownTrait,
const FunctionDecl *CurrentFunctionDecl,
ArrayRef<llvm::omp::TraitProperty> ConstructTraits);
ArrayRef<llvm::omp::TraitProperty> ConstructTraits,
int DeviceNum);

virtual ~TargetOMPContext() = default;

Expand Down
16 changes: 16 additions & 0 deletions clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,9 @@ class SemaOpenMP : public SemaBase {
ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
SourceLocation AppendArgsLoc, SourceRange SR);

/// Called on device_num selector in context selectors.
void ActOnOpenMPDeviceNum(Expr *DeviceNumExpr);

OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
SourceLocation StartLoc,
SourceLocation LParenLoc,
Expand Down Expand Up @@ -1410,6 +1413,13 @@ class SemaOpenMP : public SemaBase {

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

/// Setter and getter functions for device_num.
void setOpenMPDeviceNum(int Num);

int getOpenMPDeviceNum() const;

void setOpenMPDeviceNumID(StringRef ID);

private:
void *VarDataSharingAttributesStack;

Expand Down Expand Up @@ -1480,6 +1490,12 @@ class SemaOpenMP : public SemaBase {

/// All `omp assumes` we encountered so far.
SmallVector<OMPAssumeAttr *, 4> OMPAssumeGlobal;

/// Device number specified by the context selector.
int DeviceNum = -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment new data member

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


/// Device number identifier specified by the context selector.
StringRef DeviceNumID;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

};

} // namespace clang
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/AST/OpenMPClause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2927,9 +2927,13 @@ llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
TargetOMPContext::TargetOMPContext(
ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
const FunctionDecl *CurrentFunctionDecl,
ArrayRef<llvm::omp::TraitProperty> ConstructTraits)
ArrayRef<llvm::omp::TraitProperty> ConstructTraits, int DeviceNum)
: OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
ASTCtx.getTargetInfo().getTriple()),
ASTCtx.getTargetInfo().getTriple(),
ASTCtx.getLangOpts().OMPTargetTriples.empty()
? llvm::Triple()
: ASTCtx.getLangOpts().OMPTargetTriples[0],
DeviceNum),
FeatureValidityCheck([&](StringRef FeatureName) {
return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);
}),
Expand Down
33 changes: 24 additions & 9 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,18 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
TIProperty.Kind = TraitProperty::invalid;

SourceLocation NameLoc = Tok.getLocation();
StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
StringRef Name;
if (Selector == llvm::omp::TraitSelector::target_device_device_num) {
Name = "number";
TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Selector, Name);
ExprResult DeviceNumExprResult = ParseExpression();
if (DeviceNumExprResult.isUsable()) {
Expr *DeviceNumExpr = DeviceNumExprResult.get();
Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr);
}
return;
}
Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
if (Name.empty()) {
Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
<< CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
Expand Down Expand Up @@ -918,7 +929,8 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
<< "(<property-name>)";
return;
}
TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
TraitSelector SelectorForName =
getOpenMPContextTraitSelectorKind(Name, SetForName);
if (SelectorForName != TraitSelector::invalid) {
Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
<< Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
Expand All @@ -935,7 +947,7 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
}
for (const auto &PotentialSet :
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
TraitSet::device}) {
TraitSet::device, TraitSet::target_device}) {
TraitProperty PropertyForName =
getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
if (PropertyForName == TraitProperty::invalid)
Expand Down Expand Up @@ -1062,7 +1074,7 @@ void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
return;
}

TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
TISelector.Kind = getOpenMPContextTraitSelectorKind(Name, Set);
if (TISelector.Kind != TraitSelector::invalid) {
if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
TISelector.Kind = TraitSelector::invalid;
Expand All @@ -1084,7 +1096,7 @@ void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
}
for (const auto &PotentialSet :
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
TraitSet::device}) {
TraitSet::device, TraitSet::target_device}) {
TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
PotentialSet, TraitSelector::invalid, Name);
if (PropertyForName == TraitProperty::invalid)
Expand Down Expand Up @@ -1259,7 +1271,8 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
// It follows diagnosis and helping notes.
Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;

TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
TraitSelector SelectorForName =
getOpenMPContextTraitSelectorKind(Name, TISet.Kind);
if (SelectorForName != TraitSelector::invalid) {
Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
<< Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
Expand All @@ -1276,7 +1289,7 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
}
for (const auto &PotentialSet :
{TraitSet::construct, TraitSet::user, TraitSet::implementation,
TraitSet::device}) {
TraitSet::device, TraitSet::target_device}) {
TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
PotentialSet, TraitSelector::invalid, Name);
if (PropertyForName == TraitProperty::invalid)
Expand Down Expand Up @@ -2253,7 +2266,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
TargetOMPContext OMPCtx(
ASTCtx, std::move(DiagUnknownTrait),
/* CurrentFunctionDecl */ nullptr,
/* ConstructTraits */ ArrayRef<llvm::omp::TraitProperty>());
/* ConstructTraits */ ArrayRef<llvm::omp::TraitProperty>(),
Actions.OpenMP().getOpenMPDeviceNum());

if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI);
Expand Down Expand Up @@ -2805,7 +2819,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
};
TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
/* CurrentFunctionDecl */ nullptr,
ArrayRef<llvm::omp::TraitProperty>());
ArrayRef<llvm::omp::TraitProperty>(),
Actions.OpenMP().getOpenMPDeviceNum());

// A single match is returned for OpenMP 5.0
int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
Expand Down
34 changes: 33 additions & 1 deletion clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7134,7 +7134,7 @@ ExprResult SemaOpenMP::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
};
TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
SemaRef.getCurFunctionDecl(),
DSAStack->getConstructTraits());
DSAStack->getConstructTraits(), getOpenMPDeviceNum());

QualType CalleeFnType = CalleeFnDecl->getType();

Expand Down Expand Up @@ -15631,6 +15631,38 @@ ExprResult SemaOpenMP::VerifyPositiveIntegerConstantInClause(
return ICE;
}

void SemaOpenMP::setOpenMPDeviceNum(int Num) { DeviceNum = Num; }

void SemaOpenMP::setOpenMPDeviceNumID(StringRef ID) { DeviceNumID = ID; }

int SemaOpenMP::getOpenMPDeviceNum() const { return DeviceNum; }

void SemaOpenMP::ActOnOpenMPDeviceNum(Expr *DeviceNumExpr) {
llvm::APSInt Result;
Expr::EvalResult EvalResult;
// Evaluate the expression to an integer value
if (!DeviceNumExpr->isValueDependent() &&
DeviceNumExpr->EvaluateAsInt(EvalResult, SemaRef.Context)) {
// The device expression must evaluate to a non-negative integer value.
Result = EvalResult.Val.getInt();
if (Result.isNonNegative()) {
setOpenMPDeviceNum(Result.getZExtValue());
} else {
Diag(DeviceNumExpr->getExprLoc(),
diag::err_omp_negative_expression_in_clause)
<< "device_num" << 0 << DeviceNumExpr->getSourceRange();
}
} else if (auto *DeclRef = dyn_cast<DeclRefExpr>(DeviceNumExpr)) {
// Check if the expression is an identifier
IdentifierInfo *IdInfo = DeclRef->getDecl()->getIdentifier();
if (IdInfo) {
setOpenMPDeviceNumID(IdInfo->getName());
}
} else {
Diag(DeviceNumExpr->getExprLoc(), diag::err_expected_expression);
}
}

OMPClause *SemaOpenMP::ActOnOpenMPSafelenClause(Expr *Len,
SourceLocation StartLoc,
SourceLocation LParenLoc,
Expand Down
22 changes: 11 additions & 11 deletions clang/test/OpenMP/begin_declare_variant_messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,27 @@ const int var;
#pragma omp end declare variant
#pragma omp begin declare variant match // expected-error {{expected '(' after 'match'}}
#pragma omp end declare variant
#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 '('}}
#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 '('}}
#pragma omp end declare variant
#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}}
#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}}
#pragma omp end declare variant
#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}}
#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}}
#pragma omp end declare variant
#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}}
#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}}
#pragma omp end declare variant
#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}}
#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}}
#pragma omp end declare variant
#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 '('}}
#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 '('}}
#pragma omp end declare variant
#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 '('}}
#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 '('}}
#pragma omp end declare variant
#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}}
#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}}
#pragma omp end declare variant
#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}}
#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}}
#pragma omp end declare variant
#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}}
#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}}
#pragma omp end declare variant
#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}}
#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}}
#pragma omp end declare variant
#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}}
#pragma omp end declare variant
Expand Down
4 changes: 4 additions & 0 deletions clang/test/OpenMP/declare_variant_ast_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ int foo(void);
#pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm, xxx, ibm)}, device={kind(cpu, nohost)})
#pragma omp declare variant(foo) match(device={kind(host)})
#pragma omp declare variant(foo) match(device={kind(nohost), xxx})
#pragma omp declare variant(foo) match(target_device={kind(host)})
#pragma omp declare variant(foo) match(target_device={kind(nohost), xxx})
#pragma omp declare variant(foo) match(implementation={extension(match_all)})
#pragma omp declare variant(foo) match(implementation={extension(match_any)})
#pragma omp declare variant(foo) match(implementation={extension(match_none)})
Expand All @@ -29,6 +31,8 @@ int bar(void);
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_none)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_any)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_all)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(target_device={kind(nohost)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(target_device={kind(host)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(nohost)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(host)})
// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)}, device={kind(cpu, nohost)})
Expand Down
2 changes: 1 addition & 1 deletion clang/test/OpenMP/declare_variant_bind_to_decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ int main() {
// CHECK-LABEL: define {{[^@]+}}@main
// CHECK-SAME: () #[[ATTR1:[0-9]+]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: call void @"_Z74foo$ompvariant$S2$s7$Pppc64le$Pppc64$S3$s9$Pmatch_any$Pbind_to_declarationv"()
// CHECK-NEXT: call void @{{"_Z[0-9]+foo\$ompvariant\$.*"}}()
// CHECK-NEXT: ret i32 0
//
Loading