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/Sequence.h"
20#include "llvm/IR/CallingConv.h"
21#include "llvm/IR/InstrTypes.h"
26
27/// TableGen will produce 2 enums, RTLIB::Libcall and
28/// RTLIB::LibcallImpl. RTLIB::Libcall describes abstract functionality the
29/// compiler may choose to access, RTLIB::LibcallImpl describes a particular ABI
30/// implementation, which includes a name and type signature.
31#define GET_RUNTIME_LIBCALL_ENUM
32#include "llvm/IR/RuntimeLibcalls.inc"
33#undef GET_RUNTIME_LIBCALL_ENUM
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/// A simple container for information about the supported runtime calls.
60 const Triple &TT,
63 EABI EABIVersion = EABI::Default, StringRef ABIName = "") {
64 // FIXME: The ExceptionModel parameter is to handle the field in
65 // TargetOptions. This interface fails to distinguish the forced disable
66 // case for targets which support exceptions by default. This should
67 // probably be a module flag and removed from TargetOptions.
68 if (ExceptionModel == ExceptionHandling::None)
69 ExceptionModel = TT.getDefaultExceptionHandling();
70
71 initLibcalls(TT, ExceptionModel, FloatABI, EABIVersion, ABIName);
72 }
73
74 /// Rename the default libcall routine name for the specified libcall.
75 void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl) {
76 LibcallImpls[Call] = Impl;
77 }
78
79 /// Get the libcall routine name for the specified libcall.
80 // FIXME: This should be removed. Only LibcallImpl should have a name.
81 StringRef getLibcallName(RTLIB::Libcall Call) const {
82 return getLibcallImplName(LibcallImpls[Call]);
83 }
84
85 /// Get the libcall routine name for the specified libcall implementation.
86 static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl) {
87 if (CallImpl == RTLIB::Unsupported)
88 return StringRef();
89 return StringRef(RuntimeLibcallImplNameTable.getCString(
90 RuntimeLibcallNameOffsetTable[CallImpl]),
91 RuntimeLibcallNameSizeTable[CallImpl]);
92 }
93
94 /// Return the lowering's selection of implementation call for \p Call
95 RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const {
96 return LibcallImpls[Call];
97 }
98
99 /// Set the CallingConv that should be used for the specified libcall
100 /// implementation
101 void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) {
102 LibcallImplCallingConvs[Call] = CC;
103 }
104
105 // FIXME: Remove this wrapper in favor of directly using
106 // getLibcallImplCallingConv
108 return LibcallImplCallingConvs[LibcallImpls[Call]];
109 }
110
111 /// Get the CallingConv that should be used for the specified libcall.
113 return LibcallImplCallingConvs[Call];
114 }
115
117 // Trim UNKNOWN_LIBCALL from the back
118 return ArrayRef(LibcallImpls).drop_back();
119 }
120
121 /// Return a function name compatible with RTLIB::MEMCPY, or nullptr if fully
122 /// unsupported.
124 RTLIB::LibcallImpl Memcpy = getLibcallImpl(RTLIB::MEMCPY);
125 if (Memcpy != RTLIB::Unsupported)
126 return getLibcallImplName(Memcpy);
127
128 // Fallback to memmove if memcpy isn't available.
129 return getLibcallName(RTLIB::MEMMOVE);
130 }
131
132 /// Return the libcall provided by \p Impl
133 static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl) {
134 return ImplToLibcall[Impl];
135 }
136
137 /// Check if a function name is a recognized runtime call of any kind. This
138 /// does not consider if this call is available for any current compilation,
139 /// just that it is a known call somewhere. This returns the set of all
140 /// LibcallImpls which match the name; multiple implementations with the same
141 /// name may exist but differ in interpretation based on the target context.
142 ///
143 /// Generated by tablegen.
146 // Inlining the early exit on the string name appears to be worthwhile when
147 // querying a real set of symbols
148#define GET_LOOKUP_LIBCALL_IMPL_NAME_BODY
149#include "llvm/IR/RuntimeLibcalls.inc"
150#undef GET_LOOKUP_LIBCALL_IMPL_NAME_BODY
151 }
152
153 /// Check if this is valid libcall for the current module, otherwise
154 /// RTLIB::Unsupported.
155 LLVM_ABI RTLIB::LibcallImpl
157 for (RTLIB::LibcallImpl Impl : lookupLibcallImplName(FuncName)) {
158 // FIXME: This should not depend on looking up ImplToLibcall, only the
159 // list of libcalls for the module.
160 RTLIB::LibcallImpl Recognized = LibcallImpls[ImplToLibcall[Impl]];
161 if (Recognized != RTLIB::Unsupported)
162 return Recognized;
163 }
164
165 return RTLIB::Unsupported;
166 }
167
168private:
170 lookupLibcallImplNameImpl(StringRef Name);
171
172 /// Stores the implementation choice for each each libcall.
173 RTLIB::LibcallImpl LibcallImpls[RTLIB::UNKNOWN_LIBCALL + 1] = {
174 RTLIB::Unsupported};
175
176 static_assert(static_cast<int>(CallingConv::C) == 0,
177 "default calling conv should be encoded as 0");
178
179 /// Stores the CallingConv that should be used for each libcall
180 /// implementation.;
181 CallingConv::ID LibcallImplCallingConvs[RTLIB::NumLibcallImpls] = {};
182
183 /// Names of concrete implementations of runtime calls. e.g. __ashlsi3 for
184 /// SHL_I32
185 LLVM_ABI static const char RuntimeLibcallImplNameTableStorage[];
186 LLVM_ABI static const StringTable RuntimeLibcallImplNameTable;
187 LLVM_ABI static const uint16_t RuntimeLibcallNameOffsetTable[];
188 LLVM_ABI static const uint8_t RuntimeLibcallNameSizeTable[];
189
190 /// Map from a concrete LibcallImpl implementation to its RTLIB::Libcall kind.
191 LLVM_ABI static const RTLIB::Libcall ImplToLibcall[RTLIB::NumLibcallImpls];
192
193 /// Utility function for tablegenerated lookup function. Return a range of
194 /// enum values that apply for the function name at \p NameOffsetEntry with
195 /// the value \p StrOffset.
196 static inline iota_range<RTLIB::LibcallImpl>
197 libcallImplNameHit(uint16_t NameOffsetEntry, uint16_t StrOffset);
198
199 static bool darwinHasSinCosStret(const Triple &TT) {
200 if (!TT.isOSDarwin())
201 return false;
202
203 // Don't bother with 32 bit x86.
204 if (TT.getArch() == Triple::x86)
205 return false;
206 // Macos < 10.9 has no sincos_stret.
207 if (TT.isMacOSX())
208 return !TT.isMacOSXVersionLT(10, 9) && TT.isArch64Bit();
209 // iOS < 7.0 has no sincos_stret.
210 if (TT.isiOS())
211 return !TT.isOSVersionLT(7, 0);
212 // Any other darwin such as WatchOS/TvOS is new enough.
213 return true;
214 }
215
216 static bool hasAEABILibcalls(const Triple &TT) {
217 return TT.isTargetAEABI() || TT.isTargetGNUAEABI() ||
218 TT.isTargetMuslAEABI() || TT.isAndroid();
219 }
220
222 static bool isAAPCS_ABI(const Triple &TT, StringRef ABIName);
223
224 static bool darwinHasExp10(const Triple &TT);
225
226 /// Return true if the target has sincosf/sincos/sincosl functions
227 static bool hasSinCos(const Triple &TT) {
228 return TT.isGNUEnvironment() || TT.isOSFuchsia() ||
229 (TT.isAndroid() && !TT.isAndroidVersionLT(9));
230 }
231
232 static bool hasSinCos_f32_f64(const Triple &TT) {
233 return hasSinCos(TT) || TT.isPS();
234 }
235
236 /// Generated by tablegen.
237 void setTargetRuntimeLibcallSets(const Triple &TT,
238 ExceptionHandling ExceptionModel,
239 FloatABI::ABIType FloatABI, EABI ABIType,
240 StringRef ABIName);
241
242 /// Set default libcall names. If a target wants to opt-out of a libcall it
243 /// should be placed here.
244 LLVM_ABI void initLibcalls(const Triple &TT, ExceptionHandling ExceptionModel,
245 FloatABI::ABIType FloatABI, EABI ABIType,
246 StringRef ABIName);
247};
248
249} // namespace RTLIB
250} // namespace llvm
251
252#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
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.
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