37
37
#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
38
38
#define LLVM_ANALYSIS_ALIASANALYSIS_H
39
39
40
+ #include " llvm/ADT/DenseMap.h"
40
41
#include " llvm/ADT/None.h"
41
42
#include " llvm/ADT/Optional.h"
42
43
#include " llvm/ADT/SmallVector.h"
@@ -285,6 +286,28 @@ createModRefInfo(const FunctionModRefBehavior FMRB) {
285
286
return ModRefInfo (FMRB & static_cast <int >(ModRefInfo::ModRef));
286
287
}
287
288
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
+
288
311
class AAResults {
289
312
public:
290
313
// Make these results default constructable and movable. We have to spell
@@ -599,32 +622,8 @@ class AAResults {
599
622
// / helpers above.
600
623
ModRefInfo getModRefInfo (const Instruction *I,
601
624
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);
628
627
}
629
628
630
629
// / A convenience wrapper for constructing the memory location.
@@ -691,6 +690,69 @@ class AAResults {
691
690
}
692
691
693
692
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
+
694
756
class Concept ;
695
757
696
758
template <typename T> class Model ;
@@ -702,6 +764,47 @@ class AAResults {
702
764
std::vector<std::unique_ptr<Concept>> AAs;
703
765
704
766
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
+ }
705
808
};
706
809
707
810
// / Temporary typedef for legacy code that uses a generic \c AliasAnalysis
@@ -734,12 +837,12 @@ class AAResults::Concept {
734
837
// / each other. This is the interface that must be implemented by specific
735
838
// / alias analysis implementations.
736
839
virtual AliasResult alias (const MemoryLocation &LocA,
737
- const MemoryLocation &LocB) = 0;
840
+ const MemoryLocation &LocB, AAQueryInfo &AAQI ) = 0;
738
841
739
842
// / Checks whether the given location points to constant memory, or if
740
843
// / \p OrLocal is true whether it points to a local alloca.
741
844
virtual bool pointsToConstantMemory (const MemoryLocation &Loc,
742
- bool OrLocal) = 0;
845
+ AAQueryInfo &AAQI, bool OrLocal) = 0;
743
846
744
847
// / @}
745
848
// ===--------------------------------------------------------------------===//
@@ -763,13 +866,14 @@ class AAResults::Concept {
763
866
// / getModRefInfo (for call sites) - Return information about whether
764
867
// / a particular call site modifies or reads the specified memory location.
765
868
virtual ModRefInfo getModRefInfo (const CallBase *Call,
766
- const MemoryLocation &Loc) = 0;
869
+ const MemoryLocation &Loc,
870
+ AAQueryInfo &AAQI) = 0;
767
871
768
872
// / Return information about whether two call sites may refer to the same set
769
873
// / of memory locations. See the AA documentation for details:
770
874
// / 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;
773
877
774
878
// / @}
775
879
};
@@ -791,14 +895,14 @@ template <typename AAResultT> class AAResults::Model final : public Concept {
791
895
792
896
void setAAResults (AAResults *NewAAR) override { Result.setAAResults (NewAAR); }
793
897
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 );
797
901
}
798
902
799
- bool pointsToConstantMemory (const MemoryLocation &Loc,
903
+ bool pointsToConstantMemory (const MemoryLocation &Loc, AAQueryInfo &AAQI,
800
904
bool OrLocal) override {
801
- return Result.pointsToConstantMemory (Loc, OrLocal);
905
+ return Result.pointsToConstantMemory (Loc, AAQI, OrLocal);
802
906
}
803
907
804
908
ModRefInfo getArgModRefInfo (const CallBase *Call, unsigned ArgIdx) override {
@@ -813,14 +917,14 @@ template <typename AAResultT> class AAResults::Model final : public Concept {
813
917
return Result.getModRefBehavior (F);
814
918
}
815
919
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 );
819
923
}
820
924
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 );
824
928
}
825
929
};
826
930
@@ -866,13 +970,16 @@ template <typename DerivedT> class AAResultBase {
866
970
AAResultsProxy (AAResults *AAR, DerivedT &CurrentResult)
867
971
: AAR(AAR), CurrentResult(CurrentResult) {}
868
972
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);
871
977
}
872
978
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);
876
983
}
877
984
878
985
ModRefInfo getArgModRefInfo (const CallBase *Call, unsigned ArgIdx) {
@@ -889,14 +996,16 @@ template <typename DerivedT> class AAResultBase {
889
996
return AAR ? AAR->getModRefBehavior (F) : CurrentResult.getModRefBehavior (F);
890
997
}
891
998
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);
895
1003
}
896
1004
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);
900
1009
}
901
1010
};
902
1011
@@ -920,11 +1029,13 @@ template <typename DerivedT> class AAResultBase {
920
1029
AAResultsProxy getBestAAResults () { return AAResultsProxy (AAR, derived ()); }
921
1030
922
1031
public:
923
- AliasResult alias (const MemoryLocation &LocA, const MemoryLocation &LocB) {
1032
+ AliasResult alias (const MemoryLocation &LocA, const MemoryLocation &LocB,
1033
+ AAQueryInfo &AAQI) {
924
1034
return MayAlias;
925
1035
}
926
1036
927
- bool pointsToConstantMemory (const MemoryLocation &Loc, bool OrLocal) {
1037
+ bool pointsToConstantMemory (const MemoryLocation &Loc, AAQueryInfo &AAQI,
1038
+ bool OrLocal) {
928
1039
return false ;
929
1040
}
930
1041
@@ -940,11 +1051,13 @@ template <typename DerivedT> class AAResultBase {
940
1051
return FMRB_UnknownModRefBehavior;
941
1052
}
942
1053
943
- ModRefInfo getModRefInfo (const CallBase *Call, const MemoryLocation &Loc) {
1054
+ ModRefInfo getModRefInfo (const CallBase *Call, const MemoryLocation &Loc,
1055
+ AAQueryInfo &AAQI) {
944
1056
return ModRefInfo::ModRef;
945
1057
}
946
1058
947
- ModRefInfo getModRefInfo (const CallBase *Call1, const CallBase *Call2) {
1059
+ ModRefInfo getModRefInfo (const CallBase *Call1, const CallBase *Call2,
1060
+ AAQueryInfo &AAQI) {
948
1061
return ModRefInfo::ModRef;
949
1062
}
950
1063
};
0 commit comments