[flang][OpenMP] Version-dependent parsing of map-type-modifier
Up until 5.2, ALWAYS, CLOSE, and PRESENT were keywords of the map-type-modifier. Starting from 6.0 they all became their own single-keyword modifiers. This allowed specifying them together, unlike in the past where map-type-modifier was unique. To avoid using a single representation of the modifiers, and be able to validate them through non-conditional properties, the AST was rewritten back to the older form in canonicalization when the spec version was set to 5.2 or earlier. Now that the parser is version-aware, it can generate the desired AST from the start. Additionally, extract the OMPX_HOLD modifier out of the map-type- modifier into its own AST node regardless of version.
This commit is contained in:
parent
cf5e8828dc
commit
ce1c15a062
6 changed files with 75 additions and 78 deletions
|
|
@ -4212,9 +4212,8 @@ struct OmpMapType {
|
|||
// CLOSE | // since 5.0, until 5.2
|
||||
// PRESENT // since 5.1, until 5.2
|
||||
// Since 6.0 the map-type-modifier has been split into individual modifiers.
|
||||
//
|
||||
struct OmpMapTypeModifier {
|
||||
ENUM_CLASS(Value, Always, Close, Present, Ompx_Hold)
|
||||
ENUM_CLASS(Value, Always, Close, Present)
|
||||
WRAPPER_CLASS_BOILERPLATE(OmpMapTypeModifier, Value);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1229,7 +1229,6 @@ Map make(const parser::OmpClause::Map &inp,
|
|||
// clang-format off
|
||||
MS(Always, Always)
|
||||
MS(Close, Close)
|
||||
MS(Ompx_Hold, OmpxHold)
|
||||
MS(Present, Present)
|
||||
// clang-format on
|
||||
);
|
||||
|
|
|
|||
|
|
@ -937,14 +937,55 @@ TYPE_PARSER(construct<OmpMapper>( //
|
|||
"MAPPER"_tok >> parenthesized(Parser<ObjectName>{})))
|
||||
|
||||
// map-type -> ALLOC | DELETE | FROM | RELEASE | STORAGE | TO | TOFROM
|
||||
TYPE_PARSER(construct<OmpMapType>( //
|
||||
"ALLOC" >> pure(OmpMapType::Value::Alloc) ||
|
||||
// Parse "DELETE" as OmpDeleteModifier
|
||||
"FROM" >> pure(OmpMapType::Value::From) ||
|
||||
"RELEASE" >> pure(OmpMapType::Value::Release) ||
|
||||
"STORAGE" >> pure(OmpMapType::Value::Storage) ||
|
||||
"TO"_id >> pure(OmpMapType::Value::To) ||
|
||||
"TOFROM" >> pure(OmpMapType::Value::Tofrom)))
|
||||
struct OmpMapTypeParser {
|
||||
using resultType = OmpMapType::Value;
|
||||
|
||||
std::optional<resultType> Parse(ParseState &state) const {
|
||||
unsigned version{state.userState()->langOptions().OpenMPVersion};
|
||||
if (version < 60) {
|
||||
auto parser{//
|
||||
"ALLOC" >> pure(OmpMapType::Value::Alloc) ||
|
||||
"DELETE" >> pure(OmpMapType::Value::Delete) ||
|
||||
"FROM" >> pure(OmpMapType::Value::From) ||
|
||||
"RELEASE" >> pure(OmpMapType::Value::Release) ||
|
||||
"STORAGE" >> pure(OmpMapType::Value::Storage) ||
|
||||
"TO"_id >> pure(OmpMapType::Value::To) ||
|
||||
"TOFROM" >> pure(OmpMapType::Value::Tofrom)};
|
||||
return parser.Parse(state);
|
||||
} else {
|
||||
auto parser{//
|
||||
"ALLOC" >> pure(OmpMapType::Value::Alloc) ||
|
||||
"FROM" >> pure(OmpMapType::Value::From) ||
|
||||
"RELEASE" >> pure(OmpMapType::Value::Release) ||
|
||||
"STORAGE" >> pure(OmpMapType::Value::Storage) ||
|
||||
"TO"_id >> pure(OmpMapType::Value::To) ||
|
||||
"TOFROM" >> pure(OmpMapType::Value::Tofrom)};
|
||||
return parser.Parse(state);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TYPE_PARSER(OmpMapTypeParser{})
|
||||
|
||||
struct OmpMapTypeModifierParser {
|
||||
using resultType = OmpMapTypeModifier::Value;
|
||||
|
||||
std::optional<resultType> Parse(ParseState &state) const {
|
||||
unsigned version{state.userState()->langOptions().OpenMPVersion};
|
||||
if (version < 60) {
|
||||
auto parser{//
|
||||
"ALWAYS" >> pure(OmpMapTypeModifier::Value::Always) ||
|
||||
"CLOSE" >> pure(OmpMapTypeModifier::Value::Close) ||
|
||||
"PRESENT" >> pure(OmpMapTypeModifier::Value::Present)};
|
||||
return parser.Parse(state);
|
||||
} else {
|
||||
// No longer in 6.0.
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TYPE_PARSER(OmpMapTypeModifierParser{})
|
||||
|
||||
TYPE_PARSER(construct<OmpOrderModifier>(
|
||||
"REPRODUCIBLE" >> pure(OmpOrderModifier::Value::Reproducible) ||
|
||||
|
|
@ -1074,17 +1115,19 @@ TYPE_PARSER(sourced(
|
|||
construct<OmpLinearClause::Modifier>(Parser<OmpStepSimpleModifier>{})))
|
||||
|
||||
TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>(
|
||||
sourced(construct<OmpMapClause::Modifier>(Parser<OmpAlwaysModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpAttachModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpCloseModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpDeleteModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpPresentModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpRefModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpSelfModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpIterator>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpMapType>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpxHoldModifier>{})))))
|
||||
// Try the two custom parsers first.
|
||||
construct<OmpMapClause::Modifier>(OmpMapTypeParser{}) ||
|
||||
construct<OmpMapClause::Modifier>(OmpMapTypeModifierParser{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpAlwaysModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpAttachModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpCloseModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpDeleteModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpIterator>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpPresentModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpRefModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpSelfModifier>{}) ||
|
||||
construct<OmpMapClause::Modifier>(Parser<OmpxHoldModifier>{}))))
|
||||
|
||||
TYPE_PARSER(
|
||||
sourced(construct<OmpOrderClause::Modifier>(Parser<OmpOrderModifier>{})))
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public:
|
|||
template <typename T> bool Pre(T &) { return true; }
|
||||
template <typename T> void Post(T &) {}
|
||||
CanonicalizationOfOmp(SemanticsContext &context)
|
||||
: context_{context}, messages_{context.messages()} {}
|
||||
: messages_{context.messages()} {}
|
||||
|
||||
// Pre-visit all constructs that have both a specification part and
|
||||
// an execution part, and store the connection between the two.
|
||||
|
|
@ -66,8 +66,6 @@ public:
|
|||
CanonicalizeAllocateDirectives(spec);
|
||||
}
|
||||
|
||||
void Post(parser::OmpMapClause &map) { CanonicalizeMapModifiers(map); }
|
||||
|
||||
private:
|
||||
// Canonicalization of allocate directives
|
||||
//
|
||||
|
|
@ -325,52 +323,10 @@ private:
|
|||
omps.erase(rlast.base(), omps.end());
|
||||
}
|
||||
|
||||
// Map clause modifiers are parsed as per OpenMP 6.0 spec. That spec has
|
||||
// changed properties of some of the modifiers, for example it has expanded
|
||||
// map-type-modifier into 3 individual modifiers (one for each of the
|
||||
// possible values of the original modifier), and the "map-type" modifier
|
||||
// is no longer ultimate.
|
||||
// To utilize the modifier validation framework for semantic checks,
|
||||
// if the specified OpenMP version is less than 6.0, rewrite the affected
|
||||
// modifiers back into the pre-6.0 forms.
|
||||
void CanonicalizeMapModifiers(parser::OmpMapClause &map) {
|
||||
unsigned version{context_.langOptions().OpenMPVersion};
|
||||
if (version >= 60) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Omp{Always, Close, Present, xHold}Modifier -> OmpMapTypeModifier
|
||||
// OmpDeleteModifier -> OmpMapType
|
||||
using Modifier = parser::OmpMapClause::Modifier;
|
||||
using Modifiers = std::optional<std::list<Modifier>>;
|
||||
auto &modifiers{std::get<Modifiers>(map.t)};
|
||||
if (!modifiers) {
|
||||
return;
|
||||
}
|
||||
|
||||
using MapTypeModifier = parser::OmpMapTypeModifier;
|
||||
using MapType = parser::OmpMapType;
|
||||
|
||||
for (auto &mod : *modifiers) {
|
||||
if (std::holds_alternative<parser::OmpAlwaysModifier>(mod.u)) {
|
||||
mod.u = MapTypeModifier(MapTypeModifier::Value::Always);
|
||||
} else if (std::holds_alternative<parser::OmpCloseModifier>(mod.u)) {
|
||||
mod.u = MapTypeModifier(MapTypeModifier::Value::Close);
|
||||
} else if (std::holds_alternative<parser::OmpPresentModifier>(mod.u)) {
|
||||
mod.u = MapTypeModifier(MapTypeModifier::Value::Present);
|
||||
} else if (std::holds_alternative<parser::OmpxHoldModifier>(mod.u)) {
|
||||
mod.u = MapTypeModifier(MapTypeModifier::Value::Ompx_Hold);
|
||||
} else if (std::holds_alternative<parser::OmpDeleteModifier>(mod.u)) {
|
||||
mod.u = MapType(MapType::Value::Delete);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mapping from the specification parts to the blocks that follow in the
|
||||
// same construct. This is for converting utility constructs to executable
|
||||
// constructs.
|
||||
std::map<parser::SpecificationPart *, parser::Block *> blockForSpec_;
|
||||
SemanticsContext &context_;
|
||||
parser::Messages &messages_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
!RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
|
||||
!RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
|
||||
!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=60 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
|
||||
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=60 %s | FileCheck --check-prefix="PARSE-TREE" %s
|
||||
|
||||
subroutine f00(x)
|
||||
integer :: x
|
||||
|
|
@ -11,7 +11,7 @@ end
|
|||
!UNPARSE: SUBROUTINE f00 (x)
|
||||
!UNPARSE: INTEGER x
|
||||
!UNPARSE: !$OMP TARGET MAP(ALWAYS, CLOSE, DELETE, PRESENT, OMPX_HOLD: x)
|
||||
!UNPARSE: x = x+1
|
||||
!UNPARSE: x=x+1_4
|
||||
!UNPARSE: !$OMP END TARGET
|
||||
!UNPARSE: END SUBROUTINE
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ subroutine f01(x)
|
|||
end
|
||||
|
||||
!UNPARSE: !$OMP TARGET MAP(SELF, STORAGE: x)
|
||||
!UNPARSE: x = x+1
|
||||
!UNPARSE: x=x+1_4
|
||||
!UNPARSE: !$OMP END TARGET
|
||||
!UNPARSE: END SUBROUTINE
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ end
|
|||
!UNPARSE: SUBROUTINE f02 (x)
|
||||
!UNPARSE: INTEGER, POINTER :: x
|
||||
!UNPARSE: !$OMP TARGET MAP(REF_PTR, TO: x)
|
||||
!UNPARSE: x = x+1
|
||||
!UNPARSE: x=x+1_4
|
||||
!UNPARSE: !$OMP END TARGET
|
||||
!UNPARSE: END SUBROUTINE
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ end
|
|||
!UNPARSE: SUBROUTINE f03 (x)
|
||||
!UNPARSE: INTEGER, POINTER :: x
|
||||
!UNPARSE: !$OMP TARGET MAP(REF_PTEE, TO: x)
|
||||
!UNPARSE: x = x+1
|
||||
!UNPARSE: x=x+1_4
|
||||
!UNPARSE: !$OMP END TARGET
|
||||
!UNPARSE: END SUBROUTINE
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ end
|
|||
!UNPARSE: SUBROUTINE f04 (x)
|
||||
!UNPARSE: INTEGER, POINTER :: x
|
||||
!UNPARSE: !$OMP TARGET MAP(REF_PTR_PTEE, TO: x)
|
||||
!UNPARSE: x = x+1
|
||||
!UNPARSE: x=x+1_4
|
||||
!UNPARSE: !$OMP END TARGET
|
||||
!UNPARSE: END SUBROUTINE
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ end
|
|||
!PARSE-TREE: OmpBeginDirective
|
||||
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
|
||||
!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Ompx_Hold
|
||||
!PARSE-TREE: | | Modifier -> OmpxHoldModifier -> Value = Ompx_Hold
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Always
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Present
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Close
|
||||
|
|
@ -43,7 +43,7 @@ end
|
|||
!PARSE-TREE: OmpBeginDirective
|
||||
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
|
||||
!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Ompx_Hold
|
||||
!PARSE-TREE: | | Modifier -> OmpxHoldModifier -> Value = Ompx_Hold
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Always
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Present
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Close
|
||||
|
|
@ -108,7 +108,7 @@ end
|
|||
!PARSE-TREE: OmpBeginDirective
|
||||
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
|
||||
!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Ompx_Hold
|
||||
!PARSE-TREE: | | Modifier -> OmpxHoldModifier -> Value = Ompx_Hold
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Always
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Present
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Close
|
||||
|
|
@ -133,7 +133,7 @@ end
|
|||
!PARSE-TREE: OmpBeginDirective
|
||||
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = target
|
||||
!PARSE-TREE: | OmpClauseList -> OmpClause -> Map -> OmpMapClause
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Ompx_Hold
|
||||
!PARSE-TREE: | | Modifier -> OmpxHoldModifier -> Value = Ompx_Hold
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Always
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Present
|
||||
!PARSE-TREE: | | Modifier -> OmpMapTypeModifier -> Value = Close
|
||||
|
|
|
|||
Loading…
Reference in a new issue