blob: 77e39c20044d879bcab5a3a523ded9defdf17adb [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.
Matt Arsenault0da63502018-08-31 05:49:54 +000050AMDGPUAAResult::ASAliasRulesTy::ASAliasRulesTy(Triple::ArchType Arch_)
51 : Arch(Arch_) {
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
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000054 static const AliasResult ASAliasRulesGenIsZero[7][7] = {
55 /* Flat Global Region Group Constant Private Constant 32-bit */
56 /* Flat */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
57 /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias},
58 /* Region */ {MayAlias, NoAlias , NoAlias , NoAlias, MayAlias, NoAlias , MayAlias},
59 /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias , NoAlias},
60 /* Constant */ {MayAlias, MayAlias, MayAlias, NoAlias , NoAlias, NoAlias , MayAlias},
61 /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
62 /* Constant 32-bit */ {MayAlias, MayAlias, MayAlias, NoAlias , MayAlias, NoAlias , NoAlias}
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000063 };
Matt Arsenault0da63502018-08-31 05:49:54 +000064
Samuel Pitoiset7bd9dcf2018-08-22 16:08:48 +000065 static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 6, "Addr space out of range");
Matt Arsenault0da63502018-08-31 05:49:54 +000066
67 ASAliasRules = &ASAliasRulesGenIsZero;
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000068}
69
70AliasResult AMDGPUAAResult::ASAliasRulesTy::getAliasResult(unsigned AS1,
71 unsigned AS2) const {
Matt Arsenault0da63502018-08-31 05:49:54 +000072 if (AS1 > AMDGPUAS::MAX_AMDGPU_ADDRESS || AS2 > AMDGPUAS::MAX_AMDGPU_ADDRESS) {
Jan Vesely3c994412017-03-31 19:26:23 +000073 if (Arch == Triple::amdgcn)
74 report_fatal_error("Pointer address space out of range");
75 return AS1 == AS2 ? MayAlias : NoAlias;
76 }
77
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000078 return (*ASAliasRules)[AS1][AS2];
79}
80
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000081AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
82 const MemoryLocation &LocB) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000083 unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
84 unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000085
Yaxun Liu1a14bfa2017-03-27 14:04:01 +000086 AliasResult Result = ASAliasRules.getAliasResult(asA, asB);
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000087 if (Result == NoAlias) return Result;
88
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000089 // Forward the query to the next alias analysis.
90 return AAResultBase::alias(LocA, LocB);
91}
92
93bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
94 bool OrLocal) {
95 const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
Matt Arsenault0da63502018-08-31 05:49:54 +000096 unsigned AS = Base->getType()->getPointerAddressSpace();
97 if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
98 AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +000099 return true;
100 }
101
102 if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
103 if (GV->isConstant())
104 return true;
105 } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
106 const Function *F = Arg->getParent();
107
108 // Only assume constant memory for arguments on kernels.
109 switch (F->getCallingConv()) {
110 default:
111 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000112 case CallingConv::AMDGPU_LS:
113 case CallingConv::AMDGPU_HS:
114 case CallingConv::AMDGPU_ES:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000115 case CallingConv::AMDGPU_GS:
Tim Renoufef1ae8f2017-09-29 09:51:22 +0000116 case CallingConv::AMDGPU_VS:
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000117 case CallingConv::AMDGPU_PS:
118 case CallingConv::AMDGPU_CS:
119 case CallingConv::AMDGPU_KERNEL:
120 case CallingConv::SPIR_KERNEL:
121 break;
122 }
123
124 unsigned ArgNo = Arg->getArgNo();
125 /* On an argument, ReadOnly attribute indicates that the function does
126 not write through this pointer argument, even though it may write
127 to the memory that the pointer points to.
128 On an argument, ReadNone attribute indicates that the function does
129 not dereference that pointer argument, even though it may read or write
130 the memory that the pointer points to if accessed through other pointers.
131 */
Reid Klecknerf021fab2017-04-13 23:12:13 +0000132 if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
133 (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
134 F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
Stanislav Mekhanoshin8e45acf2017-03-17 23:56:58 +0000135 return true;
136 }
137 }
138 return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
139}