LLVM 22.0.0git
RuntimeLibcalls.cpp
Go to the documentation of this file.
1//===- RuntimeLibcalls.cpp - 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
12#include "llvm/IR/Module.h"
13#include "llvm/Support/Debug.h"
14#include "llvm/Support/xxhash.h"
16
17#define DEBUG_TYPE "runtime-libcalls-info"
18
19using namespace llvm;
20using namespace RTLIB;
21
22#define GET_RUNTIME_LIBCALLS_INFO
23#define GET_INIT_RUNTIME_LIBCALL_NAMES
24#define GET_SET_TARGET_RUNTIME_LIBCALL_SETS
25#define DEFINE_GET_LOOKUP_LIBCALL_IMPL_NAME
26#include "llvm/IR/RuntimeLibcalls.inc"
27
29 : RuntimeLibcallsInfo(M.getTargetTriple()) {
30 // TODO: Consider module flags
31}
32
33/// Set default libcall names. If a target wants to opt-out of a libcall it
34/// should be placed here.
35void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
36 ExceptionHandling ExceptionModel,
38 EABI EABIVersion, StringRef ABIName) {
39 setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI, EABIVersion,
40 ABIName);
41}
42
45RuntimeLibcallsInfo::libcallImplNameHit(uint16_t NameOffsetEntry,
46 uint16_t StrOffset) {
47 int NumAliases = 1;
48 for (uint16_t Entry : ArrayRef(RuntimeLibcallNameOffsetTable)
49 .drop_front(NameOffsetEntry + 1)) {
50 if (Entry != StrOffset)
51 break;
52 ++NumAliases;
53 }
54
55 RTLIB::LibcallImpl ImplStart = static_cast<RTLIB::LibcallImpl>(
56 &RuntimeLibcallNameOffsetTable[NameOffsetEntry] -
57 &RuntimeLibcallNameOffsetTable[0]);
58 return enum_seq(ImplStart,
59 static_cast<RTLIB::LibcallImpl>(ImplStart + NumAliases));
60}
61
62bool RuntimeLibcallsInfo::isAAPCS_ABI(const Triple &TT, StringRef ABIName) {
63 const ARM::ARMABI TargetABI = ARM::computeTargetABI(TT, ABIName);
64 return TargetABI == ARM::ARM_ABI_AAPCS || TargetABI == ARM::ARM_ABI_AAPCS16;
65}
66
67bool RuntimeLibcallsInfo::darwinHasExp10(const Triple &TT) {
68 switch (TT.getOS()) {
69 case Triple::MacOSX:
70 return !TT.isMacOSXVersionLT(10, 9);
71 case Triple::IOS:
72 return !TT.isOSVersionLT(7, 0);
74 case Triple::TvOS:
75 case Triple::WatchOS:
76 case Triple::XROS:
78 return true;
79 default:
80 return false;
81 }
82}
83
84std::pair<FunctionType *, AttributeList>
86 const DataLayout &DL,
87 RTLIB::LibcallImpl LibcallImpl) const {
88 static constexpr Attribute::AttrKind CommonFnAttrs[] = {
89 Attribute::NoCallback, Attribute::NoFree, Attribute::NoSync,
90 Attribute::NoUnwind, Attribute::WillReturn};
91
92 switch (LibcallImpl) {
93 case RTLIB::impl___sincos_stret:
94 case RTLIB::impl___sincosf_stret: {
95 if (!darwinHasSinCosStret(TT)) // Non-darwin currently unexpected
96 return {};
97
98 Type *ScalarTy = LibcallImpl == RTLIB::impl___sincosf_stret
99 ? Type::getFloatTy(Ctx)
100 : Type::getDoubleTy(Ctx);
101
102 AttrBuilder FuncAttrBuilder(Ctx);
103 for (Attribute::AttrKind Attr : CommonFnAttrs)
104 FuncAttrBuilder.addAttribute(Attr);
105
106 const bool UseSret =
107 TT.isX86_32() || ((TT.isARM() || TT.isThumb()) &&
109
110 FuncAttrBuilder.addMemoryAttr(MemoryEffects::argumentOrErrnoMemOnly(
112
113 AttributeList Attrs;
114 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
115
116 if (UseSret) {
117 AttrBuilder AttrBuilder(Ctx);
118 StructType *StructTy = StructType::get(ScalarTy, ScalarTy);
119 AttrBuilder.addStructRetAttr(StructTy);
120 AttrBuilder.addAlignmentAttr(DL.getABITypeAlign(StructTy));
122 Type::getVoidTy(Ctx), {DL.getAllocaPtrType(Ctx), ScalarTy}, false);
123
124 return {FuncTy, Attrs.addParamAttributes(Ctx, 0, AttrBuilder)};
125 }
126
127 Type *RetTy =
128 LibcallImpl == RTLIB::impl___sincosf_stret && TT.isX86_64()
129 ? static_cast<Type *>(FixedVectorType::get(ScalarTy, 2))
130 : static_cast<Type *>(StructType::get(ScalarTy, ScalarTy));
131
132 return {FunctionType::get(RetTy, {ScalarTy}, false), Attrs};
133 }
134 case RTLIB::impl_sqrtf:
135 case RTLIB::impl_sqrt: {
136 AttrBuilder FuncAttrBuilder(Ctx);
137
138 for (Attribute::AttrKind Attr : CommonFnAttrs)
139 FuncAttrBuilder.addAttribute(Attr);
140 FuncAttrBuilder.addMemoryAttr(MemoryEffects::errnoMemOnly(ModRefInfo::Mod));
141
142 AttributeList Attrs;
143 Attrs = Attrs.addFnAttributes(Ctx, FuncAttrBuilder);
144
145 Type *ScalarTy = LibcallImpl == RTLIB::impl_sqrtf ? Type::getFloatTy(Ctx)
146 : Type::getDoubleTy(Ctx);
147 FunctionType *FuncTy = FunctionType::get(ScalarTy, {ScalarTy}, false);
148
149 Attrs = Attrs.addRetAttribute(
151 fcNegNormal));
152 return {FuncTy, Attrs};
153 }
154 default:
155 return {};
156 }
157
158 return {};
159}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
Definition Compiler.h:356
Utilities for dealing with flags related to floating point properties and mode controls.
Module.h This file contains the declarations for the Module class.
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:88
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:803
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
static MemoryEffectsBase errnoMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:146
static MemoryEffectsBase argumentOrErrnoMemOnly(ModRefInfo ArgMR=ModRefInfo::ModRef, ModRefInfo ErrnoMR=ModRefInfo::ModRef)
Definition ModRef.h:167
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:414
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:281
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
Definition Type.cpp:286
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
Definition Type.cpp:285
LLVM_ABI LLVM_READONLY ARMABI computeTargetABI(const Triple &TT, StringRef ABIName="")
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
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
@ NoModRef
The access neither references nor modifies the value stored in memory.
Definition ModRef.h:30
ArrayRef(const T &OneElt) -> ArrayRef< T >
EABI
Definition CodeGen.h:73
std::pair< FunctionType *, AttributeList > getFunctionTy(LLVMContext &Ctx, const Triple &TT, const DataLayout &DL, RTLIB::LibcallImpl LibcallImpl) const