[flang-commits] [flang] [flang][NFC] Engineering option for optimizing allocatable assignments. (PR #119936)

via flang-commits flang-commits at lists.llvm.org
Fri Dec 13 15:43:20 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Slava Zakharin (vzakhari)

<details>
<summary>Changes</summary>

The options is added just for quick experiments with different apps.
If any headroom is found, we will implement proper multiversioning
of hlfir.assign with allocatable LHS.


---
Full diff: https://github.com/llvm/llvm-project/pull/119936.diff


1 Files Affected:

- (modified) flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp (+26-6) 


``````````diff
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
index 8342458e00763c..9ade904dcda835 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
@@ -42,6 +42,18 @@ namespace hlfir {
 
 #define DEBUG_TYPE "opt-bufferization"
 
+// An engineering option to allow treating hlfir.assign with realloc
+// attribute as never requiring (re)allocation of the LHS.
+// Setting it to true may result in incorrect code, so it is present
+// just for quicker benchmarking of apps that may benefit
+// from multiversioning such hlfir.assign operations under
+// the dynamic checks of the type/shape/allocation status.
+static llvm::cl::opt<bool> assumeNoLhsReallocation(
+    "flang-assume-no-lhs-reallocation",
+    llvm::cl::desc("Assume that hlfir.assign never (re)allocates the LHS, i.e. "
+                   "that the LHS and RHS are always conformant"),
+    llvm::cl::init(false));
+
 namespace {
 
 /// This transformation should match in place modification of arrays.
@@ -462,16 +474,20 @@ ElementalAssignBufferization::findMatch(hlfir::ElementalOp elemental) {
   // the incoming expression
   match.array = match.assign.getLhs();
   mlir::Type arrayType = mlir::dyn_cast<fir::SequenceType>(
-      fir::unwrapPassByRefType(match.array.getType()));
-  if (!arrayType)
+      hlfir::getFortranElementOrSequenceType(match.array.getType()));
+  if (!arrayType) {
+    LLVM_DEBUG(llvm::dbgs() << "AssignOp's result is not an array\n");
     return std::nullopt;
+  }
 
   // require that the array elements are trivial
   // TODO: this is just to make the pass easier to think about. Not an inherent
   // limitation
   mlir::Type eleTy = hlfir::getFortranElementType(arrayType);
-  if (!fir::isa_trivial(eleTy))
+  if (!fir::isa_trivial(eleTy)) {
+    LLVM_DEBUG(llvm::dbgs() << "AssignOp's data type is not trivial\n");
     return std::nullopt;
+  }
 
   // The array must have the same shape as the elemental.
   //
@@ -485,8 +501,10 @@ ElementalAssignBufferization::findMatch(hlfir::ElementalOp elemental) {
   // there is no reallocation of the lhs due to the assignment.
   // We can probably try generating multiple versions of the code
   // with checking for the shape match, length parameters match, etc.
-  if (match.assign.getRealloc())
+  if (match.assign.isAllocatableAssignment() && !assumeNoLhsReallocation) {
+    LLVM_DEBUG(llvm::dbgs() << "AssignOp may involve (re)allocation of LHS\n");
     return std::nullopt;
+  }
 
   // the transformation wants to apply the elemental in a do-loop at the
   // hlfir.assign, check there are no effects which make this unsafe
@@ -606,6 +624,8 @@ llvm::LogicalResult ElementalAssignBufferization::matchAndRewrite(
 
   // create the loop at the assignment
   builder.setInsertionPoint(match->assign);
+  hlfir::Entity arrayObj = hlfir::derefPointersAndAllocatables(
+      loc, builder, hlfir::Entity{match->array});
 
   // Generate a loop nest looping around the hlfir.elemental shape and clone
   // hlfir.elemental region inside the inner loop
@@ -619,8 +639,8 @@ llvm::LogicalResult ElementalAssignBufferization::matchAndRewrite(
   rewriter.eraseOp(yield);
 
   // Assign the element value to the array element for this iteration.
-  auto arrayElement = hlfir::getElementAt(
-      loc, builder, hlfir::Entity{match->array}, loopNest.oneBasedIndices);
+  auto arrayElement =
+      hlfir::getElementAt(loc, builder, arrayObj, loopNest.oneBasedIndices);
   builder.create<hlfir::AssignOp>(
       loc, elementValue, arrayElement, /*realloc=*/false,
       /*keep_lhs_length_if_realloc=*/false, match->assign.getTemporaryLhs());

``````````

</details>


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


More information about the flang-commits mailing list