Skip to content

Commit 87a571a

Browse files
committed
WIP: pointsToConstantMemory readonly noalias support
1 parent 4763dd6 commit 87a571a

13 files changed

Lines changed: 96 additions & 56 deletions

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -579,14 +579,17 @@ class AAResults {
579579
AliasResult::MustAlias;
580580
}
581581

582-
/// Checks whether the given location points to constant memory, or if
583-
/// \p OrLocal is true whether it points to a local alloca.
584-
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false);
582+
/// Checks whether the given location points to constant memory.
583+
/// If \p OrLocal is true, returns true if the memory points to a local alloca.
584+
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false,
585+
bool OrInvariant = false);
585586

586587
/// A convenience wrapper around the primary \c pointsToConstantMemory
587588
/// interface.
588-
bool pointsToConstantMemory(const Value *P, bool OrLocal = false) {
589-
return pointsToConstantMemory(MemoryLocation::getBeforeOrAfter(P), OrLocal);
589+
bool pointsToConstantMemory(const Value *P, bool OrLocal = false,
590+
bool OrInvariant = false) {
591+
return pointsToConstantMemory(MemoryLocation::getBeforeOrAfter(P), OrLocal,
592+
OrInvariant);
590593
}
591594

592595
/// @}
@@ -835,7 +838,7 @@ class AAResults {
835838
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
836839
AAQueryInfo &AAQI);
837840
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
838-
bool OrLocal = false);
841+
bool OrLocal = false, bool OrInvariant = false);
839842
ModRefInfo getModRefInfo(Instruction *I, const CallBase *Call2,
840843
AAQueryInfo &AAQIP);
841844
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
@@ -901,8 +904,9 @@ class BatchAAResults {
901904
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
902905
return AA.alias(LocA, LocB, AAQI);
903906
}
904-
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) {
905-
return AA.pointsToConstantMemory(Loc, AAQI, OrLocal);
907+
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false,
908+
bool OrInvariant = false) {
909+
return AA.pointsToConstantMemory(Loc, AAQI, OrLocal, OrInvariant);
906910
}
907911
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc) {
908912
return AA.getModRefInfo(Call, Loc, AAQI);
@@ -969,7 +973,8 @@ class AAResults::Concept {
969973
/// Checks whether the given location points to constant memory, or if
970974
/// \p OrLocal is true whether it points to a local alloca.
971975
virtual bool pointsToConstantMemory(const MemoryLocation &Loc,
972-
AAQueryInfo &AAQI, bool OrLocal) = 0;
976+
AAQueryInfo &AAQI, bool OrLocal,
977+
bool OrInvariant) = 0;
973978

974979
/// @}
975980
//===--------------------------------------------------------------------===//
@@ -1025,8 +1030,8 @@ template <typename AAResultT> class AAResults::Model final : public Concept {
10251030
}
10261031

10271032
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
1028-
bool OrLocal) override {
1029-
return Result.pointsToConstantMemory(Loc, AAQI, OrLocal);
1033+
bool OrLocal, bool OrInvariant) override {
1034+
return Result.pointsToConstantMemory(Loc, AAQI, OrLocal, OrInvariant);
10301035
}
10311036

10321037
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) override {
@@ -1080,7 +1085,7 @@ class AAResultBase {
10801085
}
10811086

10821087
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
1083-
bool OrLocal) {
1088+
bool OrLocal, bool OrInvariant) {
10841089
return false;
10851090
}
10861091

llvm/include/llvm/Analysis/BasicAliasAnalysis.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class BasicAAResult : public AAResultBase {
7777

7878
/// Chases pointers until we find a (constant global) or not.
7979
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
80-
bool OrLocal);
80+
bool OrLocal, bool OrInvariant);
8181

8282
/// Get the location associated with a pointer argument of a callsite.
8383
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx);
@@ -154,6 +154,11 @@ class BasicAAResult : public AAResultBase {
154154
const Value *V2, LocationSize V2Size,
155155
AAQueryInfo &AAQI, const Value *O1,
156156
const Value *O2);
157+
158+
ModRefInfo getModRefInfoForObject(const CallBase *Call,
159+
const Value *Object,
160+
const MemoryLocation &Loc,
161+
AAQueryInfo &AAQI);
157162
};
158163

159164
/// Analysis pass providing a never-invalidated alias analysis result.

llvm/include/llvm/Analysis/ObjCARCAliasAnalysis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class ObjCARCAAResult : public AAResultBase {
5353
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
5454
AAQueryInfo &AAQI);
5555
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
56-
bool OrLocal);
56+
bool OrLocal, bool OrInvariant);
5757

5858
using AAResultBase::getModRefBehavior;
5959
FunctionModRefBehavior getModRefBehavior(const Function *F);

llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class TypeBasedAAResult : public AAResultBase {
4141
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
4242
AAQueryInfo &AAQI);
4343
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
44-
bool OrLocal);
44+
bool OrLocal, bool OrInvariant);
4545
FunctionModRefBehavior getModRefBehavior(const CallBase *Call,
4646
AAQueryInfo &AAQI);
4747
FunctionModRefBehavior getModRefBehavior(const Function *F);

llvm/lib/Analysis/AliasAnalysis.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,16 @@ AliasResult AAResults::alias(const MemoryLocation &LocA,
148148
}
149149

150150
bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
151-
bool OrLocal) {
151+
bool OrLocal, bool OrInvariant) {
152152
SimpleAAQueryInfo AAQIP(*this);
153-
return pointsToConstantMemory(Loc, AAQIP, OrLocal);
153+
return pointsToConstantMemory(Loc, AAQIP, OrLocal, OrInvariant);
154154
}
155155

