[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