1 //===- AMDGPUAliasAnalysis ------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 /// This is the AMGPU address space based alias analysis pass.
10 //===----------------------------------------------------------------------===//
12 #include "AMDGPUAliasAnalysis.h"
14 #include "llvm/Analysis/ValueTracking.h"
15 #include "llvm/IR/Instructions.h"
19 #define DEBUG_TYPE "amdgpu-aa"
21 AnalysisKey
AMDGPUAA::Key
;
23 // Register this pass...
24 char AMDGPUAAWrapperPass::ID
= 0;
25 char AMDGPUExternalAAWrapper::ID
= 0;
27 INITIALIZE_PASS(AMDGPUAAWrapperPass
, "amdgpu-aa",
28 "AMDGPU Address space based Alias Analysis", false, true)
30 INITIALIZE_PASS(AMDGPUExternalAAWrapper
, "amdgpu-aa-wrapper",
31 "AMDGPU Address space based Alias Analysis Wrapper", false, true)
33 ImmutablePass
*llvm::createAMDGPUAAWrapperPass() {
34 return new AMDGPUAAWrapperPass();
37 ImmutablePass
*llvm::createAMDGPUExternalAAWrapperPass() {
38 return new AMDGPUExternalAAWrapper();
41 AMDGPUAAWrapperPass::AMDGPUAAWrapperPass() : ImmutablePass(ID
) {
42 initializeAMDGPUAAWrapperPassPass(*PassRegistry::getPassRegistry());
45 void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage
&AU
) const {
49 AliasResult
AMDGPUAAResult::alias(const MemoryLocation
&LocA
,
50 const MemoryLocation
&LocB
, AAQueryInfo
&AAQI
,
51 const Instruction
*) {
52 unsigned asA
= LocA
.Ptr
->getType()->getPointerAddressSpace();
53 unsigned asB
= LocB
.Ptr
->getType()->getPointerAddressSpace();
55 if (!AMDGPU::addrspacesMayAlias(asA
, asB
))
56 return AliasResult::NoAlias
;
58 // In general, FLAT (generic) pointers could be aliased to LOCAL or PRIVATE
59 // pointers. However, as LOCAL or PRIVATE pointers point to local objects, in
60 // certain cases, it's still viable to check whether a FLAT pointer won't
61 // alias to a LOCAL or PRIVATE pointer.
62 MemoryLocation A
= LocA
;
63 MemoryLocation B
= LocB
;
64 // Canonicalize the location order to simplify the following alias check.
65 if (asA
!= AMDGPUAS::FLAT_ADDRESS
) {
69 if (asA
== AMDGPUAS::FLAT_ADDRESS
&&
70 (asB
== AMDGPUAS::LOCAL_ADDRESS
|| asB
== AMDGPUAS::PRIVATE_ADDRESS
)) {
72 getUnderlyingObject(A
.Ptr
->stripPointerCastsForAliasAnalysis());
73 if (const LoadInst
*LI
= dyn_cast
<LoadInst
>(ObjA
)) {
74 // If a generic pointer is loaded from the constant address space, it
75 // could only be a GLOBAL or CONSTANT one as that address space is solely
76 // prepared on the host side, where only GLOBAL or CONSTANT variables are
77 // visible. Note that this even holds for regular functions.
78 if (LI
->getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS
)
79 return AliasResult::NoAlias
;
80 } else if (const Argument
*Arg
= dyn_cast
<Argument
>(ObjA
)) {
81 const Function
*F
= Arg
->getParent();
82 switch (F
->getCallingConv()) {
83 case CallingConv::AMDGPU_KERNEL
:
84 // In the kernel function, kernel arguments won't alias to (local)
85 // variables in shared or private address space.
86 return AliasResult::NoAlias
;
88 // TODO: In the regular function, if that local variable in the
89 // location B is not captured, that argument pointer won't alias to it
96 return AliasResult::MayAlias
;
99 ModRefInfo
AMDGPUAAResult::getModRefInfoMask(const MemoryLocation
&Loc
,
102 unsigned AS
= Loc
.Ptr
->getType()->getPointerAddressSpace();
103 if (AS
== AMDGPUAS::CONSTANT_ADDRESS
||
104 AS
== AMDGPUAS::CONSTANT_ADDRESS_32BIT
)
105 return ModRefInfo::NoModRef
;
107 const Value
*Base
= getUnderlyingObject(Loc
.Ptr
);
108 AS
= Base
->getType()->getPointerAddressSpace();
109 if (AS
== AMDGPUAS::CONSTANT_ADDRESS
||
110 AS
== AMDGPUAS::CONSTANT_ADDRESS_32BIT
)
111 return ModRefInfo::NoModRef
;
113 return ModRefInfo::ModRef
;