@@ -23,17 +23,17 @@ using StaticDescTy = StaticDescriptor<maxRank, true, 0>;
23
23
// for CopyElement.
24
24
struct CopyDescriptor {
25
25
// A constructor specifying all members explicitly.
26
+ // The toAt and fromAt specify subscript storages that might be
27
+ // external to CopyElement, and cannot be modified.
28
+ // The copy descriptor only establishes toAtPtr_ and fromAtPtr_
29
+ // pointers to point to these storages.
26
30
RT_API_ATTRS CopyDescriptor (const Descriptor &to, const SubscriptValue toAt[],
27
31
const Descriptor &from, const SubscriptValue fromAt[],
28
32
std::size_t elements, bool usesStaticDescriptors = false )
29
33
: to_(to), from_(from), elements_(elements),
30
34
usesStaticDescriptors_(usesStaticDescriptors) {
31
- for (int dim{0 }; dim < to.rank (); ++dim) {
32
- toAt_[dim] = toAt[dim];
33
- }
34
- for (int dim{0 }; dim < from.rank (); ++dim) {
35
- fromAt_[dim] = fromAt[dim];
36
- }
35
+ toAtPtr_ = toAt;
36
+ fromAtPtr_ = fromAt;
37
37
}
38
38
// The number of elements to copy is initialized from the to descriptor.
39
39
// The current element subscripts are initialized from the lower bounds
@@ -46,14 +46,32 @@ struct CopyDescriptor {
46
46
from.GetLowerBounds (fromAt_);
47
47
}
48
48
49
+ // Increment the toAt_ and fromAt_ subscripts to the next
50
+ // element.
51
+ RT_API_ATTRS void IncrementSubscripts (Terminator &terminator) {
52
+ // This method must not be called for copy descriptors
53
+ // using external non-modifiable subscript storage.
54
+ RUNTIME_CHECK (terminator, toAt_ == toAtPtr_ && fromAt_ == fromAtPtr_);
55
+ to_.IncrementSubscripts (toAt_);
56
+ from_.IncrementSubscripts (fromAt_);
57
+ }
58
+
49
59
// Descriptor of the destination.
50
60
const Descriptor &to_;
51
61
// A subscript specifying the current element position to copy to.
52
62
SubscriptValue toAt_[maxRank];
63
+ // A pointer to the storage of the 'to' subscript.
64
+ // It may point to toAt_ or to an external non-modifiable
65
+ // subscript storage.
66
+ const SubscriptValue *toAtPtr_{toAt_};
53
67
// Descriptor of the source.
54
68
const Descriptor &from_;
55
69
// A subscript specifying the current element position to copy from.
56
70
SubscriptValue fromAt_[maxRank];
71
+ // A pointer to the storage of the 'from' subscript.
72
+ // It may point to fromAt_ or to an external non-modifiable
73
+ // subscript storage.
74
+ const SubscriptValue *fromAtPtr_{fromAt_};
57
75
// Number of elements left to copy.
58
76
std::size_t elements_;
59
77
// Must be true, if the to and from descriptors are allocated
@@ -75,6 +93,18 @@ RT_OFFLOAD_API_GROUP_BEGIN
75
93
RT_API_ATTRS void CopyElement (const Descriptor &to, const SubscriptValue toAt[],
76
94
const Descriptor &from, const SubscriptValue fromAt[],
77
95
Terminator &terminator) {
96
+ if (!to.Addendum ()) {
97
+ // Avoid the overhead of creating the work stacks below
98
+ // for the simple non-derived type cases, because the overhead
99
+ // might be noticeable over the total amount of work that
100
+ // needs to be done for the copy.
101
+ char *toPtr{to.Element <char >(toAt)};
102
+ char *fromPtr{from.Element <char >(fromAt)};
103
+ RUNTIME_CHECK (terminator, to.ElementBytes () == from.ElementBytes ());
104
+ std::memcpy (toPtr, fromPtr, to.ElementBytes ());
105
+ return ;
106
+ }
107
+
78
108
#if !defined(RT_DEVICE_COMPILATION)
79
109
constexpr unsigned copyStackReserve{16 };
80
110
constexpr unsigned descriptorStackReserve{6 };
@@ -108,9 +138,9 @@ RT_API_ATTRS void CopyElement(const Descriptor &to, const SubscriptValue toAt[],
108
138
continue ;
109
139
}
110
140
const Descriptor &curTo{currentCopy.to_ };
111
- SubscriptValue *curToAt{currentCopy.toAt_ };
141
+ const SubscriptValue *curToAt{currentCopy.toAtPtr_ };
112
142
const Descriptor &curFrom{currentCopy.from_ };
113
- SubscriptValue *curFromAt{currentCopy.fromAt_ };
143
+ const SubscriptValue *curFromAt{currentCopy.fromAtPtr_ };
114
144
char *toPtr{curTo.Element <char >(curToAt)};
115
145
char *fromPtr{curFrom.Element <char >(curFromAt)};
116
146
RUNTIME_CHECK (terminator, curTo.ElementBytes () == curFrom.ElementBytes ());
@@ -121,8 +151,7 @@ RT_API_ATTRS void CopyElement(const Descriptor &to, const SubscriptValue toAt[],
121
151
std::memcpy (toPtr, fromPtr, curTo.ElementBytes ());
122
152
--elements;
123
153
if (elements != 0 ) {
124
- curTo.IncrementSubscripts (curToAt);
125
- curFrom.IncrementSubscripts (curFromAt);
154
+ currentCopy.IncrementSubscripts (terminator);
126
155
}
127
156
128
157
// Deep copy allocatable and automatic components if any.
0 commit comments