1ce23e970SMehdi Amini //==-LTOInternalize.cpp - LLVM Link Time Optimizer Internalization Utility -==// 2ce23e970SMehdi Amini // 3ce23e970SMehdi Amini // The LLVM Compiler Infrastructure 4ce23e970SMehdi Amini // 5ce23e970SMehdi Amini // This file is distributed under the University of Illinois Open Source 6ce23e970SMehdi Amini // License. See LICENSE.TXT for details. 7ce23e970SMehdi Amini // 8ce23e970SMehdi Amini //===----------------------------------------------------------------------===// 9ce23e970SMehdi Amini // 10ce23e970SMehdi Amini // This file defines a helper to run the internalization part of LTO. 11ce23e970SMehdi Amini // 12ce23e970SMehdi Amini //===----------------------------------------------------------------------===// 13ce23e970SMehdi Amini 145c73220fSPeter Collingbourne #include "llvm/LTO/legacy/UpdateCompilerUsed.h" 15ce23e970SMehdi Amini #include "llvm/Analysis/TargetLibraryInfo.h" 16b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetLowering.h" 17b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetSubtargetInfo.h" 18ce23e970SMehdi Amini #include "llvm/IR/LegacyPassManager.h" 19ce23e970SMehdi Amini #include "llvm/IR/Mangler.h" 20ea6d49d3SEvgeniy Stepanov #include "llvm/Transforms/Utils/ModuleUtils.h" 21ce23e970SMehdi Amini 22ce23e970SMehdi Amini using namespace llvm; 23ce23e970SMehdi Amini 24ce23e970SMehdi Amini namespace { 25ce23e970SMehdi Amini 26ce23e970SMehdi Amini // Helper class that collects AsmUsed and user supplied libcalls. 27ce23e970SMehdi Amini class PreserveLibCallsAndAsmUsed { 28ce23e970SMehdi Amini public: 29ce23e970SMehdi Amini PreserveLibCallsAndAsmUsed(const StringSet<> &AsmUndefinedRefs, 30ce23e970SMehdi Amini const TargetMachine &TM, 31ea6d49d3SEvgeniy Stepanov std::vector<GlobalValue *> &LLVMUsed) 32ce23e970SMehdi Amini : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), LLVMUsed(LLVMUsed) {} 33ce23e970SMehdi Amini 34ea6d49d3SEvgeniy Stepanov void findInModule(Module &TheModule) { 35ce23e970SMehdi Amini initializeLibCalls(TheModule); 36ea6d49d3SEvgeniy Stepanov for (Function &F : TheModule) 37ce23e970SMehdi Amini findLibCallsAndAsm(F); 38ea6d49d3SEvgeniy Stepanov for (GlobalVariable &GV : TheModule.globals()) 39ce23e970SMehdi Amini findLibCallsAndAsm(GV); 40ea6d49d3SEvgeniy Stepanov for (GlobalAlias &GA : TheModule.aliases()) 41ce23e970SMehdi Amini findLibCallsAndAsm(GA); 42ce23e970SMehdi Amini } 43ce23e970SMehdi Amini 44ce23e970SMehdi Amini private: 45ce23e970SMehdi Amini // Inputs 46ce23e970SMehdi Amini const StringSet<> &AsmUndefinedRefs; 47ce23e970SMehdi Amini const TargetMachine &TM; 48ce23e970SMehdi Amini 49ce23e970SMehdi Amini // Temps 50ce23e970SMehdi Amini llvm::Mangler Mangler; 51ce23e970SMehdi Amini StringSet<> Libcalls; 52ce23e970SMehdi Amini 53ce23e970SMehdi Amini // Output 54ea6d49d3SEvgeniy Stepanov std::vector<GlobalValue *> &LLVMUsed; 55ce23e970SMehdi Amini 56ce23e970SMehdi Amini // Collect names of runtime library functions. User-defined functions with the 57ce23e970SMehdi Amini // same names are added to llvm.compiler.used to prevent them from being 58ce23e970SMehdi Amini // deleted by optimizations. 59ce23e970SMehdi Amini void initializeLibCalls(const Module &TheModule) { 60ce23e970SMehdi Amini TargetLibraryInfoImpl TLII(Triple(TM.getTargetTriple())); 61ce23e970SMehdi Amini TargetLibraryInfo TLI(TLII); 62ce23e970SMehdi Amini 63ce23e970SMehdi Amini // TargetLibraryInfo has info on C runtime library calls on the current 64ce23e970SMehdi Amini // target. 65ce23e970SMehdi Amini for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs); 66ce23e970SMehdi Amini I != E; ++I) { 67d21529faSDavid L. Jones LibFunc F = static_cast<LibFunc>(I); 68ce23e970SMehdi Amini if (TLI.has(F)) 69ce23e970SMehdi Amini Libcalls.insert(TLI.getName(F)); 70ce23e970SMehdi Amini } 71ce23e970SMehdi Amini 72ce23e970SMehdi Amini SmallPtrSet<const TargetLowering *, 1> TLSet; 73ce23e970SMehdi Amini 74ce23e970SMehdi Amini for (const Function &F : TheModule) { 75ce23e970SMehdi Amini const TargetLowering *Lowering = 76ce23e970SMehdi Amini TM.getSubtargetImpl(F)->getTargetLowering(); 77ce23e970SMehdi Amini 78ce23e970SMehdi Amini if (Lowering && TLSet.insert(Lowering).second) 79ce23e970SMehdi Amini // TargetLowering has info on library calls that CodeGen expects to be 80ce23e970SMehdi Amini // available, both from the C runtime and compiler-rt. 81ce23e970SMehdi Amini for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL); 82ce23e970SMehdi Amini I != E; ++I) 83ce23e970SMehdi Amini if (const char *Name = 84ce23e970SMehdi Amini Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I))) 85ce23e970SMehdi Amini Libcalls.insert(Name); 86ce23e970SMehdi Amini } 87ce23e970SMehdi Amini } 88ce23e970SMehdi Amini 89ea6d49d3SEvgeniy Stepanov void findLibCallsAndAsm(GlobalValue &GV) { 90ce23e970SMehdi Amini // There are no restrictions to apply to declarations. 91ce23e970SMehdi Amini if (GV.isDeclaration()) 92ce23e970SMehdi Amini return; 93ce23e970SMehdi Amini 94ce23e970SMehdi Amini // There is nothing more restrictive than private linkage. 95ce23e970SMehdi Amini if (GV.hasPrivateLinkage()) 96ce23e970SMehdi Amini return; 97ce23e970SMehdi Amini 98*febfc4e8SWarren Ristow // Conservatively append user-supplied runtime library functions (supplied 99*febfc4e8SWarren Ristow // either directly, or via a function alias) to llvm.compiler.used. These 100*febfc4e8SWarren Ristow // could be internalized and deleted by optimizations like -globalopt, 101*febfc4e8SWarren Ristow // causing problems when later optimizations add new library calls (e.g., 102*febfc4e8SWarren Ristow // llvm.memset => memset and printf => puts). 103ce23e970SMehdi Amini // Leave it to the linker to remove any dead code (e.g. with -dead_strip). 104*febfc4e8SWarren Ristow GlobalValue *FuncAliasee = nullptr; 105*febfc4e8SWarren Ristow if (isa<GlobalAlias>(GV)) { 106*febfc4e8SWarren Ristow auto *A = cast<GlobalAlias>(&GV); 107*febfc4e8SWarren Ristow FuncAliasee = dyn_cast<Function>(A->getAliasee()); 108*febfc4e8SWarren Ristow } 109*febfc4e8SWarren Ristow if ((isa<Function>(GV) || FuncAliasee) && Libcalls.count(GV.getName())) { 110ea6d49d3SEvgeniy Stepanov LLVMUsed.push_back(&GV); 111ea6d49d3SEvgeniy Stepanov return; 112ea6d49d3SEvgeniy Stepanov } 113ce23e970SMehdi Amini 114ce23e970SMehdi Amini SmallString<64> Buffer; 115ce23e970SMehdi Amini TM.getNameWithPrefix(Buffer, &GV, Mangler); 116ce23e970SMehdi Amini if (AsmUndefinedRefs.count(Buffer)) 117ea6d49d3SEvgeniy Stepanov LLVMUsed.push_back(&GV); 118ce23e970SMehdi Amini } 119ce23e970SMehdi Amini }; 120ce23e970SMehdi Amini 121ce23e970SMehdi Amini } // namespace anonymous 122ce23e970SMehdi Amini 12353d457c6SDavide Italiano void llvm::updateCompilerUsed(Module &TheModule, const TargetMachine &TM, 124ce23e970SMehdi Amini const StringSet<> &AsmUndefinedRefs) { 125ea6d49d3SEvgeniy Stepanov std::vector<GlobalValue *> UsedValues; 126ce23e970SMehdi Amini PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues) 127ce23e970SMehdi Amini .findInModule(TheModule); 128ce23e970SMehdi Amini 129ce23e970SMehdi Amini if (UsedValues.empty()) 130ce23e970SMehdi Amini return; 131ce23e970SMehdi Amini 132ea6d49d3SEvgeniy Stepanov appendToCompilerUsed(TheModule, UsedValues); 133ce23e970SMehdi Amini } 134