Home | History | Annotate | Download | only in AMDGPU
      1 //==- AMDGPUArgumentrUsageInfo.h - Function Arg Usage Info -------*- C++ -*-==//
      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 
     10 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUARGUMENTUSAGEINFO_H
     11 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUARGUMENTUSAGEINFO_H
     12 
     13 #include "llvm/ADT/DenseMap.h"
     14 #include "llvm/IR/Function.h"
     15 #include "llvm/Pass.h"
     16 
     17 namespace llvm {
     18 
     19 class Function;
     20 class raw_ostream;
     21 class GCNSubtarget;
     22 class TargetMachine;
     23 class TargetRegisterClass;
     24 class TargetRegisterInfo;
     25 
     26 struct ArgDescriptor {
     27 private:
     28   friend struct AMDGPUFunctionArgInfo;
     29   friend class AMDGPUArgumentUsageInfo;
     30 
     31   union {
     32     unsigned Register;
     33     unsigned StackOffset;
     34   };
     35 
     36   bool IsStack : 1;
     37   bool IsSet : 1;
     38 
     39   ArgDescriptor(unsigned Val = 0, bool IsStack = false, bool IsSet = false)
     40     : Register(Val), IsStack(IsStack), IsSet(IsSet) {}
     41 public:
     42   static ArgDescriptor createRegister(unsigned Reg) {
     43     return ArgDescriptor(Reg, false, true);
     44   }
     45 
     46   static ArgDescriptor createStack(unsigned Reg) {
     47     return ArgDescriptor(Reg, true, true);
     48   }
     49 
     50   bool isSet() const {
     51     return IsSet;
     52   }
     53 
     54   explicit operator bool() const {
     55     return isSet();
     56   }
     57 
     58   bool isRegister() const {
     59     return !IsStack;
     60   }
     61 
     62   unsigned getRegister() const {
     63     assert(!IsStack);
     64     return Register;
     65   }
     66 
     67   unsigned getStackOffset() const {
     68     assert(IsStack);
     69     return StackOffset;
     70   }
     71 
     72   void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const;
     73 };
     74 
     75 inline raw_ostream &operator<<(raw_ostream &OS, const ArgDescriptor &Arg) {
     76   Arg.print(OS);
     77   return OS;
     78 }
     79 
     80 struct AMDGPUFunctionArgInfo {
     81   enum PreloadedValue {
     82     // SGPRS:
     83     PRIVATE_SEGMENT_BUFFER = 0,
     84     DISPATCH_PTR        =  1,
     85     QUEUE_PTR           =  2,
     86     KERNARG_SEGMENT_PTR =  3,
     87     DISPATCH_ID         =  4,
     88     FLAT_SCRATCH_INIT   =  5,
     89     WORKGROUP_ID_X      = 10,
     90     WORKGROUP_ID_Y      = 11,
     91     WORKGROUP_ID_Z      = 12,
     92     PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14,
     93     IMPLICIT_BUFFER_PTR = 15,
     94     IMPLICIT_ARG_PTR = 16,
     95 
     96     // VGPRS:
     97     WORKITEM_ID_X       = 17,
     98     WORKITEM_ID_Y       = 18,
     99     WORKITEM_ID_Z       = 19,
    100     FIRST_VGPR_VALUE    = WORKITEM_ID_X
    101   };
    102 
    103   // Kernel input registers setup for the HSA ABI in allocation order.
    104 
    105   // User SGPRs in kernels
    106   // XXX - Can these require argument spills?
    107   ArgDescriptor PrivateSegmentBuffer;
    108   ArgDescriptor DispatchPtr;
    109   ArgDescriptor QueuePtr;
    110   ArgDescriptor KernargSegmentPtr;
    111   ArgDescriptor DispatchID;
    112   ArgDescriptor FlatScratchInit;
    113   ArgDescriptor PrivateSegmentSize;
    114 
    115   // System SGPRs in kernels.
    116   ArgDescriptor WorkGroupIDX;
    117   ArgDescriptor WorkGroupIDY;
    118   ArgDescriptor WorkGroupIDZ;
    119   ArgDescriptor WorkGroupInfo;
    120   ArgDescriptor PrivateSegmentWaveByteOffset;
    121 
    122   // Pointer with offset from kernargsegmentptr to where special ABI arguments
    123   // are passed to callable functions.
    124   ArgDescriptor ImplicitArgPtr;
    125 
    126   // Input registers for non-HSA ABI
    127   ArgDescriptor ImplicitBufferPtr = 0;
    128 
    129   // VGPRs inputs. These are always v0, v1 and v2 for entry functions.
    130   ArgDescriptor WorkItemIDX;
    131   ArgDescriptor WorkItemIDY;
    132   ArgDescriptor WorkItemIDZ;
    133 
    134   std::pair<const ArgDescriptor *, const TargetRegisterClass *>
    135   getPreloadedValue(PreloadedValue Value) const;
    136 };
    137 
    138 class AMDGPUArgumentUsageInfo : public ImmutablePass {
    139 private:
    140   static const AMDGPUFunctionArgInfo ExternFunctionInfo;
    141   DenseMap<const Function *, AMDGPUFunctionArgInfo> ArgInfoMap;
    142 
    143 public:
    144   static char ID;
    145 
    146   AMDGPUArgumentUsageInfo() : ImmutablePass(ID) { }
    147 
    148   void getAnalysisUsage(AnalysisUsage &AU) const override {
    149     AU.setPreservesAll();
    150   }
    151 
    152   bool doInitialization(Module &M) override;
    153   bool doFinalization(Module &M) override;
    154 
    155   void print(raw_ostream &OS, const Module *M = nullptr) const override;
    156 
    157   void setFuncArgInfo(const Function &F, const AMDGPUFunctionArgInfo &ArgInfo) {
    158     ArgInfoMap[&F] = ArgInfo;
    159   }
    160 
    161   const AMDGPUFunctionArgInfo &lookupFuncArgInfo(const Function &F) const {
    162     auto I = ArgInfoMap.find(&F);
    163     if (I == ArgInfoMap.end()) {
    164       assert(F.isDeclaration());
    165       return ExternFunctionInfo;
    166     }
    167 
    168     return I->second;
    169   }
    170 };
    171 
    172 } // end namespace llvm
    173 
    174 #endif
    175