Skip to content

Commit

Permalink
[flang][NFC] Speed up large DATA statement initializations (#67585)
Browse files Browse the repository at this point in the history
To ensure that the map from symbols to their initial images has an entry
for a particular symbol, use std::map<>::find() before
std::map<>::emplace() to avoid needless memory allocation and
deallocation. Also, combine adjacent intervals in the lists of
initialized ranges so that contiguous initializations don't require long
lists.

Fixes #66452.
  • Loading branch information
klausler committed Oct 16, 2023
1 parent d85f5a6 commit 28a686a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
29 changes: 16 additions & 13 deletions flang/lib/Semantics/data-to-inits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ template <typename DSV = parser::DataStmtValue> class ValueListIterator {
};

template <typename DSV> void ValueListIterator<DSV>::SetRepetitionCount() {
for (repetitionsRemaining_ = 1; at_ != end_; ++at_) {
for (; at_ != end_; ++at_) {
auto repetitions{GetValue().repetitions};
if (repetitions < 0) {
hasFatalError_ = true;
Expand Down Expand Up @@ -335,10 +335,15 @@ bool DataInitializationCompiler<DSV>::InitElement(
}
}};
const auto GetImage{[&]() -> evaluate::InitialImage & {
auto iter{inits_.emplace(&symbol, symbol.size())};
auto &symbolInit{iter.first->second};
symbolInit.initializedRanges.emplace_back(
offsetSymbol.offset(), offsetSymbol.size());
// This could be (and was) written to always call std::map<>::emplace(),
// which should handle duplicate entries gracefully, but it was still
// causing memory allocation & deallocation with gcc.
auto iter{inits_.find(&symbol)};
if (iter == inits_.end()) {
iter = inits_.emplace(&symbol, symbol.size()).first;
}
auto &symbolInit{iter->second};
symbolInit.NoteInitializedRange(offsetSymbol);
return symbolInit.image;
}};
const auto OutOfRangeError{[&]() {
Expand Down Expand Up @@ -590,17 +595,15 @@ static void PopulateWithComponentDefaults(SymbolDataInitialization &init,
}
}
if (initialized) {
init.initializedRanges.emplace_back(
componentOffset, component.size());
init.NoteInitializedRange(componentOffset, component.size());
}
}
} else if (const auto *proc{component.detailsIf<ProcEntityDetails>()}) {
if (proc->init() && *proc->init()) {
SomeExpr procPtrInit{evaluate::ProcedureDesignator{**proc->init()}};
auto extant{init.image.AsConstantPointer(componentOffset)};
if (!extant || !(*extant == procPtrInit)) {
init.initializedRanges.emplace_back(
componentOffset, component.size());
init.NoteInitializedRange(componentOffset, component.size());
init.image.AddPointer(componentOffset, std::move(procPtrInit));
}
}
Expand Down Expand Up @@ -651,7 +654,7 @@ static void IncorporateExplicitInitialization(
if (iter != inits.end()) { // DATA statement initialization
for (const auto &range : iter->second.initializedRanges) {
auto at{offset + range.start()};
combined.initializedRanges.emplace_back(at, range.size());
combined.NoteInitializedRange(at, range.size());
combined.image.Incorporate(
at, iter->second.image, range.start(), range.size());
}
Expand All @@ -663,15 +666,15 @@ static void IncorporateExplicitInitialization(
if (IsPointer(mutableSymbol)) {
if (auto *object{mutableSymbol.detailsIf<ObjectEntityDetails>()}) {
if (object->init()) {
combined.initializedRanges.emplace_back(offset, mutableSymbol.size());
combined.NoteInitializedRange(offset, mutableSymbol.size());
combined.image.AddPointer(offset, *object->init());
if (removeOriginalInits) {
object->init().reset();
}
}
} else if (auto *proc{mutableSymbol.detailsIf<ProcEntityDetails>()}) {
if (proc->init() && *proc->init()) {
combined.initializedRanges.emplace_back(offset, mutableSymbol.size());
combined.NoteInitializedRange(offset, mutableSymbol.size());
combined.image.AddPointer(
offset, SomeExpr{evaluate::ProcedureDesignator{**proc->init()}});
if (removeOriginalInits) {
Expand All @@ -681,7 +684,7 @@ static void IncorporateExplicitInitialization(
}
} else if (auto *object{mutableSymbol.detailsIf<ObjectEntityDetails>()}) {
if (!IsNamedConstant(mutableSymbol) && object->init()) {
combined.initializedRanges.emplace_back(offset, mutableSymbol.size());
combined.NoteInitializedRange(offset, mutableSymbol.size());
combined.image.Add(
offset, mutableSymbol.size(), *object->init(), foldingContext);
if (removeOriginalInits) {
Expand Down
16 changes: 16 additions & 0 deletions flang/lib/Semantics/data-to-inits.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "flang/Common/default-kinds.h"
#include "flang/Common/interval.h"
#include "flang/Evaluate/fold-designator.h"
#include "flang/Evaluate/initial-image.h"
#include <list>
#include <map>
Expand All @@ -30,6 +31,21 @@ struct SymbolDataInitialization {
using Range = common::Interval<common::ConstantSubscript>;
explicit SymbolDataInitialization(std::size_t bytes) : image{bytes} {}
SymbolDataInitialization(SymbolDataInitialization &&) = default;

void NoteInitializedRange(Range range) {
if (initializedRanges.empty() ||
!initializedRanges.back().AnnexIfPredecessor(range)) {
initializedRanges.emplace_back(range);
}
}
void NoteInitializedRange(
common::ConstantSubscript offset, std::size_t size) {
NoteInitializedRange(Range{offset, size});
}
void NoteInitializedRange(evaluate::OffsetSymbol offsetSymbol) {
NoteInitializedRange(offsetSymbol.offset(), offsetSymbol.size());
}

evaluate::InitialImage image;
std::list<Range> initializedRanges;
};
Expand Down

0 comments on commit 28a686a

Please sign in to comment.