brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · a579783 Raw
149 lines · cpp
1//===--------------------- NVPTXAliasAnalysis.cpp--------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8/// \file9/// This is the NVPTX address space based alias analysis pass.10//===----------------------------------------------------------------------===//11 12#include "NVPTXAliasAnalysis.h"13#include "MCTargetDesc/NVPTXBaseInfo.h"14#include "NVPTX.h"15#include "llvm/Analysis/ValueTracking.h"16#include "llvm/IR/InlineAsm.h"17#include "llvm/IR/Instructions.h"18#include "llvm/Support/CommandLine.h"19 20using namespace llvm;21 22#define DEBUG_TYPE "NVPTX-aa"23 24static cl::opt<unsigned> TraverseAddressSpacesLimit(25    "nvptx-traverse-address-aliasing-limit", cl::Hidden,26    cl::desc("Depth limit for finding address space through traversal"),27    cl::init(6));28 29AnalysisKey NVPTXAA::Key;30 31char NVPTXAAWrapperPass::ID = 0;32char NVPTXExternalAAWrapper::ID = 0;33 34INITIALIZE_PASS(NVPTXAAWrapperPass, "nvptx-aa",35                "NVPTX Address space based Alias Analysis", false, true)36 37INITIALIZE_PASS(NVPTXExternalAAWrapper, "nvptx-aa-wrapper",38                "NVPTX Address space based Alias Analysis Wrapper", false, true)39 40ImmutablePass *llvm::createNVPTXAAWrapperPass() {41  return new NVPTXAAWrapperPass();42}43 44ImmutablePass *llvm::createNVPTXExternalAAWrapperPass() {45  return new NVPTXExternalAAWrapper();46}47 48NVPTXAAWrapperPass::NVPTXAAWrapperPass() : ImmutablePass(ID) {}49 50void NVPTXAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {51  AU.setPreservesAll();52}53 54static unsigned getAddressSpace(const Value *V, unsigned MaxLookup) {55  // Find the first non-generic address space traversing the UD chain.56  // It is undefined behaviour if a pointer belongs to more than one57  // non-overlapping address spaces along a valid execution path.58  auto GetAS = [](const Value *V) -> unsigned {59    if (const auto *PTy = dyn_cast<PointerType>(V->getType()))60      return PTy->getAddressSpace();61    return ADDRESS_SPACE_GENERIC;62  };63  while (MaxLookup-- && GetAS(V) == ADDRESS_SPACE_GENERIC) {64    const Value *NewV = getUnderlyingObject(V, 1);65    if (NewV == V)66      break;67    V = NewV;68  }69  return GetAS(V);70}71 72static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {73  if ((AS1 == ADDRESS_SPACE_GENERIC) || (AS2 == ADDRESS_SPACE_GENERIC))74    return AliasResult::MayAlias;75 76  // PTX s6.4.1.1. Generic Addressing:77  // A generic address maps to global memory unless it falls within78  // the window for const, local, or shared memory. The Kernel79  // Function Parameters (.param) window is contained within the80  // .global window.81  //82  // Therefore a global pointer may alias with a param pointer on some83  // GPUs via addrspacecast(param->generic->global) when cvta.param84  // instruction is used (PTX 7.7+ and SM_70+).85  //86  // TODO: cvta.param is not yet supported. We need to change aliasing87  // rules once it is added.88 89  // Distributed shared memory aliases with shared memory.90  if (((AS1 == ADDRESS_SPACE_SHARED) &&91       (AS2 == ADDRESS_SPACE_SHARED_CLUSTER)) ||92      ((AS1 == ADDRESS_SPACE_SHARED_CLUSTER) && (AS2 == ADDRESS_SPACE_SHARED)))93    return AliasResult::MayAlias;94 95  return (AS1 == AS2 ? AliasResult::MayAlias : AliasResult::NoAlias);96}97 98AliasResult NVPTXAAResult::alias(const MemoryLocation &Loc1,99                                 const MemoryLocation &Loc2, AAQueryInfo &AAQI,100                                 const Instruction *) {101  unsigned AS1 = getAddressSpace(Loc1.Ptr, TraverseAddressSpacesLimit);102  unsigned AS2 = getAddressSpace(Loc2.Ptr, TraverseAddressSpacesLimit);103 104  return getAliasResult(AS1, AS2);105}106 107// TODO: .param address space may be writable in presence of cvta.param, but108// this instruction is currently not supported. NVPTXLowerArgs also does not109// allow any writes to .param pointers.110static bool isConstOrParam(unsigned AS) {111  return AS == AddressSpace::ADDRESS_SPACE_CONST ||112         AS == AddressSpace::ADDRESS_SPACE_PARAM;113}114 115ModRefInfo NVPTXAAResult::getModRefInfoMask(const MemoryLocation &Loc,116                                            AAQueryInfo &AAQI,117                                            bool IgnoreLocals) {118  if (isConstOrParam(getAddressSpace(Loc.Ptr, TraverseAddressSpacesLimit)))119    return ModRefInfo::NoModRef;120 121  return ModRefInfo::ModRef;122}123 124MemoryEffects NVPTXAAResult::getMemoryEffects(const CallBase *Call,125                                              AAQueryInfo &AAQI) {126  // Inline assembly with no side-effect or memory clobbers should not127  // indirectly access memory in the PTX specification.128  if (const auto *IA = dyn_cast<InlineAsm>(Call->getCalledOperand())) {129    // Volatile is translated as side-effects.130    if (IA->hasSideEffects())131      return MemoryEffects::unknown();132 133    for (const InlineAsm::ConstraintInfo &Constraint : IA->ParseConstraints()) {134      // Indirect constraints (e.g. =*m) are unsupported in inline PTX.135      if (Constraint.isIndirect)136        return MemoryEffects::unknown();137 138      // Memory clobbers prevent optimization.139      if ((Constraint.Type & InlineAsm::ConstraintPrefix::isClobber) &&140          any_of(Constraint.Codes,141                 [](const auto &Code) { return Code == "{memory}"; }))142        return MemoryEffects::unknown();143    }144    return MemoryEffects::none();145  }146 147  return MemoryEffects::unknown();148}149