| //===- DeclareRuntimeLibcalls.cpp -----------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Insert declarations for all runtime library calls known for the target. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/Transforms/Utils/DeclareRuntimeLibcalls.h" |
| #include "llvm/IR/Module.h" |
| #include "llvm/IR/RuntimeLibcalls.h" |
| |
| using namespace llvm; |
| |
| static void mergeAttributes(LLVMContext &Ctx, const Module &M, |
| const DataLayout &DL, const Triple &TT, |
| Function *Func, FunctionType *FuncTy, |
| AttributeList FuncAttrs) { |
| AttributeList OldAttrs = Func->getAttributes(); |
| AttributeList NewAttrs = OldAttrs; |
| |
| { |
| AttrBuilder OldBuilder(Ctx, OldAttrs.getFnAttrs()); |
| AttrBuilder NewBuilder(Ctx, FuncAttrs.getFnAttrs()); |
| OldBuilder.merge(NewBuilder); |
| NewAttrs = NewAttrs.addFnAttributes(Ctx, OldBuilder); |
| } |
| |
| { |
| AttrBuilder OldBuilder(Ctx, OldAttrs.getRetAttrs()); |
| AttrBuilder NewBuilder(Ctx, FuncAttrs.getRetAttrs()); |
| OldBuilder.merge(NewBuilder); |
| NewAttrs = NewAttrs.addRetAttributes(Ctx, OldBuilder); |
| } |
| |
| for (unsigned I = 0, E = FuncTy->getNumParams(); I != E; ++I) { |
| AttrBuilder OldBuilder(Ctx, OldAttrs.getParamAttrs(I)); |
| AttrBuilder NewBuilder(Ctx, FuncAttrs.getParamAttrs(I)); |
| OldBuilder.merge(NewBuilder); |
| NewAttrs = NewAttrs.addParamAttributes(Ctx, I, OldBuilder); |
| } |
| |
| Func->setAttributes(NewAttrs); |
| } |
| |
| PreservedAnalyses DeclareRuntimeLibcallsPass::run(Module &M, |
| ModuleAnalysisManager &MAM) { |
| RTLIB::RuntimeLibcallsInfo RTLCI(M.getTargetTriple()); |
| LLVMContext &Ctx = M.getContext(); |
| const DataLayout &DL = M.getDataLayout(); |
| const Triple &TT = M.getTargetTriple(); |
| |
| for (RTLIB::LibcallImpl Impl : RTLIB::libcall_impls()) { |
| if (!RTLCI.isAvailable(Impl)) |
| continue; |
| |
| auto [FuncTy, FuncAttrs] = RTLCI.getFunctionTy(Ctx, TT, DL, Impl); |
| |
| // TODO: Declare with correct type, calling convention, and attributes. |
| if (!FuncTy) |
| FuncTy = FunctionType::get(Type::getVoidTy(Ctx), {}, /*IsVarArgs=*/true); |
| |
| StringRef FuncName = RTLCI.getLibcallImplName(Impl); |
| |
| Function *Func = |
| cast<Function>(M.getOrInsertFunction(FuncName, FuncTy).getCallee()); |
| if (Func->getFunctionType() == FuncTy) { |
| mergeAttributes(Ctx, M, DL, TT, Func, FuncTy, FuncAttrs); |
| Func->setCallingConv(RTLCI.getLibcallImplCallingConv(Impl)); |
| } |
| } |
| |
| return PreservedAnalyses::none(); |
| } |