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