LCOV - code coverage report
Current view: top level - lib/LTO - UpdateCompilerUsed.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 37 38 97.4 %
Date: 2018-09-23 13:06:45 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          41 :       : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), LLVMUsed(LLVMUsed) {}
      33             : 
      34          41 :   void findInModule(Module &TheModule) {
      35          41 :     initializeLibCalls(TheModule);
      36         136 :     for (Function &F : TheModule)
      37          95 :       findLibCallsAndAsm(F);
      38          66 :     for (GlobalVariable &GV : TheModule.globals())
      39          25 :       findLibCallsAndAsm(GV);
      40          41 :     for (GlobalAlias &GA : TheModule.aliases())
      41           0 :       findLibCallsAndAsm(GA);
      42          41 :   }
      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          41 :   void initializeLibCalls(const Module &TheModule) {
      60         164 :     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       17302 :     for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
      66       17343 :          I != E; ++I) {
      67             :       LibFunc F = static_cast<LibFunc>(I);
      68       34604 :       if (TLI.has(F))
      69       14876 :         Libcalls.insert(TLI.getName(F));
      70             :     }
      71             : 
      72             :     SmallPtrSet<const TargetLowering *, 1> TLSet;
      73             : 
      74         136 :     for (const Function &F : TheModule) {
      75             :       const TargetLowering *Lowering =
      76          95 :           TM.getSubtargetImpl(F)->getTargetLowering();
      77             : 
      78          95 :       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       16920 :         for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
      82       16956 :              I != E; ++I)
      83       16920 :           if (const char *Name =
      84             :                   Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
      85             :             Libcalls.insert(Name);
      86             :     }
      87          41 :   }
      88             : 
      89         120 :   void findLibCallsAndAsm(GlobalValue &GV) {
      90             :     // There are no restrictions to apply to declarations.
      91         120 :     if (GV.isDeclaration())
      92          30 :       return;
      93             : 
      94             :     // There is nothing more restrictive than private linkage.
      95          98 :     if (GV.hasPrivateLinkage())
      96             :       return;
      97             : 
      98             :     // Conservatively append user-supplied runtime library functions to
      99             :     // llvm.compiler.used.  These could be internalized and deleted by
     100             :     // optimizations like -globalopt, causing problems when later optimizations
     101             :     // add new library calls (e.g., llvm.memset => memset and printf => puts).
     102             :     // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
     103         163 :     if (isa<Function>(GV) && Libcalls.count(GV.getName())) {
     104           6 :       LLVMUsed.push_back(&GV);
     105           6 :       return;
     106             :     }
     107             : 
     108             :     SmallString<64> Buffer;
     109          90 :     TM.getNameWithPrefix(Buffer, &GV, Mangler);
     110         176 :     if (AsmUndefinedRefs.count(Buffer))
     111           4 :       LLVMUsed.push_back(&GV);
     112             :   }
     113             : };
     114             : 
     115             : } // namespace anonymous
     116             : 
     117          41 : void llvm::updateCompilerUsed(Module &TheModule, const TargetMachine &TM,
     118             :                               const StringSet<> &AsmUndefinedRefs) {
     119             :   std::vector<GlobalValue *> UsedValues;
     120          41 :   PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues)
     121          41 :       .findInModule(TheModule);
     122             : 
     123          41 :   if (UsedValues.empty())
     124             :     return;
     125             : 
     126           4 :   appendToCompilerUsed(TheModule, UsedValues);
     127             : }

Generated by: LCOV version 1.13