Skip to content

Commit bfc779e

Browse files
committed
[AliasAnalysis] Second prototype to cache BasicAA / anyAA state.
Summary: Adding contained caching to AliasAnalysis. BasicAA is currently the only one using it. AA changes: - This patch is pulling the caches from BasicAAResults to AAResults, meaning the getModRefInfo call benefits from the IsCapturedCache as well when in "batch mode". - All AAResultBase implementations add the QueryInfo member to all APIs. AAResults APIs maintain wrapper APIs such that all alias()/getModRefInfo call sites are unchanged. - AA now provides a BatchAAResults type as a wrapper to AAResults. It keeps the AAResults instance and a QueryInfo instantiated to batch mode. It delegates all work to the AAResults instance with the batched QueryInfo. More API wrappers may be needed in BatchAAResults; only the minimum needed is currently added. MemorySSA changes: - All walkers are now templated on the AA used (AliasAnalysis=AAResults or BatchAAResults). - At build time, we optimize uses; now we create a local walker (lives only as long as OptimizeUses does) using BatchAAResults. - All Walkers have an internal AA and only use that now, never the AA in MemorySSA. The Walkers receive the AA they will use when built. - The walker we use for queries after the build is instantiated on AliasAnalysis and is built after building MemorySSA and setting AA. - All static methods doing walking are now templated on AliasAnalysisType if they are used both during build and after. If used only during build, the method now only takes a BatchAAResults. If used only after build, the method now takes an AliasAnalysis. Subscribers: sanjoy, arsenm, jvesely, nhaehnle, jlebar, george.burgess.iv, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59315 llvm-svn: 356783
1 parent d627048 commit bfc779e

23 files changed

+587
-327
lines changed

llvm/include/llvm/Analysis/AliasAnalysis.h

Lines changed: 170 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
3838
#define LLVM_ANALYSIS_ALIASANALYSIS_H
3939

40+
#include "llvm/ADT/DenseMap.h"
4041
#include "llvm/ADT/None.h"
4142
#include "llvm/ADT/Optional.h"
4243
#include "llvm/ADT/SmallVector.h"
@@ -285,6 +286,28 @@ createModRefInfo(const FunctionModRefBehavior FMRB) {
285286
return ModRefInfo(FMRB & static_cast<int>(ModRefInfo::ModRef));
286287
}
287288

289+
/// This class stores info we want to provide to or retain within an alias
290+
/// query. By default, the root query is stateless and starts with a freshly
291+
/// constructed info object. Specific alias analyses can use this query info to
292+
/// store per-query state that is important for recursive or nested queries to
293+
/// avoid recomputing. To enable preserving this state across multiple queries
294+
/// where safe (due to the IR not changing), use a `BatchAAResults` wrapper.
295+
/// The information stored in an `AAQueryInfo` is currently limitted to the
296+
/// caches used by BasicAA, but can further be extended to fit other AA needs.
297+
class AAQueryInfo {
298+
public:
299+
using LocPair = std::pair<MemoryLocation, MemoryLocation>;
300+
using AliasCacheT = SmallDenseMap<LocPair, AliasResult, 8>;
301+
AliasCacheT AliasCache;
302+
303+
using IsCapturedCacheT = SmallDenseMap<const Value *, bool, 8>;
304+
IsCapturedCacheT IsCapturedCache;
305+
306+
AAQueryInfo() : AliasCache(), IsCapturedCache() {}
307+
};
308+
309+
class BatchAAResults;
310+
288311
class AAResults {
289312
public:
290313
// Make these results default constructable and movable. We have to spell
@@ -599,32 +622,8 @@ class AAResults {
599622
/// helpers above.
600623
ModRefInfo getModRefInfo(const Instruction *I,
601624
const Optional<MemoryLocation> &OptLoc) {
602-
if (OptLoc == None) {
603-
if (const auto *Call = dyn_cast<CallBase>(I)) {
604-
return createModRefInfo(getModRefBehavior(Call));
605-
}
606-
}
607-
608-
const MemoryLocation &Loc = OptLoc.getValueOr(MemoryLocation());
609-
610-
switch (I->getOpcode()) {
611-
case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc);
612-
case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc);
613-
case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc);
614-
case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc);
615-
case Instruction::AtomicCmpXchg:
616-
return getModRefInfo((const AtomicCmpXchgInst*)I, Loc);
617-
case Instruction::AtomicRMW:
618-
return getModRefInfo((const AtomicRMWInst*)I, Loc);
619-
case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc);
620-
case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc);
621-
case Instruction::CatchPad:
622-
return getModRefInfo((const CatchPadInst *)I, Loc);
623-
case Instruction::CatchRet:
624-
return getModRefInfo((const CatchReturnInst *)I, Loc);
625-
default:
626-
return ModRefInfo::NoModRef;
627-
}
625+
AAQueryInfo AAQIP;
626+
return getModRefInfo(I, OptLoc, AAQIP);
628627
}
629628

