Skip to content

Commit 1cd675b

Browse files
committed
Remove SourceKind::Direct. Include data/non-data flang in source origin
1 parent 83f065d commit 1cd675b

File tree

5 files changed

+109
-91
lines changed

5 files changed

+109
-91
lines changed

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

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ struct AliasAnalysis {
3838
HostAssoc,
3939
/// Represents direct memory access whose source cannot be further
4040
/// determined
41-
Direct,
42-
/// Represents memory allocated by unknown means and
43-
/// with the memory address defined by a memory reading
44-
/// operation (e.g. fir::LoadOp).
4541
Indirect,
4642
/// Starting point to the analysis whereby nothing is known about
4743
/// the source
@@ -53,9 +49,17 @@ struct AliasAnalysis {
5349
struct Source {
5450
using SourceUnion = llvm::PointerUnion<mlir::SymbolRefAttr, mlir::Value>;
5551
using Attributes = Fortran::common::EnumSet<Attribute, Attribute_enumSize>;
52+
53+
struct SourceOrigin {
54+
/// Source definition of a value.
55+
SourceUnion u;
56+
57+
/// Whether the source was reached following data or box reference
58+
bool isData{false};
59+
};
60+
61+
SourceOrigin origin;
5662

57-
/// Source definition of a value.
58-
SourceUnion u;
5963
/// Kind of the memory source.
6064
SourceKind kind;
6165
/// Value type of the source definition.
@@ -77,6 +81,12 @@ struct AliasAnalysis {
7781
/// attribute.
7882
bool isRecordWithPointerComponent() const;
7983

84+
bool isDummyArgument() const;
85+
bool isData() const;
86+
bool isBoxData() const;
87+
88+
mlir::Type getType() const;
89+
8090
/// Return true, if `ty` is a reference type to a boxed
8191
/// POINTER object or a raw fir::PointerType.
8292
static bool isPointerReference(mlir::Type ty);
@@ -95,6 +105,15 @@ struct AliasAnalysis {
95105
Source getSource(mlir::Value);
96106
};
97107

108+
inline bool operator==(const AliasAnalysis::Source::SourceOrigin &lhs,
109+
const AliasAnalysis::Source::SourceOrigin &rhs) {
110+
return lhs.u == rhs.u && lhs.isData == rhs.isData;
111+
}
112+
inline bool operator!=(const AliasAnalysis::Source::SourceOrigin &lhs,
113+
const AliasAnalysis::Source::SourceOrigin &rhs) {
114+
return !(lhs == rhs);
115+
}
116+
98117
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
99118
const AliasAnalysis::Source &op) {
100119
op.print(os);

flang/lib/Optimizer/Analysis/AliasAnalysis.cpp

Lines changed: 51 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,9 @@ static bool isDummyArgument(mlir::Value v) {
3333
if (!blockArg)
3434
return false;
3535

36-
mlir::Block *owner = blockArg.getOwner();
37-
if (!owner->isEntryBlock() ||
38-
!mlir::isa<mlir::FunctionOpInterface>(owner->getParentOp()))
39-
return false;
40-
return true;
36+
auto *owner{blockArg.getOwner()};
37+
return owner->isEntryBlock() &&
38+
mlir::isa<mlir::FunctionOpInterface>(owner->getParentOp());
4139
}
4240

4341
/// Temporary function to skip through all the no op operations
@@ -58,12 +56,17 @@ static mlir::Value getOriginalDef(mlir::Value v) {
5856
namespace fir {
5957

6058
void AliasAnalysis::Source::print(llvm::raw_ostream &os) const {
61-
if (auto v = llvm::dyn_cast<mlir::Value>(u))
59+
if (auto v = llvm::dyn_cast<mlir::Value>(origin.u))
6260
os << v;
63-
else if (auto gbl = llvm::dyn_cast<mlir::SymbolRefAttr>(u))
61+
else if (auto gbl = llvm::dyn_cast<mlir::SymbolRefAttr>(origin.u))
6462
os << gbl;
6563
os << " SourceKind: " << EnumToString(kind);
6664
os << " Type: " << valueType << " ";
65+
if (origin.isData) {
66+
os << " following data ";
67+
} else {
68+
os << " following box reference ";
69+
}
6770
attributes.Dump(os, EnumToString);
6871
}
6972

@@ -80,6 +83,19 @@ bool AliasAnalysis::Source::isTargetOrPointer() const {
8083
attributes.test(Attribute::Target);
8184
}
8285

86+
bool AliasAnalysis::Source::isDummyArgument() const {
87+
if (auto v = origin.u.dyn_cast<mlir::Value>()) {
88+
return ::isDummyArgument(v);
89+
}
90+
return false;
91+
}
92+
93+
bool AliasAnalysis::Source::isData() const { return origin.isData; }
94+
bool AliasAnalysis::Source::isBoxData() const {
95+
return mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(valueType)) &&
96+
origin.isData;
97+
}
98+
8399
bool AliasAnalysis::Source::isRecordWithPointerComponent() const {
84100
auto eleTy = fir::dyn_cast_ptrEleTy(valueType);
85101
if (!eleTy)
@@ -101,29 +117,20 @@ AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
101117

102118
// Indirect case currently not handled. Conservatively assume
103119
// it aliases with everything
104-
if (lhsSrc.kind > SourceKind::Direct || rhsSrc.kind > SourceKind::Direct) {
120+
if (lhsSrc.kind >= SourceKind::Indirect ||
121+
rhsSrc.kind >= SourceKind::Indirect) {
105122
return AliasResult::MayAlias;
106123
}
107124

108-
// SourceKind::Direct is set for the addresses wrapped in a global boxes.
109-
// ie: fir.global @_QMpointersEp : !fir.box<!fir.ptr<f32>>
110-
// Though nothing is known about them, they would only alias with targets or
111-
// pointers
112-
bool directSourceToNonTargetOrPointer = false;
113-
if (lhsSrc.u != rhsSrc.u || lhsSrc.kind != rhsSrc.kind) {
114-
if ((lhsSrc.kind == SourceKind::Direct && !rhsSrc.isTargetOrPointer()) ||
115-
(rhsSrc.kind == SourceKind::Direct && !lhsSrc.isTargetOrPointer()))
116-
directSourceToNonTargetOrPointer = true;
117-
}
118-
119-
if (lhsSrc.kind == SourceKind::Direct ||
120-
rhsSrc.kind == SourceKind::Direct) {
121-
if (!directSourceToNonTargetOrPointer)
122-
return AliasResult::MayAlias;
125+
// If we have reached the same source but comparing box reference against
126+
// data we are not comparing apples-to-apples. The 2 cannot alias.
127+
if ((lhsSrc.origin.u == rhsSrc.origin.u) &&
128+
lhsSrc.isData() != rhsSrc.isData()) {
129+
return AliasResult::NoAlias;
123130
}
124131

125132
if (lhsSrc.kind == rhsSrc.kind) {
126-
if (lhsSrc.u == rhsSrc.u) {
133+
if (lhsSrc.origin == rhsSrc.origin) {
127134
if (approximateSource)
128135
return AliasResult::MayAlias;
129136
return AliasResult::MustAlias;
@@ -133,13 +140,9 @@ AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
133140
if (lhsSrc.kind == SourceKind::HostAssoc)
134141
return AliasResult::MayAlias;
135142

136-
// Allocate and global memory address cannot physically alias
137-
if (lhsSrc.kind == SourceKind::Allocate ||
138-
lhsSrc.kind == SourceKind::Global)
139-
return AliasResult::NoAlias;
140-
141-
// Dummy TARGET/POINTER arguments may alias.
142-
if (lhsSrc.isTargetOrPointer() && rhsSrc.isTargetOrPointer())
143+
// TARGET/POINTER arguments may alias.
144+
if (lhsSrc.isTargetOrPointer() && rhsSrc.isTargetOrPointer() &&
145+
lhsSrc.isData() == rhsSrc.isData())
143146
return AliasResult::MayAlias;
144147

145148
// Box for POINTER component inside an object of a derived type
@@ -186,7 +189,8 @@ AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
186189
}
187190

188191
// Dummy TARGET/POINTER argument may alias with a global TARGET/POINTER.
189-
if (src1->isTargetOrPointer() && src2->isTargetOrPointer())
192+
if (src1->isTargetOrPointer() && src2->isTargetOrPointer() &&
193+
src1->isData() == src2->isData())
190194
return AliasResult::MayAlias;
191195

192196
// Box for POINTER component inside an object of a derived type
@@ -262,7 +266,10 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
262266
mlir::Type ty;
263267
bool breakFromLoop{false};
264268
bool approximateSource{false};
265-
bool followBoxAddr{mlir::isa<fir::BaseBoxType>(v.getType())};
269+
bool followBoxData{mlir::isa<fir::BaseBoxType>(v.getType())};
270+
bool isBoxRef{fir::isa_ref_type(v.getType()) &&
271+
mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(v.getType()))};
272+
bool followingData = !isBoxRef || followBoxData;
266273
mlir::SymbolRefAttr global;
267274
Source::Attributes attributes;
268275
while (defOp && !breakFromLoop) {
@@ -282,24 +289,24 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
282289
v = op->getOperand(0);
283290
defOp = v.getDefiningOp();
284291
if (mlir::isa<fir::BaseBoxType>(v.getType()))
285-
followBoxAddr = true;
292+
followBoxData = true;
286293
})
287294
.Case<fir::ArrayCoorOp, fir::CoordinateOp>([&](auto op) {
288295
v = op->getOperand(0);
289296
defOp = v.getDefiningOp();
290297
if (mlir::isa<fir::BaseBoxType>(v.getType()))
291-
followBoxAddr = true;
298+
followBoxData = true;
292299
approximateSource = true;
293300
})
294301
.Case<fir::EmboxOp, fir::ReboxOp>([&](auto op) {
295-
if (followBoxAddr) {
302+
if (followBoxData) {
296303
v = op->getOperand(0);
297304
defOp = v.getDefiningOp();
298305
} else
299306
breakFromLoop = true;
300307
})
301308
.Case<fir::LoadOp>([&](auto op) {
302-
if (followBoxAddr && mlir::isa<fir::BaseBoxType>(op.getType())) {
309+
if (followBoxData && mlir::isa<fir::BaseBoxType>(op.getType())) {
303310
// For now, support the load of an argument or fir.address_of
304311
// TODO: generalize to all operations (in particular fir.alloca and
305312
// fir.allocmem)
@@ -318,36 +325,18 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
318325
.Case<fir::AddrOfOp>([&](auto op) {
319326
// Address of a global scope object.
320327
ty = v.getType();
321-
322-
// When the global is a
323-
// fir.global @_QMpointersEp : !fir.box<!fir.ptr<f32>>
324-
// or
325-
// fir.global @_QMpointersEp : !fir.box<!fir.heap<f32>>
326-
//
327-
// and when following through the wrapped address, capture
328-
// the fact that there is nothing known about it. Therefore setting
329-
// the source to Direct.
330-
//
331-
// When not following the wrapped address, then consider the address
332-
// of the box, which has nothing to do with the wrapped address and
333-
// lies in the global memory space.
334-
if (followBoxAddr &&
335-
mlir::isa<fir::BaseBoxType>(fir::unwrapRefType(ty)))
336-
type = SourceKind::Direct;
337-
else
338-
type = SourceKind::Global;
328+
type = SourceKind::Global;
339329

340330
auto globalOpName = mlir::OperationName(
341331
fir::GlobalOp::getOperationName(), defOp->getContext());
342332
if (fir::valueHasFirAttribute(
343333
v, fir::GlobalOp::getTargetAttrName(globalOpName)))
344334
attributes.set(Attribute::Target);
345335

346-
// TODO: Take followBoxAddr into account when setting the pointer
336+
// TODO: Take followBoxData into account when setting the pointer
347337
// attribute
348338
if (Source::isPointerReference(ty))
349339
attributes.set(Attribute::Pointer);
350-
351340
global = llvm::cast<fir::AddrOfOp>(op).getSymbol();
352341
breakFromLoop = true;
353342
})
@@ -393,7 +382,7 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
393382
// MustAlias after going through a designate operation
394383
approximateSource = true;
395384
if (mlir::isa<fir::BaseBoxType>(v.getType()))
396-
followBoxAddr = true;
385+
followBoxData = true;
397386
})
398387
.Default([&](auto op) {
399388
defOp = nullptr;
@@ -412,10 +401,10 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
412401
attributes.set(Attribute::Pointer);
413402
}
414403

415-
if (type == SourceKind::Global || type == SourceKind::Direct)
416-
return {global, type, ty, attributes, approximateSource};
417-
418-
return {v, type, ty, attributes, approximateSource};
404+
if (type == SourceKind::Global) {
405+
return {{global, followingData}, type, ty, attributes, approximateSource};
406+
}
407+
return {{v, followingData}, type, ty, attributes, approximateSource};
419408
}
420409

421410
} // namespace fir

flang/lib/Optimizer/Transforms/AddAliasTags.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
145145
source.kind == fir::AliasAnalysis::SourceKind::Argument) {
146146
LLVM_DEBUG(llvm::dbgs().indent(2)
147147
<< "Found reference to dummy argument at " << *op << "\n");
148-
std::string name = getFuncArgName(source.u.get<mlir::Value>());
148+
std::string name = getFuncArgName(source.origin.u.get<mlir::Value>());
149149
if (!name.empty())
150150
tag = state.getFuncTree(func).dummyArgDataTree.getTag(name);
151151
else
@@ -155,18 +155,17 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
155155

156156
// TBAA for global variables
157157
} else if (enableGlobals &&
158-
source.kind == fir::AliasAnalysis::SourceKind::Global) {
159-
mlir::SymbolRefAttr glbl = source.u.get<mlir::SymbolRefAttr>();
158+
source.kind == fir::AliasAnalysis::SourceKind::Global && !source.isBoxData()) {
159+
mlir::SymbolRefAttr glbl = source.origin.u.get<mlir::SymbolRefAttr>();
160160
const char *name = glbl.getRootReference().data();
161161
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to global " << name
162162
<< " at " << *op << "\n");
163163
tag = state.getFuncTree(func).globalDataTree.getTag(name);
164164

165165
// TBAA for SourceKind::Direct
166-
} else if (enableDirect &&
167-
source.kind == fir::AliasAnalysis::SourceKind::Direct) {
168-
if (source.u.is<mlir::SymbolRefAttr>()) {
169-
mlir::SymbolRefAttr glbl = source.u.get<mlir::SymbolRefAttr>();
166+
} else if (enableDirect && source.isBoxData()) {
167+
if (source.origin.u.is<mlir::SymbolRefAttr>()) {
168+
mlir::SymbolRefAttr glbl = source.origin.u.get<mlir::SymbolRefAttr>();
170169
const char *name = glbl.getRootReference().data();
171170
LLVM_DEBUG(llvm::dbgs().indent(2) << "Found reference to direct " << name
172171
<< " at " << *op << "\n");
@@ -182,7 +181,7 @@ void AddAliasTagsPass::runOnAliasInterface(fir::FirAliasTagOpInterface op,
182181
} else if (enableLocalAllocs &&
183182
source.kind == fir::AliasAnalysis::SourceKind::Allocate) {
184183
std::optional<llvm::StringRef> name;
185-
mlir::Operation *sourceOp = source.u.get<mlir::Value>().getDefiningOp();
184+
mlir::Operation *sourceOp = source.origin.u.get<mlir::Value>().getDefiningOp();
186185
if (auto alloc = mlir::dyn_cast_or_null<fir::AllocaOp>(sourceOp))
187186
name = alloc.getUniqName();
188187
else if (auto alloc = mlir::dyn_cast_or_null<fir::AllocMemOp>(sourceOp))

0 commit comments

Comments
 (0)