[flang-commits] [flang] [llvm] [flang-rt] Copy out only the modified suffix of an argument temporary (PR #222101)
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Thu Sep 10 14:48:27 PDT 2026
================
@@ -271,6 +271,165 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from) {
ShallowCopy(to, from, to.IsContiguous(), from.IsContiguous());
}
+// Compares one element bitwise. As in the ShallowCopy* helpers above, the
+// compile-time element size lets the compiler inline the comparison.
+template <typename P>
+static inline RT_API_ATTRS bool ElementIsModified(
+ const char *toAt, const char *fromAt, std::size_t elementBytes) {
+ constexpr std::size_t typeElementBytes{sizeof(P)};
+ if constexpr (typeElementBytes != 1) {
+ return runtime::memcmp(toAt, fromAt, typeElementBytes) != 0;
+ } else {
+ return runtime::memcmp(toAt, fromAt, elementBytes) != 0;
+ }
+}
+
+template <typename P>
+static inline RT_API_ATTRS void CopyElement(
+ char *toAt, const char *fromAt, std::size_t elementBytes) {
+ constexpr std::size_t typeElementBytes{sizeof(P)};
+ if constexpr (typeElementBytes != 1) {
+ runtime::memcpy(toAt, fromAt, typeElementBytes);
+ } else {
+ runtime::memcpy(toAt, fromAt, elementBytes);
+ }
+}
+
+// Scans for the first bitwise difference; when one is found, copies that
+// element and everything after it, reusing the scan's position (fused, one
+// pass). Elements before the first difference are bitwise-identical and are
+// not stored to, so an unmodified copy-out performs no stores at all, and a
+// copy-out never traverses the data more than once nor stores more elements
+// than the unconditional copy would.
+template <typename P, int RANK = -1>
+static RT_API_ATTRS void ShallowCopyModifiedSuffixInner(const Descriptor &to,
+ const Descriptor &from, bool toIsContiguous, bool fromIsContiguous) {
+ std::size_t elementBytes{to.ElementBytes()};
+ std::size_t n{to.Elements()};
+ if (toIsContiguous) {
+ char *toAt{to.OffsetElement()};
+ if (fromIsContiguous) {
+ const char *fromAt{from.OffsetElement()};
+ for (; n > 0; --n, toAt += elementBytes, fromAt += elementBytes) {
----------------
vzakhari wrote:
For this case, can we use memcmp for the whole array size and then a single memcpy?
https://github.com/llvm/llvm-project/pull/222101
More information about the flang-commits
mailing list