OSDN Git Service

[AMDGPU] Fix some Clang-tidy modernize-use-using and Include What You Use warnings...
[android-x86/external-llvm.git] / lib / Target / AMDGPU / AMDGPUAliasAnalysis.cpp
1 //===- AMDGPUAliasAnalysis ------------------------------------------------===//
2 //
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
13 #include "AMDGPUAliasAnalysis.h"
14 #include "AMDGPU.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/Analysis/AliasAnalysis.h"
17 #include "llvm/Analysis/MemoryLocation.h"
18 #include "llvm/Analysis/ValueTracking.h"
19 #include "llvm/IR/Argument.h"
20 #include "llvm/IR/Attributes.h"
21 #include "llvm/IR/CallingConv.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/GlobalVariable.h"
24 #include "llvm/IR/Type.h"
25 #include "llvm/IR/Value.h"
26 #include "llvm/Pass.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include <cassert>
30
31 using namespace llvm;
32
33 #define DEBUG_TYPE "amdgpu-aa"
34
35 // Register this pass...
36 char AMDGPUAAWrapperPass::ID = 0;
37
38 INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",
39                 "AMDGPU Address space based Alias Analysis", false, true)
40
41 ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
42   return new AMDGPUAAWrapperPass();
43 }
44
45 void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
46   AU.setPreservesAll();
47 }
48
49 // Must match the table in getAliasResult.
50 AMDGPUAAResult::ASAliasRulesTy::ASAliasRulesTy(AMDGPUAS AS_, Triple::ArchType Arch_)
51   : Arch(Arch_), AS(AS_) {
52   // These arrarys are indexed by address space value
53   // enum elements 0 ... to 5
54   static const AliasResult ASAliasRulesPrivIsZero[6][6] = {
55   /*             Private    Global    Constant  Group     Flat      Region*/
56   /* Private  */ {MayAlias, NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
57   /* Global   */ {NoAlias , MayAlias, NoAlias , NoAlias , MayAlias, NoAlias},
58   /* Constant */ {NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, NoAlias},
59   /* Group    */ {NoAlias , NoAlias , NoAlias , MayAlias, MayAlias, NoAlias},
60   /* Flat     */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
61   /* Region   */ {NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, MayAlias}
62   };
63   static const AliasResult ASAliasRulesGenIsZero[6][6] = {
64   /*             Flat       Global    Constant  Group     Region    Private */
65   /* Flat     */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
66   /* Global   */ {MayAlias, MayAlias, NoAlias , NoAlias , NoAlias , NoAlias},
67   /* Constant */ {MayAlias, NoAlias , MayAlias, NoAlias , NoAlias,  NoAlias},
68   /* Group    */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias},
69   /* Region   */ {MayAlias, NoAlias , NoAlias , NoAlias,  MayAlias, NoAlias},
70   /* Private  */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias}
71   };
72   assert(AS.MAX_COMMON_ADDRESS <= 5);
73   if (AS.FLAT_ADDRESS == 0) {
74     assert(AS.GLOBAL_ADDRESS   == 1 &&
75            AS.REGION_ADDRESS   == 4 &&
76            AS.LOCAL_ADDRESS    == 3 &&
77            AS.CONSTANT_ADDRESS == 2 &&
78            AS.PRIVATE_ADDRESS  == 5);
79     ASAliasRules = &ASAliasRulesGenIsZero;
80   } else {
81     assert(AS.PRIVATE_ADDRESS  == 0 &&
82            AS.GLOBAL_ADDRESS   == 1 &&
83            AS.CONSTANT_ADDRESS == 2 &&
84            AS.LOCAL_ADDRESS    == 3 &&
85            AS.FLAT_ADDRESS     == 4 &&
86            AS.REGION_ADDRESS   == 5);
87     ASAliasRules = &ASAliasRulesPrivIsZero;
88   }
89 }
90
91 AliasResult AMDGPUAAResult::ASAliasRulesTy::getAliasResult(unsigned AS1,
92     unsigned AS2) const {
93   if (AS1 > AS.MAX_COMMON_ADDRESS || AS2 > AS.MAX_COMMON_ADDRESS) {
94     if (Arch == Triple::amdgcn)
95       report_fatal_error("Pointer address space out of range");
96     return AS1 == AS2 ? MayAlias : NoAlias;
97   }
98
99   return (*ASAliasRules)[AS1][AS2];
100 }
101
102 AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
103                                   const MemoryLocation &LocB) {
104   unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
105   unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
106
107   AliasResult Result = ASAliasRules.getAliasResult(asA, asB);
108   if (Result == NoAlias) return Result;
109
110   // Forward the query to the next alias analysis.
111   return AAResultBase::alias(LocA, LocB);
112 }
113
114 bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
115                                             bool OrLocal) {
116   const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
117
118   if (Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS) {
119     return true;
120   }
121
122   if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
123     if (GV->isConstant())
124       return true;
125   } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
126     const Function *F = Arg->getParent();
127
128     // Only assume constant memory for arguments on kernels.
129     switch (F->getCallingConv()) {
130     default:
131       return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
132     case CallingConv::AMDGPU_VS:
133     case CallingConv::AMDGPU_GS:
134     case CallingConv::AMDGPU_PS:
135     case CallingConv::AMDGPU_CS:
136     case CallingConv::AMDGPU_KERNEL:
137     case CallingConv::SPIR_KERNEL:
138       break;
139     }
140
141     unsigned ArgNo = Arg->getArgNo();
142     /* On an argument, ReadOnly attribute indicates that the function does
143        not write through this pointer argument, even though it may write
144        to the memory that the pointer points to.
145        On an argument, ReadNone attribute indicates that the function does
146        not dereference that pointer argument, even though it may read or write
147        the memory that the pointer points to if accessed through other pointers.
148      */
149     if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
150         (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
151          F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
152       return true;
153     }
154   }
155   return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
156 }