630629
/// A convenience wrapper for constructing the memory location.
@@ -691,6 +690,69 @@ class AAResults {
691690
}
692691

693692
private:
693+
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
694+
AAQueryInfo &AAQI);
695+
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
696+
bool OrLocal = false);
697+
ModRefInfo getModRefInfo(Instruction *I, const CallBase *Call2,
698+
AAQueryInfo &AAQIP);
699+
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
700+
AAQueryInfo &AAQI);
701+
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
702+
AAQueryInfo &AAQI);
703+
ModRefInfo getModRefInfo(const VAArgInst *V, const MemoryLocation &Loc,
704+
AAQueryInfo &AAQI);
705+
ModRefInfo getModRefInfo(const LoadInst *L, const MemoryLocation &Loc,
706+
AAQueryInfo &AAQI);
707+
ModRefInfo getModRefInfo(const StoreInst *S, const MemoryLocation &Loc,
708+
AAQueryInfo &AAQI);
709+
ModRefInfo getModRefInfo(const FenceInst *S, const MemoryLocation &Loc,
710+
AAQueryInfo &AAQI);
711+
ModRefInfo getModRefInfo(const AtomicCmpXchgInst *CX,
712+
const MemoryLocation &Loc, AAQueryInfo &AAQI);
713+
ModRefInfo getModRefInfo(const AtomicRMWInst *RMW, const MemoryLocation &Loc,
714+
AAQueryInfo &AAQI);
715+
ModRefInfo getModRefInfo(const CatchPadInst *I, const MemoryLocation &Loc,
716+
AAQueryInfo &AAQI);
717+
ModRefInfo getModRefInfo(const CatchReturnInst *I, const MemoryLocation &Loc,
718+
AAQueryInfo &AAQI);
719+
ModRefInfo getModRefInfo(const Instruction *I,
720+
const Optional<MemoryLocation> &OptLoc,
721+
AAQueryInfo &AAQIP) {
722+
if (OptLoc == None) {
723+
if (const auto *Call = dyn_cast<CallBase>(I)) {
724+
return createModRefInfo(getModRefBehavior(Call));
725+
}
726+
}
727+
728+
const MemoryLocation &Loc = OptLoc.getValueOr(MemoryLocation());
729+
730+
switch (I->getOpcode()) {
731+
case Instruction::VAArg:
732+
return getModRefInfo((const VAArgInst *)I, Loc, AAQIP);
733+
case Instruction::Load:
734+
return getModRefInfo((const LoadInst *)I, Loc, AAQIP);
735+
case Instruction::Store:
736+
return getModRefInfo((const StoreInst *)I, Loc, AAQIP);
737+
case Instruction::Fence:
738+
return getModRefInfo((const FenceInst *)I, Loc, AAQIP);
739+
case Instruction::AtomicCmpXchg:
740+
return getModRefInfo((const AtomicCmpXchgInst *)I, Loc, AAQIP);
741+
case Instruction::AtomicRMW:
742+
return getModRefInfo((const AtomicRMWInst *)I, Loc, AAQIP);
743+
case Instruction::Call:
744+
return getModRefInfo((const CallInst *)I, Loc, AAQIP);
745+
case Instruction::Invoke:
746+
return getModRefInfo((const InvokeInst *)I, Loc, AAQIP);
747+
case Instruction::CatchPad:
748+
return getModRefInfo((const CatchPadInst *)I, Loc, AAQIP);
749+
case Instruction::CatchRet:
750+
return getModRefInfo((const CatchReturnInst *)I, Loc, AAQIP);
751+
default:
752+
return ModRefInfo::NoModRef;
753+
}
754+
}
755+
694756
class Concept;
695757

