LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Internalize.cpp

Go to the documentation of this file.
00001 //===-- Internalize.cpp - Mark functions internal -------------------------===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This pass loops over all of the functions in the input module, looking for a
00011 // main function.  If a main function is found, all other functions and all
00012 // global variables with initializers are marked as internal.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #include "llvm/Transforms/IPO.h"
00017 #include "llvm/Pass.h"
00018 #include "llvm/Module.h"
00019 #include "llvm/Support/CommandLine.h"
00020 #include "llvm/Support/Debug.h"
00021 #include "llvm/ADT/Statistic.h"
00022 #include <fstream>
00023 #include <set>
00024 using namespace llvm;
00025 
00026 namespace {
00027   Statistic<> NumFunctions("internalize", "Number of functions internalized");
00028   Statistic<> NumGlobals  ("internalize", "Number of global vars internalized");
00029 
00030   // APIFile - A file which contains a list of symbols that should not be marked
00031   // external.
00032   cl::opt<std::string>
00033   APIFile("internalize-public-api-file", cl::value_desc("filename"),
00034           cl::desc("A file containing list of symbol names to preserve"));
00035 
00036   // APIList - A list of symbols that should not be marked internal.
00037   cl::list<std::string>
00038   APIList("internalize-public-api-list", cl::value_desc("list"),
00039           cl::desc("A list of symbol names to preserve"),
00040           cl::CommaSeparated);
00041  
00042   class InternalizePass : public ModulePass {
00043     std::set<std::string> ExternalNames;
00044   public:
00045     InternalizePass() {
00046       if (!APIFile.empty())           // If a filename is specified, use it
00047         LoadFile(APIFile.c_str());
00048       else                            // Else, if a list is specified, use it.
00049         ExternalNames.insert(APIList.begin(), APIList.end());
00050     }
00051 
00052     void LoadFile(const char *Filename) {
00053       // Load the APIFile...
00054       std::ifstream In(Filename);
00055       if (!In.good()) {
00056         std::cerr << "WARNING: Internalize couldn't load file '" << Filename
00057                   << "'!\n";
00058         return;   // Do not internalize anything...
00059       }
00060       while (In) {
00061         std::string Symbol;
00062         In >> Symbol;
00063         if (!Symbol.empty())
00064           ExternalNames.insert(Symbol);
00065       }
00066     }
00067 
00068     virtual bool runOnModule(Module &M) {
00069       // If no list or file of symbols was specified, check to see if there is a
00070       // "main" symbol defined in the module.  If so, use it, otherwise do not
00071       // internalize the module, it must be a library or something.
00072       //
00073       if (ExternalNames.empty()) {
00074         Function *MainFunc = M.getMainFunction();
00075         if (MainFunc == 0 || MainFunc->isExternal())
00076           return false;  // No main found, must be a library...
00077 
00078         // Preserve main, internalize all else.
00079         ExternalNames.insert(MainFunc->getName());
00080       }
00081 
00082       bool Changed = false;
00083       
00084       // Found a main function, mark all functions not named main as internal.
00085       for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
00086         if (!I->isExternal() &&         // Function must be defined here
00087             !I->hasInternalLinkage() &&  // Can't already have internal linkage
00088             !ExternalNames.count(I->getName())) {// Not marked to keep external?
00089           I->setLinkage(GlobalValue::InternalLinkage);
00090           Changed = true;
00091           ++NumFunctions;
00092           DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n");
00093         }
00094 
00095       // Mark all global variables with initializers as internal as well...
00096       for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
00097         if (!I->isExternal() && !I->hasInternalLinkage() &&
00098             !ExternalNames.count(I->getName())) {
00099           // Special case handling of the global ctor and dtor list.  When we
00100           // internalize it, we mark it constant, which allows elimination of
00101           // the list if it's empty.
00102           //
00103           if (I->hasAppendingLinkage() && (I->getName() == "llvm.global_ctors"||
00104                                            I->getName() == "llvm.global_dtors"))
00105             I->setConstant(true);
00106 
00107           I->setLinkage(GlobalValue::InternalLinkage);
00108           Changed = true;
00109           ++NumGlobals;
00110           DEBUG(std::cerr << "Internalizing gvar " << I->getName() << "\n");
00111         }
00112       
00113       return Changed;
00114     }
00115   };
00116 
00117   RegisterOpt<InternalizePass> X("internalize", "Internalize Global Symbols");
00118 } // end anonymous namespace
00119 
00120 ModulePass *llvm::createInternalizePass() {
00121   return new InternalizePass();
00122 }