15
15
#include " llvm/Analysis/ValueTracking.h"
16
16
#include " llvm/IR/CallingConv.h"
17
17
#include " llvm/IR/Instructions.h"
18
+ #include " llvm/Support/CommandLine.h"
18
19
19
20
using namespace llvm ;
20
21
21
22
#define DEBUG_TYPE " NVPTX-aa"
22
23
24
+ static cl::opt<unsigned > TraverseAddressSpacesLimit (
25
+ " nvptx-traverse-address-aliasing-limit" , cl::Hidden,
26
+ cl::desc (" Depth limit for finding address space through traversal" ),
27
+ cl::init(6 ));
28
+
23
29
AnalysisKey NVPTXAA::Key;
24
30
25
31
char NVPTXAAWrapperPass::ID = 0 ;
@@ -47,6 +53,28 @@ void NVPTXAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
47
53
AU.setPreservesAll ();
48
54
}
49
55
56
+ static unsigned getAddressSpace (const Value *V, unsigned MaxLookup) {
57
+ // Find the first non-generic address space traversing the UD chain.
58
+ // It is undefined behaviour if a pointer belongs to more than one
59
+ // non-overlapping address spaces along a valid execution path.
60
+ for (unsigned Count = 0 ; MaxLookup == 0 || Count < MaxLookup; ++Count) {
61
+ const auto *PTy = dyn_cast<PointerType>(V->getType ());
62
+ if (!PTy)
63
+ return AddressSpace::ADDRESS_SPACE_GENERIC;
64
+
65
+ const unsigned AS = PTy->getAddressSpace ();
66
+ if (AS != AddressSpace::ADDRESS_SPACE_GENERIC)
67
+ return AS;
68
+
69
+ // Continue traversing if address space is generic
70
+ const Value *VNext = getUnderlyingObject (V, 1 );
71
+ if (VNext == V)
72
+ return AddressSpace::ADDRESS_SPACE_GENERIC;
73
+ V = VNext;
74
+ }
75
+ return AddressSpace::ADDRESS_SPACE_GENERIC;
76
+ }
77
+
50
78
static AliasResult::Kind getAliasResult (unsigned AS1, unsigned AS2) {
51
79
if ((AS1 == ADDRESS_SPACE_GENERIC) || (AS2 == ADDRESS_SPACE_GENERIC))
52
80
return AliasResult::MayAlias;
@@ -70,8 +98,8 @@ static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {
70
98
AliasResult NVPTXAAResult::alias (const MemoryLocation &Loc1,
71
99
const MemoryLocation &Loc2, AAQueryInfo &AAQI,
72
100
const Instruction *) {
73
- unsigned AS1 = Loc1.Ptr -> getType ()-> getPointerAddressSpace ( );
74
- unsigned AS2 = Loc2.Ptr -> getType ()-> getPointerAddressSpace ( );
101
+ unsigned AS1 = getAddressSpace ( Loc1.Ptr , TraverseAddressSpacesLimit );
102
+ unsigned AS2 = getAddressSpace ( Loc2.Ptr , TraverseAddressSpacesLimit );
75
103
76
104
return getAliasResult (AS1, AS2);
77
105
}
@@ -87,11 +115,7 @@ static bool isConstOrParam(unsigned AS) {
87
115
ModRefInfo NVPTXAAResult::getModRefInfoMask (const MemoryLocation &Loc,
88
116
AAQueryInfo &AAQI,
89
117
bool IgnoreLocals) {
90
- if (isConstOrParam (Loc.Ptr ->getType ()->getPointerAddressSpace ()))
91
- return ModRefInfo::NoModRef;
92
-
93
- const Value *Base = getUnderlyingObject (Loc.Ptr );
94
- if (isConstOrParam (Base->getType ()->getPointerAddressSpace ()))
118
+ if (isConstOrParam (getAddressSpace (Loc.Ptr , TraverseAddressSpacesLimit)))
95
119
return ModRefInfo::NoModRef;
96
120
97
121
return ModRefInfo::ModRef;
0 commit comments