blob: b38b0d0b3f3bfb4fbb46d7e3d86a2b768be22f85 [file] [log] [blame]
Chris Lattner1b94c002002-04-28 05:43:27 +00001//===-- Internalize.cpp - Mark functions internal -------------------------===//
2//
3// This pass loops over all of the functions in the input module, looking for a
Chris Lattner47cc3662002-07-30 19:48:44 +00004// main function. If a main function is found, all other functions and all
5// global variables with initializers are marked as internal.
Chris Lattner1b94c002002-04-28 05:43:27 +00006//
7//===----------------------------------------------------------------------===//
8
Chris Lattner99a53f62002-07-24 17:12:05 +00009#include "llvm/Transforms/IPO.h"
Chris Lattner1b94c002002-04-28 05:43:27 +000010#include "llvm/Pass.h"
11#include "llvm/Module.h"
Chris Lattnerbf3a0992002-10-01 22:38:41 +000012#include "Support/Statistic.h"
Chris Lattner44457bb2003-05-22 19:34:49 +000013#include "Support/CommandLine.h"
14#include <fstream>
15#include <set>
Chris Lattner0b18c1d2002-05-10 15:38:35 +000016
Chris Lattnerb28b6802002-07-23 18:06:35 +000017namespace {
Chris Lattnerbf3a0992002-10-01 22:38:41 +000018 Statistic<> NumFunctions("internalize", "Number of functions internalized");
19 Statistic<> NumGlobals ("internalize", "Number of global vars internalized");
Chris Lattner1b94c002002-04-28 05:43:27 +000020
Chris Lattner44457bb2003-05-22 19:34:49 +000021 // APIFile - A file which contains a list of symbols that should not be marked
22 // external.
23 cl::opt<std::string>
24 APIFile("internalize-public-api-file", cl::value_desc("filename"),
25 cl::desc("A file containing list of globals to not internalize"));
26
Chris Lattner47cc3662002-07-30 19:48:44 +000027 class InternalizePass : public Pass {
Chris Lattner44457bb2003-05-22 19:34:49 +000028 std::set<std::string> ExternalNames;
29 public:
30 InternalizePass() {
31 if (!APIFile.empty())
32 LoadFile(APIFile.c_str());
33 else
34 ExternalNames.insert("main");
35 }
Chris Lattner17069b32002-11-08 20:34:21 +000036
Chris Lattner44457bb2003-05-22 19:34:49 +000037 void LoadFile(const char *Filename) {
38 // Load the APIFile...
39 std::ifstream In(Filename);
40 if (!In.good()) {
41 std::cerr << "WARNING: Internalize couldn't load file '" << Filename
42 << "'!: Not internalizing.\n";
43 return; // Do not internalize anything...
44 }
45 while (In) {
46 std::string Symbol;
47 In >> Symbol;
48 if (!Symbol.empty())
49 ExternalNames.insert(Symbol);
50 }
51 }
52
53 virtual bool run(Module &M) {
54 if (ExternalNames.empty()) return false; // Error loading file...
Chris Lattner47cc3662002-07-30 19:48:44 +000055 bool Changed = false;
56
57 // Found a main function, mark all functions not named main as internal.
58 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Chris Lattner44457bb2003-05-22 19:34:49 +000059 if (!I->isExternal() && // Function must be defined here
60 !I->hasInternalLinkage() && // Can't already have internal linkage
61 !ExternalNames.count(I->getName())) {// Not marked to keep external?
Chris Lattner379a8d22003-04-16 20:28:45 +000062 I->setLinkage(GlobalValue::InternalLinkage);
Chris Lattner47cc3662002-07-30 19:48:44 +000063 Changed = true;
64 ++NumFunctions;
65 DEBUG(std::cerr << "Internalizing func " << I->getName() << "\n");
66 }
Chris Lattner1b94c002002-04-28 05:43:27 +000067
Chris Lattner47cc3662002-07-30 19:48:44 +000068 // Mark all global variables with initializers as internal as well...
69 for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
Chris Lattner44457bb2003-05-22 19:34:49 +000070 if (!I->isExternal() && !I->hasInternalLinkage() &&
71 !ExternalNames.count(I->getName())) {
Chris Lattner379a8d22003-04-16 20:28:45 +000072 I->setLinkage(GlobalValue::InternalLinkage);
Chris Lattner47cc3662002-07-30 19:48:44 +000073 Changed = true;
74 ++NumGlobals;
75 DEBUG(std::cerr << "Internalizing gvar " << I->getName() << "\n");
76 }
77
78 return Changed;
79 }
80 };
Chris Lattner1b94c002002-04-28 05:43:27 +000081
Chris Lattner44457bb2003-05-22 19:34:49 +000082 RegisterOpt<InternalizePass> X("internalize", "Internalize Global Symbols");
Chris Lattnerb28b6802002-07-23 18:06:35 +000083} // end anonymous namespace
84
Chris Lattner1b94c002002-04-28 05:43:27 +000085Pass *createInternalizePass() {
86 return new InternalizePass();
87}