LLVM 23.0.0git
FunctionInfo.h
Go to the documentation of this file.
1//===----- FunctionInfo.h - ABI Function Information --------- 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// Defines FunctionInfo and associated types used in representing the
10// ABI-coerced types for function arguments and return values.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ABI_FUNCTIONINFO_H
15#define LLVM_ABI_FUNCTIONINFO_H
16
17#include "llvm/ABI/Types.h"
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/IR/CallingConv.h"
23#include <optional>
24
25namespace llvm {
26namespace abi {
27
28/// Helper class to encapsulate information about how a specific type should be
29/// passed to or returned from a function.
30class ArgInfo {
31public:
32 enum Kind {
33 /// Pass the argument directly using the normal converted LLVM type, or by
34 /// coercing to another specified type stored in 'CoerceToType'.
36 /// Valid only for integer argument types. Same as 'direct' but also emit a
37 /// zero/sign extension attribute.
39 /// Pass the argument indirectly via a hidden pointer with the specified
40 /// alignment and address space.
42 /// Ignore the argument (treat as void). Useful for void and empty structs.
44 };
45
46private:
47 const Type *CoercionType = nullptr;
48
49 struct DirectAttrInfo {
50 unsigned Offset;
51 MaybeAlign Alignment;
52 };
53
54 struct IndirectAttrInfo {
55 Align Alignment;
56 unsigned AddrSpace;
57 };
58
59 union {
60 DirectAttrInfo DirectAttr;
61 IndirectAttrInfo IndirectAttr;
62 };
63
64 Kind TheKind;
65 bool SignExt : 1;
66 bool ZeroExt : 1;
67 bool IndirectByVal : 1;
68 bool IndirectRealign : 1;
69
70 ArgInfo(Kind K = Direct)
71 : TheKind(K), SignExt(false), ZeroExt(false), IndirectByVal(false),
72 IndirectRealign(false) {}
73
74public:
75 /// \param T The type to coerce to. If null, the argument's original type is
76 /// used directly.
77 /// \param Offset Byte offset into the memory representation at which the
78 /// coerced type begins. Used when only part of a larger value
79 /// is passed directly (e.g. the high word of a multi-eightbyte
80 /// return value on x86-64).
81 /// \param Align Override for the argument's alignment. If absent, the
82 /// default alignment for \p T is used.
83 static ArgInfo getDirect(const Type *T = nullptr, unsigned Offset = 0,
84 MaybeAlign Align = std::nullopt) {
85 ArgInfo AI(Direct);
86 AI.CoercionType = T;
87 AI.DirectAttr.Offset = Offset;
88 AI.DirectAttr.Alignment = Align;
89 return AI;
90 }
91
92 static ArgInfo getExtend(const Type *T) {
93 assert(T && "Type cannot be null");
94 assert(T->isInteger() && "Unexpected type - only integers can be extended");
95
96 ArgInfo AI(Extend);
97 AI.CoercionType = T;
98 AI.DirectAttr.Offset = 0;
99 AI.DirectAttr.Alignment = std::nullopt;
100
101 const IntegerType *IntTy = cast<IntegerType>(T);
102 if (IntTy->isSigned())
103 AI.setSignExt();
104 else
105 AI.setZeroExt();
106
107 return AI;
108 }
109
110 /// Realign: the caller couldn't guarantee sufficient alignment - the callee
111 /// must copy the argument to a properly aligned temporary before use.
112 static ArgInfo getIndirect(Align Align, bool ByVal, unsigned AddrSpace = 0,
113 bool Realign = false) {
114 ArgInfo AI(Indirect);
115 AI.IndirectAttr.Alignment = Align;
116 AI.IndirectAttr.AddrSpace = AddrSpace;
117 AI.IndirectByVal = ByVal;
118 AI.IndirectRealign = Realign;
119 return AI;
120 }
121
122 static ArgInfo getIgnore() { return ArgInfo(Ignore); }
123
124 ArgInfo &setSignExt(bool SignExtend = true) {
125 this->SignExt = SignExtend;
126 if (SignExtend)
127 this->ZeroExt = false;
128 return *this;
129 }
130
131 ArgInfo &setZeroExt(bool ZeroExtend = true) {
132 this->ZeroExt = ZeroExtend;
133 if (ZeroExtend)
134 this->SignExt = false;
135 return *this;
136 }
137
138 Kind getKind() const { return TheKind; }
139 bool isDirect() const { return TheKind == Direct; }
140 bool isIndirect() const { return TheKind == Indirect; }
141 bool isIgnore() const { return TheKind == Ignore; }
142 bool isExtend() const { return TheKind == Extend; }
143
144 unsigned getDirectOffset() const {
145 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
146 return DirectAttr.Offset;
147 }
148
150 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
151 return DirectAttr.Alignment;
152 }
153
155 assert(isIndirect() && "Invalid Kind!");
156 return IndirectAttr.Alignment;
157 }
158
159 unsigned getIndirectAddrSpace() const {
160 assert(isIndirect() && "Invalid Kind!");
161 return IndirectAttr.AddrSpace;
162 }
163
164 bool getIndirectByVal() const {
165 assert(isIndirect() && "Invalid Kind!");
166 return IndirectByVal;
167 }
168
169 bool getIndirectRealign() const {
170 assert(isIndirect() && "Invalid Kind!");
171 return IndirectRealign;
172 }
173
174 bool isSignExt() const {
175 assert(isExtend() && "Invalid Kind!");
176 return SignExt;
177 }
178
179 bool isZeroExt() const {
180 assert(isExtend() && "Invalid Kind!");
181 return ZeroExt;
182 }
183
184 bool isNoExt() const {
185 assert(isExtend() && "Invalid Kind!");
186 return !SignExt && !ZeroExt;
187 }
188
189 const Type *getCoerceToType() const {
190 assert((isDirect() || isExtend()) && "Invalid Kind!");
191 return CoercionType;
192 }
193};
194
195struct ArgEntry {
196 const Type *ABIType;
198
199 ArgEntry(const Type *T) : ABIType(T), Info(ArgInfo::getDirect()) {}
200 ArgEntry(const Type *T, ArgInfo A) : ABIType(T), Info(A) {}
201};
202
203class FunctionInfo final : private TrailingObjects<FunctionInfo, ArgEntry> {
204private:
205 const Type *ReturnType;
206 ArgInfo ReturnInfo;
207 unsigned NumArgs;
209 std::optional<unsigned> NumRequired;
210
211 FunctionInfo(CallingConv::ID CC, const Type *RetTy, unsigned NumArguments,
212 std::optional<unsigned> NumRequired)
213 : ReturnType(RetTy), ReturnInfo(ArgInfo::getDirect()),
214 NumArgs(NumArguments), CC(CC), NumRequired(NumRequired) {}
215
216 friend class TrailingObjects;
217
218public:
221
222 void operator delete(void *p) { ::operator delete(p); }
224 const_arg_iterator arg_end() const { return getTrailingObjects() + NumArgs; }
226 arg_iterator arg_end() { return getTrailingObjects() + NumArgs; }
227
228 unsigned arg_size() const { return NumArgs; }
229
230 static FunctionInfo *
231 create(CallingConv::ID CC, const Type *ReturnType,
232 ArrayRef<const Type *> ArgTypes,
233 std::optional<unsigned> NumRequired = std::nullopt);
234
235 const Type *getReturnType() const { return ReturnType; }
236 ArgInfo &getReturnInfo() { return ReturnInfo; }
237 const ArgInfo &getReturnInfo() const { return ReturnInfo; }
238
240
241 bool isVariadic() const { return NumRequired.has_value(); }
242
243 unsigned getNumRequiredArgs() const {
244 return isVariadic() ? *NumRequired : arg_size();
245 }
246
248 return {getTrailingObjects(), NumArgs};
249 }
250
252 return {getTrailingObjects(), NumArgs};
253 }
254
255 ArgEntry &getArgInfo(unsigned Index) {
256 assert(Index < NumArgs && "Invalid argument index");
257 return arguments()[Index];
258 }
259
260 const ArgEntry &getArgInfo(unsigned Index) const {
261 assert(Index < NumArgs && "Invalid argument index");
262 return arguments()[Index];
263 }
264};
265
266} // namespace abi
267} // namespace llvm
268
269#endif // LLVM_ABI_FUNCTIONINFO_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define T
This header defines support for implementing classes that have some trailing object (or arrays of obj...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition ArrayRef.h:298
Helper class to encapsulate information about how a specific type should be passed to or returned fro...
bool isDirect() const
static ArgInfo getDirect(const Type *T=nullptr, unsigned Offset=0, MaybeAlign Align=std::nullopt)
const Type * getCoerceToType() const
Align getIndirectAlign() const
DirectAttrInfo DirectAttr
bool isSignExt() const
ArgInfo & setZeroExt(bool ZeroExtend=true)
static ArgInfo getIgnore()
bool isIgnore() const
unsigned getIndirectAddrSpace() const
IndirectAttrInfo IndirectAttr
Kind getKind() const
@ Extend
Valid only for integer argument types.
@ Direct
Pass the argument directly using the normal converted LLVM type, or by coercing to another specified ...
@ Ignore
Ignore the argument (treat as void). Useful for void and empty structs.
@ Indirect
Pass the argument indirectly via a hidden pointer with the specified alignment and address space.
static ArgInfo getExtend(const Type *T)
static ArgInfo getIndirect(Align Align, bool ByVal, unsigned AddrSpace=0, bool Realign=false)
Realign: the caller couldn't guarantee sufficient alignment - the callee must copy the argument to a ...
MaybeAlign getDirectAlign() const
bool isExtend() const
bool getIndirectRealign() const
ArgInfo & setSignExt(bool SignExtend=true)
bool isNoExt() const
bool getIndirectByVal() const
bool isIndirect() const
unsigned getDirectOffset() const
bool isZeroExt() const
ArrayRef< ArgEntry > arguments() const
unsigned getNumRequiredArgs() const
static FunctionInfo * create(CallingConv::ID CC, const Type *ReturnType, ArrayRef< const Type * > ArgTypes, std::optional< unsigned > NumRequired=std::nullopt)
const ArgInfo & getReturnInfo() const
const ArgEntry * const_arg_iterator
MutableArrayRef< ArgEntry > arguments()
CallingConv::ID getCallingConvention() const
const_arg_iterator arg_begin() const
const ArgEntry & getArgInfo(unsigned Index) const
friend class TrailingObjects
const_arg_iterator arg_end() const
unsigned arg_size() const
arg_iterator arg_begin()
ArgEntry & getArgInfo(unsigned Index)
const Type * getReturnType() const
Represents the ABI-specific view of a type in LLVM.
Definition Types.h:45
This file defines the type system for the LLVMABI library, which mirrors ABI-relevant aspects of fron...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
ArgEntry(const Type *T)
ArgEntry(const Type *T, ArgInfo A)
const Type * ABIType