[llvm] [flang-rt] - Reduce ShallowCopy template instantiations to improve LTO time (PR #209915)

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 16 04:00:50 PDT 2026


================
@@ -201,37 +201,36 @@ RT_API_ATTRS void ShallowCopyInner(const Descriptor &to, const Descriptor &from,
   }
 }
 
-// Most arrays are much closer to rank-1 than to maxRank.
-// Doing the recursion upwards instead of downwards puts the more common
-// cases earlier in the if-chain and has a tangible impact on performance.
-template <typename P, int RANK> struct ShallowCopyRankSpecialize {
-  static RT_API_ATTRS bool execute(const Descriptor &to, const Descriptor &from,
-      bool toIsContiguous, bool fromIsContiguous) {
-    if (to.rank() == RANK && from.rank() == RANK) {
-      ShallowCopyInner<P, RANK>(to, from, toIsContiguous, fromIsContiguous);
-      return true;
-    }
-    return ShallowCopyRankSpecialize<P, RANK + 1>::execute(
-        to, from, toIsContiguous, fromIsContiguous);
-  }
-};
-
-template <typename P> struct ShallowCopyRankSpecialize<P, maxRank + 1> {
-  static RT_API_ATTRS bool execute(const Descriptor &to, const Descriptor &from,
-      bool toIsContiguous, bool fromIsContiguous) {
-    return false;
-  }
-};
+// Specialize only for common ranks (1-4) to reduce code size.
+// Higher ranks use the generic fallback which handles any rank at runtime.
+// Most real-world Fortran arrays are rank 1-3; rank 4+ is rare.
+// This trades a small amount of potential optimization for high-rank arrays
+// in exchange for significantly reduced code size (~60% reduction in
+// ShallowCopy template instantiations).
 
 // ShallowCopy helper for specialising the variants based on array rank
 template <typename P>
 RT_API_ATTRS void ShallowCopyRank(const Descriptor &to, const Descriptor &from,
     bool toIsContiguous, bool fromIsContiguous) {
-  // Try to call a specialised ShallowCopy variant from rank-1 up to maxRank
-  bool specialized{ShallowCopyRankSpecialize<P, 1>::execute(
-      to, from, toIsContiguous, fromIsContiguous)};
-  if (!specialized) {
+  // Specialize only common low ranks; use generic fallback for higher ranks
+  switch (to.rank()) {
+  case 1:
+    ShallowCopyInner<P, 1>(to, from, toIsContiguous, fromIsContiguous);
+    return;
+  case 2:
+    ShallowCopyInner<P, 2>(to, from, toIsContiguous, fromIsContiguous);
+    return;
+  case 3:
+    ShallowCopyInner<P, 3>(to, from, toIsContiguous, fromIsContiguous);
+    return;
+  case 4:
+    ShallowCopyInner<P, 4>(to, from, toIsContiguous, fromIsContiguous);
+    return;
+  default:
+    // Generic fallback for rank > 4 (and rank 0, though that's handled
+    // by the contiguous-to-contiguous case in ShallowCopyInner)
----------------
Meinersbur wrote:

At most you could mention here why we do not specialize for all ranks.

https://github.com/llvm/llvm-project/pull/209915


More information about the llvm-commits mailing list