forked from OSchip/llvm-project
Add option to internalize to allow it to read a file to determine which symbols
should not be internalized llvm-svn: 6288
This commit is contained in:
parent
9141f8c2f6
commit
44457bb5ea
|
@ -10,25 +10,55 @@
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "Support/Statistic.h"
|
#include "Support/Statistic.h"
|
||||||
|
#include "Support/CommandLine.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
Statistic<> NumFunctions("internalize", "Number of functions internalized");
|
Statistic<> NumFunctions("internalize", "Number of functions internalized");
|
||||||
Statistic<> NumGlobals ("internalize", "Number of global vars internalized");
|
Statistic<> NumGlobals ("internalize", "Number of global vars internalized");
|
||||||
|
|
||||||
|
// APIFile - A file which contains a list of symbols that should not be marked
|
||||||
|
// external.
|
||||||
|
cl::opt<std::string>
|
||||||
|
APIFile("internalize-public-api-file", cl::value_desc("filename"),
|
||||||
|
cl::desc("A file containing list of globals to not internalize"));
|
||||||
|
|
||||||
class InternalizePass : public Pass {
|
class InternalizePass : public Pass {
|
||||||
virtual bool run(Module &M) {
|
std::set<std::string> ExternalNames;
|
||||||
Function *MainFunc = M.getMainFunction();
|
public:
|
||||||
|
InternalizePass() {
|
||||||
|
if (!APIFile.empty())
|
||||||
|
LoadFile(APIFile.c_str());
|
||||||
|
else
|
||||||
|
ExternalNames.insert("main");
|
||||||
|
}
|
||||||
|
|
||||||
if (MainFunc == 0 || MainFunc->isExternal())
|
void LoadFile(const char *Filename) {
|
||||||
return false; // No main found, must be a library...
|
// Load the APIFile...
|
||||||
|
std::ifstream In(Filename);
|
||||||
|
if (!In.good()) {
|
||||||
|
std::cerr << "WARNING: Internalize couldn't load file '" << Filename
|
||||||
|
<< "'!: Not internalizing.\n";
|
||||||
|
return; // Do not internalize anything...
|
||||||
|
}
|
||||||
|
while (In) {
|
||||||
|
std::string Symbol;
|
||||||
|
In >> Symbol;
|
||||||
|
if (!Symbol.empty())
|
||||||
|
ExternalNames.insert(Symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool run(Module &M) {
|
||||||
|
if (ExternalNames.empty()) return false; // Error loading file...
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
|
|
||||||
// Found a main function, mark all functions not named main as internal.
|
// Found a main function, mark all functions not named main as internal.
|
||||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
||||||
if (&*I != MainFunc && // Leave the main function external
|
if (!I->isExternal() && // Function must be defined here
|
||||||
!I->isExternal() && // Function must be defined here
|
!I->hasInternalLinkage() && // Can't already have internal linkage
|
||||||
!I->hasInternalLinkage()) { // Can't already have internal linkage
|
!ExternalNames.count(I->getName())) {// Not marked to keep external?
|
||||||
I->setLinkage(GlobalValue::InternalLinkage);
|
I->setLinkage(GlobalValue::InternalLinkage);
|
||||||
Changed = true;
|
Changed = true;
|
||||||
++NumFunctions;
|
++NumFunctions;
|
||||||
|
@ -37,7 +67,8 @@ namespace {
|
||||||
|
|
||||||
// Mark all global variables with initializers as internal as well...
|
// Mark all global variables with initializers as internal as well...
|
||||||
for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
|
for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
|
||||||
if (!I->isExternal() && I->hasExternalLinkage()) {
|
if (!I->isExternal() && !I->hasInternalLinkage() &&
|
||||||
|
!ExternalNames.count(I->getName())) {
|
||||||
I->setLinkage(GlobalValue::InternalLinkage);
|
I->setLinkage(GlobalValue::InternalLinkage);
|
||||||
Changed = true;
|
Changed = true;
|
||||||
++NumGlobals;
|
++NumGlobals;
|
||||||
|
@ -48,7 +79,7 @@ namespace {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
RegisterOpt<InternalizePass> X("internalize", "Internalize Functions");
|
RegisterOpt<InternalizePass> X("internalize", "Internalize Global Symbols");
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
Pass *createInternalizePass() {
|
Pass *createInternalizePass() {
|
||||||
|
|
Loading…
Reference in New Issue