blob: 392b011e387c5677fec2da5053621adcee87f301 [file] [log] [blame]
Eugene Zelenkod16eff82017-08-08 23:53:55 +00001//===- AMDGPUAliasAnalysis ------------------------------------------------===//
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +00002//
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
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000013#include "AMDGPUAliasAnalysis.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000014#include "AMDGPU.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000015#include "llvm/ADT/Triple.h"
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000016#include "llvm/Analysis/AliasAnalysis.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000017#include "llvm/Analysis/MemoryLocation.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000018#include "llvm/Analysis/ValueTracking.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000019#include "llvm/IR/Argument.h"
20#include "llvm/IR/Attributes.h"
21#include "llvm/IR/CallingConv.h"
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000022#include "llvm/IR/Function.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000023#include "llvm/IR/GlobalVariable.h"
24#include "llvm/IR/Type.h"
25#include "llvm/IR/Value.h"
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000026#include "llvm/Pass.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000027#include "llvm/Support/Casting.h"
28#include "llvm/Support/ErrorHandling.h"
29#include <cassert>
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000030
31using namespace llvm;
32
33#define DEBUG_TYPE "amdgpu-aa"
34
35// Register this pass...
36char AMDGPUAAWrapperPass::ID = 0;
Eugene Zelenkod16eff82017-08-08 23:53:55 +000037
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000038INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",
39 "AMDGPU Address space based Alias Analysis", false, true)
40
41ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
42 return new AMDGPUAAWrapperPass();
43}
44
45void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
46 AU.setPreservesAll();
47}
48
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000049// Must match the table in getAliasResult.
Jan Vesely3c994412017-03-31 19:26:23 +000050AMDGPUAAResult::ASAliasRulesTy::ASAliasRulesTy(AMDGPUAS AS_, Triple::ArchType Arch_)
51 : Arch(Arch_), AS(AS_) {
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000052 // These arrarys are indexed by address space value
53 // enum elements 0 ... to 5
54 static const AliasResult ASAliasRulesPrivIsZero[6][6] = {
55 /* Private Global Constant Group Flat Region*/
56 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
57 /* Global */ {NoAlias , MayAlias, NoAlias , NoAlias , MayAlias, NoAlias},
58 /* Constant */ {NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, NoAlias},
59 /* Group */ {NoAlias , NoAlias , NoAlias , MayAlias, MayAlias, NoAlias},
60 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
61 /* Region */ {NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, MayAlias}
62 };
63 static const AliasResult ASAliasRulesGenIsZero[6][6] = {
Yaxun Liu76ae47c2017-04-06 19:17:32 +000064 /* Flat Global Constant Group Region Private */
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000065 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
66 /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , NoAlias , NoAlias},
Yaxun Liu76ae47c2017-04-06 19:17:32 +000067 /* Constant */ {MayAlias, NoAlias , MayAlias, NoAlias , NoAlias, NoAlias},
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000068 /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias},
Yaxun Liu76ae47c2017-04-06 19:17:32 +000069 /* Region */ {MayAlias, NoAlias , NoAlias , NoAlias, MayAlias, NoAlias},
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000070 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias}
71 };
72 assert(AS.MAX_COMMON_ADDRESS <= 5);
73 if (AS.FLAT_ADDRESS == 0) {
74 assert(AS.GLOBAL_ADDRESS == 1 &&
Yaxun Liu76ae47c2017-04-06 19:17:32 +000075 AS.REGION_ADDRESS == 4 &&
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000076 AS.LOCAL_ADDRESS == 3 &&
Yaxun Liu76ae47c2017-04-06 19:17:32 +000077 AS.CONSTANT_ADDRESS == 2 &&
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000078 AS.PRIVATE_ADDRESS == 5);
79 ASAliasRules = &ASAliasRulesGenIsZero;
80 } else {
81 assert(AS.PRIVATE_ADDRESS == 0 &&
82 AS.GLOBAL_ADDRESS == 1 &&
83 AS.CONSTANT_ADDRESS == 2 &&
84 AS.LOCAL_ADDRESS == 3 &&
85 AS.FLAT_ADDRESS == 4 &&
86 AS.REGION_ADDRESS == 5);
87 ASAliasRules = &ASAliasRulesPrivIsZero;
88 }
89}
90
91AliasResult AMDGPUAAResult::ASAliasRulesTy::getAliasResult(unsigned AS1,
92 unsigned AS2) const {
Jan Vesely3c994412017-03-31 19:26:23 +000093 if (AS1 > AS.MAX_COMMON_ADDRESS || AS2 > AS.MAX_COMMON_ADDRESS) {
94 if (Arch == Triple::amdgcn)
95 report_fatal_error("Pointer address space out of range");
96 return AS1 == AS2 ? MayAlias : NoAlias;
97 }
98
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000099 return (*ASAliasRules)[AS1][AS2];
100}
101
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000102AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
103 const MemoryLocation &LocB) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000104 unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
105 unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000106
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000107 AliasResult Result = ASAliasRules.getAliasResult(asA, asB);
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000108 if (Result == NoAlias) return Result;
109
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000110 // Forward the query to the next alias analysis.
111 return AAResultBase::alias(LocA, LocB);
112}
113
114bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
115 bool OrLocal) {
116 const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
117
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000118 if (Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000119 return true;
120 }
121
122 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
123 if (GV->isConstant())
124 return true;
125 } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
126 const Function *F = Arg->getParent();
127
128 // Only assume constant memory for arguments on kernels.
129 switch (F->getCallingConv()) {
130 default:
131 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000132 case CallingConv::AMDGPU_LS:
133 case CallingConv::AMDGPU_HS:
134 case CallingConv::AMDGPU_ES:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000135 case CallingConv::AMDGPU_GS:
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000136 case CallingConv::AMDGPU_VS:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000137 case CallingConv::AMDGPU_PS:
138 case CallingConv::AMDGPU_CS:
139 case CallingConv::AMDGPU_KERNEL:
140 case CallingConv::SPIR_KERNEL:
141 break;
142 }
143
144 unsigned ArgNo = Arg->getArgNo();
145 /* On an argument, ReadOnly attribute indicates that the function does
146 not write through this pointer argument, even though it may write
147 to the memory that the pointer points to.
148 On an argument, ReadNone attribute indicates that the function does
149 not dereference that pointer argument, even though it may read or write
150 the memory that the pointer points to if accessed through other pointers.
151 */
Reid Klecknerf021fab2017-04-13 23:12:13 +0000152 if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
153 (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
154 F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000155 return true;
156 }
157 }
158 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
159}