Skip to content

Commit 28a686a

Browse files
authored
[flang][NFC] Speed up large DATA statement initializations (#67585)
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.
1 parent d85f5a6 commit 28a686a

File tree

2 files changed

+32
-13
lines changed

2 files changed

+32
-13
lines changed

flang/lib/Semantics/data-to-inits.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ template <typename DSV = parser::DataStmtValue> class ValueListIterator {
8181
};
8282

8383
template <typename DSV> void ValueListIterator<DSV>::SetRepetitionCount() {
84-
for (repetitionsRemaining_ = 1; at_ != end_; ++at_) {
84+
for (; at_ != end_; ++at_) {
8585
auto repetitions{GetValue().repetitions};
8686
if (repetitions < 0) {
8787
hasFatalError_ = true;
@@ -335,10 +335,15 @@ bool DataInitializationCompiler<DSV>::InitElement(
335335
}
336336
}};
337337
const auto GetImage{[&]() -> evaluate::InitialImage & {
338-
auto iter{inits_.emplace(&symbol, symbol.size())};
339-
auto &symbolInit{iter.first->second};
340-
symbolInit.initializedRanges.emplace_back(
341-
offsetSymbol.offset(), offsetSymbol.size());
338+
// This could be (and was) written to always call std::map<>::emplace(),
339+
// which should handle duplicate entries gracefully, but it was still
340+
// causing memory allocation & deallocation with gcc.
341+
auto iter{inits_.find(&symbol)};
342+
if (iter == inits_.end()) {
343+
iter = inits_.emplace(&symbol, symbol.size()).first;
344+
}
345+
auto &symbolInit{iter->second};
346+
symbolInit.NoteInitializedRange(offsetSymbol);
342347
return symbolInit.image;
343348
}};
344349
const auto OutOfRangeError{[&]() {
@@ -590,17 +595,15 @@ static void PopulateWithComponentDefaults(SymbolDataInitialization &init,
590595
}
591596
}
592597
if (initialized) {
593-
init.initializedRanges.emplace_back(
594-
componentOffset, component.size());
598+
init.NoteInitializedRange(componentOffset, component.size());
595599
}
596600
}
597601
} else if (const auto *proc{component.detailsIf<ProcEntityDetails>()}) {
598602
if (proc->init() && *proc->init()) {
599603
SomeExpr procPtrInit{evaluate::ProcedureDesignator{**proc->init()}};
600604
auto extant{init.image.AsConstantPointer(componentOffset)};
601605
if (!extant || !(*extant == procPtrInit)) {
602-
init.initializedRanges.emplace_back(
603-
componentOffset, component.size());
606+
init.NoteInitializedRange(componentOffset, component.size());
604607
init.image.AddPointer(componentOffset, std::move(procPtrInit));
605608
}
606609
}
@@ -651,7 +654,7 @@ static void IncorporateExplicitInitialization(
651654
if (iter != inits.end()) { // DATA statement initialization
652655
for (const auto &range : iter->second.initializedRanges) {
653656
auto at{offset + range.start()};
654-
combined.initializedRanges.emplace_back(at, range.size());
657+
combined.NoteInitializedRange(at, range.size());
655658
combined.image.Incorporate(
656659
at, iter->second.image, range.start(), range.size());
657660
}
@@ -663,15 +666,15 @@ static void IncorporateExplicitInitialization(
663666
if (IsPointer(mutableSymbol)) {
664667
if (auto *object{mutableSymbol.detailsIf<ObjectEntityDetails>()}) {
665668
if (object->init()) {
666-
combined.initializedRanges.emplace_back(offset, mutableSymbol.size());
669+
combined.NoteInitializedRange(offset, mutableSymbol.size());
667670
combined.image.AddPointer(offset, *object->init());
668671
if (removeOriginalInits) {
669672
object->init().reset();
670673
}
671674
}
672675
} else if (auto *proc{mutableSymbol.detailsIf<ProcEntityDetails>()}) {
673676
if (proc->init() && *proc->init()) {
674-
combined.initializedRanges.emplace_back(offset, mutableSymbol.size());
677+
combined.NoteInitializedRange(offset, mutableSymbol.size());
675678
combined.image.AddPointer(
676679
offset, SomeExpr{evaluate::ProcedureDesignator{**proc->init()}});
677680
if (removeOriginalInits) {
@@ -681,7 +684,7 @@ static void IncorporateExplicitInitialization(
681684
}
682685
} else if (auto *object{mutableSymbol.detailsIf<ObjectEntityDetails>()}) {
683686
if (!IsNamedConstant(mutableSymbol) && object->init()) {
684-
combined.initializedRanges.emplace_back(offset, mutableSymbol.size());
687+
combined.NoteInitializedRange(offset, mutableSymbol.size());
685688
combined.image.Add(
686689
offset, mutableSymbol.size(), *object->init(), foldingContext);
687690
if (removeOriginalInits) {

flang/lib/Semantics/data-to-inits.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "flang/Common/default-kinds.h"
1313
#include "flang/Common/interval.h"
14+
#include "flang/Evaluate/fold-designator.h"
1415
#include "flang/Evaluate/initial-image.h"
1516
#include <list>
1617
#include <map>
@@ -30,6 +31,21 @@ struct SymbolDataInitialization {
3031
using Range = common::Interval<common::ConstantSubscript>;
3132
explicit SymbolDataInitialization(std::size_t bytes) : image{bytes} {}
3233
SymbolDataInitialization(SymbolDataInitialization &&) = default;
34+
35+
void NoteInitializedRange(Range range) {
36+
if (initializedRanges.empty() ||
37+
!initializedRanges.back().AnnexIfPredecessor(range)) {
38+
initializedRanges.emplace_back(range);
39+
}
40+
}
41+
void NoteInitializedRange(
42+
common::ConstantSubscript offset, std::size_t size) {
43+
NoteInitializedRange(Range{offset, size});
44+
}
45+
void NoteInitializedRange(evaluate::OffsetSymbol offsetSymbol) {
46+
NoteInitializedRange(offsetSymbol.offset(), offsetSymbol.size());
47+
}
48+
3349
evaluate::InitialImage image;
3450
std::list<Range> initializedRanges;
3551
};

0 commit comments

Comments
 (0)