[flang] Inline array size call when dim is compile time constant
authorRazvan Lupusoru <rlupusoru@nvidia.com>
Thu, 11 May 2023 17:42:37 +0000 (10:42 -0700)
committerRazvan Lupusoru <rlupusoru@nvidia.com>
Thu, 11 May 2023 21:50:43 +0000 (14:50 -0700)
Instead of calling _FortranASizeDim, we can instead load extent
directly from descriptor. Add this support for cases where dim
is a known constant at compile time.

Reviewed By: clementval

Differential Revision: https://reviews.llvm.org/D150385

flang/lib/Optimizer/Builder/IntrinsicCall.cpp
flang/test/Lower/Intrinsics/ubound.f90

index dee08c7..2ee6f40 100644 (file)
@@ -4907,6 +4907,13 @@ IntrinsicLibrary::genSize(mlir::Type resultType,
 
   // Get the DIM argument.
   mlir::Value dim = fir::getBase(args[1]);
+  if (std::optional<std::int64_t> cstDim = fir::getIntIfConstant(dim)) {
+    // If it is a compile time constant, skip the runtime call.
+    return builder.createConvert(loc, resultType,
+                                 fir::factory::readExtent(builder, loc,
+                                                          fir::BoxValue{array},
+                                                          cstDim.value() - 1));
+  }
   if (!fir::isa_ref_type(dim.getType()))
     return builder.createConvert(
         loc, resultType, fir::runtime::genSizeDim(builder, loc, array, dim));
index 1883d5b..8210ff3 100644 (file)
@@ -69,3 +69,15 @@ subroutine ubound_test_3(a, dim, res)
 ! CHECK:         fir.store %[[VAL_16]] to %{{.*}} : !fir.ref<i64>
   res = ubound(a, dim, 8)
 end subroutine
+
+
+! CHECK-LABEL: func @_QPubound_test_const_dim(
+subroutine ubound_test_const_dim(array)
+  real :: array(11:)
+  integer :: res
+! Should not call _FortranASizeDim when dim is compile time constant. But instead load from descriptor directly.
+! CHECK:         %[[C0:.*]] = arith.constant 0 : index
+! CHECK:         %[[DIMS:.*]]:3 = fir.box_dims %arg0, %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK:         %{{.*}} = fir.convert %[[DIMS]]#1 : (index) -> i32
+  res = ubound(array, 1)
+end subroutine