2f2f06b43b5980ce0e472b306418a635cc02674c
[oota-llvm.git] / lib / Transforms / IPO / Internalize.cpp
1 //===-- Internalize.cpp - Mark functions internal -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass loops over all of the functions in the input module, looking for a
11 // main function.  If a main function is found, all other functions and all
12 // global variables with initializers are marked as internal.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "llvm/Transforms/IPO.h"
17 #include "llvm/Pass.h"
18 #include "llvm/Module.h"
19 #include "llvm/Support/CommandLine.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/ADT/Statistic.h"
22 #include <fstream>
23 #include <iostream>
24 #include <set>
25 using namespace llvm;
26
27 namespace {
28   Statistic<> NumFunctions("internalize", "Number of functions internalized");
29   Statistic<> NumGlobals  ("internalize", "Number of global vars internalized");
30
31   // APIFile - A file which contains a list of symbols that should not be marked
32   // external.
33   cl::opt<std::string>
34   APIFile("internalize-public-api-file", cl::value_desc("filename"),
35           cl::desc("A file containing list of symbol names to preserve"));
36
37   // APIList - A list of symbols that should not be marked internal.
38   cl::list<std::string>
39   APIList("internalize-public-api-list", cl::value_desc("list"),
40           cl::desc("A list of symbol names to preserve"),
41           cl::CommaSeparated);
42
43   class InternalizePass : public ModulePass {
44     std::set<std::string> ExternalNames;
45     bool DontInternalize;
46   public:
47     InternalizePass(bool InternalizeEverything = true);
48     void LoadFile(const char *Filename);
49     virtual bool runOnModule(Module &M);
50   };
51   RegisterOpt<InternalizePass> X("internalize", "Internalize Global Symbols");
52 } // end anonymous namespace
53
54 InternalizePass::InternalizePass(bool InternalizeEverything) 
55   : DontInternalize(false){
56   if (!APIFile.empty())           // If a filename is specified, use it
57     LoadFile(APIFile.c_str());
58   else if (!APIList.empty())      // Else, if a list is specified, use it.
59     ExternalNames.insert(APIList.begin(), APIList.end());
60   else if (!InternalizeEverything)
61     // Finally, if we're allowed to, internalize all but main.
62     DontInternalize = true;
63 }
64
65 void InternalizePass::LoadFile(const char *Filename) {
66   // Load the APIFile...
67   std::ifstream In(Filename);
68   if (!In.good()) {
69     std::cerr << "WARNING: Internalize couldn't load file '" << Filename
70     << "'!\n";
71     return;   // Do not internalize anything...
72   }
73   while (In) {
74     std::string Symbol;
75     In >> Symbol;
76     if (!Symbol.empty())
77       ExternalNames.insert(Symbol);
78   }
79 }
80
81 bool InternalizePass::runOnModule(Module &M) {
82   if (DontInternalize) return false;
83   
84   // If no list or file of symbols was specified, check to see if there is a
85   // "main" symbol defined in the module.  If so, use it, otherwise do not
86   // internalize the module, it must be a library or something.
87   //
88   if (ExternalNames.empty()) {
89     Function *MainFunc = M.getMainFunction();
90     if (MainFunc == 0 || MainFunc->isExternal())
91       return false;  // No main found, must be a library...
92     
93     // Preserve main, internalize all else.
94     ExternalNames.insert(MainFunc->getName());
95   }
96   
97   bool Changed = false;
98   
99   // Found a main function, mark all functions not named main as internal.
100   for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
101     if (!I->isExternal() &&         // Function must be defined here
102         !I->hasInternalLinkage() &&  // Can't already have internal linkage
103         !ExternalNames.count(I->getName())) {// Not marked to keep external?
104       I->setLinkage(GlobalValue::InternalLinkage);
105       Changed = true;
106       ++NumFunctions;
107       DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n");
108     }
109   
110   // Never internalize the llvm.used symbol.  It is used to implement
111   // attribute((used)).
112   ExternalNames.insert("llvm.used");
113   
114   // Never internalize anchors used by the debugger, else the debugger won't
115   // find them.
116   ExternalNames.insert("llvm.dbg.translation_units");
117   ExternalNames.insert("llvm.dbg.globals");
118       
119   // Mark all global variables with initializers as internal as well.
120   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
121        I != E; ++I)
122     if (!I->isExternal() && !I->hasInternalLinkage() &&
123         !ExternalNames.count(I->getName())) {
124       // Special case handling of the global ctor and dtor list.  When we
125       // internalize it, we mark it constant, which allows elimination of
126       // the list if it's empty.
127       //
128       if (I->hasAppendingLinkage() && (I->getName() == "llvm.global_ctors" ||
129                                        I->getName() == "llvm.global_dtors")) {
130         // If the global ctors/dtors list has no uses, do not internalize it, as
131         // there is no __main in this program, so the asmprinter should handle
132         // it.
133         if (I->use_empty()) continue;
134  
135         // Otherwise, also mark the list constant, as we know that it will not
136         // be mutated any longer, and the makes simple IPO xforms automatically
137         // better.
138         I->setConstant(true);
139       }
140       
141       I->setLinkage(GlobalValue::InternalLinkage);
142       Changed = true;
143       ++NumGlobals;
144       DEBUG(std::cerr << "Internalized gvar " << I->getName() << "\n");
145     }
146       
147   return Changed;
148 }
149
150 ModulePass *llvm::createInternalizePass(bool InternalizeEverything) {
151   return new InternalizePass(InternalizeEverything);
152 }