696758
template <typename T> class Model;
@@ -702,6 +764,47 @@ class AAResults {
702764
std::vector<std::unique_ptr<Concept>> AAs;
703765

704766
std::vector<AnalysisKey *> AADeps;
767+
768+
friend class BatchAAResults;
769+
};
770+
771+
/// This class is a wrapper over an AAResults, and it is intended to be used
772+
/// only when there are no IR changes inbetween queries. BatchAAResults is
773+
/// reusing the same `AAQueryInfo` to preserve the state across queries,
774+
/// esentially making AA work in "batch mode". The internal state cannot be
775+
/// cleared, so to go "out-of-batch-mode", the user must either use AAResults,
776+
/// or create a new BatchAAResults.
777+
class BatchAAResults {
778+
AAResults &AA;
779+
AAQueryInfo AAQI;
780+
781+
public:
782+
BatchAAResults(AAResults &AAR) : AA(AAR), AAQI() {}
783+
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
784+
return AA.alias(LocA, LocB, AAQI);
785+
}
786+
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal = false) {
787+
return AA.pointsToConstantMemory(Loc, AAQI, OrLocal);
788+
}
789+
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc) {
790+
return AA.getModRefInfo(Call, Loc, AAQI);
791+
}
792+
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2) {
793+
return AA.getModRefInfo(Call1, Call2, AAQI);
794+
}
795+
ModRefInfo getModRefInfo(const Instruction *I,
796+
const Optional<MemoryLocation> &OptLoc) {
797+
return AA.getModRefInfo(I, OptLoc, AAQI);
798+
}
799+
ModRefInfo getModRefInfo(Instruction *I, const CallBase *Call2) {
800+
return AA.getModRefInfo(I, Call2, AAQI);
801+
}
802+
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
803+
return AA.getArgModRefInfo(Call, ArgIdx);
804+
}
805+
FunctionModRefBehavior getModRefBehavior(const CallBase *Call) {
806+
return AA.getModRefBehavior(Call);
807+
}
705808
};
706809

707810
/// Temporary typedef for legacy code that uses a generic \c AliasAnalysis
@@ -734,12 +837,12 @@ class AAResults::Concept {
734837
/// each other. This is the interface that must be implemented by specific
735838
/// alias analysis implementations.
736839
virtual AliasResult alias(const MemoryLocation &LocA,
737-
const MemoryLocation &LocB) = 0;
840+
const MemoryLocation &LocB, AAQueryInfo &AAQI) = 0;
738841

739842
/// Checks whether the given location points to constant memory, or if
740843
/// \p OrLocal is true whether it points to a local alloca.
741844
virtual bool pointsToConstantMemory(const MemoryLocation &Loc,
742-
bool OrLocal) = 0;
845+
AAQueryInfo &AAQI, bool OrLocal) = 0;
743846

744847
/// @}
745848
//===--------------------------------------------------------------------===//
@@ -763,13 +866,14 @@ class AAResults::Concept {
763866
/// getModRefInfo (for call sites) - Return information about whether
764867
/// a particular call site modifies or reads the specified memory location.
765868
virtual ModRefInfo getModRefInfo(const CallBase *Call,
766-
const MemoryLocation &Loc) = 0;
869+
const MemoryLocation &Loc,
870+
AAQueryInfo &AAQI) = 0;
767871

768872
/// Return information about whether two call sites may refer to the same set
769873
/// of memory locations. See the AA documentation for details:
770874
/// http://llvm.org/docs/AliasAnalysis.html#ModRefInfo
771-
virtual ModRefInfo getModRefInfo(const CallBase *Call1,
772-
const CallBase *Call2) = 0;
875+
virtual ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
876+
AAQueryInfo &AAQI) = 0;
773877

