LCOV - code coverage report
Current view: top level - lib/LTO - UpdateCompilerUsed.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 39 100.0 %
Date: 2018-10-20 13:21:21 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13