blob: 629332150cc524277a708d4b38d679c43241ccef [file] [log] [blame]
Eugene Zelenkod16eff82017-08-08 23:53:55 +00001//===- AMDGPUAliasAnalysis ------------------------------------------------===//
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +00006//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This is the AMGPU address space based alias analysis pass.
10//===----------------------------------------------------------------------===//
11
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000012#include "AMDGPUAliasAnalysis.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000013#include "AMDGPU.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000014#include "llvm/ADT/Triple.h"
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000015#include "llvm/Analysis/AliasAnalysis.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000016#include "llvm/Analysis/MemoryLocation.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000017#include "llvm/Analysis/ValueTracking.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000018#include "llvm/IR/Argument.h"
19#include "llvm/IR/Attributes.h"
20#include "llvm/IR/CallingConv.h"
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000021#include "llvm/IR/Function.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000022#include "llvm/IR/GlobalVariable.h"
23#include "llvm/IR/Type.h"
24#include "llvm/IR/Value.h"
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000025#include "llvm/Pass.h"
Eugene Zelenkod16eff82017-08-08 23:53:55 +000026#include "llvm/Support/Casting.h"
27#include "llvm/Support/ErrorHandling.h"
28#include <cassert>
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000029
30using namespace llvm;
31
32#define DEBUG_TYPE "amdgpu-aa"
33
34// Register this pass...
35char AMDGPUAAWrapperPass::ID = 0;
Matt Arsenault8ba740a2018-11-07 20:26:42 +000036char AMDGPUExternalAAWrapper::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
Matt Arsenault8ba740a2018-11-07 20:26:42 +000041INITIALIZE_PASS(AMDGPUExternalAAWrapper, "amdgpu-aa-wrapper",
42 "AMDGPU Address space based Alias Analysis Wrapper", false, true)
43
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000044ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
45 return new AMDGPUAAWrapperPass();
46}
47
Matt Arsenault8ba740a2018-11-07 20:26:42 +000048ImmutablePass *llvm::createAMDGPUExternalAAWrapperPass() {
49 return new AMDGPUExternalAAWrapper();
50}
51
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000052void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
53 AU.setPreservesAll();
54}
55
Matt Arsenault796b0e72018-09-11 04:00:49 +000056// These arrays are indexed by address space value enum elements 0 ... to 6
57static const AliasResult ASAliasRules[7][7] = {
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000058 /* Flat Global Region Group Constant Private Constant 32-bit */
59 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
60 /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias},
61 /* Region */ {MayAlias, NoAlias , NoAlias , NoAlias, MayAlias, NoAlias , MayAlias},
62 /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias , NoAlias},
63 /* Constant */ {MayAlias, MayAlias, MayAlias, NoAlias , NoAlias, NoAlias , MayAlias},
64 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
65 /* Constant 32-bit */ {MayAlias, MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , NoAlias}
Matt Arsenault796b0e72018-09-11 04:00:49 +000066};
Matt Arsenault0da63502018-08-31 05:49:54 +000067
Matt Arsenault796b0e72018-09-11 04:00:49 +000068static AliasResult getAliasResult(unsigned AS1, unsigned AS2) {
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000069 static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 6, "Addr space out of range");
Matt Arsenault0da63502018-08-31 05:49:54 +000070
Matt Arsenault796b0e72018-09-11 04:00:49 +000071 if (AS1 > AMDGPUAS::MAX_AMDGPU_ADDRESS || AS2 > AMDGPUAS::MAX_AMDGPU_ADDRESS)
72 return MayAlias;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000073
Matt Arsenault796b0e72018-09-11 04:00:49 +000074 return ASAliasRules[AS1][AS2];
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000075}
76
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000077AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
78 const MemoryLocation &LocB) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000079 unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
80 unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000081
Matt Arsenault796b0e72018-09-11 04:00:49 +000082 AliasResult Result = getAliasResult(asA, asB);
83 if (Result == NoAlias)
84 return Result;
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000085
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000086 // Forward the query to the next alias analysis.
87 return AAResultBase::alias(LocA, LocB);
88}
89
90bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
91 bool OrLocal) {
92 const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
Matt Arsenault0da63502018-08-31 05:49:54 +000093 unsigned AS = Base->getType()->getPointerAddressSpace();
94 if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
95 AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000096 return true;
97 }
98
99 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
100 if (GV->isConstant())
101 return true;
102 } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
103 const Function *F = Arg->getParent();
104
105 // Only assume constant memory for arguments on kernels.
106 switch (F->getCallingConv()) {
107 default:
108 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000109 case CallingConv::AMDGPU_LS:
110 case CallingConv::AMDGPU_HS:
111 case CallingConv::AMDGPU_ES:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000112 case CallingConv::AMDGPU_GS:
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000113 case CallingConv::AMDGPU_VS:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000114 case CallingConv::AMDGPU_PS:
115 case CallingConv::AMDGPU_CS:
116 case CallingConv::AMDGPU_KERNEL:
117 case CallingConv::SPIR_KERNEL:
118 break;
119 }
120
121 unsigned ArgNo = Arg->getArgNo();
122 /* On an argument, ReadOnly attribute indicates that the function does
123 not write through this pointer argument, even though it may write
124 to the memory that the pointer points to.
125 On an argument, ReadNone attribute indicates that the function does
126 not dereference that pointer argument, even though it may read or write
127 the memory that the pointer points to if accessed through other pointers.
128 */
Reid Klecknerf021fab2017-04-13 23:12:13 +0000129 if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
130 (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
131 F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000132 return true;
133 }
134 }
135 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
136}