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

Generated by: LCOV version 1.13