LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - AMDGPUAliasAnalysis.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 36 37 97.3 %
Date: 2017-09-14 15:23:50 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      317821 : INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa",
      39             :                 "AMDGPU Address space based Alias Analysis", false, true)
      40             : 
      41        1761 : ImmutablePass *llvm::createAMDGPUAAWrapperPass() {
      42        1761 :   return new AMDGPUAAWrapperPass();
      43             : }
      44             : 
      45        1752 : void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
      46        1752 :   AU.setPreservesAll();
      47        1752 : }
      48             : 
      49             : // Must match the table in getAliasResult.
      50        1752 : AMDGPUAAResult::ASAliasRulesTy::ASAliasRulesTy(AMDGPUAS AS_, Triple::ArchType Arch_)
      51        1752 :   : 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    Constant  Group     Region    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        1752 :   if (AS.FLAT_ADDRESS == 0) {
      74             :     assert(AS.GLOBAL_ADDRESS   == 1 &&
      75             :            AS.REGION_ADDRESS   == 4 &&
      76             :            AS.LOCAL_ADDRESS    == 3 &&
      77             :            AS.CONSTANT_ADDRESS == 2 &&
      78             :            AS.PRIVATE_ADDRESS  == 5);
      79          16 :     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        1736 :     ASAliasRules = &ASAliasRulesPrivIsZero;
      88             :   }
      89        1752 : }
      90             : 
      91       52502 : AliasResult AMDGPUAAResult::ASAliasRulesTy::getAliasResult(unsigned AS1,
      92             :     unsigned AS2) const {
      93       52502 :   if (AS1 > AS.MAX_COMMON_ADDRESS || AS2 > AS.MAX_COMMON_ADDRESS) {
      94           1 :     if (Arch == Triple::amdgcn)
      95           0 :       report_fatal_error("Pointer address space out of range");
      96           1 :     return AS1 == AS2 ? MayAlias : NoAlias;
      97             :   }
      98             : 
      99       52501 :   return (*ASAliasRules)[AS1][AS2];
     100             : }
     101             : 
     102       52502 : AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA,
     103             :                                   const MemoryLocation &LocB) {
     104      105004 :   unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace();
     105      105004 :   unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace();
     106             : 
     107       52502 :   AliasResult Result = ASAliasRules.getAliasResult(asA, asB);
     108       52502 :   if (Result == NoAlias) return Result;
     109             : 
     110             :   // Forward the query to the next alias analysis.
     111       52104 :   return AAResultBase::alias(LocA, LocB);
     112             : }
     113             : 
     114       51031 : bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc,
     115             :                                             bool OrLocal) {
     116      102062 :   const Value *Base = GetUnderlyingObject(Loc.Ptr, DL);
     117             : 
     118      102062 :   if (Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS) {
     119             :     return true;
     120             :   }
     121             : 
     122        1685 :   if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
     123        1685 :     if (GV->isConstant())
     124             :       return true;
     125       40758 :   } else if (const Argument *Arg = dyn_cast<Argument>(Base)) {
     126       40758 :     const Function *F = Arg->getParent();
     127             : 
     128             :     // Only assume constant memory for arguments on kernels.
     129       40758 :     switch (F->getCallingConv()) {
     130             :     default:
     131             :       return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
     132             :     case CallingConv::AMDGPU_VS:
     133             :     case CallingConv::AMDGPU_GS:
     134             :     case CallingConv::AMDGPU_PS:
     135             :     case CallingConv::AMDGPU_CS:
     136             :     case CallingConv::AMDGPU_KERNEL:
     137             :     case CallingConv::SPIR_KERNEL:
     138             :       break;
     139             :     }
     140             : 
     141       40590 :     unsigned ArgNo = Arg->getArgNo();
     142             :     /* On an argument, ReadOnly attribute indicates that the function does
     143             :        not write through this pointer argument, even though it may write
     144             :        to the memory that the pointer points to.
     145             :        On an argument, ReadNone attribute indicates that the function does
     146             :        not dereference that pointer argument, even though it may read or write
     147             :        the memory that the pointer points to if accessed through other pointers.
     148             :      */
     149       43192 :     if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) &&
     150        5204 :         (F->hasParamAttribute(ArgNo, Attribute::ReadNone) ||
     151        2602 :          F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) {
     152             :       return true;
     153             :     }
     154             :   }
     155       45414 :   return AAResultBase::pointsToConstantMemory(Loc, OrLocal);
     156             : }

Generated by: LCOV version 1.13