Skip to content

Commit 4e64702

Browse files
committed
refactor
1 parent 0295bd1 commit 4e64702

File tree

1 file changed

+81
-88
lines changed

1 file changed

+81
-88
lines changed

flang/lib/Optimizer/Analysis/AliasAnalysis.cpp

Lines changed: 81 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,67 @@ using namespace mlir;
2828

2929
#define DEBUG_TYPE "fir-alias-analysis"
3030

31+
//===----------------------------------------------------------------------===//
32+
// AliasAnalysis: alias helpers
33+
//===----------------------------------------------------------------------===//
34+
35+
static bool tryClassifyAllocateFromEffects(mlir::Operation *op,
36+
mlir::Value candidate, bool allowValueScoped, bool allowOpScoped,
37+
mlir::Value &v, mlir::Operation *&defOp,
38+
fir::AliasAnalysis::SourceKind &type) {
39+
auto iface = llvm::dyn_cast<mlir::MemoryEffectOpInterface>(op);
40+
if (!iface)
41+
return false;
42+
43+
llvm::SmallVector<mlir::MemoryEffects::EffectInstance, 4> effects;
44+
iface.getEffects(effects);
45+
46+
if (allowValueScoped) {
47+
for (mlir::MemoryEffects::EffectInstance &e : effects) {
48+
if (mlir::isa<mlir::MemoryEffects::Allocate>(e.getEffect()) &&
49+
e.getValue() && e.getValue() == candidate) {
50+
v = candidate;
51+
defOp = op;
52+
type = fir::AliasAnalysis::SourceKind::Allocate;
53+
return true;
54+
}
55+
}
56+
}
57+
58+
if (!allowOpScoped)
59+
return false;
60+
61+
bool hasOpScopedAlloc = llvm::any_of(
62+
effects, [](const mlir::MemoryEffects::EffectInstance &e) {
63+
return !e.getValue() &&
64+
mlir::isa<mlir::MemoryEffects::Allocate>(e.getEffect());
65+
});
66+
if (!hasOpScopedAlloc)
67+
return false;
68+
69+
bool opIsViewLike =
70+
(bool)mlir::dyn_cast_or_null<mlir::ViewLikeOpInterface>(op);
71+
auto isMemoryRefLikeType = [](mlir::Type type) {
72+
return fir::isa_ref_type(type) || mlir::isa<mlir::BaseMemRefType>(type) ||
73+
mlir::isa<mlir::LLVM::LLVMPointerType>(type);
74+
};
75+
bool hasMemOperands = llvm::any_of(op->getOperands(), [&](mlir::Value o) {
76+
return isMemoryRefLikeType(o.getType());
77+
});
78+
if (opIsViewLike || hasMemOperands)
79+
return false;
80+
81+
for (mlir::Value res : op->getResults()) {
82+
if (res == candidate && isMemoryRefLikeType(res.getType())) {
83+
v = candidate;
84+
defOp = op;
85+
type = fir::AliasAnalysis::SourceKind::Allocate;
86+
return true;
87+
}
88+
}
89+
return false;
90+
}
91+
3192
//===----------------------------------------------------------------------===//
3293
// AliasAnalysis: alias
3394
//===----------------------------------------------------------------------===//
@@ -544,43 +605,22 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
544605
type = SourceKind::Indirect;
545606
}
546607
};
608+
609+
// Helper to detect memory-ref-like types.
610+
auto isMemoryRefLikeType = [](mlir::Type t) {
611+
return fir::isa_ref_type(t) || mlir::isa<mlir::BaseMemRefType>(t) ||
612+
mlir::isa<mlir::LLVM::LLVMPointerType>(t);
613+
};
614+
547615
while (defOp && !breakFromLoop) {
548616
ty = defOp->getResultTypes()[0];
549617

550-
// Effect-based detection using op-scoped Allocate with conservative
551-
// heuristics (ignore value-scoped signals per request).
552-
if (auto memIface = llvm::dyn_cast<mlir::MemoryEffectOpInterface>(defOp)) {
553-
llvm::SmallVector<mlir::MemoryEffects::EffectInstance, 4> effects;
554-
memIface.getEffects(effects);
555-
bool sawOpScopedAlloc = false;
556-
for (auto &ei : effects) {
557-
bool isAlloc = mlir::isa<mlir::MemoryEffects::Allocate>(ei.getEffect());
558-
if (!ei.getValue() && isAlloc) {
559-
sawOpScopedAlloc = true;
560-
}
561-
}
562-
if (sawOpScopedAlloc) {
563-
auto isMemoryRefLikeType = [](mlir::Type t) {
564-
return fir::isa_ref_type(t) || mlir::isa<mlir::BaseMemRefType>(t) ||
565-
mlir::isa<mlir::LLVM::LLVMPointerType>(t);
566-
};
567-
bool opIsViewLike = (bool)mlir::dyn_cast_or_null<mlir::ViewLikeOpInterface>(defOp);
568-
bool hasMemOperands = llvm::any_of(defOp->getOperands(), [&](mlir::Value opnd) {
569-
return isMemoryRefLikeType(opnd.getType());
570-
});
571-
if (!opIsViewLike && !hasMemOperands) {
572-
for (mlir::Value res : defOp->getResults()) {
573-
if (res == v && isMemoryRefLikeType(res.getType())) {
574-
type = SourceKind::Allocate;
575-
breakFromLoop = true;
576-
break;
577-
}
578-
}
579-
if (breakFromLoop)
580-
break;
581-
}
582-
}
583-
}
618+
// Effect-based detection (op-scoped heuristic only at this level).
619+
if (tryClassifyAllocateFromEffects(defOp, v,
620+
/*allowValueScoped=*/false,
621+
/*allowOpScoped=*/true,
622+
v, defOp, type))
623+
break;
584624

585625
llvm::TypeSwitch<Operation *>(defOp)
586626
.Case<hlfir::AsExprOp>([&](auto op) {
@@ -666,61 +706,14 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
666706
if (global) {
667707
type = SourceKind::Global;
668708
} else {
669-
auto def = llvm::cast<mlir::Value>(boxSrc.origin.u);
709+
mlir::Value def = llvm::cast<mlir::Value>(boxSrc.origin.u);
670710
bool classified = false;
671-
if (auto defDefOp = def.getDefiningOp()) {
672-
if (auto defIface =
673-
llvm::dyn_cast<mlir::MemoryEffectOpInterface>(defDefOp)) {
674-
llvm::SmallVector<mlir::MemoryEffects::EffectInstance, 4> eff;
675-
defIface.getEffects(eff);
676-
// Prefer value-scoped Allocate on the underlying storage.
677-
for (auto &e : eff) {
678-
if (mlir::isa<mlir::MemoryEffects::Allocate>(e.getEffect()) &&
679-
e.getValue() && e.getValue() == def) {
680-
v = def;
681-
defOp = v.getDefiningOp();
682-
type = SourceKind::Allocate;
683-
classified = true;
684-
break;
685-
}
686-
}
687-
// Heuristic for op-scoped Allocate at the underlying defining op.
688-
if (!classified) {
689-
bool sawOpScopedAlloc = llvm::any_of(
690-
eff, [](auto &e) {
691-
return !e.getValue() &&
692-
mlir::isa<mlir::MemoryEffects::Allocate>(
693-
e.getEffect());
694-
});
695-
if (sawOpScopedAlloc) {
696-
auto isMemoryRefLikeType = [](mlir::Type t) {
697-
return fir::isa_ref_type(t) ||
698-
mlir::isa<mlir::BaseMemRefType>(t) ||
699-
mlir::isa<mlir::LLVM::LLVMPointerType>(t);
700-
};
701-
bool opIsViewLike = (bool)mlir::dyn_cast_or_null<
702-
mlir::ViewLikeOpInterface>(defDefOp);
703-
bool hasMemOperands = llvm::any_of(
704-
defDefOp->getOperands(), [&](mlir::Value opnd) {
705-
return isMemoryRefLikeType(opnd.getType());
706-
});
707-
if (!opIsViewLike && !hasMemOperands) {
708-
for (mlir::Value res : defDefOp->getResults()) {
709-
if (res == def && isMemoryRefLikeType(res.getType())) {
710-
v = def;
711-
defOp = v.getDefiningOp();
712-
type = SourceKind::Allocate;
713-
classified = true;
714-
break;
715-
}
716-
}
717-
}
718-
}
719-
}
720-
}
721-
}
722-
if (!classified)
723-
classifyFallbackFrom(def);
711+
if (auto defDefOp = def.getDefiningOp())
712+
classified = tryClassifyAllocateFromEffects(
713+
defDefOp, def,
714+
/*allowValueScoped=*/true, /*allowOpScoped=*/true,
715+
v, defOp, type);
716+
if (!classified) classifyFallbackFrom(def);
724717
}
725718
breakFromLoop = true;
726719
return;

0 commit comments

Comments
 (0)