This is an archive of the discontinued LLVM Phabricator instance.

[AliasAnalysis] Return NoModRef for loads from constant memory
AbandonedPublic

Authored by aeubanks on Jun 12 2023, 12:24 PM.

Details

Summary

This noticeably increases compile times [1], but is necessary for not regressing a follow-up change to DSE that saves much more compile time.

Also update some places that assumed that all loads have a corresponding MemoryUse.

[1] https://llvm-compile-time-tracker.com/compare.php?from=9dcae2f524e7bd9c6655778fb3c4c5cac05180cb&to=a4a2b62495a63516a4f782acff1b19361906546b&stat=instructions:u

Diff Detail

Unit TestsFailed

Event Timeline

aeubanks created this revision.Jun 12 2023, 12:24 PM
aeubanks requested review of this revision.Jun 12 2023, 12:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 12 2023, 12:24 PM
aeubanks edited the summary of this revision. (Show Details)Jun 12 2023, 12:26 PM
aeubanks added reviewers: fhahn, nikic, asbirlea.

I'm concerned that this will cause us problems in the future, e.g. if we want to do MemorySSA-based GVN, because we will no longer have MemoryUses for these loads at all, even though we may want to do load CSE on them.

llvm/lib/Analysis/AliasAnalysis.cpp
482

Should probably use Loc rather than MemoryLocation::get(L) here, just like all the other methods?

nikic added inline comments.Jun 12 2023, 12:56 PM
llvm/lib/Analysis/AliasAnalysis.cpp
482

Or I guess not, if the intention is to pick up TBAA metadata from the load itself?

I'm concerned that this will cause us problems in the future, e.g. if we want to do MemorySSA-based GVN, because we will no longer have MemoryUses for these loads at all, even though we may want to do load CSE on them.

why is having a MemoryUse necessary for load CSE? can't you CSE loads of the same pointer that don't have a MemoryUse?

llvm/lib/Analysis/AliasAnalysis.cpp
482

yeah exactly

I'm concerned that this will cause us problems in the future, e.g. if we want to do MemorySSA-based GVN, because we will no longer have MemoryUses for these loads at all, even though we may want to do load CSE on them.

I think the issue is we can no longer determine when a true read happens.
The change likely needs to go into MSSA, have the isUseTriviallyOptimizableToLiveOnEntry check done during construction outside of optimizeUses, as a mandatory "cheap enough" optimization.
Over there the method is saying "it's true you may be a reading instruction, but you're not going to be modified by anything else anyway so you're getting optimized to LoE".
GVN still needs to account for two such MemoryUses and their relation to do CSE/PRE.

llvm/lib/Analysis/AliasAnalysis.cpp
482

I think there's subtle distinction here with the Store case below. For Store, if either MemoryLocation::get(S) OR Loc are invariable, the answer is still NoModRef, because, well, it's invariable and the store cannot modify any such locations. So the getModRefInfoMask check could go before the alias check and still be correct.

For the load, you should still return Ref when MemoryLocation::get(L) == Loc, and that's given by the alias check.
Ref means "this instructions is reading". This is true when the locations are the same (or may have some overlap), it *is* reading *that* invariant location. It is not true when the locations are different.
So the alias check is needed first, and if that one cannot prove NoAlias, the conservative answer should be Ref: "the Load instruction may be reading Loc, and I don't care that it's invariant, it may still be reading it".

aeubanks added inline comments.Jun 12 2023, 3:47 PM
llvm/lib/Analysis/AliasAnalysis.cpp
482

your response mostly makes sense to me and I'll send out a patch to update MemorySSA instead, but then should this be returning Ref since it can be read from?

aeubanks added inline comments.Jun 12 2023, 11:24 PM
llvm/lib/Analysis/AliasAnalysis.cpp
482

actually the llvm docs seem to be inconsistent

https://llvm.org/docs/AliasAnalysis.html#the-getmodrefinfomask-method says that globally constant memory is NoModRef and locally constant memory is Ref, but https://llvm.org/docs/LangRef.html#representation says that pointsToConstantMemory should return true for invariant tbaa metadata, but [pointsToConstantMemory](https://github.com/llvm/llvm-project/blob/3391bdc255f1a75c59d71c7305959e84d8d5f468/llvm/include/llvm/Analysis/AliasAnalysis.h#L388) is just a wrapper around isNoModRef(getModRefInfoMask())

I'm concerned that this will cause us problems in the future, e.g. if we want to do MemorySSA-based GVN, because we will no longer have MemoryUses for these loads at all, even though we may want to do load CSE on them.

I think the issue is we can no longer determine when a true read happens.

I think it's mostly a question of allowing uniform handling: Once you work on MSSA it is convenient if all your loads/stores are represented as memory accesses. Not having MemoryUses for invariant loads doesn't fundamentally prevent doing load CSE for them, but probably makes it a good bit more awkward. (It's something of a speculative concern though, as I don't think we really have an accepted approach on how MSSA should be introduced in GVN...)

The change likely needs to go into MSSA, have the isUseTriviallyOptimizableToLiveOnEntry check done during construction outside of optimizeUses, as a mandatory "cheap enough" optimization.
Over there the method is saying "it's true you may be a reading instruction, but you're not going to be modified by anything else anyway so you're getting optimized to LoE".

I think I'd prefer this approach.

llvm/lib/Analysis/AliasAnalysis.cpp
482

ModRefInfo works in terms of memory effects. A read from globally invariant memory is not observable, and as such NoModRef. You can reorder such a read past arbitrary modifications.

Returning NoModRef is fine (from a legality perspective) if either Loc or MemoryLocation::get(L) is globally invariant.

pointsToConstantMemory() is a legacy method with conservative behavior -- it should probably be replaced with getModRefInfoMask() that check the effects that are relevant for the transform.

aeubanks added inline comments.Jun 13 2023, 9:13 AM
llvm/lib/Analysis/AliasAnalysis.cpp
482

but loads with invariant tbaa metadata are not typically globally invariant right? the first doc says that corresponds to Ref, but the second doc says that it's ok to return NoModRef for this tbaa metadata

nikic added inline comments.Jun 13 2023, 9:50 AM
llvm/lib/Analysis/AliasAnalysis.cpp
482

Invariant TBAA metadata requires global invariance, NoModRef is correct.

aeubanks added inline comments.Jun 13 2023, 2:42 PM
llvm/lib/Analysis/AliasAnalysis.cpp
482

ah ok, although then I don't know what that'd be used for then if it required global invariance

anyway, https://reviews.llvm.org/D152859 for the MemorySSA change

aeubanks abandoned this revision.Sep 12 2023, 2:55 PM
llvm/test/Analysis/MemorySSA/constant-memory.ll