[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