LLVM 24.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
21#include <cassert>
22#include <climits>
23#include <cstdint>
24
25namespace llvm {
26namespace ISD {
27
28 struct ArgFlagsTy {
29 public:
30 /// Flag bits describing an argument.
31 enum Flags : uint32_t {
33 ZExt = 1U << 0, ///< Zero extended
34 SExt = 1U << 1, ///< Sign extended
35 NoExt = 1U << 2, ///< No extension
36 InReg = 1U << 3, ///< Passed in register
37 SRet = 1U << 4, ///< Hidden struct-ret ptr
38 ByVal = 1U << 5, ///< Struct passed by value
39 ByRef = 1U << 6, ///< Passed in memory
40 Nest = 1U << 7, ///< Nested fn static chain
41 Returned = 1U << 8, ///< Always returned
42 Split = 1U << 9,
43 InAlloca = 1U << 10, ///< Passed with inalloca
44 Preallocated = 1U << 11, ///< ByVal without the copy
45 SplitEnd = 1U << 12, ///< Last part of a split
46 SwiftSelf = 1U << 13, ///< Swift self parameter
47 SwiftAsync = 1U << 14, ///< Swift async context parameter
48 SwiftError = 1U << 15, ///< Swift error parameter
49 CFGuardTarget = 1U << 16, ///< Control Flow Guard target
50 Hva = 1U << 17, ///< HVA field
51 HvaStart = 1U << 18, ///< HVA structure start
52 SecArgPass = 1U << 19, ///< Second argument
55 CopyElisionCandidate = 1U << 22, ///< Argument copy elision candidate
56 Pointer = 1U << 23,
57 /// Whether this is part of a variable argument list (non-fixed).
58 VarArg = 1U << 24,
59
60 LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ VarArg)
61 };
62
63 private:
64 Flags FlagVals = NoFlags;
65 unsigned MemAlign : 6; ///< Log 2 of alignment when arg is passed in memory
66 ///< (including byval/byref). The max alignment is
67 ///< verified in IR verification.
68 unsigned OrigAlign : 5; ///< Log 2 of original alignment
69
70 unsigned ByValOrByRefSize = 0; ///< Byval or byref struct size
71
72 unsigned PointerAddrSpace = 0; ///< Address space of pointer argument
73
74 void setFlag(Flags Flag, bool Value = true) {
75 FlagVals = (FlagVals & ~Flag) | (Value ? Flag : NoFlags);
76 }
77
78 public:
79 ArgFlagsTy() : MemAlign(0), OrigAlign(0) {
80 static_assert(sizeof(*this) == 4 * sizeof(unsigned), "flags are too big");
81 }
82
83 /// Return the argument's boolean flags.
84 Flags getFlags() const { return FlagVals; }
85
86 bool isZExt() const { return FlagVals & ZExt; }
87 void setZExt() { setFlag(ZExt); }
88
89 bool isSExt() const { return FlagVals & SExt; }
90 void setSExt() { setFlag(SExt); }
91
92 bool isNoExt() const { return FlagVals & NoExt; }
93 void setNoExt() { setFlag(NoExt); }
94
95 bool isInReg() const { return FlagVals & InReg; }
96 void setInReg() { setFlag(InReg); }
97
98 bool isSRet() const { return FlagVals & SRet; }
99 void setSRet() { setFlag(SRet); }
100
101 bool isByVal() const { return FlagVals & ByVal; }
102 void setByVal() { setFlag(ByVal); }
103
104 bool isByRef() const { return FlagVals & ByRef; }
105 void setByRef() { setFlag(ByRef); }
106
107 bool isInAlloca() const { return FlagVals & InAlloca; }
108 void setInAlloca() { setFlag(InAlloca); }
109
110 bool isPreallocated() const { return FlagVals & Preallocated; }
111 void setPreallocated() { setFlag(Preallocated); }
112
113 bool isSwiftSelf() const { return FlagVals & SwiftSelf; }
114 void setSwiftSelf() { setFlag(SwiftSelf); }
115
116 bool isSwiftAsync() const { return FlagVals & SwiftAsync; }
117 void setSwiftAsync() { setFlag(SwiftAsync); }
118
119 bool isSwiftError() const { return FlagVals & SwiftError; }
120 void setSwiftError() { setFlag(SwiftError); }
121
122 bool isCFGuardTarget() const { return FlagVals & CFGuardTarget; }
123 void setCFGuardTarget() { setFlag(CFGuardTarget); }
124
125 bool isHva() const { return FlagVals & Hva; }
126 void setHva() { setFlag(Hva); }
127
128 bool isHvaStart() const { return FlagVals & HvaStart; }
129 void setHvaStart() { setFlag(HvaStart); }
130
131 bool isSecArgPass() const { return FlagVals & SecArgPass; }
132 void setSecArgPass() { setFlag(SecArgPass); }
133
134 bool isNest() const { return FlagVals & Nest; }
135 void setNest() { setFlag(Nest); }
136
137 bool isReturned() const { return FlagVals & Returned; }
138 void setReturned(bool V = true) { setFlag(Returned, V); }
139
140 bool isInConsecutiveRegs() const { return FlagVals & InConsecutiveRegs; }
141 void setInConsecutiveRegs(bool Flag = true) {
142 setFlag(InConsecutiveRegs, Flag);
143 }
144
146 return FlagVals & InConsecutiveRegsLast;
147 }
148 void setInConsecutiveRegsLast(bool Flag = true) {
149 setFlag(InConsecutiveRegsLast, Flag);
150 }
151
152 bool isSplit() const { return FlagVals & Split; }
153 void setSplit() { setFlag(Split); }
154
155 bool isSplitEnd() const { return FlagVals & SplitEnd; }
156 void setSplitEnd() { setFlag(SplitEnd); }
157
159 return FlagVals & CopyElisionCandidate;
160 }
162
163 bool isPointer() const { return FlagVals & Pointer; }
164 void setPointer() { setFlag(Pointer); }
165
166 bool isVarArg() const { return FlagVals & VarArg; }
167 void setVarArg() { setFlag(VarArg); }
168
170 return decodeMaybeAlign(MemAlign).valueOrOne();
171 }
172
174 MemAlign = encode(A);
175 assert(getNonZeroMemAlign() == A && "bitfield overflow");
176 }
177
179 assert(isByVal());
180 MaybeAlign A = decodeMaybeAlign(MemAlign);
181 assert(A && "ByValAlign must be defined");
182 return *A;
183 }
184
186 return decodeMaybeAlign(OrigAlign).valueOrOne();
187 }
188
190 OrigAlign = encode(A);
191 assert(getNonZeroOrigAlign() == A && "bitfield overflow");
192 }
193
194 unsigned getByValSize() const {
195 assert(isByVal() && !isByRef());
196 return ByValOrByRefSize;
197 }
198 void setByValSize(unsigned S) {
199 assert(isByVal() && !isByRef());
200 ByValOrByRefSize = S;
201 }
202
203 unsigned getByRefSize() const {
204 assert(!isByVal() && isByRef());
205 return ByValOrByRefSize;
206 }
207 void setByRefSize(unsigned S) {
208 assert(!isByVal() && isByRef());
209 ByValOrByRefSize = S;
210 }
211
212 unsigned getPointerAddrSpace() const { return PointerAddrSpace; }
213 void setPointerAddrSpace(unsigned AS) { PointerAddrSpace = AS; }
214};
215
216 /// InputArg - This struct carries flags and type information about a
217 /// single incoming (formal) argument or incoming (from the perspective
218 /// of the caller) return value virtual register.
219 ///
220 struct InputArg {
222 /// Legalized type of this argument part.
223 MVT VT = MVT::Other;
224 /// Usually the non-legalized type of the argument, which is the EVT
225 /// corresponding to the OrigTy IR type. However, for post-legalization
226 /// libcalls, this will be a legalized type.
228 /// Original IR type of the argument. For aggregates, this is the type of
229 /// an individual aggregate element, not the whole aggregate.
231 bool Used;
232
233 /// Index original Function's argument.
234 unsigned OrigArgIndex;
235 /// Sentinel value for implicit machine-level input arguments.
236 static const unsigned NoArgIndex = UINT_MAX;
237
238 /// Offset in bytes of current input value relative to the beginning of
239 /// original argument. E.g. if argument was splitted into four 32 bit
240 /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
241 unsigned PartOffset;
242
247
248 bool isOrigArg() const {
249 return OrigArgIndex != NoArgIndex;
250 }
251
252 unsigned getOrigArgIndex() const {
253 assert(OrigArgIndex != NoArgIndex && "Implicit machine-level argument");
254 return OrigArgIndex;
255 }
256 };
257
258 /// OutputArg - This struct carries flags and a value for a
259 /// single outgoing (actual) argument or outgoing (from the perspective
260 /// of the caller) return value virtual register.
261 ///
262 struct OutputArg {
264 // Legalized type of this argument part.
266 /// Non-legalized type of the argument. This is the EVT corresponding to
267 /// the OrigTy IR type.
269 /// Original IR type of the argument. For aggregates, this is the type of
270 /// an individual aggregate element, not the whole aggregate.
272
273 /// Index original Function's argument.
274 unsigned OrigArgIndex;
275
276 /// Offset in bytes of current output value relative to the beginning of
277 /// original argument. E.g. if argument was splitted into four 32 bit
278 /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
279 unsigned PartOffset;
280
285 };
286
287} // end namespace ISD
288} // end namespace llvm
289
290#endif // LLVM_CODEGEN_TARGETCALLINGCONV_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Machine Value Type.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:24
This is an optimization pass for GlobalISel generic memory operations.
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
Definition Alignment.h:206
@ NoFlags
No Specific Flags.
MaybeAlign decodeMaybeAlign(unsigned Value)
Dual operation of the encode function above.
Definition Alignment.h:209
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
void setInConsecutiveRegs(bool Flag=true)
bool isCopyElisionCandidate() const
Flags
Flag bits describing an argument.
@ SecArgPass
Second argument.
@ CFGuardTarget
Control Flow Guard target.
@ Nest
Nested fn static chain.
@ SwiftSelf
Swift self parameter.
@ Preallocated
ByVal without the copy.
@ ByVal
Struct passed by value.
@ InAlloca
Passed with inalloca.
@ ByRef
Passed in memory.
@ Returned
Always returned.
@ SplitEnd
Last part of a split.
@ SRet
Hidden struct-ret ptr.
@ CopyElisionCandidate
Argument copy elision candidate.
@ SwiftError
Swift error parameter.
@ VarArg
Whether this is part of a variable argument list (non-fixed).
@ SwiftAsync
Swift async context parameter.
@ InReg
Passed in register.
@ HvaStart
HVA structure start.
Align getNonZeroOrigAlign() const
void setPointerAddrSpace(unsigned AS)
unsigned getPointerAddrSpace() const
unsigned getByRefSize() const
void setReturned(bool V=true)
void setByRefSize(unsigned S)
Flags getFlags() const
Return the argument's boolean flags.
unsigned getByValSize() const
bool isInConsecutiveRegsLast() const
Align getNonZeroMemAlign() const
void setByValSize(unsigned S)
void setInConsecutiveRegsLast(bool Flag=true)
Align getNonZeroByValAlign() const
static const unsigned NoArgIndex
Sentinel value for implicit machine-level input arguments.
Type * OrigTy
Original IR type of the argument.
InputArg(ArgFlagsTy Flags, MVT VT, EVT ArgVT, Type *OrigTy, bool Used, unsigned OrigArgIndex, unsigned PartOffset)
MVT VT
Legalized type of this argument part.
unsigned PartOffset
Offset in bytes of current input value relative to the beginning of original argument.
EVT ArgVT
Usually the non-legalized type of the argument, which is the EVT corresponding to the OrigTy IR type.
unsigned getOrigArgIndex() const
unsigned OrigArgIndex
Index original Function's argument.
unsigned PartOffset
Offset in bytes of current output value relative to the beginning of original argument.
OutputArg(ArgFlagsTy Flags, MVT VT, EVT ArgVT, Type *OrigTy, unsigned OrigArgIndex, unsigned PartOffset)
Type * OrigTy
Original IR type of the argument.
EVT ArgVT
Non-legalized type of the argument.
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:106
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition Alignment.h:130