Path: blob/main/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp
35269 views
//===- AMDGPUAliasAnalysis ------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7/// \file8/// This is the AMGPU address space based alias analysis pass.9//===----------------------------------------------------------------------===//1011#include "AMDGPUAliasAnalysis.h"12#include "AMDGPU.h"13#include "llvm/Analysis/ValueTracking.h"14#include "llvm/IR/Instructions.h"1516using namespace llvm;1718#define DEBUG_TYPE "amdgpu-aa"1920AnalysisKey AMDGPUAA::Key;2122// Register this pass...23char AMDGPUAAWrapperPass::ID = 0;24char AMDGPUExternalAAWrapper::ID = 0;2526INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",27"AMDGPU Address space based Alias Analysis", false, true)2829INITIALIZE_PASS(AMDGPUExternalAAWrapper, "amdgpu-aa-wrapper",30"AMDGPU Address space based Alias Analysis Wrapper", false, true)3132ImmutablePass *llvm::createAMDGPUAAWrapperPass() {33return new AMDGPUAAWrapperPass();34}3536ImmutablePass *llvm::createAMDGPUExternalAAWrapperPass() {37return new AMDGPUExternalAAWrapper();38}3940AMDGPUAAWrapperPass::AMDGPUAAWrapperPass() : ImmutablePass(ID) {41initializeAMDGPUAAWrapperPassPass(*PassRegistry::getPassRegistry());42}4344void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {45AU.setPreservesAll();46}4748AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,49const MemoryLocation &LocB, AAQueryInfo &AAQI,50const Instruction *) {51unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();52unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();5354if (!AMDGPU::addrspacesMayAlias(asA, asB))55return AliasResult::NoAlias;5657// In general, FLAT (generic) pointers could be aliased to LOCAL or PRIVATE58// pointers. However, as LOCAL or PRIVATE pointers point to local objects, in59// certain cases, it's still viable to check whether a FLAT pointer won't60// alias to a LOCAL or PRIVATE pointer.61MemoryLocation A = LocA;62MemoryLocation B = LocB;63// Canonicalize the location order to simplify the following alias check.64if (asA != AMDGPUAS::FLAT_ADDRESS) {65std::swap(asA, asB);66std::swap(A, B);67}68if (asA == AMDGPUAS::FLAT_ADDRESS &&69(asB == AMDGPUAS::LOCAL_ADDRESS || asB == AMDGPUAS::PRIVATE_ADDRESS)) {70const auto *ObjA =71getUnderlyingObject(A.Ptr->stripPointerCastsForAliasAnalysis());72if (const LoadInst *LI = dyn_cast<LoadInst>(ObjA)) {73// If a generic pointer is loaded from the constant address space, it74// could only be a GLOBAL or CONSTANT one as that address space is solely75// prepared on the host side, where only GLOBAL or CONSTANT variables are76// visible. Note that this even holds for regular functions.77if (LI->getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS)78return AliasResult::NoAlias;79} else if (const Argument *Arg = dyn_cast<Argument>(ObjA)) {80const Function *F = Arg->getParent();81switch (F->getCallingConv()) {82case CallingConv::AMDGPU_KERNEL:83// In the kernel function, kernel arguments won't alias to (local)84// variables in shared or private address space.85return AliasResult::NoAlias;86default:87// TODO: In the regular function, if that local variable in the88// location B is not captured, that argument pointer won't alias to it89// as well.90break;91}92}93}9495return AliasResult::MayAlias;96}9798ModRefInfo AMDGPUAAResult::getModRefInfoMask(const MemoryLocation &Loc,99AAQueryInfo &AAQI,100bool IgnoreLocals) {101unsigned AS = Loc.Ptr->getType()->getPointerAddressSpace();102if (AS == AMDGPUAS::CONSTANT_ADDRESS ||103AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT)104return ModRefInfo::NoModRef;105106const Value *Base = getUnderlyingObject(Loc.Ptr);107AS = Base->getType()->getPointerAddressSpace();108if (AS == AMDGPUAS::CONSTANT_ADDRESS ||109AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT)110return ModRefInfo::NoModRef;111112return ModRefInfo::ModRef;113}114115116