Home | History | Annotate | Download | only in IPO
      1 //===-- Internalize.cpp - Mark functions internal -------------------------===//
      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 pass loops over all of the functions and variables in the input module.
     11 // If the function or variable is not in the list of external names given to
     12 // the pass it is marked as internal.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #define DEBUG_TYPE "internalize"
     17 #include "llvm/Transforms/IPO.h"
     18 #include "llvm/ADT/SmallPtrSet.h"
     19 #include "llvm/ADT/Statistic.h"
     20 #include "llvm/Analysis/CallGraph.h"
     21 #include "llvm/IR/Module.h"
     22 #include "llvm/Pass.h"
     23 #include "llvm/Support/CommandLine.h"
     24 #include "llvm/Support/Debug.h"
     25 #include "llvm/Support/raw_ostream.h"
     26 #include "llvm/Transforms/Utils/ModuleUtils.h"
     27 #include <fstream>
     28 #include <set>
     29 using namespace llvm;
     30 
     31 STATISTIC(NumAliases  , "Number of aliases internalized");
     32 STATISTIC(NumFunctions, "Number of functions internalized");
     33 STATISTIC(NumGlobals  , "Number of global vars internalized");
     34 
     35 // APIFile - A file which contains a list of symbols that should not be marked
     36 // external.
     37 static cl::opt<std::string>
     38 APIFile("internalize-public-api-file", cl::value_desc("filename"),
     39         cl::desc("A file containing list of symbol names to preserve"));
     40 
     41 // APIList - A list of symbols that should not be marked internal.
     42 static cl::list<std::string>
     43 APIList("internalize-public-api-list", cl::value_desc("list"),
     44         cl::desc("A list of symbol names to preserve"),
     45         cl::CommaSeparated);
     46 
     47 namespace {
     48   class InternalizePass : public ModulePass {
     49     std::set<std::string> ExternalNames;
     50   public:
     51     static char ID; // Pass identification, replacement for typeid
     52     explicit InternalizePass();
     53     explicit InternalizePass(ArrayRef<const char *> exportList);
     54     void LoadFile(const char *Filename);
     55     void ClearExportList();
     56     void AddToExportList(const std::string &val);
     57     virtual bool runOnModule(Module &M);
     58 
     59     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     60       AU.setPreservesCFG();
     61       AU.addPreserved<CallGraph>();
     62     }
     63   };
     64 } // end anonymous namespace
     65 
     66 char InternalizePass::ID = 0;
     67 INITIALIZE_PASS(InternalizePass, "internalize",
     68                 "Internalize Global Symbols", false, false)
     69 
     70 InternalizePass::InternalizePass()
     71   : ModulePass(ID) {
     72   initializeInternalizePassPass(*PassRegistry::getPassRegistry());
     73   if (!APIFile.empty())           // If a filename is specified, use it.
     74     LoadFile(APIFile.c_str());
     75   if (!APIList.empty())           // If a list is specified, use it as well.
     76     ExternalNames.insert(APIList.begin(), APIList.end());
     77 }
     78 
     79 InternalizePass::InternalizePass(ArrayRef<const char *> exportList)
     80   : ModulePass(ID){
     81   initializeInternalizePassPass(*PassRegistry::getPassRegistry());
     82   for(ArrayRef<const char *>::const_iterator itr = exportList.begin();
     83         itr != exportList.end(); itr++) {
     84     ExternalNames.insert(*itr);
     85   }
     86 }
     87 
     88 void InternalizePass::LoadFile(const char *Filename) {
     89   // Load the APIFile...
     90   std::ifstream In(Filename);
     91   if (!In.good()) {
     92     errs() << "WARNING: Internalize couldn't load file '" << Filename
     93          << "'! Continuing as if it's empty.\n";
     94     return; // Just continue as if the file were empty
     95   }
     96   while (In) {
     97     std::string Symbol;
     98     In >> Symbol;
     99     if (!Symbol.empty())
    100       ExternalNames.insert(Symbol);
    101   }
    102 }
    103 
    104 void InternalizePass::ClearExportList() {
    105   ExternalNames.clear();
    106 }
    107 
    108 void InternalizePass::AddToExportList(const std::string &val) {
    109   ExternalNames.insert(val);
    110 }
    111 
    112 bool InternalizePass::runOnModule(Module &M) {
    113   CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
    114   CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
    115   bool Changed = false;
    116 
    117   // Never internalize functions which code-gen might insert.
    118   // FIXME: We should probably add this (and the __stack_chk_guard) via some
    119   // type of call-back in CodeGen.
    120   ExternalNames.insert("__stack_chk_fail");
    121 
    122   SmallPtrSet<GlobalValue *, 8> Used;
    123   collectUsedGlobalVariables(M, Used, false);
    124 
    125   // We must assume that globals in llvm.used have a reference that not even
    126   // the linker can see, so we don't internalize them.
    127   // For llvm.compiler.used the situation is a bit fuzzy. The assembler and
    128   // linker can drop those symbols. If this pass is running as part of LTO,
    129   // one might think that it could just drop llvm.compiler.used. The problem
    130   // is that even in LTO llvm doesn't see every reference. For example,
    131   // we don't see references from function local inline assembly. To be
    132   // conservative, we internalize symbols in llvm.compiler.used, but we
    133   // keep llvm.compiler.used so that the symbol is not deleted by llvm.
    134   for (SmallPtrSet<GlobalValue *, 8>::iterator I = Used.begin(), E = Used.end();
    135        I != E; ++I) {
    136     GlobalValue *V = *I;
    137     ExternalNames.insert(V->getName());
    138   }
    139 
    140   // Mark all functions not in the api as internal.
    141   // FIXME: maybe use private linkage?
    142   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    143     if (!I->isDeclaration() &&         // Function must be defined here
    144         // Available externally is really just a "declaration with a body".
    145         !I->hasAvailableExternallyLinkage() &&
    146         !I->hasLocalLinkage() &&  // Can't already have internal linkage
    147         !ExternalNames.count(I->getName())) {// Not marked to keep external?
    148       I->setLinkage(GlobalValue::InternalLinkage);
    149       // Remove a callgraph edge from the external node to this function.
    150       if (ExternalNode) ExternalNode->removeOneAbstractEdgeTo((*CG)[I]);
    151       Changed = true;
    152       ++NumFunctions;
    153       DEBUG(dbgs() << "Internalizing func " << I->getName() << "\n");
    154     }
    155 
    156   // Never internalize the llvm.used symbol.  It is used to implement
    157   // attribute((used)).
    158   // FIXME: Shouldn't this just filter on llvm.metadata section??
    159   ExternalNames.insert("llvm.used");
    160   ExternalNames.insert("llvm.compiler.used");
    161 
    162   // Never internalize anchors used by the machine module info, else the info
    163   // won't find them.  (see MachineModuleInfo.)
    164   ExternalNames.insert("llvm.global_ctors");
    165   ExternalNames.insert("llvm.global_dtors");
    166   ExternalNames.insert("llvm.global.annotations");
    167 
    168   // Never internalize symbols code-gen inserts.
    169   ExternalNames.insert("__stack_chk_guard");
    170 
    171   // Mark all global variables with initializers that are not in the api as
    172   // internal as well.
    173   // FIXME: maybe use private linkage?
    174   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
    175        I != E; ++I)
    176     if (!I->isDeclaration() && !I->hasLocalLinkage() &&
    177         // Available externally is really just a "declaration with a body".
    178         !I->hasAvailableExternallyLinkage() &&
    179         !ExternalNames.count(I->getName())) {
    180       I->setLinkage(GlobalValue::InternalLinkage);
    181       Changed = true;
    182       ++NumGlobals;
    183       DEBUG(dbgs() << "Internalized gvar " << I->getName() << "\n");
    184     }
    185 
    186   // Mark all aliases that are not in the api as internal as well.
    187   for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
    188        I != E; ++I)
    189     if (!I->isDeclaration() && !I->hasInternalLinkage() &&
    190         // Available externally is really just a "declaration with a body".
    191         !I->hasAvailableExternallyLinkage() &&
    192         !ExternalNames.count(I->getName())) {
    193       I->setLinkage(GlobalValue::InternalLinkage);
    194       Changed = true;
    195       ++NumAliases;
    196       DEBUG(dbgs() << "Internalized alias " << I->getName() << "\n");
    197     }
    198 
    199   return Changed;
    200 }
    201 
    202 ModulePass *llvm::createInternalizePass() {
    203   return new InternalizePass();
    204 }
    205 
    206 ModulePass *llvm::createInternalizePass(ArrayRef<const char *> el) {
    207   return new InternalizePass(el);
    208 }
    209