aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/resolve-names-utils.cpp
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2022-03-23 14:05:50 -0700
committerPeter Klausler <pklausler@nvidia.com>2022-03-25 13:15:20 -0700
commit2ab9990c9eb79682a4d4b183dfbc7612d3e55328 (patch)
treee1b50758c6f96949781fce6536d191c60ab64b30 /flang/lib/Semantics/resolve-names-utils.cpp
parente25f4e4c4a6df1d9f84e9506d2391fb0019bc941 (diff)
downloadllvm-2ab9990c9eb79682a4d4b183dfbc7612d3e55328.zip
llvm-2ab9990c9eb79682a4d4b183dfbc7612d3e55328.tar.gz
llvm-2ab9990c9eb79682a4d4b183dfbc7612d3e55328.tar.bz2
[flang] Add & use a better visit()
Adds flang/include/flang/Common/visit.h, which defines a Fortran::common::visit() template function that is a drop-in replacement for std::visit(). Modifies most use sites in the front-end and runtime to use common::visit(). The C++ standard mandates that std::visit() have O(1) execution time, which forces implementations to build dispatch tables. This new common::visit() is O(log2 N) in the number of alternatives in a variant<>, but that N tends to be small and so this change produces a fairly significant improvement in compiler build memory requirements, a 5-10% improvement in compiler build time, and a small improvement in compiler execution time. Building with -DFLANG_USE_STD_VISIT causes common::visit() to be an alias for std::visit(). Calls to common::visit() with multiple variant arguments are referred to std::visit(), pending further work. Differential Revision: https://reviews.llvm.org/D122441
Diffstat (limited to 'flang/lib/Semantics/resolve-names-utils.cpp')
-rw-r--r--flang/lib/Semantics/resolve-names-utils.cpp31
1 files changed, 16 insertions, 15 deletions
diff --git a/flang/lib/Semantics/resolve-names-utils.cpp b/flang/lib/Semantics/resolve-names-utils.cpp
index 2d8f2c1..7aab694 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -126,7 +126,7 @@ void GenericSpecInfo::Analyze(const parser::DefinedOpName &name) {
void GenericSpecInfo::Analyze(const parser::GenericSpec &x) {
symbolName_ = x.source;
- kind_ = std::visit(
+ kind_ = common::visit(
common::visitors{
[&](const parser::Name &y) -> GenericKind {
parseName_ = &y;
@@ -134,7 +134,7 @@ void GenericSpecInfo::Analyze(const parser::GenericSpec &x) {
return GenericKind::OtherKind::Name;
},
[&](const parser::DefinedOperator &y) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::DefinedOpName &z) -> GenericKind {
Analyze(z);
@@ -265,19 +265,20 @@ ArraySpec AnalyzeCoarraySpec(
}
ArraySpec ArraySpecAnalyzer::Analyze(const parser::ComponentArraySpec &x) {
- std::visit([this](const auto &y) { Analyze(y); }, x.u);
+ common::visit([this](const auto &y) { Analyze(y); }, x.u);
CHECK(!arraySpec_.empty());
return arraySpec_;
}
ArraySpec ArraySpecAnalyzer::Analyze(const parser::ArraySpec &x) {
- std::visit(common::visitors{
- [&](const parser::AssumedSizeSpec &y) {
- Analyze(std::get<std::list<parser::ExplicitShapeSpec>>(y.t));
- Analyze(std::get<parser::AssumedImpliedSpec>(y.t));
- },
- [&](const parser::ImpliedShapeSpec &y) { Analyze(y.v); },
- [&](const auto &y) { Analyze(y); },
- },
+ common::visit(common::visitors{
+ [&](const parser::AssumedSizeSpec &y) {
+ Analyze(
+ std::get<std::list<parser::ExplicitShapeSpec>>(y.t));
+ Analyze(std::get<parser::AssumedImpliedSpec>(y.t));
+ },
+ [&](const parser::ImpliedShapeSpec &y) { Analyze(y.v); },
+ [&](const auto &y) { Analyze(y); },
+ },
x.u);
CHECK(!arraySpec_.empty());
return arraySpec_;
@@ -289,7 +290,7 @@ ArraySpec ArraySpecAnalyzer::AnalyzeDeferredShapeSpecList(
return arraySpec_;
}
ArraySpec ArraySpecAnalyzer::Analyze(const parser::CoarraySpec &x) {
- std::visit(
+ common::visit(
common::visitors{
[&](const parser::DeferredCoshapeSpecList &y) { MakeDeferred(y.v); },
[&](const parser::ExplicitCoshapeSpec &y) {
@@ -495,7 +496,7 @@ const EquivalenceObject *EquivalenceSets::Find(
}
bool EquivalenceSets::CheckDesignator(const parser::Designator &designator) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::DataRef &x) {
return CheckDataRef(designator.source, x);
@@ -520,7 +521,7 @@ bool EquivalenceSets::CheckDesignator(const parser::Designator &designator) {
bool EquivalenceSets::CheckDataRef(
const parser::CharBlock &source, const parser::DataRef &x) {
- return std::visit(
+ return common::visit(
common::visitors{
[&](const parser::Name &name) { return CheckObject(name); },
[&](const common::Indirection<parser::StructureComponent> &) {
@@ -532,7 +533,7 @@ bool EquivalenceSets::CheckDataRef(
[&](const common::Indirection<parser::ArrayElement> &elem) {
bool ok{CheckDataRef(source, elem.value().base)};
for (const auto &subscript : elem.value().subscripts) {
- ok &= std::visit(
+ ok &= common::visit(
common::visitors{
[&](const parser::SubscriptTriplet &) {
context_.Say(source, // C924, R872