Skip to content

Commit 05e4d39

Browse files
committed
first implementation
1 parent ecdd660 commit 05e4d39

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

flang/lib/Optimizer/Analysis/AliasAnalysis.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/ADT/TypeSwitch.h"
2323
#include "llvm/Support/Casting.h"
2424
#include "llvm/Support/Debug.h"
25+
#include "mlir/Interfaces/ViewLikeInterface.h"
2526

2627
using namespace mlir;
2728

@@ -535,6 +536,42 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
535536
mlir::Operation *instantiationPoint{nullptr};
536537
while (defOp && !breakFromLoop) {
537538
ty = defOp->getResultTypes()[0];
539+
540+
// Effect-based detection using op-scoped Allocate with conservative
541+
// heuristics (ignore value-scoped signals per request).
542+
if (auto memIface = llvm::dyn_cast<mlir::MemoryEffectOpInterface>(defOp)) {
543+
llvm::SmallVector<mlir::MemoryEffects::EffectInstance, 4> effects;
544+
memIface.getEffects(effects);
545+
bool sawOpScopedAlloc = false;
546+
for (auto &ei : effects) {
547+
bool isAlloc = mlir::isa<mlir::MemoryEffects::Allocate>(ei.getEffect());
548+
if (!ei.getValue() && isAlloc) {
549+
sawOpScopedAlloc = true;
550+
}
551+
}
552+
if (sawOpScopedAlloc) {
553+
auto isMemoryRefLikeType = [](mlir::Type t) {
554+
return fir::isa_ref_type(t) || mlir::isa<mlir::BaseMemRefType>(t) ||
555+
mlir::isa<mlir::LLVM::LLVMPointerType>(t);
556+
};
557+
bool opIsViewLike = (bool)mlir::dyn_cast_or_null<mlir::ViewLikeOpInterface>(defOp);
558+
bool hasMemOperands = llvm::any_of(defOp->getOperands(), [&](mlir::Value opnd) {
559+
return isMemoryRefLikeType(opnd.getType());
560+
});
561+
if (!opIsViewLike && !hasMemOperands) {
562+
for (mlir::Value res : defOp->getResults()) {
563+
if (res == v && isMemoryRefLikeType(res.getType())) {
564+
type = SourceKind::Allocate;
565+
breakFromLoop = true;
566+
break;
567+
}
568+
}
569+
if (breakFromLoop)
570+
break;
571+
}
572+
}
573+
}
574+
538575
llvm::TypeSwitch<Operation *>(defOp)
539576
.Case<hlfir::AsExprOp>([&](auto op) {
540577
v = op.getVar();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// REQUIRES: asserts
2+
// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -debug-only=fir-alias-analysis --mlir-disable-threading 2>&1 | FileCheck %s
3+
4+
// Verify that a CUF allocation is recognized as SourceKind::Allocate by
5+
// fir::AliasAnalysis::getSource.
6+
7+
module {
8+
func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
9+
// Allocate two independent device arrays and tag the results; with
10+
// op-scoped MemAlloc handling in AA, these should be classified as
11+
// Allocate and not alias.
12+
%a = cuf.alloc !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a1", data_attr = #cuf.cuda<device>, uniq_name = "_QFEa1", test.ptr = "cuf_alloc_a"} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
13+
%b = cuf.alloc !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a2", data_attr = #cuf.cuda<device>, uniq_name = "_QFEa2", test.ptr = "cuf_alloc_b"} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
14+
return
15+
}
16+
}
17+
18+
// CHECK-LABEL: Testing : "_QQmain"
19+
// Distinct allocations should not alias.
20+
// CHECK: cuf_alloc_a#0 <-> cuf_alloc_b#0: NoAlias
21+
22+

0 commit comments

Comments
 (0)