[llvm-branch-commits] [flang] [flang][hlfir] optimize hlfir.eval_in_mem bufferization (PR #118069)
Tom Eccles via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Nov 29 04:05:31 PST 2024
================
@@ -1108,6 +1108,113 @@ class ReductionMaskConversion : public mlir::OpRewritePattern<Op> {
}
};
+class EvaluateIntoMemoryAssignBufferization
+ : public mlir::OpRewritePattern<hlfir::EvaluateInMemoryOp> {
+
+public:
+ using mlir::OpRewritePattern<hlfir::EvaluateInMemoryOp>::OpRewritePattern;
+
+ llvm::LogicalResult
+ matchAndRewrite(hlfir::EvaluateInMemoryOp,
+ mlir::PatternRewriter &rewriter) const override;
+};
+
+static bool mayReadOrWrite(mlir::Region ®ion, mlir::Value var) {
+ fir::AliasAnalysis aliasAnalysis;
+ for (mlir::Operation &op : region.getOps()) {
+ if (op.hasTrait<mlir::OpTrait::HasRecursiveMemoryEffects>()) {
+ for (mlir::Region &subRegion : op.getRegions())
+ if (mayReadOrWrite(subRegion, var))
+ return true;
+ // In MLIR, RecursiveMemoryEffects can be combined with
+ // MemoryEffectOpInterface to describe extra effects on top of the
+ // effects of the nested operations. However, the presence of
+ // RecursiveMemoryEffects and the absence of MemoryEffectOpInterface
+ // implies the operation has no other memory effects than the one of its
+ // nested operations.
+ if (!mlir::isa<mlir::MemoryEffectOpInterface>(op))
+ continue;
+ }
+ if (!aliasAnalysis.getModRef(&op, var).isNoModRef())
+ return true;
+ }
+ return false;
+}
+
+static llvm::LogicalResult
+tryUsingAssignLhsDirectly(hlfir::EvaluateInMemoryOp evalInMem,
+ mlir::PatternRewriter &rewriter) {
+ mlir::Location loc = evalInMem.getLoc();
+ hlfir::DestroyOp destroy;
+ hlfir::AssignOp assign;
+ for (auto user : llvm::enumerate(evalInMem->getUsers())) {
+ if (user.index() > 2)
+ return mlir::failure();
+ mlir::TypeSwitch<mlir::Operation *, void>(user.value())
+ .Case([&](hlfir::AssignOp op) { assign = op; })
+ .Case([&](hlfir::DestroyOp op) { destroy = op; });
+ }
+ if (!assign || !destroy || destroy.mustFinalizeExpr() ||
+ assign.isAllocatableAssignment())
+ return mlir::failure();
+
+ hlfir::Entity lhs{assign.getLhs()};
+ // EvaluateInMemoryOp memory is contiguous, so in general, it can only be
+ // replace by the LHS if the LHS is contiguous.
+ if (!lhs.isSimplyContiguous())
+ return mlir::failure();
+ // Character assignment may involves truncation/padding, so the LHS
+ // cannot be used to evaluate RHS in place without proving the LHS and
+ // RHS lengths are the same.
+ if (lhs.isCharacter())
+ return mlir::failure();
+
+ // The region must not read or write the LHS.
+ if (mayReadOrWrite(evalInMem.getBody(), lhs))
----------------
tblah wrote:
Please could you add a comment explaining that currently this is used for optimizing function calls, and mlir memory effects aren't helpful for fir.call so there's no benefit in first filtering by mlir memory effects as is done below.
https://github.com/llvm/llvm-project/pull/118069
More information about the llvm-branch-commits
mailing list