-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[flang] AliasAnalysis: Fix pointer component logic #94242
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
Changes from 1 commit
484cb90
9f6d2a7
78fc160
4273b38
492efb3
9b4d39a
ad0438c
1e5fdd4
3e48239
bec0399
776a17d
09e91c6
4a73682
ee248f5
a61be3a
ea40a25
ba8e749
b14ff32
b31f352
553cf74
285c2ce
27f1d94
aa4bb45
0766eba
942a625
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,13 +17,13 @@ | |
| // end module | ||
|
|
||
|
||
| // CHECK-LABEL: Testing : "_QMmPfoo" | ||
| // TODO: x and y are non pointer, non target argument and therefore do not alias. | ||
| // CHECK-DAG: x#0 <-> y#0: MayAlias | ||
| // x and y are non pointer, non target argument and therefore do not alias. | ||
| // CHECK-DAG: x#0 <-> y#0: NoAlias | ||
|
|
||
| // TODO: y is not a pointer object and therefore does not alias with the x%next component. | ||
| // Also assigning x to y would not modify x.next | ||
| // CHECK-DAG: y#0 <-> xnext1#0: MayAlias | ||
| // CHECK-DAG: y#0 <-> xnext2#0: MayAlias | ||
| // y is not a pointer object and therefore does not alias with the x%next | ||
| // component. Also assigning x to y would not modify x.next | ||
| // CHECK-DAG: y#0 <-> xnext1#0: NoAlias | ||
| // CHECK-DAG: y#0 <-> xnext2#0: NoAlias | ||
|
|
||
| // We need to catch the fact that assigning y to x will modify xnext. | ||
| // The only side-effect between the 2 loads of x.next is the assignment to x, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Renaud-K posted the following comment as part of a commit, and I'm trying to move the conversation into this PR:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Renaud-K I could extend
Sourcewith a field likebool component;It would be set to true for anyDesignateOpspecifying a component, andapproximateSourcewould also still be set to true then. Does that seem like a reasonable direction to try?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DesignateOpis later lowered tocoordinate_offor instance. The absence of which does not mean we are not dealing with a component. The alias analysis has to work at all levels. Again,fir.coordinate_of %memref %c0is the same as%memref. We need to provide consistent results whetherfir.coordinate_ofis present or at least error on the conservative side.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. In a simple example, I see that
becomes
The latter pattern seems simple enough to detect. I did not find a later version of that IR where
fir.coordinate_ofappeared but!fir.fieldandfir.field_indexhad been optimized away. Is yourfir.coordinate_of %memref %c0an example of that?Is it true that either
hlfir.designateorfir.coordinate_ofmust be present when accessing a component? If not, then, independently of this PR, we riskapproximateSource=falseand an invalid MustAlias, right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MustAlias is correct if we can determine the source more accurately, and MayAlias is a conservative error. But in your case we could go from MayAlias (because we detect components) to NoAlias which is too optimistic. Maybe we can keep using the type, such as, if the type of the source is a derived type and the type of the starting point is not then we have a component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To finish the thought, I don't see why we have to give up (SourceKind=Indirect forces MayAlias) on tracking aliasing for a pointer just because it's a member of an alloca rather than the entire alloca.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern would be to modify getOriginalDef to return anything other than Source::Indirect.
%11with the designate case is always indirect. We have no idea what was stored in%9, it could a global, an allocatable or a dummy: we do not know.There is room to improve on SourceKind::Indirect, such as using the type system to distinguish !fir.ptr from other memory references but that would be a different discussion. In the example just above,
%11would then be indirect too since we are following the data and not interested in the box address which happens to be an SourceKind::Alloca. Today, I would guess, we would get SourceKind::Alloca with an isData flag but it would be better modeled with SourceKind::Indirect and isData. Then we could do with SourceKind::Indirect what we used to do clumsily with SourceKind::Direct.But I think, we should take it one step at a time. It would impact @tblah who is handling the (global, isData) separately. These two would become (indirect, isData)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the record, getOriginalDef does not itself choose a SourceKind. Moreover, after getSource's LoadOp case calls getOriginalDef, getSource currently returns any of Indirect, Argument, or Global. That is true independently of this patch. No modification required.
(As you have noted, there are cases like alloca that getSource's LoadOp case doesn't currently fully handle. As a result, it currently returns Indirect sometimes where, for consistency with the current handling of dummy args and globals, it should return Allocate.)
In that example, what was stored in %9 is the address of the pointer. In my above example without hlfir.designate, %3 is the address of the pointer. As far as I understand, the difference between those is whether that address is at a base address (for a global, dummy arg, alloca, etc.) or at an offset from that base address.
I don't see why that difference should affect the SourceKind for any value that is computed from the address of the pointer. In particular, if the source origin (i.e., %2) were a dummy arg or global, the SourceKind for %11 in my above example without hflir.designate would currently be Argument or Global, but the SourceKind for %11 in my above example with hlfir.designate would currently be Indirect. I see no reason for that difference. In a later patch, I would like to fix that. (Again, I would also like to add support for the alloca/Allocate case shown in the examples.)
Whatever we decide to call the SourceKind for that case, do we agree that hlfir.designate should not change the SourceKind for %11 between my previous two examples?
Agreed. Hopefully the current patch I'm trying to develop can be a next step.
Where is the discussion of his work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdenny-ornl my work was proposed here https://discourse.llvm.org/t/rfc-propagate-fir-alias-analysis-information-using-tbaa/73755
There have since been changes since then to add support for Direct variables: 6242c8c
I think in this case the proposed changes won't alter the TBAA tags. My pass doesn't tag SourceKind::Alloca (by default) or SourceKind::Indirect (at all) (there are still TBAA tags added later during codegen to distinguish box metadata access from data access, but that is different again).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tblah Thanks for the pointers!