156156
bool AAResults::pointsToConstantMemory(const MemoryLocation &Loc,
157-
AAQueryInfo &AAQI, bool OrLocal) {
157+
AAQueryInfo &AAQI, bool OrLocal,
158+
bool OrInvariant) {
158159
for (const auto &AA : AAs)
159-
if (AA->pointsToConstantMemory(Loc, AAQI, OrLocal))
160+
if (AA->pointsToConstantMemory(Loc, AAQI, OrLocal, OrInvariant))
160161
return true;
161162

162163
return false;
@@ -256,7 +257,7 @@ ModRefInfo AAResults::getModRefInfo(const CallBase *Call,
256257

257258
// If Loc is a constant memory location, the call definitely could not
258259
// modify the memory location.
259-
if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false))
260+
if (isModSet(Result) && pointsToConstantMemory(Loc, AAQI, /*OrLocal*/ false, /*OrInvariant*/ true))
260261
Result &= ModRefInfo::Ref;
261262

262263
return Result;
@@ -514,7 +515,7 @@ ModRefInfo AAResults::getModRefInfo(const StoreInst *S,
514515

515516
// If the pointer is a pointer to constant memory, then it could not have
516517
// been modified by this store.
517-
if (pointsToConstantMemory(Loc, AAQI))
518+
if (pointsToConstantMemory(Loc, AAQI, /*OrLocal=*/ false, /*OrInvariant=*/ true))
518519
return ModRefInfo::NoModRef;
519520
}
520521

@@ -533,7 +534,7 @@ ModRefInfo AAResults::getModRefInfo(const FenceInst *S,
533534
AAQueryInfo &AAQI) {
534535
// If we know that the location is a constant memory location, the fence
535536
// cannot modify this location.
536-
if (Loc.Ptr && pointsToConstantMemory(Loc, AAQI))
537+
if (Loc.Ptr && pointsToConstantMemory(Loc, AAQI, /*OrLocal=*/ false, /*OrInvariant=*/ true))
537538
return ModRefInfo::Ref;
538539
return ModRefInfo::ModRef;
539540
}

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
687687
bool 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+
10011028
ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call1,
10021029
const CallBase *Call2,
10031030
AAQueryInfo &AAQI) {

llvm/lib/Analysis/MemoryDependenceAnalysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
525525
}
526526

527527
// Stores don't alias loads from read-only memory.
528-
if (BatchAA.pointsToConstantMemory(LoadLoc))
528+
if (BatchAA.pointsToConstantMemory(LoadLoc, /*OrLocal=*/ false, /*OrInvariant=*/ true))
529529
continue;
530530

531531
// Stores depend on may/must aliased loads.

llvm/lib/Analysis/MemorySSA.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ static bool isUseTriviallyOptimizableToLiveOnEntry(AliasAnalysisType &AA,
380380
// clobbered.
381381
if (auto *LI = dyn_cast<LoadInst>(I))
382382
return I->hasMetadata(LLVMContext::MD_invariant_load) ||
383-
AA.pointsToConstantMemory(MemoryLocation::get(LI));
383+
AA.pointsToConstantMemory(MemoryLocation::get(LI), /*OrLocal=*/ false, /*OrInvariant=*/ true);
384384
return false;
385385
}
386386

llvm/lib/Analysis/ObjCARCAliasAnalysis.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,24 @@ AliasResult ObjCARCAAResult::alias(const MemoryLocation &LocA,
6969
}
7070

7171
bool ObjCARCAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
72-
AAQueryInfo &AAQI, bool OrLocal) {
72+
AAQueryInfo &AAQI, bool OrLocal,
73+
bool OrInvariant) {
7374
if (!EnableARCOpts)
74-
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
75+
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal, OrInvariant);
7576

7677
// First, strip off no-ops, including ObjC-specific no-ops, and try making
7778
// a precise alias query.
7879
const Value *S = GetRCIdentityRoot(Loc.Ptr);
7980
if (AAResultBase::pointsToConstantMemory(
80-
MemoryLocation(S, Loc.Size, Loc.AATags), AAQI, OrLocal))
81+
MemoryLocation(S, Loc.Size, Loc.AATags), AAQI, OrLocal, OrInvariant))
8182
return true;
8283

8384
// If that failed, climb to the underlying object, including climbing through
8485
// ObjC-specific no-ops, and try making an imprecise alias query.
8586
const Value *U = GetUnderlyingObjCPtr(S);
8687
if (U != S)
8788
return AAResultBase::pointsToConstantMemory(
88-
MemoryLocation::getBeforeOrAfter(U), AAQI, OrLocal);
89+
MemoryLocation::getBeforeOrAfter(U), AAQI, OrLocal, OrInvariant);
8990

9091
// If that failed, fail. We don't need to chain here, since that's covered
9192
// by the earlier precise query.

llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,21 +387,22 @@ AliasResult TypeBasedAAResult::alias(const MemoryLocation &LocA,
387387

388388
bool TypeBasedAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
389389
AAQueryInfo &AAQI,
390-
bool OrLocal) {
390+
bool OrLocal,
391+
bool OrInvariant) {
391392
if (!EnableTBAA)
392-
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
393+
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal, OrInvariant);
393394

394395
const MDNode *M = Loc.AATags.TBAA;
395396
if (!M)
396-
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
397+
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal, OrInvariant);
397398

398399
// If this is an "immutable" type, we can assume the pointer is pointing
399400
// to constant memory.
400401
if ((!isStructPathTBAA(M) && TBAANode(M).isTypeImmutable()) ||
401402
(isStructPathTBAA(M) && TBAAStructTagNode(M).isTypeImmutable()))
402403
return true;
403404

404-
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
405+
return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal, OrInvariant);
405406
}
406407

407408
FunctionModRefBehavior

0 commit comments

Comments
 (0)