llvm-project

Форк
0
89 строк · 3.9 Кб
1
//===-- runtime/copy.cpp -------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8

9
#include "copy.h"
10
#include "terminator.h"
11
#include "type-info.h"
12
#include "flang/Runtime/allocatable.h"
13
#include "flang/Runtime/descriptor.h"
14
#include <cstring>
15

16
namespace Fortran::runtime {
17
RT_OFFLOAD_API_GROUP_BEGIN
18

19
RT_API_ATTRS void CopyElement(const Descriptor &to, const SubscriptValue toAt[],
20
    const Descriptor &from, const SubscriptValue fromAt[],
21
    Terminator &terminator) {
22
  char *toPtr{to.Element<char>(toAt)};
23
  char *fromPtr{from.Element<char>(fromAt)};
24
  RUNTIME_CHECK(terminator, to.ElementBytes() == from.ElementBytes());
25
  std::memcpy(toPtr, fromPtr, to.ElementBytes());
26
  // Deep copy allocatable and automatic components if any.
27
  if (const auto *addendum{to.Addendum()}) {
28
    if (const auto *derived{addendum->derivedType()};
29
        derived && !derived->noDestructionNeeded()) {
30
      RUNTIME_CHECK(terminator,
31
          from.Addendum() && derived == from.Addendum()->derivedType());
32
      const Descriptor &componentDesc{derived->component()};
33
      const typeInfo::Component *component{
34
          componentDesc.OffsetElement<typeInfo::Component>()};
35
      std::size_t nComponents{componentDesc.Elements()};
36
      for (std::size_t j{0}; j < nComponents; ++j, ++component) {
37
        if (component->genre() == typeInfo::Component::Genre::Allocatable ||
38
            component->genre() == typeInfo::Component::Genre::Automatic) {
39
          Descriptor &toDesc{
40
              *reinterpret_cast<Descriptor *>(toPtr + component->offset())};
41
          if (toDesc.raw().base_addr != nullptr) {
42
            toDesc.set_base_addr(nullptr);
43
            RUNTIME_CHECK(terminator, toDesc.Allocate() == CFI_SUCCESS);
44
            const Descriptor &fromDesc{*reinterpret_cast<const Descriptor *>(
45
                fromPtr + component->offset())};
46
            CopyArray(toDesc, fromDesc, terminator);
47
          }
48
        } else if (component->genre() == typeInfo::Component::Genre::Data &&
49
            component->derivedType() &&
50
            !component->derivedType()->noDestructionNeeded()) {
51
          SubscriptValue extents[maxRank];
52
          const typeInfo::Value *bounds{component->bounds()};
53
          for (int dim{0}; dim < component->rank(); ++dim) {
54
            SubscriptValue lb{bounds[2 * dim].GetValue(&to).value_or(0)};
55
            SubscriptValue ub{bounds[2 * dim + 1].GetValue(&to).value_or(0)};
56
            extents[dim] = ub >= lb ? ub - lb + 1 : 0;
57
          }
58
          const typeInfo::DerivedType &compType{*component->derivedType()};
59
          StaticDescriptor<maxRank, true, 0> toStaticDescriptor;
60
          Descriptor &toCompDesc{toStaticDescriptor.descriptor()};
61
          toCompDesc.Establish(compType, toPtr + component->offset(),
62
              component->rank(), extents);
63
          StaticDescriptor<maxRank, true, 0> fromStaticDescriptor;
64
          Descriptor &fromCompDesc{fromStaticDescriptor.descriptor()};
65
          fromCompDesc.Establish(compType, fromPtr + component->offset(),
66
              component->rank(), extents);
67
          CopyArray(toCompDesc, fromCompDesc, terminator);
68
        }
69
      }
70
    }
71
  }
72
}
73

74
RT_API_ATTRS void CopyArray(
75
    const Descriptor &to, const Descriptor &from, Terminator &terminator) {
76
  std::size_t elements{to.Elements()};
77
  RUNTIME_CHECK(terminator, elements == from.Elements());
78
  SubscriptValue toAt[maxRank], fromAt[maxRank];
79
  to.GetLowerBounds(toAt);
80
  from.GetLowerBounds(fromAt);
81
  while (elements-- > 0) {
82
    CopyElement(to, toAt, from, fromAt, terminator);
83
    to.IncrementSubscripts(toAt);
84
    from.IncrementSubscripts(fromAt);
85
  }
86
}
87

88
RT_OFFLOAD_API_GROUP_END
89
} // namespace Fortran::runtime
90

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.