@@ -685,7 +685,9 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
685685// / the function, with global constants being considered local to all
686686// / functions.
687687bool BasicAAResult::pointsToConstantMemory (const MemoryLocation &Loc,
688- AAQueryInfo &AAQI, bool OrLocal) {
688+ AAQueryInfo &AAQI,
689+ bool OrLocal,
690+ bool OrInvariant) {
689691 assert (Visited.empty () && " Visited must be cleared after use!" );
690692 auto _ = make_scope_exit ([&]{ Visited.clear (); });
691693
@@ -695,7 +697,16 @@ bool BasicAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
695697 do {
696698 const Value *V = getUnderlyingObject (Worklist.pop_back_val ());
697699 if (!Visited.insert (V).second )
698- return AAResultBase::pointsToConstantMemory (Loc, AAQI, OrLocal);
700+ return AAResultBase::pointsToConstantMemory (Loc, AAQI, OrLocal, OrInvariant);
701+
702+ // A readonly, noalias argument is invariant for the entire lifetime of the
703+ // SSA value.
704+ if (OrInvariant) {
705+ if (const Argument *Arg = dyn_cast<Argument>(V)) {
706+ if (Arg->hasNoAliasAttr () && Arg->hasAttribute (Attribute::ReadOnly))
707+ continue ;
708+ }
709+ }
699710
700711 // An alloca instruction defines local memory.
701712 if (OrLocal && isa<AllocaInst>(V))
@@ -707,7 +718,7 @@ bool BasicAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
707718 // global to be marked constant in some modules and non-constant in
708719 // others. GV may even be a declaration, not a definition.
709720 if (!GV->isConstant ())
710- return AAResultBase::pointsToConstantMemory (Loc, AAQI, OrLocal);
721+ return AAResultBase::pointsToConstantMemory (Loc, AAQI, OrLocal, OrInvariant );
711722 continue ;
712723 }
713724
@@ -723,13 +734,13 @@ bool BasicAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
723734 if (const PHINode *PN = dyn_cast<PHINode>(V)) {
724735 // Don't bother inspecting phi nodes with many operands.
725736 if (PN->getNumIncomingValues () > MaxLookup)
726- return AAResultBase::pointsToConstantMemory (Loc, AAQI, OrLocal);
737+ return AAResultBase::pointsToConstantMemory (Loc, AAQI, OrLocal, OrInvariant );
727738 append_range (Worklist, PN->incoming_values ());
728739 continue ;
729740 }
730741
731742 // Otherwise be conservative.
732- return AAResultBase::pointsToConstantMemory (Loc, AAQI, OrLocal);
743+ return AAResultBase::pointsToConstantMemory (Loc, AAQI, OrLocal, OrInvariant );
733744 } while (!Worklist.empty () && --MaxLookup);
734745
735746 return Worklist.empty ();
@@ -866,20 +877,10 @@ AliasResult BasicAAResult::alias(const MemoryLocation &LocA,
866877 return aliasCheck (LocA.Ptr , LocA.Size , LocB.Ptr , LocB.Size , AAQI);
867878}
868879
869- // / Checks to see if the specified callsite can clobber the specified memory
870- // / object.
871- // /
872- // / Since we only look at local properties of this function, we really can't
873- // / say much about this query. We do, however, use simple "address taken"
874- // / analysis on local objects.
875- ModRefInfo BasicAAResult::getModRefInfo (const CallBase *Call,
876- const MemoryLocation &Loc,
877- AAQueryInfo &AAQI) {
878- assert (notDifferentParent (Call, Loc.Ptr ) &&
879- " AliasAnalysis query involving multiple functions!" );
880-
881- const Value *Object = getUnderlyingObject (Loc.Ptr );
882-
880+ ModRefInfo BasicAAResult::getModRefInfoForObject (const CallBase *Call,
881+ const Value *Object,
882+ const MemoryLocation &Loc,
883+ AAQueryInfo &AAQI) {
883884 // Calls marked 'tail' cannot read or write allocas from the current frame
884885 // because the current frame might be destroyed by the time they run. However,
885886 // a tail call may use an alloca with byval. Calling with byval copies the
@@ -998,6 +999,32 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
998999 return AAResultBase::getModRefInfo (Call, Loc, AAQI);
9991000}
10001001
1002+ // / Checks to see if the specified callsite can clobber the specified memory
1003+ // / object.
1004+ // /
1005+ // / Since we only look at local properties of this function, we really can't
1006+ // / say much about this query. We do, however, use simple "address taken"
1007+ // / analysis on local objects.
1008+ ModRefInfo BasicAAResult::getModRefInfo (const CallBase *Call,
1009+ const MemoryLocation &Loc,
1010+ AAQueryInfo &AAQI) {
1011+ assert (notDifferentParent (Call, Loc.Ptr ) &&
1012+ " AliasAnalysis query involving multiple functions!" );
1013+
1014+ const Value *Object = getUnderlyingObject (Loc.Ptr );
1015+
1016+ ModRefInfo MRI = getModRefInfoForObject (Call, Object, Loc, AAQI);
1017+
1018+ /*
1019+ if (const Argument *Arg = dyn_cast<Argument>(Object)) {
1020+ if (Arg->hasNoAliasAttr() && Arg->hasAttribute(Attribute::ReadOnly) && isModSet(MRI))
1021+ MRI = isRefSet(MRI) ? ModRefInfo::Ref : ModRefInfo::NoModRef;
1022+ }
1023+ */
1024+
1025+ return MRI;
1026+ }
1027+
10011028ModRefInfo BasicAAResult::getModRefInfo (const CallBase *Call1,
10021029 const CallBase *Call2,
10031030 AAQueryInfo &AAQI) {
0 commit comments