FLANG
AliasAnalysis.h
1//===-- AliasAnalysis.h - Alias Analysis in FIR -----------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef FORTRAN_OPTIMIZER_ANALYSIS_ALIASANALYSIS_H
10#define FORTRAN_OPTIMIZER_ANALYSIS_ALIASANALYSIS_H
11
12#include "flang/Common/enum-class.h"
13#include "flang/Common/enum-set.h"
14#include "mlir/Analysis/AliasAnalysis.h"
15#include "mlir/IR/SymbolTable.h"
16#include "mlir/IR/Value.h"
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/PointerUnion.h"
19
20namespace fir {
21
22//===----------------------------------------------------------------------===//
23// AliasAnalysis
24//===----------------------------------------------------------------------===//
26 // Structures to describe the memory source of a value.
27
29 ENUM_CLASS(SourceKind,
32 Allocate,
34 Global,
37 Argument,
40 HostAssoc,
44 Indirect,
47 Unknown);
48
50 ENUM_CLASS(Attribute, Target, Pointer, IntentIn, CrayPointer, CrayPointee);
51
52 // See
53 // https://discourse.llvm.org/t/rfc-distinguish-between-data-and-non-data-in-fir-alias-analysis/78759/1
54 //
55 // It is possible, while following the source of a memory reference through
56 // the use-def chain, to arrive at the same origin, even though the starting
57 // points were known to not alias.
58 //
59 // clang-format off
60 // Example:
61 // ------------------- test.f90 --------------------
62 // module top
63 // real, pointer :: a(:)
64 // end module
65 //
66 // subroutine test()
67 // use top
68 // a(1) = 1
69 // end subroutine
70 // -------------------------------------------------
71 //
72 // flang -fc1 -emit-fir test.f90 -o test.fir
73 //
74 // ------------------- test.fir --------------------
75 // fir.global @_QMtopEa : !fir.box<!fir.ptr<!fir.array<?xf32>>>
76 //
77 // func.func @_QPtest() {
78 // %c1 = arith.constant 1 : index
79 // %cst = arith.constant 1.000000e+00 : f32
80 // %0 = fir.address_of(@_QMtopEa) : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
81 // %1 = fir.declare %0 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtopEa"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
82 // %2 = fir.load %1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
83 // ...
84 // %5 = fir.array_coor %2 %c1 : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>, index) -> !fir.ref<f32>
85 // fir.store %cst to %5 : !fir.ref<f32>
86 // return
87 // }
88 // -------------------------------------------------
89 //
90 // With high level operations, such as fir.array_coor, it is possible to
91 // reach into the data wrapped by the box (the descriptor). Therefore when
92 // asking about the memory source of %5, we are really asking about the
93 // source of the data of box %2.
94 //
95 // When asking about the source of %0 which is the address of the box, we
96 // reach the same source as in the first case: the global @_QMtopEa. Yet one
97 // source refers to the data while the other refers to the address of the box
98 // itself.
99 //
100 // To distinguish between the two, the isData flag has been added, whereby
101 // data is defined as any memory reference that is not a box reference.
102 // Additionally, because it is relied on in HLFIR lowering, we allow querying
103 // on a box SSA value, which is interpreted as querying on its data.
104 //
105 // So in the above example, !fir.ref<f32> and !fir.box<!fir.ptr<!fir.array<?xf32>>> is data,
106 // while !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> is not data.
107
108 // This also applies to function arguments. In the example below, %arg0
109 // is data, %arg1 is not data but a load of %arg1 is.
110 //
111 // func.func @_QFPtest2(%arg0: !fir.ref<f32>, %arg1: !fir.ref<!fir.box<!fir.ptr<f32>>> ) {
112 // %0 = fir.load %arg1 : !fir.ref<!fir.box<!fir.ptr<f32>>>
113 // ... }
114 //
115 // clang-format on
116
117 struct Source {
118 using SourceUnion = llvm::PointerUnion<mlir::SymbolRefAttr, mlir::Value>;
120
123 SourceUnion u;
124
134 mlir::Operation *instantiationPoint;
135
137 bool isData{false};
138 };
139
140 SourceOrigin origin;
141
143 SourceKind kind;
145 mlir::Type valueType;
147 Attributes attributes;
153
155 void print(llvm::raw_ostream &os) const;
156
158 bool isTargetOrPointer() const;
159
161 bool isTarget() const;
162
164 bool isPointer() const;
165
167 bool isCrayPointer() const;
168
170 bool isCrayPointee() const;
171
173 bool isCrayPointerOrPointee() const;
174
175 bool isDummyArgument() const;
176 bool isData() const;
177 bool isBoxData() const;
178
180 bool isFortranUserVariable() const;
181
188
192 bool mayBeDummyArgOrHostAssoc() const;
194 bool mayBePtrDummyArgOrHostAssoc() const;
196 bool mayBeActualArg() const;
199 bool mayBeActualArgWithPtr(const mlir::Value *val) const;
201
202 mlir::Type getType() const;
203 };
204
205 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
206 const AliasAnalysis::Source &op);
207
209 mlir::AliasResult alias(Source lhsSrc, Source rhsSrc, mlir::Value lhs,
210 mlir::Value rhs);
211
213 mlir::AliasResult alias(mlir::Value lhs, mlir::Value rhs);
214
216 mlir::ModRefResult getModRef(mlir::Operation *op, mlir::Value location);
217
222 mlir::ModRefResult getModRef(mlir::Region &region, mlir::Value location);
223
229 bool getLastInstantiationPoint = false);
230
233 static bool isPointerReference(mlir::Type ty);
234
235private:
238 static bool isRecordWithPointerComponent(mlir::Type ty);
239
243 const mlir::SymbolTable *getNearestSymbolTable(mlir::Operation *from);
244
248 bool symbolMayHaveTargetAttr(mlir::SymbolRefAttr symbol,
249 mlir::Operation *from);
250
264 llvm::DenseMap<mlir::Operation *, mlir::SymbolTable> symTabMap;
265};
266
267inline bool operator==(const AliasAnalysis::Source::SourceOrigin &lhs,
269 return lhs.u == rhs.u && lhs.isData == rhs.isData;
270}
271inline bool operator!=(const AliasAnalysis::Source::SourceOrigin &lhs,
272 const AliasAnalysis::Source::SourceOrigin &rhs) {
273 return !(lhs == rhs);
274}
275
276inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
277 const AliasAnalysis::Source &op) {
278 op.print(os);
279 return os;
280}
281
282} // namespace fir
283
284#endif // FORTRAN_OPTIMIZER_ANALYSIS_ALIASANALYSIS_H
Definition enum-set.h:28
Definition AbstractConverter.h:37
Definition AliasAnalysis.h:121
mlir::Operation * instantiationPoint
Definition AliasAnalysis.h:134
SourceUnion u
Source definition of a value.
Definition AliasAnalysis.h:123
bool isData
Whether the source was reached following data or box reference.
Definition AliasAnalysis.h:137
Definition AliasAnalysis.h:117
bool isCrayPointer() const
Return true, if CrayPointer attribute is set.
Definition AliasAnalysis.cpp:165
bool isCapturedInInternalProcedure
Source object is used in an internal procedure via host association.
Definition AliasAnalysis.h:152
bool isFortranUserVariable() const
Is this source a variable from the Fortran source?
Definition AliasAnalysis.cpp:186
Attributes attributes
Attributes of the memory source object, e.g. Target.
Definition AliasAnalysis.h:147
bool isPointer() const
Return true, if Pointer attribute is set.
Definition AliasAnalysis.cpp:157
SourceKind kind
Kind of the memory source.
Definition AliasAnalysis.h:143
bool isCrayPointee() const
Return true, if CrayPointee attribute is set.
Definition AliasAnalysis.cpp:161
void print(llvm::raw_ostream &os) const
Print information about the memory source to os.
Definition AliasAnalysis.cpp:117
bool mayBePtrDummyArgOrHostAssoc() const
mayBeDummyArgOrHostAssoc and the address of a pointer?
Definition AliasAnalysis.cpp:201
bool isTargetOrPointer() const
Return true, if Target or Pointer attribute is set.
Definition AliasAnalysis.cpp:148
bool mayBeDummyArgOrHostAssoc() const
Definition AliasAnalysis.cpp:197
bool approximateSource
Definition AliasAnalysis.h:150
bool mayBeActualArgWithPtr(const mlir::Value *val) const
Definition AliasAnalysis.cpp:216
mlir::Type valueType
Value type of the source definition.
Definition AliasAnalysis.h:145
bool isCrayPointerOrPointee() const
Return true, if CrayPointer or CrayPointee attribute is set.
Definition AliasAnalysis.cpp:169
bool isTarget() const
Return true, if Target attribute is set.
Definition AliasAnalysis.cpp:153
bool mayBeActualArg() const
The address of an actual argument of the current function?
Definition AliasAnalysis.cpp:212
Definition AliasAnalysis.h:25
mlir::AliasResult alias(Source lhsSrc, Source rhsSrc, mlir::Value lhs, mlir::Value rhs)
Given the values and their sources, return their aliasing behavior.
Definition AliasAnalysis.cpp:239
static bool isPointerReference(mlir::Type ty)
Definition AliasAnalysis.cpp:140
ENUM_CLASS(Attribute, Target, Pointer, IntentIn, CrayPointer, CrayPointee)
Attributes of the memory source object.
ENUM_CLASS(SourceKind, Allocate, Global, Argument, HostAssoc, Indirect, Unknown)
Kind of the memory source referenced by a value.
fir::AliasAnalysis::Source getSource(mlir::Value, bool getLastInstantiationPoint=false)
Definition AliasAnalysis.cpp:603
mlir::ModRefResult getModRef(mlir::Operation *op, mlir::Value location)
Return the modify-reference behavior of op on location.