| Eugene Zelenko | d16eff8 | 2017-08-08 23:53:55 +0000 | [diff] [blame] | 1 | //===- AMDGPUAliasAnalysis ------------------------------------------------===// | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 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 |  | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 13 | #include "AMDGPUAliasAnalysis.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 14 | #include "AMDGPU.h" | 
| Eugene Zelenko | d16eff8 | 2017-08-08 23:53:55 +0000 | [diff] [blame] | 15 | #include "llvm/ADT/Triple.h" | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 16 | #include "llvm/Analysis/AliasAnalysis.h" | 
| Eugene Zelenko | d16eff8 | 2017-08-08 23:53:55 +0000 | [diff] [blame] | 17 | #include "llvm/Analysis/MemoryLocation.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 18 | #include "llvm/Analysis/ValueTracking.h" | 
| Eugene Zelenko | d16eff8 | 2017-08-08 23:53:55 +0000 | [diff] [blame] | 19 | #include "llvm/IR/Argument.h" | 
|  | 20 | #include "llvm/IR/Attributes.h" | 
|  | 21 | #include "llvm/IR/CallingConv.h" | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 22 | #include "llvm/IR/Function.h" | 
| Eugene Zelenko | d16eff8 | 2017-08-08 23:53:55 +0000 | [diff] [blame] | 23 | #include "llvm/IR/GlobalVariable.h" | 
|  | 24 | #include "llvm/IR/Type.h" | 
|  | 25 | #include "llvm/IR/Value.h" | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 26 | #include "llvm/Pass.h" | 
| Eugene Zelenko | d16eff8 | 2017-08-08 23:53:55 +0000 | [diff] [blame] | 27 | #include "llvm/Support/Casting.h" | 
|  | 28 | #include "llvm/Support/ErrorHandling.h" | 
|  | 29 | #include <cassert> | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 30 |  | 
|  | 31 | using namespace llvm; | 
|  | 32 |  | 
|  | 33 | #define DEBUG_TYPE "amdgpu-aa" | 
|  | 34 |  | 
|  | 35 | // Register this pass... | 
|  | 36 | char AMDGPUAAWrapperPass::ID = 0; | 
| Eugene Zelenko | d16eff8 | 2017-08-08 23:53:55 +0000 | [diff] [blame] | 37 |  | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 38 | INITIALIZE_PASS(AMDGPUAAWrapperPass, "amdgpu-aa", | 
|  | 39 | "AMDGPU Address space based Alias Analysis", false, true) | 
|  | 40 |  | 
|  | 41 | ImmutablePass *llvm::createAMDGPUAAWrapperPass() { | 
|  | 42 | return new AMDGPUAAWrapperPass(); | 
|  | 43 | } | 
|  | 44 |  | 
|  | 45 | void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { | 
|  | 46 | AU.setPreservesAll(); | 
|  | 47 | } | 
|  | 48 |  | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 49 | // Must match the table in getAliasResult. | 
| Jan Vesely | 3c99441 | 2017-03-31 19:26:23 +0000 | [diff] [blame] | 50 | AMDGPUAAResult::ASAliasRulesTy::ASAliasRulesTy(AMDGPUAS AS_, Triple::ArchType Arch_) | 
|  | 51 | : Arch(Arch_), AS(AS_) { | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 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] = { | 
| Yaxun Liu | 76ae47c | 2017-04-06 19:17:32 +0000 | [diff] [blame] | 64 | /*             Flat       Global    Constant  Group     Region    Private */ | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 65 | /* Flat     */ {MayAlias, MayAlias, MayAlias, MayAlias, MayAlias, MayAlias}, | 
|  | 66 | /* Global   */ {MayAlias, MayAlias, NoAlias , NoAlias , NoAlias , NoAlias}, | 
| Yaxun Liu | 76ae47c | 2017-04-06 19:17:32 +0000 | [diff] [blame] | 67 | /* Constant */ {MayAlias, NoAlias , MayAlias, NoAlias , NoAlias,  NoAlias}, | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 68 | /* Group    */ {MayAlias, NoAlias , NoAlias , MayAlias, NoAlias , NoAlias}, | 
| Yaxun Liu | 76ae47c | 2017-04-06 19:17:32 +0000 | [diff] [blame] | 69 | /* Region   */ {MayAlias, NoAlias , NoAlias , NoAlias,  MayAlias, NoAlias}, | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 70 | /* Private  */ {MayAlias, NoAlias , NoAlias , NoAlias , NoAlias , MayAlias} | 
|  | 71 | }; | 
|  | 72 | assert(AS.MAX_COMMON_ADDRESS <= 5); | 
|  | 73 | if (AS.FLAT_ADDRESS == 0) { | 
|  | 74 | assert(AS.GLOBAL_ADDRESS   == 1 && | 
| Yaxun Liu | 76ae47c | 2017-04-06 19:17:32 +0000 | [diff] [blame] | 75 | AS.REGION_ADDRESS   == 4 && | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 76 | AS.LOCAL_ADDRESS    == 3 && | 
| Yaxun Liu | 76ae47c | 2017-04-06 19:17:32 +0000 | [diff] [blame] | 77 | AS.CONSTANT_ADDRESS == 2 && | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 78 | AS.PRIVATE_ADDRESS  == 5); | 
|  | 79 | 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 | ASAliasRules = &ASAliasRulesPrivIsZero; | 
|  | 88 | } | 
|  | 89 | } | 
|  | 90 |  | 
|  | 91 | AliasResult AMDGPUAAResult::ASAliasRulesTy::getAliasResult(unsigned AS1, | 
|  | 92 | unsigned AS2) const { | 
| Jan Vesely | 3c99441 | 2017-03-31 19:26:23 +0000 | [diff] [blame] | 93 | if (AS1 > AS.MAX_COMMON_ADDRESS || AS2 > AS.MAX_COMMON_ADDRESS) { | 
|  | 94 | if (Arch == Triple::amdgcn) | 
|  | 95 | report_fatal_error("Pointer address space out of range"); | 
|  | 96 | return AS1 == AS2 ? MayAlias : NoAlias; | 
|  | 97 | } | 
|  | 98 |  | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 99 | return (*ASAliasRules)[AS1][AS2]; | 
|  | 100 | } | 
|  | 101 |  | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 102 | AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA, | 
|  | 103 | const MemoryLocation &LocB) { | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 104 | unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace(); | 
|  | 105 | unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace(); | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 106 |  | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 107 | AliasResult Result = ASAliasRules.getAliasResult(asA, asB); | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 108 | if (Result == NoAlias) return Result; | 
|  | 109 |  | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 110 | // Forward the query to the next alias analysis. | 
|  | 111 | return AAResultBase::alias(LocA, LocB); | 
|  | 112 | } | 
|  | 113 |  | 
|  | 114 | bool AMDGPUAAResult::pointsToConstantMemory(const MemoryLocation &Loc, | 
|  | 115 | bool OrLocal) { | 
|  | 116 | const Value *Base = GetUnderlyingObject(Loc.Ptr, DL); | 
|  | 117 |  | 
| Yaxun Liu | 1a14bfa | 2017-03-27 14:04:01 +0000 | [diff] [blame] | 118 | if (Base->getType()->getPointerAddressSpace() == AS.CONSTANT_ADDRESS) { | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 119 | return true; | 
|  | 120 | } | 
|  | 121 |  | 
|  | 122 | if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) { | 
|  | 123 | if (GV->isConstant()) | 
|  | 124 | return true; | 
|  | 125 | } else if (const Argument *Arg = dyn_cast<Argument>(Base)) { | 
|  | 126 | const Function *F = Arg->getParent(); | 
|  | 127 |  | 
|  | 128 | // Only assume constant memory for arguments on kernels. | 
|  | 129 | 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 | 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 | */ | 
| Reid Kleckner | f021fab | 2017-04-13 23:12:13 +0000 | [diff] [blame] | 149 | if (F->hasParamAttribute(ArgNo, Attribute::NoAlias) && | 
|  | 150 | (F->hasParamAttribute(ArgNo, Attribute::ReadNone) || | 
|  | 151 | F->hasParamAttribute(ArgNo, Attribute::ReadOnly))) { | 
| Stanislav Mekhanoshin | 8e45acf | 2017-03-17 23:56:58 +0000 | [diff] [blame] | 152 | return true; | 
|  | 153 | } | 
|  | 154 | } | 
|  | 155 | return AAResultBase::pointsToConstantMemory(Loc, OrLocal); | 
|  | 156 | } |