774878
/// @}
775879
};
@@ -791,14 +895,14 @@ template <typename AAResultT> class AAResults::Model final : public Concept {
791895

792896
void setAAResults(AAResults *NewAAR) override { Result.setAAResults(NewAAR); }
793897

794-
AliasResult alias(const MemoryLocation &LocA,
795-
const MemoryLocation &LocB) override {
796-
return Result.alias(LocA, LocB);
898+
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
899+
AAQueryInfo &AAQI) override {
900+
return Result.alias(LocA, LocB, AAQI);
797901
}
798902

799-
bool pointsToConstantMemory(const MemoryLocation &Loc,
903+
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
800904
bool OrLocal) override {
801-
return Result.pointsToConstantMemory(Loc, OrLocal);
905+
return Result.pointsToConstantMemory(Loc, AAQI, OrLocal);
802906
}
803907

804908
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) override {
@@ -813,14 +917,14 @@ template <typename AAResultT> class AAResults::Model final : public Concept {
813917
return Result.getModRefBehavior(F);
814918
}
815919

816-
ModRefInfo getModRefInfo(const CallBase *Call,
817-
const MemoryLocation &Loc) override {
818-
return Result.getModRefInfo(Call, Loc);
920+
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
921+
AAQueryInfo &AAQI) override {
922+
return Result.getModRefInfo(Call, Loc, AAQI);
819923
}
820924

821-
ModRefInfo getModRefInfo(const CallBase *Call1,
822-
const CallBase *Call2) override {
823-
return Result.getModRefInfo(Call1, Call2);
925+
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
926+
AAQueryInfo &AAQI) override {
927+
return Result.getModRefInfo(Call1, Call2, AAQI);
824928
}
825929
};
826930

@@ -866,13 +970,16 @@ template <typename DerivedT> class AAResultBase {
866970
AAResultsProxy(AAResults *AAR, DerivedT &CurrentResult)
867971
: AAR(AAR), CurrentResult(CurrentResult) {}
868972

869-
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
870-
return AAR ? AAR->alias(LocA, LocB) : CurrentResult.alias(LocA, LocB);
973+
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
974+
AAQueryInfo &AAQI) {
975+
return AAR ? AAR->alias(LocA, LocB, AAQI)
976+
: CurrentResult.alias(LocA, LocB, AAQI);
871977
}
872978

873-
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) {
874-
return AAR ? AAR->pointsToConstantMemory(Loc, OrLocal)
875-
: CurrentResult.pointsToConstantMemory(Loc, OrLocal);
979+
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
980+
bool OrLocal) {
981+
return AAR ? AAR->pointsToConstantMemory(Loc, AAQI, OrLocal)
982+
: CurrentResult.pointsToConstantMemory(Loc, AAQI, OrLocal);
876983
}
877984

878985
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx) {
@@ -889,14 +996,16 @@ template <typename DerivedT> class AAResultBase {
889996
return AAR ? AAR->getModRefBehavior(F) : CurrentResult.getModRefBehavior(F);
890997
}
891998

892-
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc) {
893-
return AAR ? AAR->getModRefInfo(Call, Loc)
894-
: CurrentResult.getModRefInfo(Call, Loc);
999+
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
1000+
AAQueryInfo &AAQI) {
1001+
return AAR ? AAR->getModRefInfo(Call, Loc, AAQI)
1002+
: CurrentResult.getModRefInfo(Call, Loc, AAQI);
8951003
}
8961004

897-
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2) {
898-
return AAR ? AAR->getModRefInfo(Call1, Call2)
899-
: CurrentResult.getModRefInfo(Call1, Call2);
1005+
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
1006+
AAQueryInfo &AAQI) {
1007+
return AAR ? AAR->getModRefInfo(Call1, Call2, AAQI)
1008+
: CurrentResult.getModRefInfo(Call1, Call2, AAQI);
9001009
}
9011010
};
9021011

@@ -920,11 +1029,13 @@ template <typename DerivedT> class AAResultBase {
9201029
AAResultsProxy getBestAAResults() { return AAResultsProxy(AAR, derived()); }
9211030

9221031
public:
923-
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
1032+
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB,
1033+
AAQueryInfo &AAQI) {
9241034
return MayAlias;
9251035
}
9261036

927-
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) {
1037+
bool pointsToConstantMemory(const MemoryLocation &Loc, AAQueryInfo &AAQI,
1038+
bool OrLocal) {
9281039
return false;
9291040
}
9301041

@@ -940,11 +1051,13 @@ template <typename DerivedT> class AAResultBase {
9401051
return FMRB_UnknownModRefBehavior;
9411052
}
9421053

943-
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc) {
1054+
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc,
1055+
AAQueryInfo &AAQI) {
9441056
return ModRefInfo::ModRef;
9451057
}
9461058

947-
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2) {
1059+
ModRefInfo getModRefInfo(const CallBase *Call1, const CallBase *Call2,
1060+
AAQueryInfo &AAQI) {
9481061
return ModRefInfo::ModRef;
9491062
}
9501063
};

0 commit comments

Comments
 (0)