Skip to content

[flang] Add FIR AliasAnalysis alias() wrapper to allow external getSource() method #115073

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Nov 6, 2024
Merged
19 changes: 12 additions & 7 deletions flang/include/flang/Optimizer/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ struct AliasAnalysis {
// module top
// real, pointer :: a(:)
// end module
//
//
// subroutine test()
// use top
// a(1) = 1
// end subroutine
// -------------------------------------------------
//
//
// flang -fc1 -emit-fir test.f90 -o test.fir
//
// ------------------- test.fir --------------------
// fir.global @_QMtopEa : !fir.box<!fir.ptr<!fir.array<?xf32>>>
//
// fir.global @_QMtopEa : !fir.box<!fir.ptr<!fir.array<?xf32>>>
//
// func.func @_QPtest() {
// %c1 = arith.constant 1 : index
// %cst = arith.constant 1.000000e+00 : f32
Expand Down Expand Up @@ -100,12 +100,12 @@ struct AliasAnalysis {
// Additionally, because it is relied on in HLFIR lowering, we allow querying
// on a box SSA value, which is interpreted as querying on its data.
//
// So in the above example, !fir.ref<f32> and !fir.box<!fir.ptr<!fir.array<?xf32>>> is data,
// So in the above example, !fir.ref<f32> and !fir.box<!fir.ptr<!fir.array<?xf32>>> is data,
// while !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> is not data.

// This also applies to function arguments. In the example below, %arg0
// is data, %arg1 is not data but a load of %arg1 is.
//
//
// func.func @_QFPtest2(%arg0: !fir.ref<f32>, %arg1: !fir.ref<!fir.box<!fir.ptr<f32>>> ) {
// %0 = fir.load %arg1 : !fir.ref<!fir.box<!fir.ptr<f32>>>
// ... }
Expand Down Expand Up @@ -183,6 +183,10 @@ struct AliasAnalysis {
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
const AliasAnalysis::Source &op);

/// Given the values and their sources, return their aliasing behavior.
mlir::AliasResult alias(Source lhsSrc, Source rhsSrc, mlir::Value lhs,
mlir::Value rhs);

/// Given two values, return their aliasing behavior.
mlir::AliasResult alias(mlir::Value lhs, mlir::Value rhs);

Expand All @@ -193,7 +197,8 @@ struct AliasAnalysis {
/// If getInstantiationPoint is true, the search for the source
/// will stop at [hl]fir.declare if it represents a dummy
/// argument declaration (i.e. it has the dummy_scope operand).
Source getSource(mlir::Value, bool getInstantiationPoint = false);
fir::AliasAnalysis::Source getSource(mlir::Value,
bool getInstantiationPoint = false);

private:
/// Return true, if `ty` is a reference type to an object of derived type
Expand Down
12 changes: 10 additions & 2 deletions flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,19 @@ bool AliasAnalysis::Source::mayBeActualArgWithPtr(
}

AliasResult AliasAnalysis::alias(mlir::Value lhs, mlir::Value rhs) {
// A wrapper around alias(Source lhsSrc, Source rhsSrc, mlir::Value lhs,
// mlir::Value rhs) This allows a user to provide Source that may be obtained
// through other dialects
auto lhsSrc = getSource(lhs);
auto rhsSrc = getSource(rhs);
return alias(lhsSrc, rhsSrc, lhs, rhs);
}

AliasResult AliasAnalysis::alias(Source lhsSrc, Source rhsSrc, mlir::Value lhs,
mlir::Value rhs) {
// TODO: alias() has to be aware of the function scopes.
// After MLIR inlining, the current implementation may
// not recognize non-aliasing entities.
auto lhsSrc = getSource(lhs);
auto rhsSrc = getSource(rhs);
bool approximateSource = lhsSrc.approximateSource || rhsSrc.approximateSource;
LLVM_DEBUG(llvm::dbgs() << "\nAliasAnalysis::alias\n";
llvm::dbgs() << " lhs: " << lhs << "\n";
Expand Down