xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===- AMDGPUAliasAnalysis ------------------------------------------------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This is the AMGPU address space based alias analysis pass.
10 //===----------------------------------------------------------------------===//
11 
12 #include "AMDGPUAliasAnalysis.h"
13 #include "AMDGPU.h"
14 #include "llvm/Analysis/ValueTracking.h"
15 #include "llvm/IR/Instructions.h"
16 
17 using namespace llvm;
18 
19 #define DEBUG_TYPE "amdgpu-aa"
20 
21 AnalysisKey AMDGPUAA::Key;
22 
23 // Register this pass...
24 char AMDGPUAAWrapperPass::ID = 0;
25 char AMDGPUExternalAAWrapper::ID = 0;
26 
27 INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",
28                 "AMDGPU Address space based Alias Analysis", false, true)
29 
30 INITIALIZE_PASS(AMDGPUExternalAAWrapper, "amdgpu-aa-wrapper",
31                 "AMDGPU Address space based Alias Analysis Wrapper", false, true)
32 
33 ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
34   return new AMDGPUAAWrapperPass();
35 }
36 
37 ImmutablePass *llvm::createAMDGPUExternalAAWrapperPass() {
38   return new AMDGPUExternalAAWrapper();
39 }
40 
41 AMDGPUAAWrapperPass::AMDGPUAAWrapperPass() : ImmutablePass(ID) {}
42 
43 void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
44   AU.setPreservesAll();
45 }
46 
47 AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
48                                   const MemoryLocation &LocB, AAQueryInfo &AAQI,
49                                   const Instruction *) {
50   unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
51   unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
52 
53   if (!AMDGPU::addrspacesMayAlias(asA, asB))
54     return AliasResult::NoAlias;
55 
56   // In general, FLAT (generic) pointers could be aliased to LOCAL or PRIVATE
57   // pointers. However, as LOCAL or PRIVATE pointers point to local objects, in
58   // certain cases, it's still viable to check whether a FLAT pointer won't
59   // alias to a LOCAL or PRIVATE pointer.
60   MemoryLocation A = LocA;
61   MemoryLocation B = LocB;
62   // Canonicalize the location order to simplify the following alias check.
63   if (asA != AMDGPUAS::FLAT_ADDRESS) {
64     std::swap(asA, asB);
65     std::swap(A, B);
66   }
67   if (asA == AMDGPUAS::FLAT_ADDRESS &&
68       (asB == AMDGPUAS::LOCAL_ADDRESS || asB == AMDGPUAS::PRIVATE_ADDRESS)) {
69     const auto *ObjA =
70         getUnderlyingObject(A.Ptr->stripPointerCastsForAliasAnalysis());
71     if (const LoadInst *LI = dyn_cast<LoadInst>(ObjA)) {
72       // If a generic pointer is loaded from the constant address space, it
73       // could only be a GLOBAL or CONSTANT one as that address space is solely
74       // prepared on the host side, where only GLOBAL or CONSTANT variables are
75       // visible. Note that this even holds for regular functions.
76       if (LI->getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS)
77         return AliasResult::NoAlias;
78     } else if (const Argument *Arg = dyn_cast<Argument>(ObjA)) {
79       const Function *F = Arg->getParent();
80       switch (F->getCallingConv()) {
81       case CallingConv::AMDGPU_KERNEL: {
82         // In the kernel function, kernel arguments won't alias to (local)
83         // variables in shared or private address space.
84         const auto *ObjB =
85             getUnderlyingObject(B.Ptr->stripPointerCastsForAliasAnalysis());
86         return ObjA != ObjB && isIdentifiedObject(ObjB) ? AliasResult::NoAlias
87                                                         : AliasResult::MayAlias;
88       }
89       default:
90         // TODO: In the regular function, if that local variable in the
91         // location B is not captured, that argument pointer won't alias to it
92         // as well.
93         break;
94       }
95     }
96   }
97 
98   return AliasResult::MayAlias;
99 }
100 
101 ModRefInfo AMDGPUAAResult::getModRefInfoMask(const MemoryLocation &Loc,
102                                              AAQueryInfo &AAQI,
103                                              bool IgnoreLocals) {
104   unsigned AS = Loc.Ptr->getType()->getPointerAddressSpace();
105   if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
106       AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT)
107     return ModRefInfo::NoModRef;
108 
109   const Value *Base = getUnderlyingObject(Loc.Ptr);
110   AS = Base->getType()->getPointerAddressSpace();
111   if (AS == AMDGPUAS::CONSTANT_ADDRESS ||
112       AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT)
113     return ModRefInfo::NoModRef;
114 
115   return ModRefInfo::ModRef;
116 }
117