blob: 974fbcb87191e57e763fbd9ca1e151c4e3ebefd4 [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
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000053 // enum elements 0 ... to 6
54 static const AliasResult ASAliasRulesPrivIsZero[7][7] = {
55 /* Private Global Constant Group Flat Region Constant 32-bit */
56 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , MayAlias, NoAlias , NoAlias},
57 /* Global */ {NoAlias , MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , MayAlias},
58 /* Constant */ {NoAlias , MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , MayAlias},
59 /* Group */ {NoAlias , NoAlias , NoAlias , MayAlias, MayAlias, NoAlias , NoAlias},
60 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
61 /* Region */ {NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, MayAlias, NoAlias},
62 /* Constant 32-bit */ {NoAlias , MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , MayAlias}
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000063 };
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000064 static const AliasResult ASAliasRulesGenIsZero[7][7] = {
65 /* Flat Global Region Group Constant Private Constant 32-bit */
66 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
67 /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias},
68 /* Region */ {MayAlias, NoAlias , NoAlias , NoAlias, MayAlias, NoAlias , MayAlias},
69 /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias , NoAlias},
70 /* Constant */ {MayAlias, MayAlias, MayAlias, NoAlias , NoAlias, NoAlias , MayAlias},
71 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
72 /* Constant 32-bit */ {MayAlias, MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , NoAlias}
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000073 };
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000074 static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 6, "Addr space out of range");
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000075 if (AS.FLAT_ADDRESS == 0) {
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000076 assert(AS.GLOBAL_ADDRESS == 1 &&
77 AS.REGION_ADDRESS == 2 &&
78 AS.LOCAL_ADDRESS == 3 &&
79 AS.CONSTANT_ADDRESS == 4 &&
80 AS.PRIVATE_ADDRESS == 5 &&
81 AS.CONSTANT_ADDRESS_32BIT == 6);
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000082 ASAliasRules = &ASAliasRulesGenIsZero;
83 } else {
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000084 assert(AS.PRIVATE_ADDRESS == 0 &&
85 AS.GLOBAL_ADDRESS == 1 &&
86 AS.CONSTANT_ADDRESS == 2 &&
87 AS.LOCAL_ADDRESS == 3 &&
88 AS.FLAT_ADDRESS == 4 &&
89 AS.REGION_ADDRESS == 5 &&
90 AS.CONSTANT_ADDRESS_32BIT == 6);
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000091 ASAliasRules = &ASAliasRulesPrivIsZero;
92 }
93}
94
95AliasResult AMDGPUAAResult::ASAliasRulesTy::getAliasResult(unsigned AS1,
96 unsigned AS2) const {
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000097 if (AS1 > AS.MAX_AMDGPU_ADDRESS || AS2 > AS.MAX_AMDGPU_ADDRESS) {
Jan Vesely3c994412017-03-31 19:26:23 +000098 if (Arch == Triple::amdgcn)
99 report_fatal_error("Pointer address space out of range");
100 return AS1 == AS2 ? MayAlias : NoAlias;
101 }
102
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000103 return (*ASAliasRules)[AS1][AS2];
104}
105
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000106AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
107 const MemoryLocation &LocB) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000108 unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
109 unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000110
Yaxun Liu1a14bfa2017-03-27 14:04:01 +0000111 AliasResult Result = ASAliasRules.getAliasResult(asA, asB);
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000112 if (Result == NoAlias) return Result;
113
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000114 // Forward the query to the next alias analysis.
115 return AAResultBase::alias(LocA, LocB);
116}
117
118bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
119 bool OrLocal) {
120 const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
121
Matt Arsenault923712b2018-02-09 16:57:57 +0000122 if (Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS ||
123 Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS_32BIT) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000124 return true;
125 }
126
127 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
128 if (GV->isConstant())
129 return true;
130 } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
131 const Function *F = Arg->getParent();
132
133 // Only assume constant memory for arguments on kernels.
134 switch (F->getCallingConv()) {
135 default:
136 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000137 case CallingConv::AMDGPU_LS:
138 case CallingConv::AMDGPU_HS:
139 case CallingConv::AMDGPU_ES:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000140 case CallingConv::AMDGPU_GS:
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000141 case CallingConv::AMDGPU_VS:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000142 case CallingConv::AMDGPU_PS:
143 case CallingConv::AMDGPU_CS:
144 case CallingConv::AMDGPU_KERNEL:
145 case CallingConv::SPIR_KERNEL:
146 break;
147 }
148
149 unsigned ArgNo = Arg->getArgNo();
150 /* On an argument, ReadOnly attribute indicates that the function does
151 not write through this pointer argument, even though it may write
152 to the memory that the pointer points to.
153 On an argument, ReadNone attribute indicates that the function does
154 not dereference that pointer argument, even though it may read or write
155 the memory that the pointer points to if accessed through other pointers.
156 */
Reid Klecknerf021fab2017-04-13 23:12:13 +0000157 if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
158 (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
159 F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000160 return true;
161 }
162 }
163 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
164}