blob: 73709ba13643ee06673f64a380b5c93f2d29de4e [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;
Matt Arsenault8ba740a2018-11-07 20:26:42 +000037char AMDGPUExternalAAWrapper::ID = 0;
Eugene Zelenkod16eff82017-08-08 23:53:55 +000038
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000039INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",
40 "AMDGPU Address space based Alias Analysis", false, true)
41
Matt Arsenault8ba740a2018-11-07 20:26:42 +000042INITIALIZE_PASS(AMDGPUExternalAAWrapper, "amdgpu-aa-wrapper",
43 "AMDGPU Address space based Alias Analysis Wrapper", false, true)
44
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000045ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
46 return new AMDGPUAAWrapperPass();
47}
48
Matt Arsenault8ba740a2018-11-07 20:26:42 +000049ImmutablePass *llvm::createAMDGPUExternalAAWrapperPass() {
50 return new AMDGPUExternalAAWrapper();
51}
52
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000053void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
54 AU.setPreservesAll();
55}
56
Matt Arsenault796b0e72018-09-11 04:00:49 +000057// These arrays are indexed by address space value enum elements 0 ... to 6
58static const AliasResult ASAliasRules[7][7] = {
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000059 /* Flat Global Region Group Constant Private Constant 32-bit */
60 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
61 /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias},
62 /* Region */ {MayAlias, NoAlias , NoAlias , NoAlias, MayAlias, NoAlias , MayAlias},
63 /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias , NoAlias},
64 /* Constant */ {MayAlias, MayAlias, MayAlias, NoAlias , NoAlias, NoAlias , MayAlias},
65 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
66 /* Constant 32-bit */ {MayAlias, MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , NoAlias}
Matt Arsenault796b0e72018-09-11 04:00:49 +000067};
Matt Arsenault0da63502018-08-31 05:49:54 +000068
Matt Arsenault796b0e72018-09-11 04:00:49 +000069static AliasResult getAliasResult(unsigned AS1, unsigned AS2) {
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000070 static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 6, "Addr space out of range");
Matt Arsenault0da63502018-08-31 05:49:54 +000071
Matt Arsenault796b0e72018-09-11 04:00:49 +000072 if (AS1 > AMDGPUAS::MAX_AMDGPU_ADDRESS || AS2 > AMDGPUAS::MAX_AMDGPU_ADDRESS)
73 return MayAlias;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000074
Matt Arsenault796b0e72018-09-11 04:00:49 +000075 return ASAliasRules[AS1][AS2];
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000076}
77
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000078AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
79 const MemoryLocation &LocB) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000080 unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
81 unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000082
Matt Arsenault796b0e72018-09-11 04:00:49 +000083 AliasResult Result = getAliasResult(asA, asB);
84 if (Result == NoAlias)
85 return Result;
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000086
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000087 // Forward the query to the next alias analysis.
88 return AAResultBase::alias(LocA, LocB);
89}
90
91bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
92 bool OrLocal) {
93 const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
Matt Arsenault0da63502018-08-31 05:49:54 +000094 unsigned AS = Base->getType()->getPointerAddressSpace();
95 if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
96 AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000097 return true;
98 }
99
100 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
101 if (GV->isConstant())
102 return true;
103 } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
104 const Function *F = Arg->getParent();
105
106 // Only assume constant memory for arguments on kernels.
107 switch (F->getCallingConv()) {
108 default:
109 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000110 case CallingConv::AMDGPU_LS:
111 case CallingConv::AMDGPU_HS:
112 case CallingConv::AMDGPU_ES:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000113 case CallingConv::AMDGPU_GS:
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000114 case CallingConv::AMDGPU_VS:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000115 case CallingConv::AMDGPU_PS:
116 case CallingConv::AMDGPU_CS:
117 case CallingConv::AMDGPU_KERNEL:
118 case CallingConv::SPIR_KERNEL:
119 break;
120 }
121
122 unsigned ArgNo = Arg->getArgNo();
123 /* On an argument, ReadOnly attribute indicates that the function does
124 not write through this pointer argument, even though it may write
125 to the memory that the pointer points to.
126 On an argument, ReadNone attribute indicates that the function does
127 not dereference that pointer argument, even though it may read or write
128 the memory that the pointer points to if accessed through other pointers.
129 */
Reid Klecknerf021fab2017-04-13 23:12:13 +0000130 if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
131 (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
132 F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000133 return true;
134 }
135 }
136 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
137}