[llvm-branch-commits] [flang] [flang][OpenMP] Store DECLARE_TARGET information in WithOmpDeclarative (PR #201103)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jun 2 05:30:56 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-semantics
Author: Krzysztof Parzyszek (kparzysz)
<details>
<summary>Changes</summary>
This will be used to emit DECLARE_TARGET directives into module files.
When a symbol apperars in DECLARE_TARGET (explicitly or explicitly), the OmpDeclareTarget flag will be set on it. The set of accompanying clauses will be stored in the associated details, in the WithOmpDeclarative mixin. The mixin was added to ObjectEntityDetails, ProcEntityDetails, and CommonBlockDetails.
The design goal was to be able to reconstruct the appropriate DECLARE_ TARGET directive for individual symbols for the purpose of emitting it in a module file. Simply storing and then unparsing the AST node may include symbols that should not be emitted.
Additionally, refactor the WithOmpDeclarative printing code for reuse in symbol dumping for debugging, and for printing clause sets.
---
Patch is 27.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/201103.diff
14 Files Affected:
- (modified) flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp (+1-2)
- (modified) flang/include/flang/Parser/dump-parse-tree.h (+1-1)
- (modified) flang/include/flang/Parser/parse-tree.h (+1-1)
- (modified) flang/include/flang/Semantics/symbol.h (+23-3)
- (modified) flang/include/flang/Support/Fortran.h (+3)
- (modified) flang/lib/Parser/unparse.cpp (+1-2)
- (modified) flang/lib/Semantics/mod-file.cpp (+41-27)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+63)
- (modified) flang/lib/Semantics/symbol.cpp (+43-22)
- (modified) flang/test/Parser/OpenMP/declare_target-device_type.f90 (+9-9)
- (modified) flang/test/Parser/OpenMP/groupprivate.f90 (+1-1)
- (added) flang/test/Semantics/OpenMP/declare-target-flags.f90 (+36)
- (added) flang/test/Semantics/OpenMP/declare-target-modfile.f90 (+41)
- (modified) flang/test/Semantics/OpenMP/dump-requires-details.f90 (+1-1)
``````````diff
diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
index d9cb10a352708..c4ca3b22489d7 100644
--- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
+++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp
@@ -137,8 +137,7 @@ void OpenMPCounterVisitor::Post(
}
void OpenMPCounterVisitor::Post(
const OmpDeviceTypeClause::DeviceTypeDescription &c) {
- clauseDetails +=
- "type=" + std::string{OmpDeviceTypeClause::EnumToString(c)} + ";";
+ clauseDetails += "type=" + std::string{common::EnumToString(c)} + ";";
}
void OpenMPCounterVisitor::Post(
const OmpDefaultmapClause::ImplicitBehavior &c) {
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index b4680e1cb656d..ff5c7a8ec01cf 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -66,6 +66,7 @@ class ParseTreeDumper {
NODE_ENUM(common, CUDASubprogramAttrs)
NODE_ENUM(common, ImportKind)
NODE_ENUM(common, OmpDependenceKind)
+ NODE_ENUM(common, OmpDeviceType)
NODE_ENUM(common, OmpMemoryOrderType)
NODE_ENUM(common, OpenACCDeviceType)
NODE(format, ControlEditDesc)
@@ -605,7 +606,6 @@ class ParseTreeDumper {
NODE_ENUM(OmpDeviceModifier, Value)
NODE(parser, OmpDeviceSafesyncClause)
NODE(parser, OmpDeviceTypeClause)
- NODE_ENUM(OmpDeviceTypeClause, DeviceTypeDescription)
NODE(parser, OmpDimsModifier)
NODE(parser, OmpDirectiveName)
NODE(parser, OmpDirectiveSpecification)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 4efae0c9772b3..b8d622edf2b1a 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -4591,7 +4591,7 @@ struct OmpDeviceSafesyncClause {
// device-type-clause ->
// DEVICE_TYPE(ANY | HOST | NOHOST) // since 5.0
struct OmpDeviceTypeClause {
- ENUM_CLASS(DeviceTypeDescription, Any, Host, Nohost)
+ using DeviceTypeDescription = common::OmpDeviceType;
WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription);
};
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index a7647665973d2..bb5a2dbbba409 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -66,6 +66,18 @@ class WithOmpDeclarative {
ompAtomicDefaultMemOrder_ = flags;
}
+ const OmpClauseSet &ompDeclTarget() const { return ompDeclTarget_; }
+ void set_ompDeclTarget(OmpClauseSet clauses) { ompDeclTarget_ = clauses; }
+
+ const std::optional<common::OmpDeviceType> &ompDeviceType() const {
+ return ompDeviceType_;
+ }
+ void set_ompDeclTarget(common::OmpDeviceType device) {
+ ompDeviceType_ = device;
+ }
+
+ void printClauseSet(llvm::raw_ostream &os, const OmpClauseSet &clauses,
+ parser::CharBlock name = parser::CharBlock{}) const;
friend llvm::raw_ostream &operator<<(
llvm::raw_ostream &, const WithOmpDeclarative &);
@@ -81,6 +93,12 @@ class WithOmpDeclarative {
// The argument to ATOMIC_DEFAULT_MEM_ORDER. Only needed when the ADMO
// clause is present in the ompRequires_ set.
std::optional<common::OmpMemoryOrderType> ompAtomicDefaultMemOrder_;
+ // The set of clauses on DECLARE_TARGET directive that apply to this
+ // symbol.
+ OmpClauseSet ompDeclTarget_;
+ // The argument to DEVICE_TYPE clause. Only needed when the clause is
+ // present in the ompDeclTarget_ set.
+ std::optional<common::OmpDeviceType> ompDeviceType_;
};
// A module or submodule.
@@ -379,7 +397,7 @@ class AssocEntityDetails : public EntityDetails {
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const AssocEntityDetails &);
// An entity known to be an object.
-class ObjectEntityDetails : public EntityDetails {
+class ObjectEntityDetails : public EntityDetails, public WithOmpDeclarative {
public:
explicit ObjectEntityDetails(EntityDetails &&);
ObjectEntityDetails(const ObjectEntityDetails &) = default;
@@ -450,7 +468,9 @@ class WithPassArg {
// A procedure pointer (other than one defined with POINTER and an
// INTERFACE block), a dummy procedure (without an INTERFACE but with
// EXTERNAL or use in a procedure reference), or external procedure.
-class ProcEntityDetails : public EntityDetails, public WithPassArg {
+class ProcEntityDetails : public EntityDetails,
+ public WithPassArg,
+ public WithOmpDeclarative {
public:
ProcEntityDetails() = default;
explicit ProcEntityDetails(EntityDetails &&);
@@ -587,7 +607,7 @@ class NamelistDetails {
SymbolVector objects_;
};
-class CommonBlockDetails : public WithBindName {
+class CommonBlockDetails : public WithBindName, public WithOmpDeclarative {
public:
explicit CommonBlockDetails(SourceName location)
: sourceLocation_{location} {}
diff --git a/flang/include/flang/Support/Fortran.h b/flang/include/flang/Support/Fortran.h
index 057b0c3da8c47..1118b2f8080a8 100644
--- a/flang/include/flang/Support/Fortran.h
+++ b/flang/include/flang/Support/Fortran.h
@@ -78,6 +78,9 @@ ENUM_CLASS(OmpDependenceKind, In, Out, Inout, Inoutset, Mutexinoutset, Depobj)
// OpenMP memory-order types
ENUM_CLASS(OmpMemoryOrderType, Acq_Rel, Acquire, Relaxed, Release, Seq_Cst)
+// OpenMP device-type
+ENUM_CLASS(OmpDeviceType, Any, Host, Nohost)
+
// Fortran names may have up to 63 characters (See Fortran 2018 C601).
static constexpr int maxNameLen{63};
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index fd9fcaa0405b2..58ecb365e138a 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2846,6 +2846,7 @@ class UnparseVisitor {
WALK_NESTED_ENUM(common, CUDADataAttr) // CUDA
WALK_NESTED_ENUM(common, CUDASubprogramAttrs) // CUDA
WALK_NESTED_ENUM(common, OmpDependenceKind)
+ WALK_NESTED_ENUM(common, OmpDeviceType)
WALK_NESTED_ENUM(common, OmpMemoryOrderType)
WALK_NESTED_ENUM(IntentSpec, Intent) // R826
WALK_NESTED_ENUM(ImplicitStmt, ImplicitNoneNameSpec) // R866
@@ -2873,8 +2874,6 @@ class UnparseVisitor {
WALK_NESTED_ENUM(OmpThreadsetClause, ThreadsetPolicy) // OMP threadset
WALK_NESTED_ENUM(OmpAccessGroup, Value)
WALK_NESTED_ENUM(OmpDeviceModifier, Value) // OMP device modifier
- WALK_NESTED_ENUM(
- OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type
WALK_NESTED_ENUM(OmpReductionModifier, Value) // OMP reduction-modifier
WALK_NESTED_ENUM(OmpExpectation, Value) // OMP motion-expectation
WALK_NESTED_ENUM(OmpFallbackModifier, Value) // OMP fallback-modifier
diff --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 6e89ae92b882a..4f3d989d35235 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -364,39 +364,51 @@ void ModFileWriter::PrepareRenamings(const Scope &scope) {
}
}
+static const WithOmpDeclarative *GetOmpDeclarative(const Symbol &symbol) {
+ return common::visit(
+ [&](auto &&details) -> const WithOmpDeclarative * {
+ using TypeD = llvm::remove_cvref_t<decltype(details)>;
+ if constexpr (std::is_base_of_v<WithOmpDeclarative, TypeD>) {
+ return &static_cast<const WithOmpDeclarative &>(details);
+ } else {
+ return nullptr;
+ }
+ },
+ symbol.details());
+}
+
+
static void PutOpenMPRequirements(
llvm::raw_ostream &os, const Symbol &symbol, SemanticsContext &semaCtx) {
using OmpClauseSet = WithOmpDeclarative::OmpClauseSet;
- using OmpMemoryOrderType = common::OmpMemoryOrderType;
unsigned version{semaCtx.langOptions().OpenMPVersion};
- const auto [reqs, order]{common::visit(
- [&](auto &&details)
- -> std::pair<const OmpClauseSet *, const OmpMemoryOrderType *> {
- if constexpr (std::is_convertible_v<decltype(details),
- const WithOmpDeclarative &>) {
- if (const auto &memOrder{details.ompAtomicDefaultMemOrder()}) {
- return {&details.ompRequires(), &*memOrder};
- }
- return {&details.ompRequires(), nullptr};
- } else {
- return {nullptr, nullptr};
- }
- },
- symbol.details())};
-
- if (reqs->count()) {
- os << "!$omp requires";
- reqs->IterateOverMembers([&, order = order](llvm::omp::Clause f) {
- os << ' '
- << parser::ToLowerCaseLetters(
- llvm::omp::getOpenMPClauseName(f, version));
- if (f == llvm::omp::Clause::OMPC_atomic_default_mem_order) {
- os << '(' << parser::ToLowerCaseLetters(EnumToString(DEREF(order)))
- << ')';
+ if (const auto *decls{GetOmpDeclarative(symbol)}) {
+ if (const OmpClauseSet &reqs{decls->ompRequires()}; reqs.count()) {
+ os << "!$omp "
+ << parser::ToLowerCaseLetters(llvm::omp::getOpenMPDirectiveName(
+ llvm::omp::Directive::OMPD_requires, version));
+ decls->printClauseSet(os, reqs);
+ os << "\n";
+ }
+ }
+}
+
+static void PutOpenMPDeclarativeDirectives(llvm::raw_ostream &os,
+ const SymbolVector &symbols, SemanticsContext &semaCtx) {
+ using OmpClauseSet = WithOmpDeclarative::OmpClauseSet;
+ unsigned version{semaCtx.langOptions().OpenMPVersion};
+
+ for (const Symbol &symbol : symbols) {
+ if (const auto *decls{GetOmpDeclarative(symbol)}) {
+ if (const OmpClauseSet &dtgt{decls->ompDeclTarget()}; dtgt.count()) {
+ os << "!$omp "
+ << parser::ToLowerCaseLetters(llvm::omp::getOpenMPDirectiveName(
+ llvm::omp::Directive::OMPD_declare_target, version)) << " ";
+ decls->printClauseSet(os, dtgt, symbol.name());
+ os << "\n";
}
- });
- os << "\n";
+ }
}
}
@@ -438,6 +450,8 @@ void ModFileWriter::PutSymbols(
PutUse(symbol);
}
PutOpenMPRequirements(decls_, DEREF(scope.symbol()), context_);
+ PutOpenMPDeclarativeDirectives(decls_, sorted, context_);
+
for (const auto &set : scope.equivalenceSets()) {
if (!set.empty() &&
!set.front().symbol.test(Symbol::Flag::CompilerCreated)) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index b86bf64d18bd3..84d65d87c6a82 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2191,9 +2191,29 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPCriticalConstruct &x) {
bool OmpAttributeVisitor::Pre(const parser::OmpDeclareTargetDirective &x) {
PushContext(x.source, llvm::omp::Directive::OMPD_declare_target);
+ using OmpClauseSet = WithOmpDeclarative::OmpClauseSet;
+ std::map<const Symbol *, WithOmpDeclarative> details;
+ std::optional<common::OmpDeviceType> device;
+
+ if (auto *devClause{
+ parser::omp::FindClause(x.v, llvm::omp::Clause::OMPC_device_type)}) {
+ device = parser::UnwrapRef<common::OmpDeviceType>(*devClause);
+ }
+
+ auto addClause{[&](const parser::OmpObject &object,
+ llvm::omp::Clause clauseId) {
+ if (const Symbol *sym{omp::GetObjectSymbol(object)}) {
+ auto &clauseSet{const_cast<OmpClauseSet &>(details[sym].ompDeclTarget())};
+ clauseSet.set(clauseId);
+ }
+ }};
+
for (const parser::OmpArgument &arg : x.v.Arguments().v) {
if (auto *object{parser::omp::GetArgumentObject(arg)}) {
ResolveOmpObject(*object, Symbol::Flag::OmpDeclareTarget);
+ // Always record this as "enter", even with older OpenMP versions
+ // (as opposed to "to").
+ addClause(*object, llvm::omp::Clause::OMPC_enter);
}
}
@@ -2201,9 +2221,52 @@ bool OmpAttributeVisitor::Pre(const parser::OmpDeclareTargetDirective &x) {
if (auto *objects{parser::omp::GetOmpObjectList(clause)}) {
for (const parser::OmpObject &object : objects->v) {
ResolveOmpObject(object, Symbol::Flag::OmpDeclareTarget);
+ addClause(object, clause.Id());
}
}
}
+
+ if (x.v.Arguments().v.empty() && x.v.Clauses().v.empty()) {
+ // "!$omp declare_target" alone applies to the associated procedure.
+ const Scope &scope{omp::GetScopingUnit(context_.FindScope(x.source))};
+ if (auto *proc{const_cast<Symbol *>(scope.symbol())}) {
+ proc->flags().set(Symbol::Flag::OmpDeclareTarget);
+ auto &clauseSet{
+ const_cast<OmpClauseSet &>(details[proc].ompDeclTarget())};
+ clauseSet.set(llvm::omp::Clause::OMPC_enter);
+ }
+ }
+
+ for (auto &pair : details) {
+ const Symbol *sym{&pair.first->GetUltimate()};
+ const WithOmpDeclarative &decl{pair.second};
+ common::visit(
+ [&](auto &d) {
+ using TypeD = llvm::remove_cvref_t<decltype(d)>;
+ if constexpr (std::is_base_of_v<WithOmpDeclarative, TypeD>) {
+ auto &clauseSet{const_cast<OmpClauseSet &>(d.ompDeclTarget())};
+ clauseSet |= decl.ompDeclTarget();
+ if (device) {
+ clauseSet.set(llvm::omp::Clause::OMPC_device_type);
+ auto &deviceType{
+ const_cast<decltype(device) &>(d.ompDeviceType())};
+ deviceType = device;
+ }
+ } else if constexpr (std::is_same_v<GenericDetails, TypeD> ||
+ std::is_same_v<TypeParamDetails, TypeD> ||
+ std::is_same_v<MiscDetails, TypeD>) { // e.g. KindParamInquiry
+ // These cannot be specified on DECLARE_TARGET. The symbol will
+ // receive the OmpDeclareTarget flag (for a diagnostic message),
+ // but no details will be modified.
+ } else {
+ // Catch any unexpected cases.
+ assert((std::is_base_of_v<WithOmpDeclarative, TypeD>) &&
+ "Unexpected details type");
+ }
+ },
+ const_cast<Symbol *>(sym)->details());
+ }
+
return true;
}
diff --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 7712091a03210..b162a61d105ee 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -70,37 +70,55 @@ static void DumpList(llvm::raw_ostream &os, const char *label, const T &list) {
}
}
-llvm::raw_ostream &operator<<(
- llvm::raw_ostream &os, const WithOmpDeclarative &x) {
- using OmpClauseSet = WithOmpDeclarative::OmpClauseSet;
-
+void WithOmpDeclarative::printClauseSet(llvm::raw_ostream &os,
+ const OmpClauseSet &clauses, parser::CharBlock name) const {
auto toLower = [](std::string_view sv) {
return parser::ToLowerCaseLetters(sv);
};
auto getLowerName = [&](llvm::omp::Clause c) {
- return toLower(llvm::omp::getOpenMPClauseName(c, x.version_));
+ return toLower(llvm::omp::getOpenMPClauseName(c, version_));
};
- auto printClauses = [&](const OmpClauseSet &cs) {
- size_t idx{0}, size{cs.count()};
- cs.IterateOverMembers([&](llvm::omp::Clause c) {
- os << getLowerName(c);
- switch (c) {
- case llvm::omp::Clause::OMPC_atomic_default_mem_order:
- os << '(' << toLower(EnumToString(*x.ompAtomicDefaultMemOrder()))
- << ')';
- break;
- default:
- break;
- }
- if (++idx < size) {
- os << ',';
+
+ size_t idx{0}, size{clauses.count()};
+ clauses.IterateOverMembers([&](llvm::omp::Clause c) {
+ os << getLowerName(c);
+ switch (c) {
+ case llvm::omp::Clause::OMPC_atomic_default_mem_order:
+ os << '(' << toLower(EnumToString(*ompAtomicDefaultMemOrder())) << ')';
+ break;
+ case llvm::omp::Clause::OMPC_device_type:
+ os << "(" << toLower(EnumToString(*ompDeviceType())) << ')';
+ break;
+ case llvm::omp::Clause::OMPC_enter:
+ case llvm::omp::Clause::OMPC_link:
+ if (!name.empty()) {
+ os << '(' << name.ToString() << ')';
}
- });
- };
+ break;
+ case llvm::omp::Clause::OMPC_indirect:
+ os << "(true)";
+ break;
+ default:
+ break;
+ }
+ if (++idx < size) {
+ os << ' ';
+ }
+ });
+}
+
+llvm::raw_ostream &operator<<(
+ llvm::raw_ostream &os, const WithOmpDeclarative &x) {
+ using OmpClauseSet = WithOmpDeclarative::OmpClauseSet;
if (const OmpClauseSet &reqs{x.ompRequires()}; reqs.count()) {
os << " OmpRequirements:(";
- printClauses(reqs);
+ x.printClauseSet(os, reqs);
+ os << ')';
+ }
+ if (const OmpClauseSet &dtgt{x.ompDeclTarget()}; dtgt.count()) {
+ os << " OmpDeclareTargetFlags:(";
+ x.printClauseSet(os, dtgt);
os << ')';
}
return os;
@@ -545,6 +563,7 @@ llvm::raw_ostream &operator<<(
if (x.cudaDataAttr()) {
os << " cudaDataAttr: " << common::EnumToString(*x.cudaDataAttr());
}
+ os << static_cast<const WithOmpDeclarative &>(x);
return os;
}
@@ -584,6 +603,7 @@ llvm::raw_ostream &operator<<(
if (x.isCUDAKernel()) {
os << " isCUDAKernel";
}
+ os << static_cast<const WithOmpDeclarative &>(x);
return os;
}
@@ -679,6 +699,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Details &details) {
for (const auto &object : x.objects()) {
os << ' ' << object->name();
}
+ os << static_cast<const WithOmpDeclarative &>(x);
},
[&](const TypeParamDetails &x) {
DumpOptional(os, "type", x.type());
diff --git a/flang/test/Parser/OpenMP/declare_target-device_type.f90 b/flang/test/Parser/OpenMP/declare_target-device_type.f90
index 4b61fb6f16f33..9c2e63c12941c 100644
--- a/flang/test/Parser/OpenMP/declare_target-device_type.f90
+++ b/flang/test/Parser/OpenMP/declare_target-device_type.f90
@@ -7,7 +7,7 @@ subroutine openmp_declare_target
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareTargetDirective -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target
-!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Host
+!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> OmpDeviceType = Host
!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | Flags = {}
@@ -17,7 +17,7 @@ subroutine openmp_declare_target
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareTargetDirective -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target
-!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Nohost
+!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> OmpDeviceType = Nohost
!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | Flags = {}
@@ -27,7 +27,7 @@ subroutine openmp_declare_target
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareTargetDirective -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target
-!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Any
+!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> OmpDeviceType = Any
!PARSE-TREE: | OmpClause -> Enter -> OmpEnterClause
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | Flags = {}
@@ -37,7 +37,7 @@ subroutine openmp_declare_target
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareTargetDirective -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare target
-!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> DeviceTypeDescription = Host
+!PARSE-TREE: | OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> OmpDeviceType = Host
!PARSE-TREE: | OmpClause -> To -> OmpToClause
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x'
!PARSE-TREE: | | bool = 'true'
@@ -48,7 +48,7 @@ subroutine openmp_declare_target
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareTargetDirective -> OmpDirectiveSpecification
!PARSE-TREE: | OmpDirectiveName -> llvm:...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/201103
More information about the llvm-branch-commits
mailing list