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