@@ -33,11 +33,9 @@ static bool isDummyArgument(mlir::Value v) {
33
33
if (!blockArg)
34
34
return false ;
35
35
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 ());
41
39
}
42
40
43
41
// / Temporary function to skip through all the no op operations
@@ -58,12 +56,17 @@ static mlir::Value getOriginalDef(mlir::Value v) {
58
56
namespace fir {
59
57
60
58
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 ))
62
60
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 ))
64
62
os << gbl;
65
63
os << " SourceKind: " << EnumToString (kind);
66
64
os << " Type: " << valueType << " " ;
65
+ if (origin.isData ) {
66
+ os << " following data " ;
67
+ } else {
68
+ os << " following box reference " ;
69
+ }
67
70
attributes.Dump (os, EnumToString);
68
71
}
69
72
@@ -80,6 +83,19 @@ bool AliasAnalysis::Source::isTargetOrPointer() const {
80
83
attributes.test (Attribute::Target);
81
84
}
82
85
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
+
83
99
bool AliasAnalysis::Source::isRecordWithPointerComponent () const {
84
100
auto eleTy = fir::dyn_cast_ptrEleTy (valueType);
85
101
if (!eleTy)
@@ -101,29 +117,20 @@ AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
101
117
102
118
// Indirect case currently not handled. Conservatively assume
103
119
// 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) {
105
122
return AliasResult::MayAlias;
106
123
}
107
124
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;
123
130
}
124
131
125
132
if (lhsSrc.kind == rhsSrc.kind ) {
126
- if (lhsSrc.u == rhsSrc.u ) {
133
+ if (lhsSrc.origin == rhsSrc.origin ) {
127
134
if (approximateSource)
128
135
return AliasResult::MayAlias;
129
136
return AliasResult::MustAlias;
@@ -133,13 +140,9 @@ AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
133
140
if (lhsSrc.kind == SourceKind::HostAssoc)
134
141
return AliasResult::MayAlias;
135
142
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 ())
143
146
return AliasResult::MayAlias;
144
147
145
148
// Box for POINTER component inside an object of a derived type
@@ -186,7 +189,8 @@ AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
186
189
}
187
190
188
191
// 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 ())
190
194
return AliasResult::MayAlias;
191
195
192
196
// Box for POINTER component inside an object of a derived type
@@ -262,7 +266,10 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
262
266
mlir::Type ty;
263
267
bool breakFromLoop{false };
264
268
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;
266
273
mlir::SymbolRefAttr global;
267
274
Source::Attributes attributes;
268
275
while (defOp && !breakFromLoop) {
@@ -282,24 +289,24 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
282
289
v = op->getOperand (0 );
283
290
defOp = v.getDefiningOp ();
284
291
if (mlir::isa<fir::BaseBoxType>(v.getType ()))
285
- followBoxAddr = true ;
292
+ followBoxData = true ;
286
293
})
287
294
.Case <fir::ArrayCoorOp, fir::CoordinateOp>([&](auto op) {
288
295
v = op->getOperand (0 );
289
296
defOp = v.getDefiningOp ();
290
297
if (mlir::isa<fir::BaseBoxType>(v.getType ()))
291
- followBoxAddr = true ;
298
+ followBoxData = true ;
292
299
approximateSource = true ;
293
300
})
294
301
.Case <fir::EmboxOp, fir::ReboxOp>([&](auto op) {
295
- if (followBoxAddr ) {
302
+ if (followBoxData ) {
296
303
v = op->getOperand (0 );
297
304
defOp = v.getDefiningOp ();
298
305
} else
299
306
breakFromLoop = true ;
300
307
})
301
308
.Case <fir::LoadOp>([&](auto op) {
302
- if (followBoxAddr && mlir::isa<fir::BaseBoxType>(op.getType ())) {
309
+ if (followBoxData && mlir::isa<fir::BaseBoxType>(op.getType ())) {
303
310
// For now, support the load of an argument or fir.address_of
304
311
// TODO: generalize to all operations (in particular fir.alloca and
305
312
// fir.allocmem)
@@ -318,36 +325,18 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
318
325
.Case <fir::AddrOfOp>([&](auto op) {
319
326
// Address of a global scope object.
320
327
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;
339
329
340
330
auto globalOpName = mlir::OperationName (
341
331
fir::GlobalOp::getOperationName (), defOp->getContext ());
342
332
if (fir::valueHasFirAttribute (
343
333
v, fir::GlobalOp::getTargetAttrName (globalOpName)))
344
334
attributes.set (Attribute::Target);
345
335
346
- // TODO: Take followBoxAddr into account when setting the pointer
336
+ // TODO: Take followBoxData into account when setting the pointer
347
337
// attribute
348
338
if (Source::isPointerReference (ty))
349
339
attributes.set (Attribute::Pointer);
350
-
351
340
global = llvm::cast<fir::AddrOfOp>(op).getSymbol ();
352
341
breakFromLoop = true ;
353
342
})
@@ -393,7 +382,7 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
393
382
// MustAlias after going through a designate operation
394
383
approximateSource = true ;
395
384
if (mlir::isa<fir::BaseBoxType>(v.getType ()))
396
- followBoxAddr = true ;
385
+ followBoxData = true ;
397
386
})
398
387
.Default ([&](auto op) {
399
388
defOp = nullptr ;
@@ -412,10 +401,10 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v) {
412
401
attributes.set (Attribute::Pointer);
413
402
}
414
403
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};
419
408
}
420
409
421
410
} // namespace fir
0 commit comments