Line data Source code
1 : //===- AMDGPUAliasAnalysis ------------------------------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : /// \file
10 : /// This is the AMGPU address space based alias analysis pass.
11 : //===----------------------------------------------------------------------===//
12 :
13 : #include "AMDGPUAliasAnalysis.h"
14 : #include "AMDGPU.h"
15 : #include "llvm/ADT/Triple.h"
16 : #include "llvm/Analysis/AliasAnalysis.h"
17 : #include "llvm/Analysis/MemoryLocation.h"
18 : #include "llvm/Analysis/ValueTracking.h"
19 : #include "llvm/IR/Argument.h"
20 : #include "llvm/IR/Attributes.h"
21 : #include "llvm/IR/CallingConv.h"
22 : #include "llvm/IR/Function.h"
23 : #include "llvm/IR/GlobalVariable.h"
24 : #include "llvm/IR/Type.h"
25 : #include "llvm/IR/Value.h"
26 : #include "llvm/Pass.h"
27 : #include "llvm/Support/Casting.h"
28 : #include "llvm/Support/ErrorHandling.h"
29 : #include <cassert>
30 :
31 : using namespace llvm;
32 :
33 : #define DEBUG_TYPE "amdgpu-aa"
34 :
35 : // Register this pass...
36 : char AMDGPUAAWrapperPass::ID = 0;
37 :
38 201357 : INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",
39 : "AMDGPU Address space based Alias Analysis", false, true)
40 :
41 2333 : ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
42 2333 : return new AMDGPUAAWrapperPass();
43 : }
44 :
45 2316 : void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
46 : AU.setPreservesAll();
47 2316 : }
48 :
49 : // These arrays are indexed by address space value enum elements 0 ... to 6
50 : static const AliasResult ASAliasRules[7][7] = {
51 : /* Flat Global Region Group Constant Private Constant 32-bit */
52 : /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
53 : /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias},
54 : /* Region */ {MayAlias, NoAlias , NoAlias , NoAlias, MayAlias, NoAlias , MayAlias},
55 : /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias , NoAlias},
56 : /* Constant */ {MayAlias, MayAlias, MayAlias, NoAlias , NoAlias, NoAlias , MayAlias},
57 : /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
58 : /* Constant 32-bit */ {MayAlias, MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , NoAlias}
59 : };
60 :
61 : static AliasResult getAliasResult(unsigned AS1, unsigned AS2) {
62 : static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 6, "Addr space out of range");
63 :
64 74837 : if (AS1 > AMDGPUAS::MAX_AMDGPU_ADDRESS || AS2 > AMDGPUAS::MAX_AMDGPU_ADDRESS)
65 : return MayAlias;
66 :
67 74819 : return ASAliasRules[AS1][AS2];
68 : }
69 :
70 74837 : AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
71 : const MemoryLocation &LocB) {
72 74837 : unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
73 74837 : unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
74 :
75 : AliasResult Result = getAliasResult(asA, asB);
76 74819 : if (Result == NoAlias)
77 11043 : return Result;
78 :
79 : // Forward the query to the next alias analysis.
80 : return AAResultBase::alias(LocA, LocB);
81 : }
82 :
83 89121 : bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
84 : bool OrLocal) {
85 89121 : const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
86 89121 : unsigned AS = Base->getType()->getPointerAddressSpace();
87 178242 : if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
88 89121 : AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) {
89 : return true;
90 : }
91 :
92 : if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
93 2218 : if (GV->isConstant())
94 : return true;
95 : } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
96 12038 : const Function *F = Arg->getParent();
97 :
98 : // Only assume constant memory for arguments on kernels.
99 : switch (F->getCallingConv()) {
100 : default:
101 : return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
102 : case CallingConv::AMDGPU_LS:
103 : case CallingConv::AMDGPU_HS:
104 : case CallingConv::AMDGPU_ES:
105 : case CallingConv::AMDGPU_GS:
106 : case CallingConv::AMDGPU_VS:
107 : case CallingConv::AMDGPU_PS:
108 : case CallingConv::AMDGPU_CS:
109 : case CallingConv::AMDGPU_KERNEL:
110 : case CallingConv::SPIR_KERNEL:
111 : break;
112 : }
113 :
114 10973 : unsigned ArgNo = Arg->getArgNo();
115 : /* On an argument, ReadOnly attribute indicates that the function does
116 : not write through this pointer argument, even though it may write
117 : to the memory that the pointer points to.
118 : On an argument, ReadNone attribute indicates that the function does
119 : not dereference that pointer argument, even though it may read or write
120 : the memory that the pointer points to if accessed through other pointers.
121 : */
122 14023 : if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
123 3050 : (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
124 : F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
125 223 : return true;
126 : }
127 : }
128 62454 : return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
129 : }
|