@@ -787,9 +787,6 @@ namespace llvm {
787
787
namespace AA {
788
788
namespace PointerInfo {
789
789
790
- // / An access kind description as used by AAPointerInfo.
791
- struct OffsetAndSize ;
792
-
793
790
struct State ;
794
791
795
792
} // namespace PointerInfo
@@ -807,7 +804,7 @@ struct DenseMapInfo<AAPointerInfo::Access> : DenseMapInfo<Instruction *> {
807
804
808
805
// / Helper that allows OffsetAndSize as a key in a DenseMap.
809
806
template <>
810
- struct DenseMapInfo <AA::PointerInfo ::OffsetAndSize>
807
+ struct DenseMapInfo <AAPointerInfo ::OffsetAndSize>
811
808
: DenseMapInfo<std::pair<int64_t , int64_t >> {};
812
809
813
810
// / Helper for AA::PointerInfo::Acccess DenseMap/Set usage ignoring everythign
@@ -823,38 +820,6 @@ struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> {
823
820
824
821
} // namespace llvm
825
822
826
- // / Helper to represent an access offset and size, with logic to deal with
827
- // / uncertainty and check for overlapping accesses.
828
- struct AA ::PointerInfo::OffsetAndSize : public std::pair<int64_t , int64_t > {
829
- using BaseTy = std::pair<int64_t , int64_t >;
830
- OffsetAndSize (int64_t Offset, int64_t Size) : BaseTy(Offset, Size) {}
831
- OffsetAndSize (const BaseTy &P) : BaseTy(P) {}
832
- int64_t getOffset () const { return first; }
833
- int64_t getSize () const { return second; }
834
- static OffsetAndSize getUnknown () { return OffsetAndSize (Unknown, Unknown); }
835
-
836
- // / Return true if offset or size are unknown.
837
- bool offsetOrSizeAreUnknown () const {
838
- return getOffset () == OffsetAndSize::Unknown ||
839
- getSize () == OffsetAndSize::Unknown;
840
- }
841
-
842
- // / Return true if this offset and size pair might describe an address that
843
- // / overlaps with \p OAS.
844
- bool mayOverlap (const OffsetAndSize &OAS) const {
845
- // Any unknown value and we are giving up -> overlap.
846
- if (offsetOrSizeAreUnknown () || OAS.offsetOrSizeAreUnknown ())
847
- return true ;
848
-
849
- // Check if one offset point is in the other interval [offset, offset+size].
850
- return OAS.getOffset () + OAS.getSize () > getOffset () &&
851
- OAS.getOffset () < getOffset () + getSize ();
852
- }
853
-
854
- // / Constant used to represent unknown offset or sizes.
855
- static constexpr int64_t Unknown = 1 << 31 ;
856
- };
857
-
858
823
// / Implementation of the DenseMapInfo.
859
824
// /
860
825
// /{
@@ -988,14 +953,14 @@ struct AA::PointerInfo::State : public AbstractState {
988
953
using Accesses = DenseSet<AAPointerInfo::Access, AccessAsInstructionInfo>;
989
954
990
955
// / We store all accesses in bins denoted by their offset and size.
991
- using AccessBinsTy = DenseMap<OffsetAndSize, Accesses>;
956
+ using AccessBinsTy = DenseMap<AAPointerInfo:: OffsetAndSize, Accesses>;
992
957
993
958
AccessBinsTy::const_iterator begin () const { return AccessBins.begin (); }
994
959
AccessBinsTy::const_iterator end () const { return AccessBins.end (); }
995
960
996
961
protected:
997
962
// / The bins with all the accesses for the associated pointer.
998
- DenseMap<OffsetAndSize, Accesses> AccessBins;
963
+ DenseMap<AAPointerInfo:: OffsetAndSize, Accesses> AccessBins;
999
964
1000
965
// / Add a new access to the state at offset \p Offset and with size \p Size.
1001
966
// / The access is associated with \p I, writes \p Content (if anything), and
@@ -1006,7 +971,7 @@ struct AA::PointerInfo::State : public AbstractState {
1006
971
AAPointerInfo::AccessKind Kind, Type *Ty,
1007
972
Instruction *RemoteI = nullptr ,
1008
973
Accesses *BinPtr = nullptr ) {
1009
- OffsetAndSize Key{Offset, Size};
974
+ AAPointerInfo:: OffsetAndSize Key{Offset, Size};
1010
975
Accesses &Bin = BinPtr ? *BinPtr : AccessBins[Key];
1011
976
AAPointerInfo::Access Acc (&I, RemoteI ? RemoteI : &I, Content, Kind, Ty);
1012
977
// Check if we have an access for this instruction in this bin, if not,
@@ -1023,14 +988,34 @@ struct AA::PointerInfo::State : public AbstractState {
1023
988
return *It == Before ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
1024
989
}
1025
990
991
+ // / See AAPointerInfo::forallInterferingAccesses.
992
+ bool forallInterferingAccesses (
993
+ AAPointerInfo::OffsetAndSize OAS,
994
+ function_ref<bool (const AAPointerInfo::Access &, bool )> CB) const {
995
+ if (!isValidState ())
996
+ return false ;
997
+
998
+ for (auto &It : AccessBins) {
999
+ AAPointerInfo::OffsetAndSize ItOAS = It.getFirst ();
1000
+ if (!OAS.mayOverlap (ItOAS))
1001
+ continue ;
1002
+ bool IsExact = OAS == ItOAS && !OAS.offsetOrSizeAreUnknown ();
1003
+ for (auto &Access : It.getSecond ())
1004
+ if (!CB (Access, IsExact))
1005
+ return false ;
1006
+ }
1007
+ return true ;
1008
+ }
1009
+
1026
1010
// / See AAPointerInfo::forallInterferingAccesses.
1027
1011
bool forallInterferingAccesses (
1028
1012
Instruction &I,
1029
1013
function_ref<bool (const AAPointerInfo::Access &, bool )> CB) const {
1030
1014
if (!isValidState ())
1031
1015
return false ;
1016
+
1032
1017
// First find the offset and size of I.
1033
- OffsetAndSize OAS (-1 , -1 );
1018
+ AAPointerInfo:: OffsetAndSize OAS (-1 , -1 );
1034
1019
for (auto &It : AccessBins) {
1035
1020
for (auto &Access : It.getSecond ()) {
1036
1021
if (Access.getRemoteInst () == &I) {
@@ -1041,21 +1026,13 @@ struct AA::PointerInfo::State : public AbstractState {
1041
1026
if (OAS.getSize () != -1 )
1042
1027
break ;
1043
1028
}
1029
+ // No access for I was found, we are done.
1044
1030
if (OAS.getSize () == -1 )
1045
1031
return true ;
1046
1032
1047
1033
// Now that we have an offset and size, find all overlapping ones and use
1048
1034
// the callback on the accesses.
1049
- for (auto &It : AccessBins) {
1050
- OffsetAndSize ItOAS = It.getFirst ();
1051
- if (!OAS.mayOverlap (ItOAS))
1052
- continue ;
1053
- bool IsExact = OAS == ItOAS && !OAS.offsetOrSizeAreUnknown ();
1054
- for (auto &Access : It.getSecond ())
1055
- if (!CB (Access, IsExact))
1056
- return false ;
1057
- }
1058
- return true ;
1035
+ return forallInterferingAccesses (OAS, CB);
1059
1036
}
1060
1037
1061
1038
private:
@@ -1084,6 +1061,12 @@ struct AAPointerInfoImpl
1084
1061
return AAPointerInfo::manifest (A);
1085
1062
}
1086
1063
1064
+ bool forallInterferingAccesses (
1065
+ OffsetAndSize OAS,
1066
+ function_ref<bool (const AAPointerInfo::Access &, bool )> CB)
1067
+ const override {
1068
+ return State::forallInterferingAccesses (OAS, CB);
1069
+ }
1087
1070
bool forallInterferingAccesses (
1088
1071
LoadInst &LI, function_ref<bool (const AAPointerInfo::Access &, bool )> CB)
1089
1072
const override {
@@ -1306,7 +1289,7 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {
1306
1289
bool handleAccess (Attributor &A, Instruction &I, Value &Ptr,
1307
1290
Optional<Value *> Content, AccessKind Kind, int64_t Offset,
1308
1291
ChangeStatus &Changed, Type *Ty,
1309
- int64_t Size = AA::PointerInfo:: OffsetAndSize::Unknown) {
1292
+ int64_t Size = OffsetAndSize::Unknown) {
1310
1293
using namespace AA ::PointerInfo;
1311
1294
// No need to find a size if one is given or the offset is unknown.
1312
1295
if (Offset != OffsetAndSize::Unknown && Size == OffsetAndSize::Unknown &&
@@ -1322,7 +1305,7 @@ struct AAPointerInfoFloating : public AAPointerInfoImpl {
1322
1305
1323
1306
// / Helper struct, will support ranges eventually.
1324
1307
struct OffsetInfo {
1325
- int64_t Offset = AA::PointerInfo:: OffsetAndSize::Unknown;
1308
+ int64_t Offset = OffsetAndSize::Unknown;
1326
1309
1327
1310
bool operator ==(const OffsetInfo &OI) const { return Offset == OI.Offset ; }
1328
1311
};
0 commit comments