Put all LLVM code into the llvm namespace, as per bug 109.
[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 "Support/CommandLine.h"
20 #include "Support/Debug.h"
21 #include "Support/Statistic.h"
22 #include <fstream>
23 #include <set>
24
25 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 Pass {
44     std::set<std::string> ExternalNames;
45   public:
46     InternalizePass() {
47       if (!APIFile.empty())           // If a filename is specified, use it
48         LoadFile(APIFile.c_str());
49       else                            // Else, if a list is specified, use it.
50         ExternalNames.insert(APIList.begin(), APIList.end());
51     }
52
53     void LoadFile(const char *Filename) {
54       // Load the APIFile...
55       std::ifstream In(Filename);
56       if (!In.good()) {
57         std::cerr << "WARNING: Internalize couldn't load file '" << Filename
58                   << "'!\n";
59         return;   // Do not internalize anything...
60       }
61       while (In) {
62         std::string Symbol;
63         In >> Symbol;
64         if (!Symbol.empty())
65           ExternalNames.insert(Symbol);
66       }
67     }
68
69     virtual bool run(Module &M) {
70       // If no list or file of symbols was specified, check to see if there is a
71       // "main" symbol defined in the module.  If so, use it, otherwise do not
72       // internalize the module, it must be a library or something.
73       //
74       if (ExternalNames.empty()) {
75         Function *MainFunc = M.getMainFunction();
76         if (MainFunc == 0 || MainFunc->isExternal())
77           return false;  // No main found, must be a library...
78
79         // Preserve main, internalize all else.
80         ExternalNames.insert(MainFunc->getName());
81       }
82
83       bool Changed = false;
84       
85       // Found a main function, mark all functions not named main as internal.
86       for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
87         if (!I->isExternal() &&         // Function must be defined here
88             !I->hasInternalLinkage() &&  // Can't already have internal linkage
89             !ExternalNames.count(I->getName())) {// Not marked to keep external?
90           I->setLinkage(GlobalValue::InternalLinkage);
91           Changed = true;
92           ++NumFunctions;
93           DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n");
94         }
95
96       // Mark all global variables with initializers as internal as well...
97       for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
98         if (!I->isExternal() && !I->hasInternalLinkage() &&
99             !ExternalNames.count(I->getName())) {
100           // Special case handling of the global ctor and dtor list.  When we
101           // internalize it, we mark it constant, which allows elimination of
102           // the list if it's empty.
103           //
104           if (I->hasAppendingLinkage() && (I->getName() == "llvm.global_ctors"||
105                                            I->getName() == "llvm.global_dtors"))
106             I->setConstant(true);
107
108           I->setLinkage(GlobalValue::InternalLinkage);
109           Changed = true;
110           ++NumGlobals;
111           DEBUG(std::cerr << "Internalizing gvar " << I->getName() << "\n");
112         }
113       
114       return Changed;
115     }
116   };
117
118   RegisterOpt<InternalizePass> X("internalize", "Internalize Global Symbols");
119 } // end anonymous namespace
120
121 Pass *createInternalizePass() {
122   return new InternalizePass();
123 }
124
125 } // End llvm namespace