Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
35271 views
//===- BuildLibCalls.cpp - Utility builder for libcalls -------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements some functions that will create standard C libcalls.9//10//===----------------------------------------------------------------------===//1112#include "llvm/Transforms/Utils/BuildLibCalls.h"13#include "llvm/ADT/SmallString.h"14#include "llvm/ADT/Statistic.h"15#include "llvm/Analysis/MemoryBuiltins.h"16#include "llvm/Analysis/TargetLibraryInfo.h"17#include "llvm/IR/Argument.h"18#include "llvm/IR/CallingConv.h"19#include "llvm/IR/Constants.h"20#include "llvm/IR/DataLayout.h"21#include "llvm/IR/Function.h"22#include "llvm/IR/IRBuilder.h"23#include "llvm/IR/Module.h"24#include "llvm/IR/Type.h"25#include "llvm/Support/TypeSize.h"26#include <optional>2728using namespace llvm;2930#define DEBUG_TYPE "build-libcalls"3132//- Infer Attributes ---------------------------------------------------------//3334STATISTIC(NumReadNone, "Number of functions inferred as readnone");35STATISTIC(NumInaccessibleMemOnly,36"Number of functions inferred as inaccessiblememonly");37STATISTIC(NumReadOnly, "Number of functions inferred as readonly");38STATISTIC(NumWriteOnly, "Number of functions inferred as writeonly");39STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");40STATISTIC(NumInaccessibleMemOrArgMemOnly,41"Number of functions inferred as inaccessiblemem_or_argmemonly");42STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");43STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");44STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");45STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");46STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");47STATISTIC(NumNoUndef, "Number of function returns inferred as noundef returns");48STATISTIC(NumReturnedArg, "Number of arguments inferred as returned");49STATISTIC(NumWillReturn, "Number of functions inferred as willreturn");5051static bool setDoesNotAccessMemory(Function &F) {52if (F.doesNotAccessMemory())53return false;54F.setDoesNotAccessMemory();55++NumReadNone;56return true;57}5859static bool setOnlyAccessesInaccessibleMemory(Function &F) {60if (F.onlyAccessesInaccessibleMemory())61return false;62F.setOnlyAccessesInaccessibleMemory();63++NumInaccessibleMemOnly;64return true;65}6667static bool setOnlyReadsMemory(Function &F) {68if (F.onlyReadsMemory())69return false;70F.setOnlyReadsMemory();71++NumReadOnly;72return true;73}7475static bool setOnlyWritesMemory(Function &F) {76if (F.onlyWritesMemory()) // writeonly or readnone77return false;78++NumWriteOnly;79F.setOnlyWritesMemory();80return true;81}8283static bool setOnlyAccessesArgMemory(Function &F) {84if (F.onlyAccessesArgMemory())85return false;86F.setOnlyAccessesArgMemory();87++NumArgMemOnly;88return true;89}9091static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) {92if (F.onlyAccessesInaccessibleMemOrArgMem())93return false;94F.setOnlyAccessesInaccessibleMemOrArgMem();95++NumInaccessibleMemOrArgMemOnly;96return true;97}9899static bool setDoesNotThrow(Function &F) {100if (F.doesNotThrow())101return false;102F.setDoesNotThrow();103++NumNoUnwind;104return true;105}106107static bool setRetDoesNotAlias(Function &F) {108if (F.hasRetAttribute(Attribute::NoAlias))109return false;110F.addRetAttr(Attribute::NoAlias);111++NumNoAlias;112return true;113}114115static bool setDoesNotCapture(Function &F, unsigned ArgNo) {116if (F.hasParamAttribute(ArgNo, Attribute::NoCapture))117return false;118F.addParamAttr(ArgNo, Attribute::NoCapture);119++NumNoCapture;120return true;121}122123static bool setDoesNotAlias(Function &F, unsigned ArgNo) {124if (F.hasParamAttribute(ArgNo, Attribute::NoAlias))125return false;126F.addParamAttr(ArgNo, Attribute::NoAlias);127++NumNoAlias;128return true;129}130131static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {132if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))133return false;134F.addParamAttr(ArgNo, Attribute::ReadOnly);135++NumReadOnlyArg;136return true;137}138139static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) {140if (F.hasParamAttribute(ArgNo, Attribute::WriteOnly))141return false;142F.addParamAttr(ArgNo, Attribute::WriteOnly);143++NumWriteOnlyArg;144return true;145}146147static bool setRetNoUndef(Function &F) {148if (!F.getReturnType()->isVoidTy() &&149!F.hasRetAttribute(Attribute::NoUndef)) {150F.addRetAttr(Attribute::NoUndef);151++NumNoUndef;152return true;153}154return false;155}156157static bool setArgsNoUndef(Function &F) {158bool Changed = false;159for (unsigned ArgNo = 0; ArgNo < F.arg_size(); ++ArgNo) {160if (!F.hasParamAttribute(ArgNo, Attribute::NoUndef)) {161F.addParamAttr(ArgNo, Attribute::NoUndef);162++NumNoUndef;163Changed = true;164}165}166return Changed;167}168169static bool setArgNoUndef(Function &F, unsigned ArgNo) {170if (F.hasParamAttribute(ArgNo, Attribute::NoUndef))171return false;172F.addParamAttr(ArgNo, Attribute::NoUndef);173++NumNoUndef;174return true;175}176177static bool setRetAndArgsNoUndef(Function &F) {178bool UndefAdded = false;179UndefAdded |= setRetNoUndef(F);180UndefAdded |= setArgsNoUndef(F);181return UndefAdded;182}183184static bool setReturnedArg(Function &F, unsigned ArgNo) {185if (F.hasParamAttribute(ArgNo, Attribute::Returned))186return false;187F.addParamAttr(ArgNo, Attribute::Returned);188++NumReturnedArg;189return true;190}191192static bool setNonLazyBind(Function &F) {193if (F.hasFnAttribute(Attribute::NonLazyBind))194return false;195F.addFnAttr(Attribute::NonLazyBind);196return true;197}198199static bool setDoesNotFreeMemory(Function &F) {200if (F.hasFnAttribute(Attribute::NoFree))201return false;202F.addFnAttr(Attribute::NoFree);203return true;204}205206static bool setWillReturn(Function &F) {207if (F.hasFnAttribute(Attribute::WillReturn))208return false;209F.addFnAttr(Attribute::WillReturn);210++NumWillReturn;211return true;212}213214static bool setAlignedAllocParam(Function &F, unsigned ArgNo) {215if (F.hasParamAttribute(ArgNo, Attribute::AllocAlign))216return false;217F.addParamAttr(ArgNo, Attribute::AllocAlign);218return true;219}220221static bool setAllocatedPointerParam(Function &F, unsigned ArgNo) {222if (F.hasParamAttribute(ArgNo, Attribute::AllocatedPointer))223return false;224F.addParamAttr(ArgNo, Attribute::AllocatedPointer);225return true;226}227228static bool setAllocSize(Function &F, unsigned ElemSizeArg,229std::optional<unsigned> NumElemsArg) {230if (F.hasFnAttribute(Attribute::AllocSize))231return false;232F.addFnAttr(Attribute::getWithAllocSizeArgs(F.getContext(), ElemSizeArg,233NumElemsArg));234return true;235}236237static bool setAllocFamily(Function &F, StringRef Family) {238if (F.hasFnAttribute("alloc-family"))239return false;240F.addFnAttr("alloc-family", Family);241return true;242}243244static bool setAllocKind(Function &F, AllocFnKind K) {245if (F.hasFnAttribute(Attribute::AllocKind))246return false;247F.addFnAttr(248Attribute::get(F.getContext(), Attribute::AllocKind, uint64_t(K)));249return true;250}251252bool llvm::inferNonMandatoryLibFuncAttrs(Module *M, StringRef Name,253const TargetLibraryInfo &TLI) {254Function *F = M->getFunction(Name);255if (!F)256return false;257return inferNonMandatoryLibFuncAttrs(*F, TLI);258}259260bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,261const TargetLibraryInfo &TLI) {262LibFunc TheLibFunc;263if (!(TLI.getLibFunc(F, TheLibFunc) && TLI.has(TheLibFunc)))264return false;265266bool Changed = false;267268if (F.getParent() != nullptr && F.getParent()->getRtLibUseGOT())269Changed |= setNonLazyBind(F);270271switch (TheLibFunc) {272case LibFunc_strlen:273case LibFunc_strnlen:274case LibFunc_wcslen:275Changed |= setOnlyReadsMemory(F);276Changed |= setDoesNotThrow(F);277Changed |= setOnlyAccessesArgMemory(F);278Changed |= setWillReturn(F);279Changed |= setDoesNotCapture(F, 0);280break;281case LibFunc_strchr:282case LibFunc_strrchr:283Changed |= setOnlyAccessesArgMemory(F);284Changed |= setOnlyReadsMemory(F);285Changed |= setDoesNotThrow(F);286Changed |= setWillReturn(F);287break;288case LibFunc_strtol:289case LibFunc_strtod:290case LibFunc_strtof:291case LibFunc_strtoul:292case LibFunc_strtoll:293case LibFunc_strtold:294case LibFunc_strtoull:295Changed |= setDoesNotThrow(F);296Changed |= setWillReturn(F);297Changed |= setDoesNotCapture(F, 1);298Changed |= setOnlyReadsMemory(F, 0);299break;300case LibFunc_strcat:301case LibFunc_strncat:302Changed |= setOnlyAccessesArgMemory(F);303Changed |= setDoesNotThrow(F);304Changed |= setWillReturn(F);305Changed |= setReturnedArg(F, 0);306Changed |= setDoesNotCapture(F, 1);307Changed |= setOnlyReadsMemory(F, 1);308Changed |= setDoesNotAlias(F, 0);309Changed |= setDoesNotAlias(F, 1);310break;311case LibFunc_strcpy:312case LibFunc_strncpy:313Changed |= setReturnedArg(F, 0);314[[fallthrough]];315case LibFunc_stpcpy:316case LibFunc_stpncpy:317Changed |= setOnlyAccessesArgMemory(F);318Changed |= setDoesNotThrow(F);319Changed |= setWillReturn(F);320Changed |= setDoesNotCapture(F, 1);321Changed |= setOnlyWritesMemory(F, 0);322Changed |= setOnlyReadsMemory(F, 1);323Changed |= setDoesNotAlias(F, 0);324Changed |= setDoesNotAlias(F, 1);325break;326case LibFunc_strxfrm:327Changed |= setDoesNotThrow(F);328Changed |= setWillReturn(F);329Changed |= setDoesNotCapture(F, 0);330Changed |= setDoesNotCapture(F, 1);331Changed |= setOnlyReadsMemory(F, 1);332break;333case LibFunc_strcmp: // 0,1334case LibFunc_strspn: // 0,1335case LibFunc_strncmp: // 0,1336case LibFunc_strcspn: // 0,1337Changed |= setDoesNotThrow(F);338Changed |= setOnlyAccessesArgMemory(F);339Changed |= setWillReturn(F);340Changed |= setOnlyReadsMemory(F);341Changed |= setDoesNotCapture(F, 0);342Changed |= setDoesNotCapture(F, 1);343break;344case LibFunc_strcoll:345case LibFunc_strcasecmp: // 0,1346case LibFunc_strncasecmp: //347// Those functions may depend on the locale, which may be accessed through348// global memory.349Changed |= setOnlyReadsMemory(F);350Changed |= setDoesNotThrow(F);351Changed |= setWillReturn(F);352Changed |= setDoesNotCapture(F, 0);353Changed |= setDoesNotCapture(F, 1);354break;355case LibFunc_strstr:356case LibFunc_strpbrk:357Changed |= setOnlyAccessesArgMemory(F);358Changed |= setOnlyReadsMemory(F);359Changed |= setDoesNotThrow(F);360Changed |= setWillReturn(F);361Changed |= setDoesNotCapture(F, 1);362break;363case LibFunc_strtok:364case LibFunc_strtok_r:365Changed |= setDoesNotThrow(F);366Changed |= setWillReturn(F);367Changed |= setDoesNotCapture(F, 1);368Changed |= setOnlyReadsMemory(F, 1);369break;370case LibFunc_scanf:371Changed |= setRetAndArgsNoUndef(F);372Changed |= setDoesNotThrow(F);373Changed |= setDoesNotCapture(F, 0);374Changed |= setOnlyReadsMemory(F, 0);375break;376case LibFunc_setbuf:377case LibFunc_setvbuf:378Changed |= setRetAndArgsNoUndef(F);379Changed |= setDoesNotThrow(F);380Changed |= setDoesNotCapture(F, 0);381break;382case LibFunc_strndup:383Changed |= setArgNoUndef(F, 1);384[[fallthrough]];385case LibFunc_strdup:386Changed |= setAllocFamily(F, "malloc");387Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);388Changed |= setDoesNotThrow(F);389Changed |= setRetDoesNotAlias(F);390Changed |= setWillReturn(F);391Changed |= setDoesNotCapture(F, 0);392Changed |= setOnlyReadsMemory(F, 0);393break;394case LibFunc_stat:395case LibFunc_statvfs:396Changed |= setRetAndArgsNoUndef(F);397Changed |= setDoesNotThrow(F);398Changed |= setDoesNotCapture(F, 0);399Changed |= setDoesNotCapture(F, 1);400Changed |= setOnlyReadsMemory(F, 0);401break;402case LibFunc_sscanf:403Changed |= setRetAndArgsNoUndef(F);404Changed |= setDoesNotThrow(F);405Changed |= setDoesNotCapture(F, 0);406Changed |= setDoesNotCapture(F, 1);407Changed |= setOnlyReadsMemory(F, 0);408Changed |= setOnlyReadsMemory(F, 1);409break;410case LibFunc_sprintf:411Changed |= setRetAndArgsNoUndef(F);412Changed |= setDoesNotThrow(F);413Changed |= setDoesNotCapture(F, 0);414Changed |= setDoesNotAlias(F, 0);415Changed |= setOnlyWritesMemory(F, 0);416Changed |= setDoesNotCapture(F, 1);417Changed |= setOnlyReadsMemory(F, 1);418break;419case LibFunc_snprintf:420Changed |= setRetAndArgsNoUndef(F);421Changed |= setDoesNotThrow(F);422Changed |= setDoesNotCapture(F, 0);423Changed |= setDoesNotAlias(F, 0);424Changed |= setOnlyWritesMemory(F, 0);425Changed |= setDoesNotCapture(F, 2);426Changed |= setOnlyReadsMemory(F, 2);427break;428case LibFunc_setitimer:429Changed |= setRetAndArgsNoUndef(F);430Changed |= setDoesNotThrow(F);431Changed |= setWillReturn(F);432Changed |= setDoesNotCapture(F, 1);433Changed |= setDoesNotCapture(F, 2);434Changed |= setOnlyReadsMemory(F, 1);435break;436case LibFunc_system:437// May throw; "system" is a valid pthread cancellation point.438Changed |= setRetAndArgsNoUndef(F);439Changed |= setDoesNotCapture(F, 0);440Changed |= setOnlyReadsMemory(F, 0);441break;442case LibFunc_aligned_alloc:443Changed |= setAlignedAllocParam(F, 0);444Changed |= setAllocSize(F, 1, std::nullopt);445Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Uninitialized | AllocFnKind::Aligned);446[[fallthrough]];447case LibFunc_valloc:448case LibFunc_malloc:449case LibFunc_vec_malloc:450Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_malloc ? "vec_malloc"451: "malloc");452Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Uninitialized);453Changed |= setAllocSize(F, 0, std::nullopt);454Changed |= setOnlyAccessesInaccessibleMemory(F);455Changed |= setRetAndArgsNoUndef(F);456Changed |= setDoesNotThrow(F);457Changed |= setRetDoesNotAlias(F);458Changed |= setWillReturn(F);459break;460case LibFunc_memcmp:461Changed |= setOnlyAccessesArgMemory(F);462Changed |= setOnlyReadsMemory(F);463Changed |= setDoesNotThrow(F);464Changed |= setWillReturn(F);465Changed |= setDoesNotCapture(F, 0);466Changed |= setDoesNotCapture(F, 1);467break;468case LibFunc_memchr:469case LibFunc_memrchr:470Changed |= setDoesNotThrow(F);471Changed |= setOnlyAccessesArgMemory(F);472Changed |= setOnlyReadsMemory(F);473Changed |= setWillReturn(F);474break;475case LibFunc_modf:476case LibFunc_modff:477case LibFunc_modfl:478Changed |= setDoesNotThrow(F);479Changed |= setWillReturn(F);480Changed |= setOnlyAccessesArgMemory(F);481Changed |= setOnlyWritesMemory(F);482Changed |= setDoesNotCapture(F, 1);483break;484case LibFunc_memcpy:485Changed |= setDoesNotThrow(F);486Changed |= setOnlyAccessesArgMemory(F);487Changed |= setWillReturn(F);488Changed |= setDoesNotAlias(F, 0);489Changed |= setReturnedArg(F, 0);490Changed |= setOnlyWritesMemory(F, 0);491Changed |= setDoesNotAlias(F, 1);492Changed |= setDoesNotCapture(F, 1);493Changed |= setOnlyReadsMemory(F, 1);494break;495case LibFunc_memmove:496Changed |= setDoesNotThrow(F);497Changed |= setOnlyAccessesArgMemory(F);498Changed |= setWillReturn(F);499Changed |= setReturnedArg(F, 0);500Changed |= setOnlyWritesMemory(F, 0);501Changed |= setDoesNotCapture(F, 1);502Changed |= setOnlyReadsMemory(F, 1);503break;504case LibFunc_mempcpy:505case LibFunc_memccpy:506Changed |= setWillReturn(F);507[[fallthrough]];508case LibFunc_memcpy_chk:509Changed |= setDoesNotThrow(F);510Changed |= setOnlyAccessesArgMemory(F);511Changed |= setDoesNotAlias(F, 0);512Changed |= setOnlyWritesMemory(F, 0);513Changed |= setDoesNotAlias(F, 1);514Changed |= setDoesNotCapture(F, 1);515Changed |= setOnlyReadsMemory(F, 1);516break;517case LibFunc_memalign:518Changed |= setAllocFamily(F, "malloc");519Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Aligned |520AllocFnKind::Uninitialized);521Changed |= setAllocSize(F, 1, std::nullopt);522Changed |= setAlignedAllocParam(F, 0);523Changed |= setOnlyAccessesInaccessibleMemory(F);524Changed |= setRetNoUndef(F);525Changed |= setDoesNotThrow(F);526Changed |= setRetDoesNotAlias(F);527Changed |= setWillReturn(F);528break;529case LibFunc_mkdir:530Changed |= setRetAndArgsNoUndef(F);531Changed |= setDoesNotThrow(F);532Changed |= setDoesNotCapture(F, 0);533Changed |= setOnlyReadsMemory(F, 0);534break;535case LibFunc_mktime:536Changed |= setRetAndArgsNoUndef(F);537Changed |= setDoesNotThrow(F);538Changed |= setWillReturn(F);539Changed |= setDoesNotCapture(F, 0);540break;541case LibFunc_realloc:542case LibFunc_reallocf:543case LibFunc_vec_realloc:544Changed |= setAllocFamily(545F, TheLibFunc == LibFunc_vec_realloc ? "vec_malloc" : "malloc");546Changed |= setAllocKind(F, AllocFnKind::Realloc);547Changed |= setAllocatedPointerParam(F, 0);548Changed |= setAllocSize(F, 1, std::nullopt);549Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);550Changed |= setRetNoUndef(F);551Changed |= setDoesNotThrow(F);552Changed |= setRetDoesNotAlias(F);553Changed |= setWillReturn(F);554Changed |= setDoesNotCapture(F, 0);555Changed |= setArgNoUndef(F, 1);556break;557case LibFunc_read:558// May throw; "read" is a valid pthread cancellation point.559Changed |= setRetAndArgsNoUndef(F);560Changed |= setDoesNotCapture(F, 1);561break;562case LibFunc_rewind:563Changed |= setRetAndArgsNoUndef(F);564Changed |= setDoesNotThrow(F);565Changed |= setDoesNotCapture(F, 0);566break;567case LibFunc_rmdir:568case LibFunc_remove:569case LibFunc_realpath:570Changed |= setRetAndArgsNoUndef(F);571Changed |= setDoesNotThrow(F);572Changed |= setDoesNotCapture(F, 0);573Changed |= setOnlyReadsMemory(F, 0);574break;575case LibFunc_rename:576Changed |= setRetAndArgsNoUndef(F);577Changed |= setDoesNotThrow(F);578Changed |= setDoesNotCapture(F, 0);579Changed |= setDoesNotCapture(F, 1);580Changed |= setOnlyReadsMemory(F, 0);581Changed |= setOnlyReadsMemory(F, 1);582break;583case LibFunc_readlink:584Changed |= setRetAndArgsNoUndef(F);585Changed |= setDoesNotThrow(F);586Changed |= setDoesNotCapture(F, 0);587Changed |= setDoesNotCapture(F, 1);588Changed |= setOnlyReadsMemory(F, 0);589break;590case LibFunc_write:591// May throw; "write" is a valid pthread cancellation point.592Changed |= setRetAndArgsNoUndef(F);593Changed |= setDoesNotCapture(F, 1);594Changed |= setOnlyReadsMemory(F, 1);595break;596case LibFunc_bcopy:597Changed |= setDoesNotThrow(F);598Changed |= setOnlyAccessesArgMemory(F);599Changed |= setWillReturn(F);600Changed |= setDoesNotCapture(F, 0);601Changed |= setOnlyReadsMemory(F, 0);602Changed |= setOnlyWritesMemory(F, 1);603Changed |= setDoesNotCapture(F, 1);604break;605case LibFunc_bcmp:606Changed |= setDoesNotThrow(F);607Changed |= setOnlyAccessesArgMemory(F);608Changed |= setOnlyReadsMemory(F);609Changed |= setWillReturn(F);610Changed |= setDoesNotCapture(F, 0);611Changed |= setDoesNotCapture(F, 1);612break;613case LibFunc_bzero:614Changed |= setDoesNotThrow(F);615Changed |= setOnlyAccessesArgMemory(F);616Changed |= setWillReturn(F);617Changed |= setDoesNotCapture(F, 0);618Changed |= setOnlyWritesMemory(F, 0);619break;620case LibFunc_calloc:621case LibFunc_vec_calloc:622Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_calloc ? "vec_malloc"623: "malloc");624Changed |= setAllocKind(F, AllocFnKind::Alloc | AllocFnKind::Zeroed);625Changed |= setAllocSize(F, 0, 1);626Changed |= setOnlyAccessesInaccessibleMemory(F);627Changed |= setRetAndArgsNoUndef(F);628Changed |= setDoesNotThrow(F);629Changed |= setRetDoesNotAlias(F);630Changed |= setWillReturn(F);631break;632case LibFunc_chmod:633case LibFunc_chown:634Changed |= setRetAndArgsNoUndef(F);635Changed |= setDoesNotThrow(F);636Changed |= setDoesNotCapture(F, 0);637Changed |= setOnlyReadsMemory(F, 0);638break;639case LibFunc_ctermid:640case LibFunc_clearerr:641case LibFunc_closedir:642Changed |= setRetAndArgsNoUndef(F);643Changed |= setDoesNotThrow(F);644Changed |= setDoesNotCapture(F, 0);645break;646case LibFunc_atoi:647case LibFunc_atol:648case LibFunc_atof:649case LibFunc_atoll:650Changed |= setDoesNotThrow(F);651Changed |= setOnlyReadsMemory(F);652Changed |= setWillReturn(F);653Changed |= setDoesNotCapture(F, 0);654break;655case LibFunc_access:656Changed |= setRetAndArgsNoUndef(F);657Changed |= setDoesNotThrow(F);658Changed |= setDoesNotCapture(F, 0);659Changed |= setOnlyReadsMemory(F, 0);660break;661case LibFunc_fopen:662Changed |= setRetAndArgsNoUndef(F);663Changed |= setDoesNotThrow(F);664Changed |= setRetDoesNotAlias(F);665Changed |= setDoesNotCapture(F, 0);666Changed |= setDoesNotCapture(F, 1);667Changed |= setOnlyReadsMemory(F, 0);668Changed |= setOnlyReadsMemory(F, 1);669break;670case LibFunc_fdopen:671Changed |= setRetAndArgsNoUndef(F);672Changed |= setDoesNotThrow(F);673Changed |= setRetDoesNotAlias(F);674Changed |= setDoesNotCapture(F, 1);675Changed |= setOnlyReadsMemory(F, 1);676break;677case LibFunc_feof:678Changed |= setRetAndArgsNoUndef(F);679Changed |= setDoesNotThrow(F);680Changed |= setDoesNotCapture(F, 0);681break;682case LibFunc_free:683case LibFunc_vec_free:684Changed |= setAllocFamily(F, TheLibFunc == LibFunc_vec_free ? "vec_malloc"685: "malloc");686Changed |= setAllocKind(F, AllocFnKind::Free);687Changed |= setAllocatedPointerParam(F, 0);688Changed |= setOnlyAccessesInaccessibleMemOrArgMem(F);689Changed |= setArgsNoUndef(F);690Changed |= setDoesNotThrow(F);691Changed |= setWillReturn(F);692Changed |= setDoesNotCapture(F, 0);693break;694case LibFunc_fseek:695case LibFunc_ftell:696case LibFunc_fgetc:697case LibFunc_fgetc_unlocked:698case LibFunc_fseeko:699case LibFunc_ftello:700case LibFunc_fileno:701case LibFunc_fflush:702case LibFunc_fclose:703case LibFunc_fsetpos:704case LibFunc_flockfile:705case LibFunc_funlockfile:706case LibFunc_ftrylockfile:707Changed |= setRetAndArgsNoUndef(F);708Changed |= setDoesNotThrow(F);709Changed |= setDoesNotCapture(F, 0);710break;711case LibFunc_ferror:712Changed |= setRetAndArgsNoUndef(F);713Changed |= setDoesNotThrow(F);714Changed |= setDoesNotCapture(F, 0);715Changed |= setOnlyReadsMemory(F);716break;717case LibFunc_fputc:718case LibFunc_fputc_unlocked:719case LibFunc_fstat:720Changed |= setRetAndArgsNoUndef(F);721Changed |= setDoesNotThrow(F);722Changed |= setDoesNotCapture(F, 1);723break;724case LibFunc_frexp:725case LibFunc_frexpf:726case LibFunc_frexpl:727Changed |= setDoesNotThrow(F);728Changed |= setWillReturn(F);729Changed |= setOnlyAccessesArgMemory(F);730Changed |= setOnlyWritesMemory(F);731Changed |= setDoesNotCapture(F, 1);732break;733case LibFunc_fstatvfs:734Changed |= setRetAndArgsNoUndef(F);735Changed |= setDoesNotThrow(F);736Changed |= setDoesNotCapture(F, 1);737break;738case LibFunc_fgets:739case LibFunc_fgets_unlocked:740Changed |= setRetAndArgsNoUndef(F);741Changed |= setDoesNotThrow(F);742Changed |= setDoesNotCapture(F, 2);743break;744case LibFunc_fread:745case LibFunc_fread_unlocked:746Changed |= setRetAndArgsNoUndef(F);747Changed |= setDoesNotThrow(F);748Changed |= setDoesNotCapture(F, 0);749Changed |= setDoesNotCapture(F, 3);750break;751case LibFunc_fwrite:752case LibFunc_fwrite_unlocked:753Changed |= setRetAndArgsNoUndef(F);754Changed |= setDoesNotThrow(F);755Changed |= setDoesNotCapture(F, 0);756Changed |= setDoesNotCapture(F, 3);757// FIXME: readonly #1?758break;759case LibFunc_fputs:760case LibFunc_fputs_unlocked:761Changed |= setRetAndArgsNoUndef(F);762Changed |= setDoesNotThrow(F);763Changed |= setDoesNotCapture(F, 0);764Changed |= setDoesNotCapture(F, 1);765Changed |= setOnlyReadsMemory(F, 0);766break;767case LibFunc_fscanf:768case LibFunc_fprintf:769Changed |= setRetAndArgsNoUndef(F);770Changed |= setDoesNotThrow(F);771Changed |= setDoesNotCapture(F, 0);772Changed |= setDoesNotCapture(F, 1);773Changed |= setOnlyReadsMemory(F, 1);774break;775case LibFunc_fgetpos:776Changed |= setRetAndArgsNoUndef(F);777Changed |= setDoesNotThrow(F);778Changed |= setDoesNotCapture(F, 0);779Changed |= setDoesNotCapture(F, 1);780break;781case LibFunc_getc:782Changed |= setRetAndArgsNoUndef(F);783Changed |= setDoesNotThrow(F);784Changed |= setDoesNotCapture(F, 0);785break;786case LibFunc_getlogin_r:787Changed |= setRetAndArgsNoUndef(F);788Changed |= setDoesNotThrow(F);789Changed |= setDoesNotCapture(F, 0);790break;791case LibFunc_getc_unlocked:792Changed |= setRetAndArgsNoUndef(F);793Changed |= setDoesNotThrow(F);794Changed |= setDoesNotCapture(F, 0);795break;796case LibFunc_getenv:797Changed |= setRetAndArgsNoUndef(F);798Changed |= setDoesNotThrow(F);799Changed |= setOnlyReadsMemory(F);800Changed |= setDoesNotCapture(F, 0);801break;802case LibFunc_gets:803case LibFunc_getchar:804case LibFunc_getchar_unlocked:805Changed |= setRetAndArgsNoUndef(F);806Changed |= setDoesNotThrow(F);807break;808case LibFunc_getitimer:809Changed |= setRetAndArgsNoUndef(F);810Changed |= setDoesNotThrow(F);811Changed |= setDoesNotCapture(F, 1);812break;813case LibFunc_getpwnam:814Changed |= setRetAndArgsNoUndef(F);815Changed |= setDoesNotThrow(F);816Changed |= setDoesNotCapture(F, 0);817Changed |= setOnlyReadsMemory(F, 0);818break;819case LibFunc_ungetc:820Changed |= setRetAndArgsNoUndef(F);821Changed |= setDoesNotThrow(F);822Changed |= setDoesNotCapture(F, 1);823break;824case LibFunc_uname:825Changed |= setRetAndArgsNoUndef(F);826Changed |= setDoesNotThrow(F);827Changed |= setDoesNotCapture(F, 0);828break;829case LibFunc_unlink:830Changed |= setRetAndArgsNoUndef(F);831Changed |= setDoesNotThrow(F);832Changed |= setDoesNotCapture(F, 0);833Changed |= setOnlyReadsMemory(F, 0);834break;835case LibFunc_unsetenv:836Changed |= setRetAndArgsNoUndef(F);837Changed |= setDoesNotThrow(F);838Changed |= setDoesNotCapture(F, 0);839Changed |= setOnlyReadsMemory(F, 0);840break;841case LibFunc_utime:842case LibFunc_utimes:843Changed |= setRetAndArgsNoUndef(F);844Changed |= setDoesNotThrow(F);845Changed |= setDoesNotCapture(F, 0);846Changed |= setDoesNotCapture(F, 1);847Changed |= setOnlyReadsMemory(F, 0);848Changed |= setOnlyReadsMemory(F, 1);849break;850case LibFunc_putc:851case LibFunc_putc_unlocked:852Changed |= setRetAndArgsNoUndef(F);853Changed |= setDoesNotThrow(F);854Changed |= setDoesNotCapture(F, 1);855break;856case LibFunc_puts:857case LibFunc_printf:858case LibFunc_perror:859Changed |= setRetAndArgsNoUndef(F);860Changed |= setDoesNotThrow(F);861Changed |= setDoesNotCapture(F, 0);862Changed |= setOnlyReadsMemory(F, 0);863break;864case LibFunc_pread:865// May throw; "pread" is a valid pthread cancellation point.866Changed |= setRetAndArgsNoUndef(F);867Changed |= setDoesNotCapture(F, 1);868break;869case LibFunc_pwrite:870// May throw; "pwrite" is a valid pthread cancellation point.871Changed |= setRetAndArgsNoUndef(F);872Changed |= setDoesNotCapture(F, 1);873Changed |= setOnlyReadsMemory(F, 1);874break;875case LibFunc_putchar:876case LibFunc_putchar_unlocked:877Changed |= setRetAndArgsNoUndef(F);878Changed |= setDoesNotThrow(F);879break;880case LibFunc_popen:881Changed |= setRetAndArgsNoUndef(F);882Changed |= setDoesNotThrow(F);883Changed |= setRetDoesNotAlias(F);884Changed |= setDoesNotCapture(F, 0);885Changed |= setDoesNotCapture(F, 1);886Changed |= setOnlyReadsMemory(F, 0);887Changed |= setOnlyReadsMemory(F, 1);888break;889case LibFunc_pclose:890Changed |= setRetAndArgsNoUndef(F);891Changed |= setDoesNotThrow(F);892Changed |= setDoesNotCapture(F, 0);893break;894case LibFunc_vscanf:895Changed |= setRetAndArgsNoUndef(F);896Changed |= setDoesNotThrow(F);897Changed |= setDoesNotCapture(F, 0);898Changed |= setOnlyReadsMemory(F, 0);899break;900case LibFunc_vsscanf:901Changed |= setRetAndArgsNoUndef(F);902Changed |= setDoesNotThrow(F);903Changed |= setDoesNotCapture(F, 0);904Changed |= setDoesNotCapture(F, 1);905Changed |= setOnlyReadsMemory(F, 0);906Changed |= setOnlyReadsMemory(F, 1);907break;908case LibFunc_vfscanf:909Changed |= setRetAndArgsNoUndef(F);910Changed |= setDoesNotThrow(F);911Changed |= setDoesNotCapture(F, 0);912Changed |= setDoesNotCapture(F, 1);913Changed |= setOnlyReadsMemory(F, 1);914break;915case LibFunc_vprintf:916Changed |= setRetAndArgsNoUndef(F);917Changed |= setDoesNotThrow(F);918Changed |= setDoesNotCapture(F, 0);919Changed |= setOnlyReadsMemory(F, 0);920break;921case LibFunc_vfprintf:922case LibFunc_vsprintf:923Changed |= setRetAndArgsNoUndef(F);924Changed |= setDoesNotThrow(F);925Changed |= setDoesNotCapture(F, 0);926Changed |= setDoesNotCapture(F, 1);927Changed |= setOnlyReadsMemory(F, 1);928break;929case LibFunc_vsnprintf:930Changed |= setRetAndArgsNoUndef(F);931Changed |= setDoesNotThrow(F);932Changed |= setDoesNotCapture(F, 0);933Changed |= setDoesNotCapture(F, 2);934Changed |= setOnlyReadsMemory(F, 2);935break;936case LibFunc_open:937// May throw; "open" is a valid pthread cancellation point.938Changed |= setRetAndArgsNoUndef(F);939Changed |= setDoesNotCapture(F, 0);940Changed |= setOnlyReadsMemory(F, 0);941break;942case LibFunc_opendir:943Changed |= setRetAndArgsNoUndef(F);944Changed |= setDoesNotThrow(F);945Changed |= setRetDoesNotAlias(F);946Changed |= setDoesNotCapture(F, 0);947Changed |= setOnlyReadsMemory(F, 0);948break;949case LibFunc_tmpfile:950Changed |= setRetAndArgsNoUndef(F);951Changed |= setDoesNotThrow(F);952Changed |= setRetDoesNotAlias(F);953break;954case LibFunc_times:955Changed |= setRetAndArgsNoUndef(F);956Changed |= setDoesNotThrow(F);957Changed |= setDoesNotCapture(F, 0);958break;959case LibFunc_htonl:960case LibFunc_htons:961case LibFunc_ntohl:962case LibFunc_ntohs:963Changed |= setDoesNotThrow(F);964Changed |= setDoesNotAccessMemory(F);965break;966case LibFunc_lstat:967Changed |= setRetAndArgsNoUndef(F);968Changed |= setDoesNotThrow(F);969Changed |= setDoesNotCapture(F, 0);970Changed |= setDoesNotCapture(F, 1);971Changed |= setOnlyReadsMemory(F, 0);972break;973case LibFunc_lchown:974Changed |= setRetAndArgsNoUndef(F);975Changed |= setDoesNotThrow(F);976Changed |= setDoesNotCapture(F, 0);977Changed |= setOnlyReadsMemory(F, 0);978break;979case LibFunc_qsort:980// May throw; places call through function pointer.981// Cannot give undef pointer/size982Changed |= setRetAndArgsNoUndef(F);983Changed |= setDoesNotCapture(F, 3);984break;985case LibFunc_dunder_strndup:986Changed |= setArgNoUndef(F, 1);987[[fallthrough]];988case LibFunc_dunder_strdup:989Changed |= setDoesNotThrow(F);990Changed |= setRetDoesNotAlias(F);991Changed |= setWillReturn(F);992Changed |= setDoesNotCapture(F, 0);993Changed |= setOnlyReadsMemory(F, 0);994break;995case LibFunc_dunder_strtok_r:996Changed |= setDoesNotThrow(F);997Changed |= setDoesNotCapture(F, 1);998Changed |= setOnlyReadsMemory(F, 1);999break;1000case LibFunc_under_IO_getc:1001Changed |= setRetAndArgsNoUndef(F);1002Changed |= setDoesNotThrow(F);1003Changed |= setDoesNotCapture(F, 0);1004break;1005case LibFunc_under_IO_putc:1006Changed |= setRetAndArgsNoUndef(F);1007Changed |= setDoesNotThrow(F);1008Changed |= setDoesNotCapture(F, 1);1009break;1010case LibFunc_dunder_isoc99_scanf:1011Changed |= setRetAndArgsNoUndef(F);1012Changed |= setDoesNotThrow(F);1013Changed |= setDoesNotCapture(F, 0);1014Changed |= setOnlyReadsMemory(F, 0);1015break;1016case LibFunc_stat64:1017case LibFunc_lstat64:1018case LibFunc_statvfs64:1019Changed |= setRetAndArgsNoUndef(F);1020Changed |= setDoesNotThrow(F);1021Changed |= setDoesNotCapture(F, 0);1022Changed |= setDoesNotCapture(F, 1);1023Changed |= setOnlyReadsMemory(F, 0);1024break;1025case LibFunc_dunder_isoc99_sscanf:1026Changed |= setRetAndArgsNoUndef(F);1027Changed |= setDoesNotThrow(F);1028Changed |= setDoesNotCapture(F, 0);1029Changed |= setDoesNotCapture(F, 1);1030Changed |= setOnlyReadsMemory(F, 0);1031Changed |= setOnlyReadsMemory(F, 1);1032break;1033case LibFunc_fopen64:1034Changed |= setRetAndArgsNoUndef(F);1035Changed |= setDoesNotThrow(F);1036Changed |= setRetDoesNotAlias(F);1037Changed |= setDoesNotCapture(F, 0);1038Changed |= setDoesNotCapture(F, 1);1039Changed |= setOnlyReadsMemory(F, 0);1040Changed |= setOnlyReadsMemory(F, 1);1041break;1042case LibFunc_fseeko64:1043case LibFunc_ftello64:1044Changed |= setRetAndArgsNoUndef(F);1045Changed |= setDoesNotThrow(F);1046Changed |= setDoesNotCapture(F, 0);1047break;1048case LibFunc_tmpfile64:1049Changed |= setRetAndArgsNoUndef(F);1050Changed |= setDoesNotThrow(F);1051Changed |= setRetDoesNotAlias(F);1052break;1053case LibFunc_fstat64:1054case LibFunc_fstatvfs64:1055Changed |= setRetAndArgsNoUndef(F);1056Changed |= setDoesNotThrow(F);1057Changed |= setDoesNotCapture(F, 1);1058break;1059case LibFunc_open64:1060// May throw; "open" is a valid pthread cancellation point.1061Changed |= setRetAndArgsNoUndef(F);1062Changed |= setDoesNotCapture(F, 0);1063Changed |= setOnlyReadsMemory(F, 0);1064break;1065case LibFunc_gettimeofday:1066// Currently some platforms have the restrict keyword on the arguments to1067// gettimeofday. To be conservative, do not add noalias to gettimeofday's1068// arguments.1069Changed |= setRetAndArgsNoUndef(F);1070Changed |= setDoesNotThrow(F);1071Changed |= setDoesNotCapture(F, 0);1072Changed |= setDoesNotCapture(F, 1);1073break;1074case LibFunc_memset_pattern4:1075case LibFunc_memset_pattern8:1076case LibFunc_memset_pattern16:1077Changed |= setDoesNotCapture(F, 0);1078Changed |= setDoesNotCapture(F, 1);1079Changed |= setOnlyReadsMemory(F, 1);1080[[fallthrough]];1081case LibFunc_memset:1082Changed |= setWillReturn(F);1083[[fallthrough]];1084case LibFunc_memset_chk:1085Changed |= setOnlyAccessesArgMemory(F);1086Changed |= setOnlyWritesMemory(F, 0);1087Changed |= setDoesNotThrow(F);1088break;1089// int __nvvm_reflect(const char *)1090case LibFunc_nvvm_reflect:1091Changed |= setRetAndArgsNoUndef(F);1092Changed |= setDoesNotAccessMemory(F);1093Changed |= setDoesNotThrow(F);1094break;1095case LibFunc_ldexp:1096case LibFunc_ldexpf:1097case LibFunc_ldexpl:1098Changed |= setWillReturn(F);1099break;1100case LibFunc_remquo:1101case LibFunc_remquof:1102case LibFunc_remquol:1103Changed |= setDoesNotCapture(F, 2);1104[[fallthrough]];1105case LibFunc_abs:1106case LibFunc_acos:1107case LibFunc_acosf:1108case LibFunc_acosh:1109case LibFunc_acoshf:1110case LibFunc_acoshl:1111case LibFunc_acosl:1112case LibFunc_asin:1113case LibFunc_asinf:1114case LibFunc_asinh:1115case LibFunc_asinhf:1116case LibFunc_asinhl:1117case LibFunc_asinl:1118case LibFunc_atan:1119case LibFunc_atan2:1120case LibFunc_atan2f:1121case LibFunc_atan2l:1122case LibFunc_atanf:1123case LibFunc_atanh:1124case LibFunc_atanhf:1125case LibFunc_atanhl:1126case LibFunc_atanl:1127case LibFunc_cbrt:1128case LibFunc_cbrtf:1129case LibFunc_cbrtl:1130case LibFunc_ceil:1131case LibFunc_ceilf:1132case LibFunc_ceill:1133case LibFunc_copysign:1134case LibFunc_copysignf:1135case LibFunc_copysignl:1136case LibFunc_cos:1137case LibFunc_cosh:1138case LibFunc_coshf:1139case LibFunc_coshl:1140case LibFunc_cosf:1141case LibFunc_cosl:1142case LibFunc_cospi:1143case LibFunc_cospif:1144case LibFunc_erf:1145case LibFunc_erff:1146case LibFunc_erfl:1147case LibFunc_exp:1148case LibFunc_expf:1149case LibFunc_expl:1150case LibFunc_exp2:1151case LibFunc_exp2f:1152case LibFunc_exp2l:1153case LibFunc_expm1:1154case LibFunc_expm1f:1155case LibFunc_expm1l:1156case LibFunc_fabs:1157case LibFunc_fabsf:1158case LibFunc_fabsl:1159case LibFunc_ffs:1160case LibFunc_ffsl:1161case LibFunc_ffsll:1162case LibFunc_floor:1163case LibFunc_floorf:1164case LibFunc_floorl:1165case LibFunc_fls:1166case LibFunc_flsl:1167case LibFunc_flsll:1168case LibFunc_fmax:1169case LibFunc_fmaxf:1170case LibFunc_fmaxl:1171case LibFunc_fmin:1172case LibFunc_fminf:1173case LibFunc_fminl:1174case LibFunc_fmod:1175case LibFunc_fmodf:1176case LibFunc_fmodl:1177case LibFunc_isascii:1178case LibFunc_isdigit:1179case LibFunc_labs:1180case LibFunc_llabs:1181case LibFunc_log:1182case LibFunc_log10:1183case LibFunc_log10f:1184case LibFunc_log10l:1185case LibFunc_log1p:1186case LibFunc_log1pf:1187case LibFunc_log1pl:1188case LibFunc_log2:1189case LibFunc_log2f:1190case LibFunc_log2l:1191case LibFunc_logb:1192case LibFunc_logbf:1193case LibFunc_logbl:1194case LibFunc_logf:1195case LibFunc_logl:1196case LibFunc_nearbyint:1197case LibFunc_nearbyintf:1198case LibFunc_nearbyintl:1199case LibFunc_pow:1200case LibFunc_powf:1201case LibFunc_powl:1202case LibFunc_remainder:1203case LibFunc_remainderf:1204case LibFunc_remainderl:1205case LibFunc_rint:1206case LibFunc_rintf:1207case LibFunc_rintl:1208case LibFunc_round:1209case LibFunc_roundf:1210case LibFunc_roundl:1211case LibFunc_sin:1212case LibFunc_sincospif_stret:1213case LibFunc_sinf:1214case LibFunc_sinh:1215case LibFunc_sinhf:1216case LibFunc_sinhl:1217case LibFunc_sinl:1218case LibFunc_sinpi:1219case LibFunc_sinpif:1220case LibFunc_sqrt:1221case LibFunc_sqrtf:1222case LibFunc_sqrtl:1223case LibFunc_tan:1224case LibFunc_tanf:1225case LibFunc_tanh:1226case LibFunc_tanhf:1227case LibFunc_tanhl:1228case LibFunc_tanl:1229case LibFunc_toascii:1230case LibFunc_trunc:1231case LibFunc_truncf:1232case LibFunc_truncl:1233Changed |= setDoesNotThrow(F);1234Changed |= setDoesNotFreeMemory(F);1235Changed |= setOnlyWritesMemory(F);1236Changed |= setWillReturn(F);1237break;1238default:1239// FIXME: It'd be really nice to cover all the library functions we're1240// aware of here.1241break;1242}1243// We have to do this step after AllocKind has been inferred on functions so1244// we can reliably identify free-like and realloc-like functions.1245if (!isLibFreeFunction(&F, TheLibFunc) && !isReallocLikeFn(&F))1246Changed |= setDoesNotFreeMemory(F);1247return Changed;1248}12491250static void setArgExtAttr(Function &F, unsigned ArgNo,1251const TargetLibraryInfo &TLI, bool Signed = true) {1252Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Param(Signed);1253if (ExtAttr != Attribute::None && !F.hasParamAttribute(ArgNo, ExtAttr))1254F.addParamAttr(ArgNo, ExtAttr);1255}12561257static void setRetExtAttr(Function &F,1258const TargetLibraryInfo &TLI, bool Signed = true) {1259Attribute::AttrKind ExtAttr = TLI.getExtAttrForI32Return(Signed);1260if (ExtAttr != Attribute::None && !F.hasRetAttribute(ExtAttr))1261F.addRetAttr(ExtAttr);1262}12631264// Modeled after X86TargetLowering::markLibCallAttributes.1265void llvm::markRegisterParameterAttributes(Function *F) {1266if (!F->arg_size() || F->isVarArg())1267return;12681269const CallingConv::ID CC = F->getCallingConv();1270if (CC != CallingConv::C && CC != CallingConv::X86_StdCall)1271return;12721273const Module *M = F->getParent();1274unsigned N = M->getNumberRegisterParameters();1275if (!N)1276return;12771278const DataLayout &DL = M->getDataLayout();12791280for (Argument &A : F->args()) {1281Type *T = A.getType();1282if (!T->isIntOrPtrTy())1283continue;12841285const TypeSize &TS = DL.getTypeAllocSize(T);1286if (TS > 8)1287continue;12881289assert(TS <= 4 && "Need to account for parameters larger than word size");1290const unsigned NumRegs = TS > 4 ? 2 : 1;1291if (N < NumRegs)1292return;12931294N -= NumRegs;1295F->addParamAttr(A.getArgNo(), Attribute::InReg);1296}1297}12981299FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,1300LibFunc TheLibFunc, FunctionType *T,1301AttributeList AttributeList) {1302assert(TLI.has(TheLibFunc) &&1303"Creating call to non-existing library function.");1304StringRef Name = TLI.getName(TheLibFunc);1305FunctionCallee C = M->getOrInsertFunction(Name, T, AttributeList);13061307// Make sure any mandatory argument attributes are added.13081309// Any outgoing i32 argument should be handled with setArgExtAttr() which1310// will add an extension attribute if the target ABI requires it. Adding1311// argument extensions is typically done by the front end but when an1312// optimizer is building a library call on its own it has to take care of1313// this. Each such generated function must be handled here with sign or1314// zero extensions as needed. F is retreived with cast<> because we demand1315// of the caller to have called isLibFuncEmittable() first.1316Function *F = cast<Function>(C.getCallee());1317assert(F->getFunctionType() == T && "Function type does not match.");1318switch (TheLibFunc) {1319case LibFunc_fputc:1320case LibFunc_putchar:1321setArgExtAttr(*F, 0, TLI);1322break;1323case LibFunc_ldexp:1324case LibFunc_ldexpf:1325case LibFunc_ldexpl:1326case LibFunc_memchr:1327case LibFunc_memrchr:1328case LibFunc_strchr:1329setArgExtAttr(*F, 1, TLI);1330break;1331case LibFunc_memccpy:1332setArgExtAttr(*F, 2, TLI);1333break;13341335// These are functions that are known to not need any argument extension1336// on any target: A size_t argument (which may be an i32 on some targets)1337// should not trigger the assert below.1338case LibFunc_bcmp:1339setRetExtAttr(*F, TLI);1340break;1341case LibFunc_calloc:1342case LibFunc_fwrite:1343case LibFunc_malloc:1344case LibFunc_memcmp:1345case LibFunc_memcpy_chk:1346case LibFunc_mempcpy:1347case LibFunc_memset_pattern16:1348case LibFunc_snprintf:1349case LibFunc_stpncpy:1350case LibFunc_strlcat:1351case LibFunc_strlcpy:1352case LibFunc_strncat:1353case LibFunc_strncmp:1354case LibFunc_strncpy:1355case LibFunc_vsnprintf:1356break;13571358default:1359#ifndef NDEBUG1360for (unsigned i = 0; i < T->getNumParams(); i++)1361assert(!isa<IntegerType>(T->getParamType(i)) &&1362"Unhandled integer argument.");1363#endif1364break;1365}13661367markRegisterParameterAttributes(F);13681369return C;1370}13711372FunctionCallee llvm::getOrInsertLibFunc(Module *M, const TargetLibraryInfo &TLI,1373LibFunc TheLibFunc, FunctionType *T) {1374return getOrInsertLibFunc(M, TLI, TheLibFunc, T, AttributeList());1375}13761377bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,1378LibFunc TheLibFunc) {1379StringRef FuncName = TLI->getName(TheLibFunc);1380if (!TLI->has(TheLibFunc))1381return false;13821383// Check if the Module already has a GlobalValue with the same name, in1384// which case it must be a Function with the expected type.1385if (GlobalValue *GV = M->getNamedValue(FuncName)) {1386if (auto *F = dyn_cast<Function>(GV))1387return TLI->isValidProtoForLibFunc(*F->getFunctionType(), TheLibFunc, *M);1388return false;1389}13901391return true;1392}13931394bool llvm::isLibFuncEmittable(const Module *M, const TargetLibraryInfo *TLI,1395StringRef Name) {1396LibFunc TheLibFunc;1397return TLI->getLibFunc(Name, TheLibFunc) &&1398isLibFuncEmittable(M, TLI, TheLibFunc);1399}14001401bool llvm::hasFloatFn(const Module *M, const TargetLibraryInfo *TLI, Type *Ty,1402LibFunc DoubleFn, LibFunc FloatFn, LibFunc LongDoubleFn) {1403switch (Ty->getTypeID()) {1404case Type::HalfTyID:1405return false;1406case Type::FloatTyID:1407return isLibFuncEmittable(M, TLI, FloatFn);1408case Type::DoubleTyID:1409return isLibFuncEmittable(M, TLI, DoubleFn);1410default:1411return isLibFuncEmittable(M, TLI, LongDoubleFn);1412}1413}14141415StringRef llvm::getFloatFn(const Module *M, const TargetLibraryInfo *TLI,1416Type *Ty, LibFunc DoubleFn, LibFunc FloatFn,1417LibFunc LongDoubleFn, LibFunc &TheLibFunc) {1418assert(hasFloatFn(M, TLI, Ty, DoubleFn, FloatFn, LongDoubleFn) &&1419"Cannot get name for unavailable function!");14201421switch (Ty->getTypeID()) {1422case Type::HalfTyID:1423llvm_unreachable("No name for HalfTy!");1424case Type::FloatTyID:1425TheLibFunc = FloatFn;1426return TLI->getName(FloatFn);1427case Type::DoubleTyID:1428TheLibFunc = DoubleFn;1429return TLI->getName(DoubleFn);1430default:1431TheLibFunc = LongDoubleFn;1432return TLI->getName(LongDoubleFn);1433}1434}14351436//- Emit LibCalls ------------------------------------------------------------//14371438static IntegerType *getIntTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {1439return B.getIntNTy(TLI->getIntSize());1440}14411442static IntegerType *getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI) {1443const Module *M = B.GetInsertBlock()->getModule();1444return B.getIntNTy(TLI->getSizeTSize(*M));1445}14461447static Value *emitLibCall(LibFunc TheLibFunc, Type *ReturnType,1448ArrayRef<Type *> ParamTypes,1449ArrayRef<Value *> Operands, IRBuilderBase &B,1450const TargetLibraryInfo *TLI,1451bool IsVaArgs = false) {1452Module *M = B.GetInsertBlock()->getModule();1453if (!isLibFuncEmittable(M, TLI, TheLibFunc))1454return nullptr;14551456StringRef FuncName = TLI->getName(TheLibFunc);1457FunctionType *FuncType = FunctionType::get(ReturnType, ParamTypes, IsVaArgs);1458FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, FuncType);1459inferNonMandatoryLibFuncAttrs(M, FuncName, *TLI);1460CallInst *CI = B.CreateCall(Callee, Operands, FuncName);1461if (const Function *F =1462dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))1463CI->setCallingConv(F->getCallingConv());1464return CI;1465}14661467Value *llvm::emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,1468const TargetLibraryInfo *TLI) {1469Type *CharPtrTy = B.getPtrTy();1470Type *SizeTTy = getSizeTTy(B, TLI);1471return emitLibCall(LibFunc_strlen, SizeTTy, CharPtrTy, Ptr, B, TLI);1472}14731474Value *llvm::emitStrDup(Value *Ptr, IRBuilderBase &B,1475const TargetLibraryInfo *TLI) {1476Type *CharPtrTy = B.getPtrTy();1477return emitLibCall(LibFunc_strdup, CharPtrTy, CharPtrTy, Ptr, B, TLI);1478}14791480Value *llvm::emitStrChr(Value *Ptr, char C, IRBuilderBase &B,1481const TargetLibraryInfo *TLI) {1482Type *CharPtrTy = B.getPtrTy();1483Type *IntTy = getIntTy(B, TLI);1484return emitLibCall(LibFunc_strchr, CharPtrTy, {CharPtrTy, IntTy},1485{Ptr, ConstantInt::get(IntTy, C)}, B, TLI);1486}14871488Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,1489const DataLayout &DL, const TargetLibraryInfo *TLI) {1490Type *CharPtrTy = B.getPtrTy();1491Type *IntTy = getIntTy(B, TLI);1492Type *SizeTTy = getSizeTTy(B, TLI);1493return emitLibCall(1494LibFunc_strncmp, IntTy,1495{CharPtrTy, CharPtrTy, SizeTTy},1496{Ptr1, Ptr2, Len}, B, TLI);1497}14981499Value *llvm::emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,1500const TargetLibraryInfo *TLI) {1501Type *CharPtrTy = Dst->getType();1502return emitLibCall(LibFunc_strcpy, CharPtrTy, {CharPtrTy, CharPtrTy},1503{Dst, Src}, B, TLI);1504}15051506Value *llvm::emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B,1507const TargetLibraryInfo *TLI) {1508Type *CharPtrTy = B.getPtrTy();1509return emitLibCall(LibFunc_stpcpy, CharPtrTy, {CharPtrTy, CharPtrTy},1510{Dst, Src}, B, TLI);1511}15121513Value *llvm::emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,1514const TargetLibraryInfo *TLI) {1515Type *CharPtrTy = B.getPtrTy();1516Type *SizeTTy = getSizeTTy(B, TLI);1517return emitLibCall(LibFunc_strncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy},1518{Dst, Src, Len}, B, TLI);1519}15201521Value *llvm::emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,1522const TargetLibraryInfo *TLI) {1523Type *CharPtrTy = B.getPtrTy();1524Type *SizeTTy = getSizeTTy(B, TLI);1525return emitLibCall(LibFunc_stpncpy, CharPtrTy, {CharPtrTy, CharPtrTy, SizeTTy},1526{Dst, Src, Len}, B, TLI);1527}15281529Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,1530IRBuilderBase &B, const DataLayout &DL,1531const TargetLibraryInfo *TLI) {1532Module *M = B.GetInsertBlock()->getModule();1533if (!isLibFuncEmittable(M, TLI, LibFunc_memcpy_chk))1534return nullptr;15351536AttributeList AS;1537AS = AttributeList::get(M->getContext(), AttributeList::FunctionIndex,1538Attribute::NoUnwind);1539Type *VoidPtrTy = B.getPtrTy();1540Type *SizeTTy = getSizeTTy(B, TLI);1541FunctionCallee MemCpy = getOrInsertLibFunc(M, *TLI, LibFunc_memcpy_chk,1542AttributeList::get(M->getContext(), AS), VoidPtrTy,1543VoidPtrTy, VoidPtrTy, SizeTTy, SizeTTy);1544CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize});1545if (const Function *F =1546dyn_cast<Function>(MemCpy.getCallee()->stripPointerCasts()))1547CI->setCallingConv(F->getCallingConv());1548return CI;1549}15501551Value *llvm::emitMemPCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,1552const DataLayout &DL, const TargetLibraryInfo *TLI) {1553Type *VoidPtrTy = B.getPtrTy();1554Type *SizeTTy = getSizeTTy(B, TLI);1555return emitLibCall(LibFunc_mempcpy, VoidPtrTy,1556{VoidPtrTy, VoidPtrTy, SizeTTy},1557{Dst, Src, Len}, B, TLI);1558}15591560Value *llvm::emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,1561const DataLayout &DL, const TargetLibraryInfo *TLI) {1562Type *VoidPtrTy = B.getPtrTy();1563Type *IntTy = getIntTy(B, TLI);1564Type *SizeTTy = getSizeTTy(B, TLI);1565return emitLibCall(LibFunc_memchr, VoidPtrTy,1566{VoidPtrTy, IntTy, SizeTTy},1567{Ptr, Val, Len}, B, TLI);1568}15691570Value *llvm::emitMemRChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,1571const DataLayout &DL, const TargetLibraryInfo *TLI) {1572Type *VoidPtrTy = B.getPtrTy();1573Type *IntTy = getIntTy(B, TLI);1574Type *SizeTTy = getSizeTTy(B, TLI);1575return emitLibCall(LibFunc_memrchr, VoidPtrTy,1576{VoidPtrTy, IntTy, SizeTTy},1577{Ptr, Val, Len}, B, TLI);1578}15791580Value *llvm::emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,1581const DataLayout &DL, const TargetLibraryInfo *TLI) {1582Type *VoidPtrTy = B.getPtrTy();1583Type *IntTy = getIntTy(B, TLI);1584Type *SizeTTy = getSizeTTy(B, TLI);1585return emitLibCall(LibFunc_memcmp, IntTy,1586{VoidPtrTy, VoidPtrTy, SizeTTy},1587{Ptr1, Ptr2, Len}, B, TLI);1588}15891590Value *llvm::emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,1591const DataLayout &DL, const TargetLibraryInfo *TLI) {1592Type *VoidPtrTy = B.getPtrTy();1593Type *IntTy = getIntTy(B, TLI);1594Type *SizeTTy = getSizeTTy(B, TLI);1595return emitLibCall(LibFunc_bcmp, IntTy,1596{VoidPtrTy, VoidPtrTy, SizeTTy},1597{Ptr1, Ptr2, Len}, B, TLI);1598}15991600Value *llvm::emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,1601IRBuilderBase &B, const TargetLibraryInfo *TLI) {1602Type *VoidPtrTy = B.getPtrTy();1603Type *IntTy = getIntTy(B, TLI);1604Type *SizeTTy = getSizeTTy(B, TLI);1605return emitLibCall(LibFunc_memccpy, VoidPtrTy,1606{VoidPtrTy, VoidPtrTy, IntTy, SizeTTy},1607{Ptr1, Ptr2, Val, Len}, B, TLI);1608}16091610Value *llvm::emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,1611ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,1612const TargetLibraryInfo *TLI) {1613Type *CharPtrTy = B.getPtrTy();1614Type *IntTy = getIntTy(B, TLI);1615Type *SizeTTy = getSizeTTy(B, TLI);1616SmallVector<Value *, 8> Args{Dest, Size, Fmt};1617llvm::append_range(Args, VariadicArgs);1618return emitLibCall(LibFunc_snprintf, IntTy,1619{CharPtrTy, SizeTTy, CharPtrTy},1620Args, B, TLI, /*IsVaArgs=*/true);1621}16221623Value *llvm::emitSPrintf(Value *Dest, Value *Fmt,1624ArrayRef<Value *> VariadicArgs, IRBuilderBase &B,1625const TargetLibraryInfo *TLI) {1626Type *CharPtrTy = B.getPtrTy();1627Type *IntTy = getIntTy(B, TLI);1628SmallVector<Value *, 8> Args{Dest, Fmt};1629llvm::append_range(Args, VariadicArgs);1630return emitLibCall(LibFunc_sprintf, IntTy,1631{CharPtrTy, CharPtrTy}, Args, B, TLI,1632/*IsVaArgs=*/true);1633}16341635Value *llvm::emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B,1636const TargetLibraryInfo *TLI) {1637Type *CharPtrTy = B.getPtrTy();1638return emitLibCall(LibFunc_strcat, CharPtrTy,1639{CharPtrTy, CharPtrTy},1640{Dest, Src}, B, TLI);1641}16421643Value *llvm::emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,1644const TargetLibraryInfo *TLI) {1645Type *CharPtrTy = B.getPtrTy();1646Type *SizeTTy = getSizeTTy(B, TLI);1647return emitLibCall(LibFunc_strlcpy, SizeTTy,1648{CharPtrTy, CharPtrTy, SizeTTy},1649{Dest, Src, Size}, B, TLI);1650}16511652Value *llvm::emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,1653const TargetLibraryInfo *TLI) {1654Type *CharPtrTy = B.getPtrTy();1655Type *SizeTTy = getSizeTTy(B, TLI);1656return emitLibCall(LibFunc_strlcat, SizeTTy,1657{CharPtrTy, CharPtrTy, SizeTTy},1658{Dest, Src, Size}, B, TLI);1659}16601661Value *llvm::emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,1662const TargetLibraryInfo *TLI) {1663Type *CharPtrTy = B.getPtrTy();1664Type *SizeTTy = getSizeTTy(B, TLI);1665return emitLibCall(LibFunc_strncat, CharPtrTy,1666{CharPtrTy, CharPtrTy, SizeTTy},1667{Dest, Src, Size}, B, TLI);1668}16691670Value *llvm::emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,1671IRBuilderBase &B, const TargetLibraryInfo *TLI) {1672Type *CharPtrTy = B.getPtrTy();1673Type *IntTy = getIntTy(B, TLI);1674Type *SizeTTy = getSizeTTy(B, TLI);1675return emitLibCall(1676LibFunc_vsnprintf, IntTy,1677{CharPtrTy, SizeTTy, CharPtrTy, VAList->getType()},1678{Dest, Size, Fmt, VAList}, B, TLI);1679}16801681Value *llvm::emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList,1682IRBuilderBase &B, const TargetLibraryInfo *TLI) {1683Type *CharPtrTy = B.getPtrTy();1684Type *IntTy = getIntTy(B, TLI);1685return emitLibCall(LibFunc_vsprintf, IntTy,1686{CharPtrTy, CharPtrTy, VAList->getType()},1687{Dest, Fmt, VAList}, B, TLI);1688}16891690/// Append a suffix to the function name according to the type of 'Op'.1691static void appendTypeSuffix(Value *Op, StringRef &Name,1692SmallString<20> &NameBuffer) {1693if (!Op->getType()->isDoubleTy()) {1694NameBuffer += Name;16951696if (Op->getType()->isFloatTy())1697NameBuffer += 'f';1698else1699NameBuffer += 'l';17001701Name = NameBuffer;1702}1703}17041705static Value *emitUnaryFloatFnCallHelper(Value *Op, LibFunc TheLibFunc,1706StringRef Name, IRBuilderBase &B,1707const AttributeList &Attrs,1708const TargetLibraryInfo *TLI) {1709assert((Name != "") && "Must specify Name to emitUnaryFloatFnCall");17101711Module *M = B.GetInsertBlock()->getModule();1712FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op->getType(),1713Op->getType());1714CallInst *CI = B.CreateCall(Callee, Op, Name);17151716// The incoming attribute set may have come from a speculatable intrinsic, but1717// is being replaced with a library call which is not allowed to be1718// speculatable.1719CI->setAttributes(1720Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable));1721if (const Function *F =1722dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))1723CI->setCallingConv(F->getCallingConv());17241725return CI;1726}17271728Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,1729StringRef Name, IRBuilderBase &B,1730const AttributeList &Attrs) {1731SmallString<20> NameBuffer;1732appendTypeSuffix(Op, Name, NameBuffer);17331734LibFunc TheLibFunc;1735TLI->getLibFunc(Name, TheLibFunc);17361737return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);1738}17391740Value *llvm::emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,1741LibFunc DoubleFn, LibFunc FloatFn,1742LibFunc LongDoubleFn, IRBuilderBase &B,1743const AttributeList &Attrs) {1744// Get the name of the function according to TLI.1745Module *M = B.GetInsertBlock()->getModule();1746LibFunc TheLibFunc;1747StringRef Name = getFloatFn(M, TLI, Op->getType(), DoubleFn, FloatFn,1748LongDoubleFn, TheLibFunc);17491750return emitUnaryFloatFnCallHelper(Op, TheLibFunc, Name, B, Attrs, TLI);1751}17521753static Value *emitBinaryFloatFnCallHelper(Value *Op1, Value *Op2,1754LibFunc TheLibFunc,1755StringRef Name, IRBuilderBase &B,1756const AttributeList &Attrs,1757const TargetLibraryInfo *TLI) {1758assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");17591760Module *M = B.GetInsertBlock()->getModule();1761FunctionCallee Callee = getOrInsertLibFunc(M, *TLI, TheLibFunc, Op1->getType(),1762Op1->getType(), Op2->getType());1763inferNonMandatoryLibFuncAttrs(M, Name, *TLI);1764CallInst *CI = B.CreateCall(Callee, { Op1, Op2 }, Name);17651766// The incoming attribute set may have come from a speculatable intrinsic, but1767// is being replaced with a library call which is not allowed to be1768// speculatable.1769CI->setAttributes(1770Attrs.removeFnAttribute(B.getContext(), Attribute::Speculatable));1771if (const Function *F =1772dyn_cast<Function>(Callee.getCallee()->stripPointerCasts()))1773CI->setCallingConv(F->getCallingConv());17741775return CI;1776}17771778Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,1779const TargetLibraryInfo *TLI,1780StringRef Name, IRBuilderBase &B,1781const AttributeList &Attrs) {1782assert((Name != "") && "Must specify Name to emitBinaryFloatFnCall");17831784SmallString<20> NameBuffer;1785appendTypeSuffix(Op1, Name, NameBuffer);17861787LibFunc TheLibFunc;1788TLI->getLibFunc(Name, TheLibFunc);17891790return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);1791}17921793Value *llvm::emitBinaryFloatFnCall(Value *Op1, Value *Op2,1794const TargetLibraryInfo *TLI,1795LibFunc DoubleFn, LibFunc FloatFn,1796LibFunc LongDoubleFn, IRBuilderBase &B,1797const AttributeList &Attrs) {1798// Get the name of the function according to TLI.1799Module *M = B.GetInsertBlock()->getModule();1800LibFunc TheLibFunc;1801StringRef Name = getFloatFn(M, TLI, Op1->getType(), DoubleFn, FloatFn,1802LongDoubleFn, TheLibFunc);18031804return emitBinaryFloatFnCallHelper(Op1, Op2, TheLibFunc, Name, B, Attrs, TLI);1805}18061807// Emit a call to putchar(int) with Char as the argument. Char must have1808// the same precision as int, which need not be 32 bits.1809Value *llvm::emitPutChar(Value *Char, IRBuilderBase &B,1810const TargetLibraryInfo *TLI) {1811Module *M = B.GetInsertBlock()->getModule();1812if (!isLibFuncEmittable(M, TLI, LibFunc_putchar))1813return nullptr;18141815Type *IntTy = getIntTy(B, TLI);1816StringRef PutCharName = TLI->getName(LibFunc_putchar);1817FunctionCallee PutChar = getOrInsertLibFunc(M, *TLI, LibFunc_putchar,1818IntTy, IntTy);1819inferNonMandatoryLibFuncAttrs(M, PutCharName, *TLI);1820CallInst *CI = B.CreateCall(PutChar, Char, PutCharName);18211822if (const Function *F =1823dyn_cast<Function>(PutChar.getCallee()->stripPointerCasts()))1824CI->setCallingConv(F->getCallingConv());1825return CI;1826}18271828Value *llvm::emitPutS(Value *Str, IRBuilderBase &B,1829const TargetLibraryInfo *TLI) {1830Module *M = B.GetInsertBlock()->getModule();1831if (!isLibFuncEmittable(M, TLI, LibFunc_puts))1832return nullptr;18331834Type *IntTy = getIntTy(B, TLI);1835StringRef PutsName = TLI->getName(LibFunc_puts);1836FunctionCallee PutS = getOrInsertLibFunc(M, *TLI, LibFunc_puts, IntTy,1837B.getPtrTy());1838inferNonMandatoryLibFuncAttrs(M, PutsName, *TLI);1839CallInst *CI = B.CreateCall(PutS, Str, PutsName);1840if (const Function *F =1841dyn_cast<Function>(PutS.getCallee()->stripPointerCasts()))1842CI->setCallingConv(F->getCallingConv());1843return CI;1844}18451846Value *llvm::emitFPutC(Value *Char, Value *File, IRBuilderBase &B,1847const TargetLibraryInfo *TLI) {1848Module *M = B.GetInsertBlock()->getModule();1849if (!isLibFuncEmittable(M, TLI, LibFunc_fputc))1850return nullptr;18511852Type *IntTy = getIntTy(B, TLI);1853StringRef FPutcName = TLI->getName(LibFunc_fputc);1854FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputc, IntTy,1855IntTy, File->getType());1856if (File->getType()->isPointerTy())1857inferNonMandatoryLibFuncAttrs(M, FPutcName, *TLI);1858CallInst *CI = B.CreateCall(F, {Char, File}, FPutcName);18591860if (const Function *Fn =1861dyn_cast<Function>(F.getCallee()->stripPointerCasts()))1862CI->setCallingConv(Fn->getCallingConv());1863return CI;1864}18651866Value *llvm::emitFPutS(Value *Str, Value *File, IRBuilderBase &B,1867const TargetLibraryInfo *TLI) {1868Module *M = B.GetInsertBlock()->getModule();1869if (!isLibFuncEmittable(M, TLI, LibFunc_fputs))1870return nullptr;18711872Type *IntTy = getIntTy(B, TLI);1873StringRef FPutsName = TLI->getName(LibFunc_fputs);1874FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fputs, IntTy,1875B.getPtrTy(), File->getType());1876if (File->getType()->isPointerTy())1877inferNonMandatoryLibFuncAttrs(M, FPutsName, *TLI);1878CallInst *CI = B.CreateCall(F, {Str, File}, FPutsName);18791880if (const Function *Fn =1881dyn_cast<Function>(F.getCallee()->stripPointerCasts()))1882CI->setCallingConv(Fn->getCallingConv());1883return CI;1884}18851886Value *llvm::emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B,1887const DataLayout &DL, const TargetLibraryInfo *TLI) {1888Module *M = B.GetInsertBlock()->getModule();1889if (!isLibFuncEmittable(M, TLI, LibFunc_fwrite))1890return nullptr;18911892Type *SizeTTy = getSizeTTy(B, TLI);1893StringRef FWriteName = TLI->getName(LibFunc_fwrite);1894FunctionCallee F = getOrInsertLibFunc(M, *TLI, LibFunc_fwrite,1895SizeTTy, B.getPtrTy(), SizeTTy,1896SizeTTy, File->getType());18971898if (File->getType()->isPointerTy())1899inferNonMandatoryLibFuncAttrs(M, FWriteName, *TLI);1900CallInst *CI =1901B.CreateCall(F, {Ptr, Size,1902ConstantInt::get(SizeTTy, 1), File});19031904if (const Function *Fn =1905dyn_cast<Function>(F.getCallee()->stripPointerCasts()))1906CI->setCallingConv(Fn->getCallingConv());1907return CI;1908}19091910Value *llvm::emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL,1911const TargetLibraryInfo *TLI) {1912Module *M = B.GetInsertBlock()->getModule();1913if (!isLibFuncEmittable(M, TLI, LibFunc_malloc))1914return nullptr;19151916StringRef MallocName = TLI->getName(LibFunc_malloc);1917Type *SizeTTy = getSizeTTy(B, TLI);1918FunctionCallee Malloc = getOrInsertLibFunc(M, *TLI, LibFunc_malloc,1919B.getPtrTy(), SizeTTy);1920inferNonMandatoryLibFuncAttrs(M, MallocName, *TLI);1921CallInst *CI = B.CreateCall(Malloc, Num, MallocName);19221923if (const Function *F =1924dyn_cast<Function>(Malloc.getCallee()->stripPointerCasts()))1925CI->setCallingConv(F->getCallingConv());19261927return CI;1928}19291930Value *llvm::emitCalloc(Value *Num, Value *Size, IRBuilderBase &B,1931const TargetLibraryInfo &TLI) {1932Module *M = B.GetInsertBlock()->getModule();1933if (!isLibFuncEmittable(M, &TLI, LibFunc_calloc))1934return nullptr;19351936StringRef CallocName = TLI.getName(LibFunc_calloc);1937Type *SizeTTy = getSizeTTy(B, &TLI);1938FunctionCallee Calloc = getOrInsertLibFunc(M, TLI, LibFunc_calloc,1939B.getPtrTy(), SizeTTy, SizeTTy);1940inferNonMandatoryLibFuncAttrs(M, CallocName, TLI);1941CallInst *CI = B.CreateCall(Calloc, {Num, Size}, CallocName);19421943if (const auto *F =1944dyn_cast<Function>(Calloc.getCallee()->stripPointerCasts()))1945CI->setCallingConv(F->getCallingConv());19461947return CI;1948}19491950Value *llvm::emitHotColdNew(Value *Num, IRBuilderBase &B,1951const TargetLibraryInfo *TLI, LibFunc NewFunc,1952uint8_t HotCold) {1953Module *M = B.GetInsertBlock()->getModule();1954if (!isLibFuncEmittable(M, TLI, NewFunc))1955return nullptr;19561957StringRef Name = TLI->getName(NewFunc);1958FunctionCallee Func = M->getOrInsertFunction(Name, B.getPtrTy(),1959Num->getType(), B.getInt8Ty());1960inferNonMandatoryLibFuncAttrs(M, Name, *TLI);1961CallInst *CI = B.CreateCall(Func, {Num, B.getInt8(HotCold)}, Name);19621963if (const Function *F =1964dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))1965CI->setCallingConv(F->getCallingConv());19661967return CI;1968}19691970Value *llvm::emitHotColdNewNoThrow(Value *Num, Value *NoThrow, IRBuilderBase &B,1971const TargetLibraryInfo *TLI,1972LibFunc NewFunc, uint8_t HotCold) {1973Module *M = B.GetInsertBlock()->getModule();1974if (!isLibFuncEmittable(M, TLI, NewFunc))1975return nullptr;19761977StringRef Name = TLI->getName(NewFunc);1978FunctionCallee Func =1979M->getOrInsertFunction(Name, B.getPtrTy(), Num->getType(),1980NoThrow->getType(), B.getInt8Ty());1981inferNonMandatoryLibFuncAttrs(M, Name, *TLI);1982CallInst *CI = B.CreateCall(Func, {Num, NoThrow, B.getInt8(HotCold)}, Name);19831984if (const Function *F =1985dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))1986CI->setCallingConv(F->getCallingConv());19871988return CI;1989}19901991Value *llvm::emitHotColdNewAligned(Value *Num, Value *Align, IRBuilderBase &B,1992const TargetLibraryInfo *TLI,1993LibFunc NewFunc, uint8_t HotCold) {1994Module *M = B.GetInsertBlock()->getModule();1995if (!isLibFuncEmittable(M, TLI, NewFunc))1996return nullptr;19971998StringRef Name = TLI->getName(NewFunc);1999FunctionCallee Func = M->getOrInsertFunction(2000Name, B.getPtrTy(), Num->getType(), Align->getType(), B.getInt8Ty());2001inferNonMandatoryLibFuncAttrs(M, Name, *TLI);2002CallInst *CI = B.CreateCall(Func, {Num, Align, B.getInt8(HotCold)}, Name);20032004if (const Function *F =2005dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))2006CI->setCallingConv(F->getCallingConv());20072008return CI;2009}20102011Value *llvm::emitHotColdNewAlignedNoThrow(Value *Num, Value *Align,2012Value *NoThrow, IRBuilderBase &B,2013const TargetLibraryInfo *TLI,2014LibFunc NewFunc, uint8_t HotCold) {2015Module *M = B.GetInsertBlock()->getModule();2016if (!isLibFuncEmittable(M, TLI, NewFunc))2017return nullptr;20182019StringRef Name = TLI->getName(NewFunc);2020FunctionCallee Func = M->getOrInsertFunction(2021Name, B.getPtrTy(), Num->getType(), Align->getType(),2022NoThrow->getType(), B.getInt8Ty());2023inferNonMandatoryLibFuncAttrs(M, Name, *TLI);2024CallInst *CI =2025B.CreateCall(Func, {Num, Align, NoThrow, B.getInt8(HotCold)}, Name);20262027if (const Function *F =2028dyn_cast<Function>(Func.getCallee()->stripPointerCasts()))2029CI->setCallingConv(F->getCallingConv());20302031return CI;2032}203320342035