LLVM 22.0.0git
RuntimeLibcalls.h
Go to the documentation of this file.
1//===- RuntimeLibcalls.h - Interface for runtime libcalls -------*- 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 implements a common interface to work with library calls into a
10// runtime that may be emitted by a given backend.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_IR_RUNTIME_LIBCALLS_H
15#define LLVM_IR_RUNTIME_LIBCALLS_H
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/Bitset.h"
19#include "llvm/ADT/Sequence.h"
21#include "llvm/IR/CallingConv.h"
22#include "llvm/IR/InstrTypes.h"
27
28/// TableGen will produce 2 enums, RTLIB::Libcall and
29/// RTLIB::LibcallImpl. RTLIB::Libcall describes abstract functionality the
30/// compiler may choose to access, RTLIB::LibcallImpl describes a particular ABI
31/// implementation, which includes a name and type signature.
32#define GET_RUNTIME_LIBCALL_ENUM
33#include "llvm/IR/RuntimeLibcalls.inc"
34
35namespace llvm {
36
37template <> struct enum_iteration_traits<RTLIB::Libcall> {
38 static constexpr bool is_iterable = true;
39};
40
41template <> struct enum_iteration_traits<RTLIB::LibcallImpl> {
42 static constexpr bool is_iterable = true;
43};
44
45namespace RTLIB {
46
47// Return an iterator over all Libcall values.
48static inline auto libcalls() {
49 return enum_seq(static_cast<RTLIB::Libcall>(0), RTLIB::UNKNOWN_LIBCALL);
50}
51
52static inline auto libcall_impls() {
53 return enum_seq(static_cast<RTLIB::LibcallImpl>(1),
54 static_cast<RTLIB::LibcallImpl>(RTLIB::NumLibcallImpls));
55}
56
57/// Manage a bitset representing the list of available libcalls for a module.
58class LibcallImplBitset : public Bitset<RTLIB::NumLibcallImpls> {
59public:
60 constexpr LibcallImplBitset() = default;
62 const std::array<uint64_t, (RTLIB::NumLibcallImpls + 63) / 64> &Src)
63 : Bitset(Src) {}
64};
65
66/// A simple container for information about the supported runtime calls.
68private:
69 /// Bitset of libcalls a module may emit a call to.
70 LibcallImplBitset AvailableLibcallImpls;
71
72public:
74 const Triple &TT,
77 EABI EABIVersion = EABI::Default, StringRef ABIName = "") {
78 // FIXME: The ExceptionModel parameter is to handle the field in
79 // TargetOptions. This interface fails to distinguish the forced disable
80 // case for targets which support exceptions by default. This should
81 // probably be a module flag and removed from TargetOptions.
82 if (ExceptionModel == ExceptionHandling::None)
83 ExceptionModel = TT.getDefaultExceptionHandling();
84
85 initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion, ABIName);
86 }
87
88 /// Rename the default libcall routine name for the specified libcall.
89 void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
90 LibcallImpls[Call] = Impl;
91 }
92
93 /// Get the libcall routine name for the specified libcall.
94 // FIXME: This should be removed. Only LibcallImpl should have a name.
95 StringRef getLibcallName(RTLIB::Libcall Call) const {
96 return getLibcallImplName(LibcallImpls[Call]);
97 }
98
99 /// Get the libcall routine name for the specified libcall implementation.
100 static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl) {
101 if (CallImpl == RTLIB::Unsupported)
102 return StringRef();
103 return StringRef(RuntimeLibcallImplNameTable.getCString(
104 RuntimeLibcallNameOffsetTable[CallImpl]),
105 RuntimeLibcallNameSizeTable[CallImpl]);
106 }
107
108 /// Return the lowering's selection of implementation call for \p Call
109 RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
110 return LibcallImpls[Call];
111 }
112
113 /// Set the CallingConv that should be used for the specified libcall
114 /// implementation
115 void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
116 LibcallImplCallingConvs[Call] = CC;
117 }
118
119 // FIXME: Remove this wrapper in favor of directly using
120 // getLibcallImplCallingConv
122 return LibcallImplCallingConvs[LibcallImpls[Call]];
123 }
124
125 /// Get the CallingConv that should be used for the specified libcall.
127 return LibcallImplCallingConvs[Call];
128 }
129
131 // Trim UNKNOWN_LIBCALL from the back
132 return ArrayRef(LibcallImpls).drop_back();
133 }
134
135 /// Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully
136 /// unsupported.
138 RTLIB::LibcallImpl Memcpy = getLibcallImpl(RTLIB::MEMCPY);
139 if (Memcpy != RTLIB::Unsupported)
140 return getLibcallImplName(Memcpy);
141
142 // Fallback to memmove if memcpy isn't available.
143 return getLibcallName(RTLIB::MEMMOVE);
144 }
145
146 bool isAvailable(RTLIB::LibcallImpl Impl) const {
147 return AvailableLibcallImpls.test(Impl);
148 }
149
150 void setAvailable(RTLIB::LibcallImpl Impl) {
151 AvailableLibcallImpls.set(Impl);
152 }
153
154 /// Return the libcall provided by \p Impl
155 static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
156 return ImplToLibcall[Impl];
157 }
158
159 /// Check if a function name is a recognized runtime call of any kind. This
160 /// does not consider if this call is available for any current compilation,
161 /// just that it is a known call somewhere. This returns the set of all
162 /// LibcallImpls which match the name; multiple implementations with the same
163 /// name may exist but differ in interpretation based on the target context.
164 ///
165 /// Generated by tablegen.
168 // Inlining the early exit on the string name appears to be worthwhile when
169 // querying a real set of symbols
170#define GET_LOOKUP_LIBCALL_IMPL_NAME_BODY
171#include "llvm/IR/RuntimeLibcalls.inc"
172 }
173
174 /// Check if this is valid libcall for the current module, otherwise
175 /// RTLIB::Unsupported.
176 LLVM_ABI RTLIB::LibcallImpl
178 for (RTLIB::LibcallImpl Impl : lookupLibcallImplName(FuncName)) {
179 // FIXME: This should not depend on looking up ImplToLibcall, only the
180 // list of libcalls for the module.
181 RTLIB::LibcallImpl Recognized = LibcallImpls[ImplToLibcall[Impl]];
182 if (Recognized != RTLIB::Unsupported)
183 return Recognized;
184 }
185
186 return RTLIB::Unsupported;
187 }
188
189private:
191 lookupLibcallImplNameImpl(StringRef Name);
192
193 /// Stores the implementation choice for each each libcall.
194 RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
195 RTLIB::Unsupported};
196
197 static_assert(static_cast<int>(CallingConv::C) == 0,
198 "default calling conv should be encoded as 0");
199
200 /// Stores the CallingConv that should be used for each libcall
201 /// implementation.;
202 CallingConv::ID LibcallImplCallingConvs[RTLIB::NumLibcallImpls] = {};
203
204 /// Names of concrete implementations of runtime calls. e.g. __ashlsi3 for
205 /// SHL_I32
206 LLVM_ABI static const char RuntimeLibcallImplNameTableStorage[];
207 LLVM_ABI static const StringTable RuntimeLibcallImplNameTable;
208 LLVM_ABI static const uint16_t RuntimeLibcallNameOffsetTable[];
209 LLVM_ABI static const uint8_t RuntimeLibcallNameSizeTable[];
210
211 /// Map from a concrete LibcallImpl implementation to its RTLIB::Libcall kind.
212 LLVM_ABI static const RTLIB::Libcall ImplToLibcall[RTLIB::NumLibcallImpls];
213
214 /// Utility function for tablegenerated lookup function. Return a range of
215 /// enum values that apply for the function name at \p NameOffsetEntry with
216 /// the value \p StrOffset.
217 static inline iota_range<RTLIB::LibcallImpl>
218 libcallImplNameHit(uint16_t NameOffsetEntry, uint16_t StrOffset);
219
220 static bool darwinHasSinCosStret(const Triple &TT) {
221 if (!TT.isOSDarwin())
222 return false;
223
224 // Don't bother with 32 bit x86.
225 if (TT.getArch() == Triple::x86)
226 return false;
227 // Macos < 10.9 has no sincos_stret.
228 if (TT.isMacOSX())
229 return !TT.isMacOSXVersionLT(10, 9) && TT.isArch64Bit();
230 // iOS < 7.0 has no sincos_stret.
231 if (TT.isiOS())
232 return !TT.isOSVersionLT(7, 0);
233 // Any other darwin such as WatchOS/TvOS is new enough.
234 return true;
235 }
236
237 static bool hasAEABILibcalls(const Triple &TT) {
238 return TT.isTargetAEABI() || TT.isTargetGNUAEABI() ||
239 TT.isTargetMuslAEABI() || TT.isOSFuchsia() || TT.isAndroid();
240 }
241
243 static bool isAAPCS_ABI(const Triple &TT, StringRef ABIName);
244
245 static bool darwinHasExp10(const Triple &TT);
246
247 /// Return true if the target has sincosf/sincos/sincosl functions
248 static bool hasSinCos(const Triple &TT) {
249 return TT.isGNUEnvironment() || TT.isOSFuchsia() || TT.isAndroid();
250 }
251
252 static bool hasSinCos_f32_f64(const Triple &TT) {
253 return hasSinCos(TT) || TT.isPS();
254 }
255
256 /// Generated by tablegen.
257 void setTargetRuntimeLibcallSets(const Triple &TT,
258 ExceptionHandling ExceptionModel,
259 FloatABI::ABIType FloatABI, EABI ABIType,
260 StringRef ABIName);
261
262 /// Set default libcall names. If a target wants to opt-out of a libcall it
263 /// should be placed here.
264 LLVM_ABI void initLibcalls(const Triple &TT, ExceptionHandling ExceptionModel,
265 FloatABI::ABIType FloatABI, EABI ABIType,
266 StringRef ABIName);
267};
268
269} // namespace RTLIB
270} // namespace llvm
271
272#endif // LLVM_IR_RUNTIME_LIBCALLS_H
Atomic ordering constants.
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_READONLY
Definition Compiler.h:322
Provides some synthesis utilities to produce sequences of values.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
constexpr Bitset(const std::array< uint64_t,(NumBits+63)/64 > &B)
Definition Bitset.h:45
Manage a bitset representing the list of available libcalls for a module.
constexpr LibcallImplBitset(const std::array< uint64_t,(RTLIB::NumLibcallImpls+63)/64 > &Src)
constexpr LibcallImplBitset()=default
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
CallInst * Call
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
static auto libcall_impls()
static auto libcalls()
This is an optimization pass for GlobalISel generic memory operations.
auto enum_seq(EnumT Begin, EnumT End)
Iterate over an enum type from Begin up to - but not including - End.
Definition Sequence.h:337
ExceptionHandling
Definition CodeGen.h:53
@ None
No exception support.
Definition CodeGen.h:54
ArrayRef(const T &OneElt) -> ArrayRef< T >
EABI
Definition CodeGen.h:73
static LLVM_ABI iota_range< RTLIB::LibcallImpl > lookupLibcallImplName(StringRef Name)
Check if a function name is a recognized runtime call of any kind.
CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const
Get the CallingConv that should be used for the specified libcall.
bool isAvailable(RTLIB::LibcallImpl Impl) const
void setAvailable(RTLIB::LibcallImpl Impl)
void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl)
Rename the default libcall routine name for the specified libcall.
StringRef getMemcpyName() const
Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully unsupported.
LLVM_ABI RTLIB::LibcallImpl getSupportedLibcallImpl(StringRef FuncName) const
Check if this is valid libcall for the current module, otherwise RTLIB::Unsupported.
StringRef getLibcallName(RTLIB::Libcall Call) const
Get the libcall routine name for the specified libcall.
RuntimeLibcallsInfo(const Triple &TT, ExceptionHandling ExceptionModel=ExceptionHandling::None, FloatABI::ABIType FloatABI=FloatABI::Default, EABI EABIVersion=EABI::Default, StringRef ABIName="")
RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const
Return the lowering's selection of implementation call for Call.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC)
Set the CallingConv that should be used for the specified libcall implementation.
ArrayRef< RTLIB::LibcallImpl > getLibcallImpls() const
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl)
Return the libcall provided by Impl.
CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const