Skip to content

Commit d68b5b2

Browse files
committed
PR118069 comment: mayReadOrWrite to getModRef
1 parent 6be998e commit d68b5b2

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

flang/include/flang/Optimizer/Analysis/AliasAnalysis.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,12 @@ struct AliasAnalysis {
198198
/// Return the modify-reference behavior of `op` on `location`.
199199
mlir::ModRefResult getModRef(mlir::Operation *op, mlir::Value location);
200200

201+
/// Return the modify-reference behavior of operations inside `region` on
202+
/// `location`. Contrary to getModRef(operation, location), this will visit
203+
/// nested regions recursively according to the HasRecursiveMemoryEffects
204+
/// trait.
205+
mlir::ModRefResult getModRef(mlir::Region &region, mlir::Value location);
206+
201207
/// Return the memory source of a value.
202208
/// If getLastInstantiationPoint is true, the search for the source
203209
/// will stop at [hl]fir.declare if it represents a dummy

flang/lib/Optimizer/Analysis/AliasAnalysis.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,33 @@ ModRefResult AliasAnalysis::getModRef(Operation *op, Value location) {
464464
return result;
465465
}
466466

467+
ModRefResult AliasAnalysis::getModRef(mlir::Region &region,
468+
mlir::Value location) {
469+
ModRefResult result = ModRefResult::getNoModRef();
470+
for (mlir::Operation &op : region.getOps()) {
471+
if (op.hasTrait<mlir::OpTrait::HasRecursiveMemoryEffects>()) {
472+
for (mlir::Region &subRegion : op.getRegions()) {
473+
result = result.merge(getModRef(subRegion, location));
474+
// Fast return is already mod and ref.
475+
if (result.isModAndRef())
476+
return result;
477+
}
478+
// In MLIR, RecursiveMemoryEffects can be combined with
479+
// MemoryEffectOpInterface to describe extra effects on top of the
480+
// effects of the nested operations. However, the presence of
481+
// RecursiveMemoryEffects and the absence of MemoryEffectOpInterface
482+
// implies the operation has no other memory effects than the one of its
483+
// nested operations.
484+
if (!mlir::isa<mlir::MemoryEffectOpInterface>(op))
485+
continue;
486+
}
487+
result = result.merge(getModRef(&op, location));
488+
if (result.isModAndRef())
489+
return result;
490+
}
491+
return result;
492+
}
493+
467494
AliasAnalysis::Source::Attributes
468495
getAttrsFromVariable(fir::FortranVariableOpInterface var) {
469496
AliasAnalysis::Source::Attributes attrs;

flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,28 +1119,6 @@ class EvaluateIntoMemoryAssignBufferization
11191119
mlir::PatternRewriter &rewriter) const override;
11201120
};
11211121

1122-
static bool mayReadOrWrite(mlir::Region &region, mlir::Value var) {
1123-
fir::AliasAnalysis aliasAnalysis;
1124-
for (mlir::Operation &op : region.getOps()) {
1125-
if (op.hasTrait<mlir::OpTrait::HasRecursiveMemoryEffects>()) {
1126-
for (mlir::Region &subRegion : op.getRegions())
1127-
if (mayReadOrWrite(subRegion, var))
1128-
return true;
1129-
// In MLIR, RecursiveMemoryEffects can be combined with
1130-
// MemoryEffectOpInterface to describe extra effects on top of the
1131-
// effects of the nested operations. However, the presence of
1132-
// RecursiveMemoryEffects and the absence of MemoryEffectOpInterface
1133-
// implies the operation has no other memory effects than the one of its
1134-
// nested operations.
1135-
if (!mlir::isa<mlir::MemoryEffectOpInterface>(op))
1136-
continue;
1137-
}
1138-
if (!aliasAnalysis.getModRef(&op, var).isNoModRef())
1139-
return true;
1140-
}
1141-
return false;
1142-
}
1143-
11441122
static llvm::LogicalResult
11451123
tryUsingAssignLhsDirectly(hlfir::EvaluateInMemoryOp evalInMem,
11461124
mlir::PatternRewriter &rewriter) {
@@ -1168,9 +1146,17 @@ tryUsingAssignLhsDirectly(hlfir::EvaluateInMemoryOp evalInMem,
11681146
// RHS lengths are the same.
11691147
if (lhs.isCharacter())
11701148
return mlir::failure();
1171-
1149+
fir::AliasAnalysis aliasAnalysis;
11721150
// The region must not read or write the LHS.
1173-
if (mayReadOrWrite(evalInMem.getBody(), lhs))
1151+
// Note that getModRef is used instead of mlir::MemoryEffects because
1152+
// EvaluateInMemoryOp is typically expected to hold fir.calls and that
1153+
// Fortran calls cannot be modeled in a useful way with mlir::MemoryEffects:
1154+
// it is hard/impossible to list all the read/written SSA values in a call,
1155+
// but it is often possible to tell that an SSA value cannot be accessed,
1156+
// hence getModRef is needed here and below. Also note that getModRef uses
1157+
// mlir::MemoryEffects for operations that do not have special handling in
1158+
// getModRef.
1159+
if (aliasAnalysis.getModRef(evalInMem.getBody(), lhs).isModOrRef())
11741160
return mlir::failure();
11751161
// Any variables affected between the hlfir.evalInMem and assignment must not
11761162
// be read or written inside the region since it will be moved at the
@@ -1184,7 +1170,8 @@ tryUsingAssignLhsDirectly(hlfir::EvaluateInMemoryOp evalInMem,
11841170
}
11851171
for (const mlir::MemoryEffects::EffectInstance &effect : *effects) {
11861172
mlir::Value affected = effect.getValue();
1187-
if (!affected || mayReadOrWrite(evalInMem.getBody(), affected))
1173+
if (!affected ||
1174+
aliasAnalysis.getModRef(evalInMem.getBody(), affected).isModOrRef())
11881175
return mlir::failure();
11891176
}
11901177

0 commit comments

Comments
 (0)