AMDGPUArgumentUsageInfo.h revision 360784
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
17namespace llvm {
18
19class Function;
20class raw_ostream;
21class GCNSubtarget;
22class TargetMachine;
23class TargetRegisterClass;
24class TargetRegisterInfo;
25
26struct ArgDescriptor {
27private:
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
42public:
43  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 ArgDescriptor createRegister(Register Reg, unsigned Mask = ~0u) {
48    return ArgDescriptor(Reg, Mask, false, true);
49  }
50
51  static ArgDescriptor createStack(unsigned Offset, unsigned Mask = ~0u) {
52    return ArgDescriptor(Offset, Mask, true, true);
53  }
54
55  static ArgDescriptor createArg(const ArgDescriptor &Arg, 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  Register 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
92inline raw_ostream &operator<<(raw_ostream &OS, const ArgDescriptor &Arg) {
93  Arg.print(OS);
94  return OS;
95}
96
97struct 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 = 0;
145
146  // VGPRs inputs. These are always v0, v1 and v2 for entry functions.
147  ArgDescriptor WorkItemIDX;
148  ArgDescriptor WorkItemIDY;
149  ArgDescriptor WorkItemIDZ;
150
151  std::pair<const ArgDescriptor *, const TargetRegisterClass *>
152  getPreloadedValue(PreloadedValue Value) const;
153};
154
155class AMDGPUArgumentUsageInfo : public ImmutablePass {
156private:
157  static const AMDGPUFunctionArgInfo ExternFunctionInfo;
158  DenseMap<const Function *, AMDGPUFunctionArgInfo> ArgInfoMap;
159
160public:
161  static char ID;
162
163  AMDGPUArgumentUsageInfo() : ImmutablePass(ID) { }
164
165  void getAnalysisUsage(AnalysisUsage &AU) const override {
166    AU.setPreservesAll();
167  }
168
169  bool doInitialization(Module &M) override;
170  bool doFinalization(Module &M) override;
171
172  void print(raw_ostream &OS, const Module *M = nullptr) const override;
173
174  void setFuncArgInfo(const Function &F, const AMDGPUFunctionArgInfo &ArgInfo) {
175    ArgInfoMap[&F] = ArgInfo;
176  }
177
178  const AMDGPUFunctionArgInfo &lookupFuncArgInfo(const Function &F) const {
179    auto I = ArgInfoMap.find(&F);
180    if (I == ArgInfoMap.end()) {
181      assert(F.isDeclaration());
182      return ExternFunctionInfo;
183    }
184
185    return I->second;
186  }
187};
188
189} // end namespace llvm
190
191#endif
192