82 lines · cpp
1//===- DeclareRuntimeLibcalls.cpp -----------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// Insert declarations for all runtime library calls known for the target.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Transforms/Utils/DeclareRuntimeLibcalls.h"14#include "llvm/Analysis/RuntimeLibcallInfo.h"15#include "llvm/IR/Module.h"16#include "llvm/IR/RuntimeLibcalls.h"17 18using namespace llvm;19 20static void mergeAttributes(LLVMContext &Ctx, const Module &M,21 const DataLayout &DL, const Triple &TT,22 Function *Func, FunctionType *FuncTy,23 AttributeList FuncAttrs) {24 AttributeList OldAttrs = Func->getAttributes();25 AttributeList NewAttrs = OldAttrs;26 27 {28 AttrBuilder OldBuilder(Ctx, OldAttrs.getFnAttrs());29 AttrBuilder NewBuilder(Ctx, FuncAttrs.getFnAttrs());30 OldBuilder.merge(NewBuilder);31 NewAttrs = NewAttrs.addFnAttributes(Ctx, OldBuilder);32 }33 34 {35 AttrBuilder OldBuilder(Ctx, OldAttrs.getRetAttrs());36 AttrBuilder NewBuilder(Ctx, FuncAttrs.getRetAttrs());37 OldBuilder.merge(NewBuilder);38 NewAttrs = NewAttrs.addRetAttributes(Ctx, OldBuilder);39 }40 41 for (unsigned I = 0, E = FuncTy->getNumParams(); I != E; ++I) {42 AttrBuilder OldBuilder(Ctx, OldAttrs.getParamAttrs(I));43 AttrBuilder NewBuilder(Ctx, FuncAttrs.getParamAttrs(I));44 OldBuilder.merge(NewBuilder);45 NewAttrs = NewAttrs.addParamAttributes(Ctx, I, OldBuilder);46 }47 48 Func->setAttributes(NewAttrs);49}50 51PreservedAnalyses DeclareRuntimeLibcallsPass::run(Module &M,52 ModuleAnalysisManager &MAM) {53 const RTLIB::RuntimeLibcallsInfo &RTLCI =54 MAM.getResult<RuntimeLibraryAnalysis>(M);55 56 LLVMContext &Ctx = M.getContext();57 const DataLayout &DL = M.getDataLayout();58 const Triple &TT = M.getTargetTriple();59 60 for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) {61 if (!RTLCI.isAvailable(Impl))62 continue;63 64 auto [FuncTy, FuncAttrs] = RTLCI.getFunctionTy(Ctx, TT, DL, Impl);65 66 // TODO: Declare with correct type, calling convention, and attributes.67 if (!FuncTy)68 FuncTy = FunctionType::get(Type::getVoidTy(Ctx), {}, /*IsVarArgs=*/true);69 70 StringRef FuncName = RTLCI.getLibcallImplName(Impl);71 72 Function *Func =73 cast<Function>(M.getOrInsertFunction(FuncName, FuncTy).getCallee());74 if (Func->getFunctionType() == FuncTy) {75 mergeAttributes(Ctx, M, DL, TT, Func, FuncTy, FuncAttrs);76 Func->setCallingConv(RTLCI.getLibcallImplCallingConv(Impl));77 }78 }79 80 return PreservedAnalyses::none();81}82