[flang-commits] [flang] [flang] Avoid recursion in runtime derived type initialization (PR #102394)
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Mon Aug 19 13:45:39 PDT 2024
================
@@ -29,97 +30,92 @@ static RT_API_ATTRS void GetComponentExtents(SubscriptValue (&extents)[maxRank],
}
}
-RT_API_ATTRS int Initialize(const Descriptor &instance,
- const typeInfo::DerivedType &derived, Terminator &terminator, bool hasStat,
- const Descriptor *errMsg) {
- const Descriptor &componentDesc{derived.component()};
- std::size_t elements{instance.Elements()};
- int stat{StatOk};
- // Initialize data components in each element; the per-element iterations
- // constitute the inner loops, not the outer ones
- std::size_t myComponents{componentDesc.Elements()};
- for (std::size_t k{0}; k < myComponents; ++k) {
+RT_API_ATTRS auto engine::Initialization::Resume(Engine &engine) -> ResultType {
+ while (component_.Iterating(components_)) {
const auto &comp{
- *componentDesc.ZeroBasedIndexedElement<typeInfo::Component>(k)};
- SubscriptValue at[maxRank];
- instance.GetLowerBounds(at);
+ *componentDesc_->ZeroBasedIndexedElement<typeInfo::Component>(
+ component_.at)};
if (comp.genre() == typeInfo::Component::Genre::Allocatable ||
comp.genre() == typeInfo::Component::Genre::Automatic) {
- for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) {
- Descriptor &allocDesc{
- *instance.ElementComponent<Descriptor>(at, comp.offset())};
- comp.EstablishDescriptor(allocDesc, instance, terminator);
+ while (element_.Iterating(elements_, &instance_)) {
+ Descriptor &allocDesc{*instance_.ElementComponent<Descriptor>(
+ element_.subscripts, comp.offset())};
+ comp.EstablishDescriptor(allocDesc, instance_, engine.terminator());
allocDesc.raw().attribute = CFI_attribute_allocatable;
if (comp.genre() == typeInfo::Component::Genre::Automatic) {
- stat = ReturnError(terminator, allocDesc.Allocate(), errMsg, hasStat);
- if (stat == StatOk) {
- if (const DescriptorAddendum * addendum{allocDesc.Addendum()}) {
- if (const auto *derived{addendum->derivedType()}) {
- if (!derived->noInitializationNeeded()) {
- stat = Initialize(
- allocDesc, *derived, terminator, hasStat, errMsg);
- }
+ if (auto stat{ReturnError(engine.terminator(), allocDesc.Allocate(),
+ engine.errMsg(), engine.hasStat())};
+ stat != StatOk) {
+ return engine.Fail(stat);
+ }
+ if (const DescriptorAddendum * addendum{allocDesc.Addendum()}) {
+ if (const auto *derived{addendum->derivedType()}) {
+ if (!derived->noInitializationNeeded()) {
+ component_.ResumeAtSameIteration();
+ return engine.Begin(Job::Initialization, allocDesc, derived);
}
}
}
- if (stat != StatOk) {
- break;
- }
}
}
} else if (const void *init{comp.initialization()}) {
// Explicit initialization of data pointers and
// non-allocatable non-automatic components
- std::size_t bytes{comp.SizeInBytes(instance)};
- for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) {
- char *ptr{instance.ElementComponent<char>(at, comp.offset())};
+ std::size_t bytes{comp.SizeInBytes(instance_)};
+ while (element_.Iterating(elements_, &instance_)) {
+ char *ptr{instance_.ElementComponent<char>(
+ element_.subscripts, comp.offset())};
std::memcpy(ptr, init, bytes);
}
} else if (comp.genre() == typeInfo::Component::Genre::Pointer) {
// Data pointers without explicit initialization are established
// so that they are valid right-hand side targets of pointer
// assignment statements.
- for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) {
- Descriptor &ptrDesc{
- *instance.ElementComponent<Descriptor>(at, comp.offset())};
- comp.EstablishDescriptor(ptrDesc, instance, terminator);
+ while (element_.Iterating(elements_, &instance_)) {
+ Descriptor &ptrDesc{*instance_.ElementComponent<Descriptor>(
+ element_.subscripts, comp.offset())};
+ comp.EstablishDescriptor(ptrDesc, instance_, engine.terminator());
ptrDesc.raw().attribute = CFI_attribute_pointer;
}
} else if (comp.genre() == typeInfo::Component::Genre::Data &&
comp.derivedType() && !comp.derivedType()->noInitializationNeeded()) {
// Default initialization of non-pointer non-allocatable/automatic
- // data component. Handles parent component's elements. Recursive.
- SubscriptValue extents[maxRank];
- GetComponentExtents(extents, comp, instance);
- StaticDescriptor<maxRank, true, 0> staticDescriptor;
- Descriptor &compDesc{staticDescriptor.descriptor()};
- const typeInfo::DerivedType &compType{*comp.derivedType()};
- for (std::size_t j{0}; j++ < elements; instance.IncrementSubscripts(at)) {
+ // data component. Handles parent component's elements.
+ if (!element_.active) {
----------------
vzakhari wrote:
nit: maybe use `element_.at == 0` as in two other instances.
https://github.com/llvm/llvm-project/pull/102394
More information about the flang-commits
mailing list