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,24 @@ 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
+ auto GetAS = [](const Value *V) -> unsigned {
61
+ if (const auto *PTy = dyn_cast<PointerType>(V->getType ()))
62
+ return PTy->getAddressSpace ();
63
+ return ADDRESS_SPACE_GENERIC;
64
+ };
65
+ while (MaxLookup-- && GetAS (V) == ADDRESS_SPACE_GENERIC) {
66
+ const Value *NewV = getUnderlyingObject (V, 1 );
67
+ if (NewV == V)
68
+ break ;
69
+ V = NewV;
70
+ }
71
+ return GetAS (V);
72
+ }
73
+
50
74
static AliasResult::Kind getAliasResult (unsigned AS1, unsigned AS2) {
51
75
if ((AS1 == ADDRESS_SPACE_GENERIC) || (AS2 == ADDRESS_SPACE_GENERIC))
52
76
return AliasResult::MayAlias;
@@ -70,8 +94,8 @@ static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {
70
94
AliasResult NVPTXAAResult::alias (const MemoryLocation &Loc1,
71
95
const MemoryLocation &Loc2, AAQueryInfo &AAQI,
72
96
const Instruction *) {
73
- unsigned AS1 = Loc1.Ptr -> getType ()-> getPointerAddressSpace ( );
74
- unsigned AS2 = Loc2.Ptr -> getType ()-> getPointerAddressSpace ( );
97
+ unsigned AS1 = getAddressSpace ( Loc1.Ptr , TraverseAddressSpacesLimit );
98
+ unsigned AS2 = getAddressSpace ( Loc2.Ptr , TraverseAddressSpacesLimit );
75
99
76
100
return getAliasResult (AS1, AS2);
77
101
}
@@ -87,11 +111,7 @@ static bool isConstOrParam(unsigned AS) {
87
111
ModRefInfo NVPTXAAResult::getModRefInfoMask (const MemoryLocation &Loc,
88
112
AAQueryInfo &AAQI,
89
113
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 ()))
114
+ if (isConstOrParam (getAddressSpace (Loc.Ptr , TraverseAddressSpacesLimit)))
95
115
return ModRefInfo::NoModRef;
96
116
97
117
return ModRefInfo::ModRef;
0 commit comments