LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPUAliasAnalysis.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 30 32 93.8 %
Date: 2018-07-13 00:08:38 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- AMDGPUAliasAnalysis ------------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : /// \file
      10             : /// This is the AMGPU address space based alias analysis pass.
      11             : //===----------------------------------------------------------------------===//
      12             : 
      13             : #include "AMDGPUAliasAnalysis.h"
      14             : #include "AMDGPU.h"
      15             : #include "llvm/ADT/Triple.h"
      16             : #include "llvm/Analysis/AliasAnalysis.h"
      17             : #include "llvm/Analysis/MemoryLocation.h"
      18             : #include "llvm/Analysis/ValueTracking.h"
      19             : #include "llvm/IR/Argument.h"
      20             : #include "llvm/IR/Attributes.h"
      21             : #include "llvm/IR/CallingConv.h"
      22             : #include "llvm/IR/Function.h"
      23             : #include "llvm/IR/GlobalVariable.h"
      24             : #include "llvm/IR/Type.h"
      25             : #include "llvm/IR/Value.h"
      26             : #include "llvm/Pass.h"
      27             : #include "llvm/Support/Casting.h"
      28             : #include "llvm/Support/ErrorHandling.h"
      29             : #include <cassert>
      30             : 
      31             : using namespace llvm;
      32             : 
      33             : #define DEBUG_TYPE "amdgpu-aa"
      34             : 
      35             : // Register this pass...
      36             : char AMDGPUAAWrapperPass::ID = 0;
      37             : 
      38      346840 : INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",
      39             :                 "AMDGPU Address space based Alias Analysis", false, true)
      40             : 
      41        2135 : ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
      42        2135 :   return new AMDGPUAAWrapperPass();
      43             : }
      44             : 
      45        2122 : void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
      46             :   AU.setPreservesAll();
      47        2122 : }
      48             : 
      49             : // Must match the table in getAliasResult.
      50        2122 : AMDGPUAAResult::ASAliasRulesTy::ASAliasRulesTy(AMDGPUAS AS_, Triple::ArchType Arch_)
      51        2122 :   : Arch(Arch_), AS(AS_) {
      52             :   // These arrarys are indexed by address space value
      53             :   // enum elements 0 ... to 5
      54             :   static const AliasResult ASAliasRulesPrivIsZero[6][6] = {
      55             :   /*             Private    Global    Constant  Group     Flat      Region*/
      56             :   /* Private  */ {MayAlias, NoAlias , NoAlias , NoAlias , MayAlias, NoAlias},
      57             :   /* Global   */ {NoAlias , MayAlias, NoAlias , NoAlias , MayAlias, NoAlias},
      58             :   /* Constant */ {NoAlias , NoAlias , MayAlias, NoAlias , MayAlias, NoAlias},
      59             :   /* Group    */ {NoAlias , NoAlias , NoAlias , MayAlias, MayAlias, NoAlias},
      60             :   /* Flat     */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
      61             :   /* Region   */ {NoAlias , NoAlias , NoAlias , NoAlias , MayAlias, MayAlias}
      62             :   };
      63             :   static const AliasResult ASAliasRulesGenIsZero[6][6] = {
      64             :   /*             Flat       Global    Region    Group     Constant  Private */
      65             :   /* Flat     */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias},
      66             :   /* Global   */ {MayAlias, MayAlias, NoAlias , NoAlias , NoAlias , NoAlias},
      67             :   /* Constant */ {MayAlias, NoAlias , MayAlias, NoAlias , NoAlias,  NoAlias},
      68             :   /* Group    */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias},
      69             :   /* Region   */ {MayAlias, NoAlias , NoAlias , NoAlias,  MayAlias, NoAlias},
      70             :   /* Private  */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias}
      71             :   };
      72             :   assert(AS.MAX_COMMON_ADDRESS <= 5);
      73        2122 :   if (AS.FLAT_ADDRESS == 0) {
      74             :     assert(AS.GLOBAL_ADDRESS   == 1 &&
      75             :            AS.REGION_ADDRESS   == 2 &&
      76             :            AS.LOCAL_ADDRESS    == 3 &&
      77             :            AS.CONSTANT_ADDRESS == 4 &&
      78             :            AS.PRIVATE_ADDRESS  == 5);
      79        2122 :     ASAliasRules = &ASAliasRulesGenIsZero;
      80             :   } else {
      81             :     assert(AS.PRIVATE_ADDRESS  == 0 &&
      82             :            AS.GLOBAL_ADDRESS   == 1 &&
      83             :            AS.CONSTANT_ADDRESS == 2 &&
      84             :            AS.LOCAL_ADDRESS    == 3 &&
      85             :            AS.FLAT_ADDRESS     == 4 &&
      86             :            AS.REGION_ADDRESS   == 5);
      87           0 :     ASAliasRules = &ASAliasRulesPrivIsZero;
      88             :   }
      89        2122 : }
      90             : 
      91       71863 : AliasResult AMDGPUAAResult::ASAliasRulesTy::getAliasResult(unsigned AS1,
      92             :     unsigned AS2) const {
      93       71863 :   if (AS1 > AS.MAX_COMMON_ADDRESS || AS2 > AS.MAX_COMMON_ADDRESS) {
      94           3 :     if (Arch == Triple::amdgcn)
      95           0 :       report_fatal_error("Pointer address space out of range");
      96           3 :     return AS1 == AS2 ? MayAlias : NoAlias;
      97             :   }
      98             : 
      99       71860 :   return (*ASAliasRules)[AS1][AS2];
     100             : }
     101             : 
     102       71863 : AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
     103             :                                   const MemoryLocation &LocB) {
     104       71863 :   unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
     105       71863 :   unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
     106             : 
     107       71863 :   AliasResult Result = ASAliasRules.getAliasResult(asA, asB);
     108       71863 :   if (Result == NoAlias) return Result;
     109             : 
     110             :   // Forward the query to the next alias analysis.
     111       66175 :   return AAResultBase::alias(LocA, LocB);
     112             : }
     113             : 
     114       81796 : bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
     115             :                                             bool OrLocal) {
     116       81796 :   const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
     117             : 
     118      163592 :   if (Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS ||
     119             :       Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS_32BIT) {
     120             :     return true;
     121             :   }
     122             : 
     123             :   if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
     124        2253 :     if (GV->isConstant())
     125             :       return true;
     126             :   } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
     127       11558 :     const Function *F = Arg->getParent();
     128             : 
     129             :     // Only assume constant memory for arguments on kernels.
     130             :     switch (F->getCallingConv()) {
     131             :     default:
     132             :       return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
     133             :     case CallingConv::AMDGPU_LS:
     134             :     case CallingConv::AMDGPU_HS:
     135             :     case CallingConv::AMDGPU_ES:
     136             :     case CallingConv::AMDGPU_GS:
     137             :     case CallingConv::AMDGPU_VS:
     138             :     case CallingConv::AMDGPU_PS:
     139             :     case CallingConv::AMDGPU_CS:
     140             :     case CallingConv::AMDGPU_KERNEL:
     141             :     case CallingConv::SPIR_KERNEL:
     142             :       break;
     143             :     }
     144             : 
     145       10675 :     unsigned ArgNo = Arg->getArgNo();
     146             :     /* On an argument, ReadOnly attribute indicates that the function does
     147             :        not write through this pointer argument, even though it may write
     148             :        to the memory that the pointer points to.
     149             :        On an argument, ReadNone attribute indicates that the function does
     150             :        not dereference that pointer argument, even though it may read or write
     151             :        the memory that the pointer points to if accessed through other pointers.
     152             :      */
     153       13721 :     if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
     154        3046 :         (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
     155             :          F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
     156             :       return true;
     157             :     }
     158             :   }
     159       56870 :   return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
     160             : }

Generated by: LCOV version 1.13