blob: de54db3b1b02de6919f7efa86827277e98303dd8 [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
Neil Henning523dab02019-03-18 14:44:28 +000056// These arrays are indexed by address space value enum elements 0 ... to 7
57static const AliasResult ASAliasRules[8][8] = {
58 /* Flat Global Region Group Constant Private Constant 32-bit Buffer Fat Ptr */
59 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
60 /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, MayAlias},
61 /* Region */ {MayAlias, NoAlias , NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, NoAlias},
62 /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias , NoAlias , NoAlias},
63 /* Constant */ {MayAlias, MayAlias, MayAlias, NoAlias , NoAlias , NoAlias , MayAlias, MayAlias},
64 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, NoAlias , NoAlias},
65 /* Constant 32-bit */ {MayAlias, MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , NoAlias , MayAlias},
66 /* Buffer Fat Ptr */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, MayAlias}
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) {
Neil Henning523dab02019-03-18 14:44:28 +000070 static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 7, "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,
Alina Sbirleabfc779e2019-03-22 17:22:19 +000079 const MemoryLocation &LocB,
80 AAQueryInfo &AAQI) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000081 unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
82 unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000083
Matt Arsenault796b0e72018-09-11 04:00:49 +000084 AliasResult Result = getAliasResult(asA, asB);
85 if (Result == NoAlias)
86 return Result;
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000087
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000088 // Forward the query to the next alias analysis.
Alina Sbirleabfc779e2019-03-22 17:22:19 +000089 return AAResultBase::alias(LocA, LocB, AAQI);
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000090}
91
92bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
Alina Sbirleabfc779e2019-03-22 17:22:19 +000093 AAQueryInfo &AAQI, bool OrLocal) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000094 const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
Matt Arsenault0da63502018-08-31 05:49:54 +000095 unsigned AS = Base->getType()->getPointerAddressSpace();
96 if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
97 AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000098 return true;
99 }
100
101 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
102 if (GV->isConstant())
103 return true;
104 } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
105 const Function *F = Arg->getParent();
106
107 // Only assume constant memory for arguments on kernels.
108 switch (F->getCallingConv()) {
109 default:
Alina Sbirleabfc779e2019-03-22 17:22:19 +0000110 return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000111 case CallingConv::AMDGPU_LS:
112 case CallingConv::AMDGPU_HS:
113 case CallingConv::AMDGPU_ES:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000114 case CallingConv::AMDGPU_GS:
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000115 case CallingConv::AMDGPU_VS:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000116 case CallingConv::AMDGPU_PS:
117 case CallingConv::AMDGPU_CS:
118 case CallingConv::AMDGPU_KERNEL:
119 case CallingConv::SPIR_KERNEL:
120 break;
121 }
122
123 unsigned ArgNo = Arg->getArgNo();
124 /* On an argument, ReadOnly attribute indicates that the function does
125 not write through this pointer argument, even though it may write
126 to the memory that the pointer points to.
127 On an argument, ReadNone attribute indicates that the function does
128 not dereference that pointer argument, even though it may read or write
129 the memory that the pointer points to if accessed through other pointers.
130 */
Reid Klecknerf021fab2017-04-13 23:12:13 +0000131 if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
132 (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
133 F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000134 return true;
135 }
136 }
Alina Sbirleabfc779e2019-03-22 17:22:19 +0000137 return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal);
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000138}