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