blob: aa5ebae2d9fdb1e85c1bfe227f2ac306b1248a70 [file] [log] [blame]
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +00001//===- AMDGPUAliasAnalysis ---------------------------------------*- C++ -*-==//
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 "AMDGPU.h"
14#include "AMDGPUAliasAnalysis.h"
15#include "llvm/Analysis/AliasAnalysis.h"
16#include "llvm/Analysis/ValueTracking.h"
17#include "llvm/Analysis/Passes.h"
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/IR/Function.h"
20#include "llvm/IR/Module.h"
21#include "llvm/Pass.h"
22
23using namespace llvm;
24
25#define DEBUG_TYPE "amdgpu-aa"
26
27// Register this pass...
28char AMDGPUAAWrapperPass::ID = 0;
29INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",
30 "AMDGPU Address space based Alias Analysis", false, true)
31
32ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
33 return new AMDGPUAAWrapperPass();
34}
35
36void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
37 AU.setPreservesAll();
38}
39
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000040// Must match the table in getAliasResult.
41AMDGPUAAResult::ASAliasRulesTy::ASAliasRulesTy(AMDGPUAS AS_) : AS(AS_) {
42 // These arrarys are indexed by address space value
43 // enum elements 0 ... to 5
44 static const AliasResult ASAliasRulesPrivIsZero[6][6] = {
45 /* Private Global Constant Group Flat Region*/
46 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
47 /* Global */ {NoAlias , MayAlias, NoAlias , NoAlias , MayAlias, NoAlias},
48 /* Constant */ {NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, NoAlias},
49 /* Group */ {NoAlias , NoAlias , NoAlias , MayAlias, MayAlias, NoAlias},
50 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
51 /* Region */ {NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, MayAlias}
52 };
53 static const AliasResult ASAliasRulesGenIsZero[6][6] = {
54 /* Flat Global Region Group Constant Private */
55 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
56 /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , NoAlias , NoAlias},
57 /* Region */ {NoAlias , NoAlias , MayAlias, NoAlias, NoAlias , MayAlias},
58 /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias},
59 /* Constant */ {MayAlias, NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
60 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias}
61 };
62 assert(AS.MAX_COMMON_ADDRESS <= 5);
63 if (AS.FLAT_ADDRESS == 0) {
64 assert(AS.GLOBAL_ADDRESS == 1 &&
65 AS.REGION_ADDRESS == 2 &&
66 AS.LOCAL_ADDRESS == 3 &&
67 AS.CONSTANT_ADDRESS == 4 &&
68 AS.PRIVATE_ADDRESS == 5);
69 ASAliasRules = &ASAliasRulesGenIsZero;
70 } else {
71 assert(AS.PRIVATE_ADDRESS == 0 &&
72 AS.GLOBAL_ADDRESS == 1 &&
73 AS.CONSTANT_ADDRESS == 2 &&
74 AS.LOCAL_ADDRESS == 3 &&
75 AS.FLAT_ADDRESS == 4 &&
76 AS.REGION_ADDRESS == 5);
77 ASAliasRules = &ASAliasRulesPrivIsZero;
78 }
79}
80
81AliasResult AMDGPUAAResult::ASAliasRulesTy::getAliasResult(unsigned AS1,
82 unsigned AS2) const {
83 if (AS1 > AS.MAX_COMMON_ADDRESS || AS2 > AS.MAX_COMMON_ADDRESS)
84 report_fatal_error("Pointer address space out of range");
85 return (*ASAliasRules)[AS1][AS2];
86}
87
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000088AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
89 const MemoryLocation &LocB) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000090 unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
91 unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000092
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000093 AliasResult Result = ASAliasRules.getAliasResult(asA, asB);
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000094 if (Result == NoAlias) return Result;
95
96 if (isa<Argument>(LocA.Ptr) && isa<Argument>(LocB.Ptr)) {
97 Type *T1 = cast<PointerType>(LocA.Ptr->getType())->getElementType();
98 Type *T2 = cast<PointerType>(LocB.Ptr->getType())->getElementType();
99
100 if ((T1->isVectorTy() && !T2->isVectorTy()) ||
101 (T2->isVectorTy() && !T1->isVectorTy()))
102 return NoAlias;
103 }
104 // Forward the query to the next alias analysis.
105 return AAResultBase::alias(LocA, LocB);
106}
107
108bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
109 bool OrLocal) {
110 const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
111
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000112 if (Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000113 return true;
114 }
115
116 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
117 if (GV->isConstant())
118 return true;
119 } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
120 const Function *F = Arg->getParent();
121
122 // Only assume constant memory for arguments on kernels.
123 switch (F->getCallingConv()) {
124 default:
125 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
126 case CallingConv::AMDGPU_VS:
127 case CallingConv::AMDGPU_GS:
128 case CallingConv::AMDGPU_PS:
129 case CallingConv::AMDGPU_CS:
130 case CallingConv::AMDGPU_KERNEL:
131 case CallingConv::SPIR_KERNEL:
132 break;
133 }
134
135 unsigned ArgNo = Arg->getArgNo();
136 /* On an argument, ReadOnly attribute indicates that the function does
137 not write through this pointer argument, even though it may write
138 to the memory that the pointer points to.
139 On an argument, ReadNone attribute indicates that the function does
140 not dereference that pointer argument, even though it may read or write
141 the memory that the pointer points to if accessed through other pointers.
142 */
143 if (F->getAttributes().hasAttribute(ArgNo + 1, Attribute::NoAlias) &&
144 (F->getAttributes().hasAttribute(ArgNo + 1, Attribute::ReadNone) ||
145 F->getAttributes().hasAttribute(ArgNo + 1, Attribute::ReadOnly))) {
146 return true;
147 }
148 }
149 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
150}