/// Does this instruction write some memory? This only returns true for things /// that we can analyze with other helpers below. static bool hasMemoryWrite(Instruction *I, const TargetLibraryInfo &TLI) { if (isa<StoreInst>(I)) return true; if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { switch (II->getIntrinsicID()) { default: return false; case Intrinsic::memset: case Intrinsic::memmove: case Intrinsic::memcpy: case Intrinsic::init_trampoline: case Intrinsic::lifetime_end: return true; } } if (auto CS = CallSite(I)) { if (Function *F = CS.getCalledFunction()) { StringRef FnName = F->getName(); if (TLI.has(LibFunc::strcpy) && FnName == TLI.getName(LibFunc::strcpy)) return true; if (TLI.has(LibFunc::strncpy) && FnName == TLI.getName(LibFunc::strncpy)) return true; if (TLI.has(LibFunc::strcat) && FnName == TLI.getName(LibFunc::strcat)) return true; if (TLI.has(LibFunc::strncat) && FnName == TLI.getName(LibFunc::strncat)) return true; } } return false; }
// Collect names of runtime library functions. User-defined functions with the // same names are added to llvm.compiler.used to prevent them from being // deleted by optimizations. static void accumulateAndSortLibcalls(std::vector<StringRef> &Libcalls, const TargetLibraryInfo& TLI, const Module &Mod, const TargetMachine &TM) { // TargetLibraryInfo has info on C runtime library calls on the current // target. for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs); I != E; ++I) { LibFunc::Func F = static_cast<LibFunc::Func>(I); if (TLI.has(F)) Libcalls.push_back(TLI.getName(F)); } SmallPtrSet<const TargetLowering *, 1> TLSet; for (const Function &F : Mod) { const TargetLowering *Lowering = TM.getSubtargetImpl(F)->getTargetLowering(); if (Lowering && TLSet.insert(Lowering).second) // TargetLowering has info on library calls that CodeGen expects to be // available, both from the C runtime and compiler-rt. for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL); I != E; ++I) if (const char *Name = Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I))) Libcalls.push_back(Name); } array_pod_sort(Libcalls.begin(), Libcalls.end()); Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()), Libcalls.end()); }
static void accumulateAndSortLibcalls(std::vector<StringRef> &Libcalls, const TargetLibraryInfo& TLI, const TargetLowering *Lowering) { // TargetLibraryInfo has info on C runtime library calls on the current // target. for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs); I != E; ++I) { LibFunc::Func F = static_cast<LibFunc::Func>(I); if (TLI.has(F)) Libcalls.push_back(TLI.getName(F)); } // TargetLowering has info on library calls that CodeGen expects to be // available, both from the C runtime and compiler-rt. if (Lowering) for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL); I != E; ++I) if (const char *Name = Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I))) Libcalls.push_back(Name); array_pod_sort(Libcalls.begin(), Libcalls.end()); Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()), Libcalls.end()); }
static void createLibraryFunction(llvm::LibFunc::Func funcId, llvm::FunctionType *funcType, Module* module) { TargetLibraryInfo targetLib; if (targetLib.has(funcId)) { Function::Create(funcType, Function::ExternalLinkage, targetLib.getName(funcId), module); } else { string msg = "native target does not have library function for "; msg += targetLib.getName(funcId); throw_llvm_exception(msg); } }