@@ -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) {
5856namespace fir {
5957
6058void 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+
8399bool 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
0 commit comments