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