1d16eff81SEugene Zelenko //===- AMDGPUAliasAnalysis ------------------------------------------------===// 28e45acfcSStanislav Mekhanoshin // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68e45acfcSStanislav Mekhanoshin // 78e45acfcSStanislav Mekhanoshin //===----------------------------------------------------------------------===// 88e45acfcSStanislav Mekhanoshin /// \file 98e45acfcSStanislav Mekhanoshin /// This is the AMGPU address space based alias analysis pass. 108e45acfcSStanislav Mekhanoshin //===----------------------------------------------------------------------===// 118e45acfcSStanislav Mekhanoshin 128e45acfcSStanislav Mekhanoshin #include "AMDGPUAliasAnalysis.h" 136bda14b3SChandler Carruth #include "AMDGPU.h" 14d16eff81SEugene Zelenko #include "llvm/ADT/Triple.h" 158e45acfcSStanislav Mekhanoshin #include "llvm/Analysis/AliasAnalysis.h" 16d16eff81SEugene Zelenko #include "llvm/Analysis/MemoryLocation.h" 176bda14b3SChandler Carruth #include "llvm/Analysis/ValueTracking.h" 18d16eff81SEugene Zelenko #include "llvm/IR/Argument.h" 19d16eff81SEugene Zelenko #include "llvm/IR/Attributes.h" 20d16eff81SEugene Zelenko #include "llvm/IR/CallingConv.h" 218e45acfcSStanislav Mekhanoshin #include "llvm/IR/Function.h" 22d16eff81SEugene Zelenko #include "llvm/IR/GlobalVariable.h" 23d16eff81SEugene Zelenko #include "llvm/IR/Type.h" 24d16eff81SEugene Zelenko #include "llvm/IR/Value.h" 258e45acfcSStanislav Mekhanoshin #include "llvm/Pass.h" 26d16eff81SEugene Zelenko #include "llvm/Support/Casting.h" 27d16eff81SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 28d16eff81SEugene Zelenko #include <cassert> 298e45acfcSStanislav Mekhanoshin 308e45acfcSStanislav Mekhanoshin using namespace llvm; 318e45acfcSStanislav Mekhanoshin 328e45acfcSStanislav Mekhanoshin #define DEBUG_TYPE "amdgpu-aa" 338e45acfcSStanislav Mekhanoshin 348e45acfcSStanislav Mekhanoshin // Register this pass... 358e45acfcSStanislav Mekhanoshin char AMDGPUAAWrapperPass::ID = 0; 368ba740a5SMatt Arsenault char AMDGPUExternalAAWrapper::ID = 0; 37d16eff81SEugene Zelenko 388e45acfcSStanislav Mekhanoshin INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa", 398e45acfcSStanislav Mekhanoshin "AMDGPU Address space based Alias Analysis", false, true) 408e45acfcSStanislav Mekhanoshin 418ba740a5SMatt Arsenault INITIALIZE_PASS(AMDGPUExternalAAWrapper, "amdgpu-aa-wrapper", 428ba740a5SMatt Arsenault "AMDGPU Address space based Alias Analysis Wrapper", false, true) 438ba740a5SMatt Arsenault 448e45acfcSStanislav Mekhanoshin ImmutablePass *llvm::createAMDGPUAAWrapperPass() { 458e45acfcSStanislav Mekhanoshin return new AMDGPUAAWrapperPass(); 468e45acfcSStanislav Mekhanoshin } 478e45acfcSStanislav Mekhanoshin 488ba740a5SMatt Arsenault ImmutablePass *llvm::createAMDGPUExternalAAWrapperPass() { 498ba740a5SMatt Arsenault return new AMDGPUExternalAAWrapper(); 508ba740a5SMatt Arsenault } 518ba740a5SMatt Arsenault 528e45acfcSStanislav Mekhanoshin void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { 538e45acfcSStanislav Mekhanoshin AU.setPreservesAll(); 548e45acfcSStanislav Mekhanoshin } 558e45acfcSStanislav Mekhanoshin 56523dab07SNeil Henning // These arrays are indexed by address space value enum elements 0 ... to 7 57523dab07SNeil Henning static const AliasResult ASAliasRules[8][8] = { 58523dab07SNeil Henning /* Flat Global Region Group Constant Private Constant 32-bit Buffer Fat Ptr */ 59a256b8b7SNicolai Haehnle /* Flat */ {MayAlias, MayAlias, NoAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias}, 60523dab07SNeil Henning /* Global */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, MayAlias}, 61a256b8b7SNicolai Haehnle /* Region */ {NoAlias, NoAlias , MayAlias, NoAlias , NoAlias, NoAlias , NoAlias, NoAlias}, 62523dab07SNeil Henning /* Group */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias , NoAlias , NoAlias}, 63a256b8b7SNicolai Haehnle /* Constant */ {MayAlias, MayAlias, NoAlias, NoAlias , NoAlias , NoAlias , MayAlias, MayAlias}, 64523dab07SNeil Henning /* Private */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, NoAlias , NoAlias}, 65a256b8b7SNicolai Haehnle /* Constant 32-bit */ {MayAlias, MayAlias, NoAlias, NoAlias , MayAlias, NoAlias , NoAlias , MayAlias}, 66523dab07SNeil Henning /* Buffer Fat Ptr */ {MayAlias, MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, MayAlias} 671a14bfa0SYaxun Liu }; 680da6350dSMatt Arsenault 69796b0e7aSMatt Arsenault static AliasResult getAliasResult(unsigned AS1, unsigned AS2) { 70523dab07SNeil Henning static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 7, "Addr space out of range"); 710da6350dSMatt Arsenault 72796b0e7aSMatt Arsenault if (AS1 > AMDGPUAS::MAX_AMDGPU_ADDRESS || AS2 > AMDGPUAS::MAX_AMDGPU_ADDRESS) 73796b0e7aSMatt Arsenault return MayAlias; 741a14bfa0SYaxun Liu 75796b0e7aSMatt Arsenault return ASAliasRules[AS1][AS2]; 761a14bfa0SYaxun Liu } 771a14bfa0SYaxun Liu 788e45acfcSStanislav Mekhanoshin AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA, 79bfc779e4SAlina Sbirlea const MemoryLocation &LocB, 80bfc779e4SAlina Sbirlea AAQueryInfo &AAQI) { 818e45acfcSStanislav Mekhanoshin unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace(); 828e45acfcSStanislav Mekhanoshin unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace(); 838e45acfcSStanislav Mekhanoshin 84796b0e7aSMatt Arsenault AliasResult Result = getAliasResult(asA, asB); 85796b0e7aSMatt Arsenault if (Result == NoAlias) 86796b0e7aSMatt Arsenault return Result; 878e45acfcSStanislav Mekhanoshin 888e45acfcSStanislav Mekhanoshin // Forward the query to the next alias analysis. 89bfc779e4SAlina Sbirlea return AAResultBase::alias(LocA, LocB, AAQI); 908e45acfcSStanislav Mekhanoshin } 918e45acfcSStanislav Mekhanoshin 928e45acfcSStanislav Mekhanoshin bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc, 93bfc779e4SAlina Sbirlea AAQueryInfo &AAQI, bool OrLocal) { 94beda9d04SMatt Arsenault unsigned AS = Loc.Ptr->getType()->getPointerAddressSpace(); 950da6350dSMatt Arsenault if (AS == AMDGPUAS::CONSTANT_ADDRESS || 96beda9d04SMatt Arsenault AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) 978e45acfcSStanislav Mekhanoshin return true; 98beda9d04SMatt Arsenault 99*b0eb40caSVitaly Buka const Value *Base = getUnderlyingObject(Loc.Ptr); 100beda9d04SMatt Arsenault AS = Base->getType()->getPointerAddressSpace(); 101beda9d04SMatt Arsenault if (AS == AMDGPUAS::CONSTANT_ADDRESS || 102beda9d04SMatt Arsenault AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) 103beda9d04SMatt Arsenault return true; 1048e45acfcSStanislav Mekhanoshin 1058e45acfcSStanislav Mekhanoshin if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) { 1068e45acfcSStanislav Mekhanoshin if (GV->isConstant()) 1078e45acfcSStanislav Mekhanoshin return true; 1088e45acfcSStanislav Mekhanoshin } else if (const Argument *Arg = dyn_cast<Argument>(Base)) { 1098e45acfcSStanislav Mekhanoshin const Function *F = Arg->getParent(); 1108e45acfcSStanislav Mekhanoshin 1118e45acfcSStanislav Mekhanoshin // Only assume constant memory for arguments on kernels. 1128e45acfcSStanislav Mekhanoshin switch (F->getCallingConv()) { 1138e45acfcSStanislav Mekhanoshin default: 114bfc779e4SAlina Sbirlea return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal); 115ef1ae8ffSTim Renouf case CallingConv::AMDGPU_LS: 116ef1ae8ffSTim Renouf case CallingConv::AMDGPU_HS: 117ef1ae8ffSTim Renouf case CallingConv::AMDGPU_ES: 1188e45acfcSStanislav Mekhanoshin case CallingConv::AMDGPU_GS: 119ef1ae8ffSTim Renouf case CallingConv::AMDGPU_VS: 1208e45acfcSStanislav Mekhanoshin case CallingConv::AMDGPU_PS: 1218e45acfcSStanislav Mekhanoshin case CallingConv::AMDGPU_CS: 1228e45acfcSStanislav Mekhanoshin case CallingConv::AMDGPU_KERNEL: 1238e45acfcSStanislav Mekhanoshin case CallingConv::SPIR_KERNEL: 1248e45acfcSStanislav Mekhanoshin break; 1258e45acfcSStanislav Mekhanoshin } 1268e45acfcSStanislav Mekhanoshin 1278e45acfcSStanislav Mekhanoshin unsigned ArgNo = Arg->getArgNo(); 1288e45acfcSStanislav Mekhanoshin /* On an argument, ReadOnly attribute indicates that the function does 1298e45acfcSStanislav Mekhanoshin not write through this pointer argument, even though it may write 1308e45acfcSStanislav Mekhanoshin to the memory that the pointer points to. 1318e45acfcSStanislav Mekhanoshin On an argument, ReadNone attribute indicates that the function does 1328e45acfcSStanislav Mekhanoshin not dereference that pointer argument, even though it may read or write 1338e45acfcSStanislav Mekhanoshin the memory that the pointer points to if accessed through other pointers. 1348e45acfcSStanislav Mekhanoshin */ 135f021fab2SReid Kleckner if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) && 136f021fab2SReid Kleckner (F->hasParamAttribute(ArgNo, Attribute::ReadNone) || 137f021fab2SReid Kleckner F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) { 1388e45acfcSStanislav Mekhanoshin return true; 1398e45acfcSStanislav Mekhanoshin } 1408e45acfcSStanislav Mekhanoshin } 141bfc779e4SAlina Sbirlea return AAResultBase::pointsToConstantMemory(Loc, AAQI, OrLocal); 1428e45acfcSStanislav Mekhanoshin } 143