LLVM 20.0.0git
TargetCallingConv.h
Go to the documentation of this file.
1//===-- llvm/CodeGen/TargetCallingConv.h - Calling Convention ---*- 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// This file defines types for working with calling-convention information.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CODEGEN_TARGETCALLINGCONV_H
14#define LLVM_CODEGEN_TARGETCALLINGCONV_H
15
20#include <cassert>
21#include <climits>
22#include <cstdint>
23
24namespace llvm {
25namespace ISD {
26
27 struct ArgFlagsTy {
28 private:
29 unsigned IsZExt : 1; ///< Zero extended
30 unsigned IsSExt : 1; ///< Sign extended
31 unsigned IsNoExt : 1; ///< No extension
32 unsigned IsInReg : 1; ///< Passed in register
33 unsigned IsSRet : 1; ///< Hidden struct-ret ptr
34 unsigned IsByVal : 1; ///< Struct passed by value
35 unsigned IsByRef : 1; ///< Passed in memory
36 unsigned IsNest : 1; ///< Nested fn static chain
37 unsigned IsReturned : 1; ///< Always returned
38 unsigned IsSplit : 1;
39 unsigned IsInAlloca : 1; ///< Passed with inalloca
40 unsigned IsPreallocated : 1; ///< ByVal without the copy
41 unsigned IsSplitEnd : 1; ///< Last part of a split
42 unsigned IsSwiftSelf : 1; ///< Swift self parameter
43 unsigned IsSwiftAsync : 1; ///< Swift async context parameter
44 unsigned IsSwiftError : 1; ///< Swift error parameter
45 unsigned IsCFGuardTarget : 1; ///< Control Flow Guard target
46 unsigned IsHva : 1; ///< HVA field for
47 unsigned IsHvaStart : 1; ///< HVA structure start
48 unsigned IsSecArgPass : 1; ///< Second argument
49 unsigned MemAlign : 6; ///< Log 2 of alignment when arg is passed in memory
50 ///< (including byval/byref). The max alignment is
51 ///< verified in IR verification.
52 unsigned OrigAlign : 5; ///< Log 2 of original alignment
53 unsigned IsInConsecutiveRegsLast : 1;
54 unsigned IsInConsecutiveRegs : 1;
55 unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
56 unsigned IsPointer : 1;
57
58 unsigned ByValOrByRefSize = 0; ///< Byval or byref struct size
59
60 unsigned PointerAddrSpace = 0; ///< Address space of pointer argument
61
62 public:
64 : IsZExt(0), IsSExt(0), IsNoExt(0), IsInReg(0), IsSRet(0), IsByVal(0),
65 IsByRef(0), IsNest(0), IsReturned(0), IsSplit(0), IsInAlloca(0),
66 IsPreallocated(0), IsSplitEnd(0), IsSwiftSelf(0), IsSwiftAsync(0),
67 IsSwiftError(0), IsCFGuardTarget(0), IsHva(0), IsHvaStart(0),
68 IsSecArgPass(0), MemAlign(0), OrigAlign(0),
69 IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
70 IsCopyElisionCandidate(0), IsPointer(0) {
71 static_assert(sizeof(*this) == 4 * sizeof(unsigned), "flags are too big");
72 }
73
74 bool isZExt() const { return IsZExt; }
75 void setZExt() { IsZExt = 1; }
76
77 bool isSExt() const { return IsSExt; }
78 void setSExt() { IsSExt = 1; }
79
80 bool isNoExt() const { return IsNoExt; }
81 void setNoExt() { IsNoExt = 1; }
82
83 bool isInReg() const { return IsInReg; }
84 void setInReg() { IsInReg = 1; }
85
86 bool isSRet() const { return IsSRet; }
87 void setSRet() { IsSRet = 1; }
88
89 bool isByVal() const { return IsByVal; }
90 void setByVal() { IsByVal = 1; }
91
92 bool isByRef() const { return IsByRef; }
93 void setByRef() { IsByRef = 1; }
94
95 bool isInAlloca() const { return IsInAlloca; }
96 void setInAlloca() { IsInAlloca = 1; }
97
98 bool isPreallocated() const { return IsPreallocated; }
99 void setPreallocated() { IsPreallocated = 1; }
100
101 bool isSwiftSelf() const { return IsSwiftSelf; }
102 void setSwiftSelf() { IsSwiftSelf = 1; }
103
104 bool isSwiftAsync() const { return IsSwiftAsync; }
105 void setSwiftAsync() { IsSwiftAsync = 1; }
106
107 bool isSwiftError() const { return IsSwiftError; }
108 void setSwiftError() { IsSwiftError = 1; }
109
110 bool isCFGuardTarget() const { return IsCFGuardTarget; }
111 void setCFGuardTarget() { IsCFGuardTarget = 1; }
112
113 bool isHva() const { return IsHva; }
114 void setHva() { IsHva = 1; }
115
116 bool isHvaStart() const { return IsHvaStart; }
117 void setHvaStart() { IsHvaStart = 1; }
118
119 bool isSecArgPass() const { return IsSecArgPass; }
120 void setSecArgPass() { IsSecArgPass = 1; }
121
122 bool isNest() const { return IsNest; }
123 void setNest() { IsNest = 1; }
124
125 bool isReturned() const { return IsReturned; }
126 void setReturned(bool V = true) { IsReturned = V; }
127
128 bool isInConsecutiveRegs() const { return IsInConsecutiveRegs; }
129 void setInConsecutiveRegs(bool Flag = true) { IsInConsecutiveRegs = Flag; }
130
131 bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
132 void setInConsecutiveRegsLast(bool Flag = true) {
133 IsInConsecutiveRegsLast = Flag;
134 }
135
136 bool isSplit() const { return IsSplit; }
137 void setSplit() { IsSplit = 1; }
138
139 bool isSplitEnd() const { return IsSplitEnd; }
140 void setSplitEnd() { IsSplitEnd = 1; }
141
142 bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
143 void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
144
145 bool isPointer() const { return IsPointer; }
146 void setPointer() { IsPointer = 1; }
147
149 return decodeMaybeAlign(MemAlign).valueOrOne();
150 }
151
153 MemAlign = encode(A);
154 assert(getNonZeroMemAlign() == A && "bitfield overflow");
155 }
156
158 assert(isByVal());
159 MaybeAlign A = decodeMaybeAlign(MemAlign);
160 assert(A && "ByValAlign must be defined");
161 return *A;
162 }
163
165 return decodeMaybeAlign(OrigAlign).valueOrOne();
166 }
167
169 OrigAlign = encode(A);
170 assert(getNonZeroOrigAlign() == A && "bitfield overflow");
171 }
172
173 unsigned getByValSize() const {
174 assert(isByVal() && !isByRef());
175 return ByValOrByRefSize;
176 }
177 void setByValSize(unsigned S) {
178 assert(isByVal() && !isByRef());
179 ByValOrByRefSize = S;
180 }
181
182 unsigned getByRefSize() const {
183 assert(!isByVal() && isByRef());
184 return ByValOrByRefSize;
185 }
186 void setByRefSize(unsigned S) {
187 assert(!isByVal() && isByRef());
188 ByValOrByRefSize = S;
189 }
190
191 unsigned getPointerAddrSpace() const { return PointerAddrSpace; }
192 void setPointerAddrSpace(unsigned AS) { PointerAddrSpace = AS; }
193};
194
195 /// InputArg - This struct carries flags and type information about a
196 /// single incoming (formal) argument or incoming (from the perspective
197 /// of the caller) return value virtual register.
198 ///
199 struct InputArg {
201 MVT VT = MVT::Other;
203 bool Used = false;
204
205 /// Index original Function's argument.
206 unsigned OrigArgIndex;
207 /// Sentinel value for implicit machine-level input arguments.
208 static const unsigned NoArgIndex = UINT_MAX;
209
210 /// Offset in bytes of current input value relative to the beginning of
211 /// original argument. E.g. if argument was splitted into four 32 bit
212 /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
213 unsigned PartOffset;
214
215 InputArg() = default;
216 InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
217 unsigned origIdx, unsigned partOffs)
218 : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
219 VT = vt.getSimpleVT();
220 ArgVT = argvt;
221 }
222
223 bool isOrigArg() const {
224 return OrigArgIndex != NoArgIndex;
225 }
226
227 unsigned getOrigArgIndex() const {
228 assert(OrigArgIndex != NoArgIndex && "Implicit machine-level argument");
229 return OrigArgIndex;
230 }
231 };
232
233 /// OutputArg - This struct carries flags and a value for a
234 /// single outgoing (actual) argument or outgoing (from the perspective
235 /// of the caller) return value virtual register.
236 ///
237 struct OutputArg {
241
242 /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
243 bool IsFixed = false;
244
245 /// Index original Function's argument.
246 unsigned OrigArgIndex;
247
248 /// Offset in bytes of current output value relative to the beginning of
249 /// original argument. E.g. if argument was splitted into four 32 bit
250 /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
251 unsigned PartOffset;
252
253 OutputArg() = default;
254 OutputArg(ArgFlagsTy flags, MVT vt, EVT argvt, bool isfixed,
255 unsigned origIdx, unsigned partOffs)
256 : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
257 PartOffset(partOffs) {
258 VT = vt;
259 ArgVT = argvt;
260 }
261 };
262
263} // end namespace ISD
264} // end namespace llvm
265
266#endif // LLVM_CODEGEN_TARGETCALLINGCONV_H
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Machine Value Type.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
Definition: Alignment.h:217
MaybeAlign decodeMaybeAlign(unsigned Value)
Dual operation of the encode function above.
Definition: Alignment.h:220
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Extended Value Type.
Definition: ValueTypes.h:35
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
bool isInConsecutiveRegs() const
void setInConsecutiveRegs(bool Flag=true)
bool isCopyElisionCandidate() const
Align getNonZeroOrigAlign() const
void setPointerAddrSpace(unsigned AS)
unsigned getPointerAddrSpace() const
unsigned getByRefSize() const
void setReturned(bool V=true)
void setByRefSize(unsigned S)
unsigned getByValSize() const
bool isInConsecutiveRegsLast() const
Align getNonZeroMemAlign() const
void setByValSize(unsigned S)
void setInConsecutiveRegsLast(bool Flag=true)
Align getNonZeroByValAlign() const
InputArg - This struct carries flags and type information about a single incoming (formal) argument o...
static const unsigned NoArgIndex
Sentinel value for implicit machine-level input arguments.
unsigned PartOffset
Offset in bytes of current input value relative to the beginning of original argument.
unsigned getOrigArgIndex() const
unsigned OrigArgIndex
Index original Function's argument.
InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used, unsigned origIdx, unsigned partOffs)
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
OutputArg(ArgFlagsTy flags, MVT vt, EVT argvt, bool isfixed, unsigned origIdx, unsigned partOffs)
unsigned PartOffset
Offset in bytes of current output value relative to the beginning of original argument.
bool IsFixed
IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
unsigned OrigArgIndex
Index original Function's argument.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition: Alignment.h:141