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