mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-24 12:20:00 +00:00
Change the internalize pass to internalize all symbols when given an empty
list of externals. This makes sense since a shared library with no symbols can still be useful if it has static constructors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166795 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
276c43f022
commit
e5551ed9ce
@ -82,7 +82,7 @@ namespace {
|
||||
(void) llvm::createIPSCCPPass();
|
||||
(void) llvm::createIndVarSimplifyPass();
|
||||
(void) llvm::createInstructionCombiningPass();
|
||||
(void) llvm::createInternalizePass(false);
|
||||
(void) llvm::createInternalizePass();
|
||||
(void) llvm::createLCSSAPass();
|
||||
(void) llvm::createLICMPass();
|
||||
(void) llvm::createLazyValueInfoPass();
|
||||
|
@ -103,24 +103,15 @@ Pass *createAlwaysInlinerPass(bool InsertLifetime);
|
||||
Pass *createPruneEHPass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// createInternalizePass - This pass loops over all of the functions in the
|
||||
/// input module, internalizing all globals (functions and variables) not part
|
||||
/// of the api. If a list of symbols is specified with the
|
||||
/// -internalize-public-api-* command line options, those symbols are not
|
||||
/// internalized and all others are. Otherwise if AllButMain is set and the
|
||||
/// main function is found, all other globals are marked as internal. If no api
|
||||
/// is supplied and AllButMain is not set, or no main function is found, nothing
|
||||
/// is internalized.
|
||||
///
|
||||
ModulePass *createInternalizePass(bool AllButMain);
|
||||
|
||||
/// createInternalizePass - This pass loops over all of the functions in the
|
||||
/// input module, internalizing all globals (functions and variables) not in the
|
||||
/// given exportList.
|
||||
///
|
||||
/// Note that commandline options that are used with the above function are not
|
||||
/// used now! Also, when exportList is empty, nothing is internalized.
|
||||
/// used now!
|
||||
ModulePass *createInternalizePass(const std::vector<const char *> &exportList);
|
||||
/// createInternalizePass - Same as above, but with an empty exportList.
|
||||
ModulePass *createInternalizePass();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// createDeadArgEliminationPass - This pass removes arguments from functions
|
||||
|
@ -95,7 +95,10 @@ void LLVMAddIPSCCPPass(LLVMPassManagerRef PM) {
|
||||
}
|
||||
|
||||
void LLVMAddInternalizePass(LLVMPassManagerRef PM, unsigned AllButMain) {
|
||||
unwrap(PM)->add(createInternalizePass(AllButMain != 0));
|
||||
std::vector<const char *> Export;
|
||||
if (AllButMain)
|
||||
Export.push_back("main");
|
||||
unwrap(PM)->add(createInternalizePass(Export));
|
||||
}
|
||||
|
||||
void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM) {
|
||||
|
@ -7,9 +7,9 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This pass loops over all of the functions in the input module, looking for a
|
||||
// main function. If a main function is found, all other functions and all
|
||||
// global variables with initializers are marked as internal.
|
||||
// This pass loops over all of the functions and variables in the input module.
|
||||
// If the function or variable is not in the list of external names given to
|
||||
// the pass it is marked as internal.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -45,12 +45,9 @@ APIList("internalize-public-api-list", cl::value_desc("list"),
|
||||
namespace {
|
||||
class InternalizePass : public ModulePass {
|
||||
std::set<std::string> ExternalNames;
|
||||
/// If no api symbols were specified and a main function is defined,
|
||||
/// assume the main function is the only API
|
||||
bool AllButMain;
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
explicit InternalizePass(bool AllButMain = true);
|
||||
explicit InternalizePass();
|
||||
explicit InternalizePass(const std::vector <const char *>& exportList);
|
||||
void LoadFile(const char *Filename);
|
||||
virtual bool runOnModule(Module &M);
|
||||
@ -66,8 +63,8 @@ char InternalizePass::ID = 0;
|
||||
INITIALIZE_PASS(InternalizePass, "internalize",
|
||||
"Internalize Global Symbols", false, false)
|
||||
|
||||
InternalizePass::InternalizePass(bool AllButMain)
|
||||
: ModulePass(ID), AllButMain(AllButMain){
|
||||
InternalizePass::InternalizePass()
|
||||
: ModulePass(ID) {
|
||||
initializeInternalizePassPass(*PassRegistry::getPassRegistry());
|
||||
if (!APIFile.empty()) // If a filename is specified, use it.
|
||||
LoadFile(APIFile.c_str());
|
||||
@ -76,7 +73,7 @@ InternalizePass::InternalizePass(bool AllButMain)
|
||||
}
|
||||
|
||||
InternalizePass::InternalizePass(const std::vector<const char *>&exportList)
|
||||
: ModulePass(ID), AllButMain(false){
|
||||
: ModulePass(ID){
|
||||
initializeInternalizePassPass(*PassRegistry::getPassRegistry());
|
||||
for(std::vector<const char *>::const_iterator itr = exportList.begin();
|
||||
itr != exportList.end(); itr++) {
|
||||
@ -103,23 +100,6 @@ void InternalizePass::LoadFile(const char *Filename) {
|
||||
bool InternalizePass::runOnModule(Module &M) {
|
||||
CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
|
||||
CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
|
||||
|
||||
if (ExternalNames.empty()) {
|
||||
// Return if we're not in 'all but main' mode and have no external api
|
||||
if (!AllButMain)
|
||||
return false;
|
||||
// If no list or file of symbols was specified, check to see if there is a
|
||||
// "main" symbol defined in the module. If so, use it, otherwise do not
|
||||
// internalize the module, it must be a library or something.
|
||||
//
|
||||
Function *MainFunc = M.getFunction("main");
|
||||
if (MainFunc == 0 || MainFunc->isDeclaration())
|
||||
return false; // No main found, must be a library...
|
||||
|
||||
// Preserve main, internalize all else.
|
||||
ExternalNames.insert(MainFunc->getName());
|
||||
}
|
||||
|
||||
bool Changed = false;
|
||||
|
||||
// Never internalize functions which code-gen might insert.
|
||||
@ -189,8 +169,8 @@ bool InternalizePass::runOnModule(Module &M) {
|
||||
return Changed;
|
||||
}
|
||||
|
||||
ModulePass *llvm::createInternalizePass(bool AllButMain) {
|
||||
return new InternalizePass(AllButMain);
|
||||
ModulePass *llvm::createInternalizePass() {
|
||||
return new InternalizePass();
|
||||
}
|
||||
|
||||
ModulePass *llvm::createInternalizePass(const std::vector <const char *> &el) {
|
||||
|
@ -245,8 +245,11 @@ void PassManagerBuilder::populateLTOPassManager(PassManagerBase &PM,
|
||||
// Now that composite has been compiled, scan through the module, looking
|
||||
// for a main function. If main is defined, mark all other functions
|
||||
// internal.
|
||||
if (Internalize)
|
||||
PM.add(createInternalizePass(true));
|
||||
if (Internalize) {
|
||||
std::vector<const char*> E;
|
||||
E.push_back("main");
|
||||
PM.add(createInternalizePass(E));
|
||||
}
|
||||
|
||||
// Propagate constants at call sites into the functions they call. This
|
||||
// opens opportunities for globalopt (and inlining) by substituting function
|
||||
|
13
test/Other/link-opts.ll
Normal file
13
test/Other/link-opts.ll
Normal file
@ -0,0 +1,13 @@
|
||||
;RUN: opt -S -std-link-opts < %s | FileCheck %s
|
||||
; Simple test to check that -std-link-opts keeps only the main function.
|
||||
|
||||
; CHECK-NOT: define
|
||||
; CHECK: define void @main
|
||||
; CHECK-NOT: define
|
||||
define void @main() {
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo() {
|
||||
ret void
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
; No arguments means internalize all but main
|
||||
; No arguments means internalize everything
|
||||
; RUN: opt < %s -internalize -S | FileCheck --check-prefix=NOARGS %s
|
||||
|
||||
; Internalize all but foo and j
|
||||
; RUN: opt < %s -internalize -internalize-public-api-list foo -internalize-public-api-list j -S | FileCheck --check-prefix=LIST %s
|
||||
|
||||
; Non existent files should be treated as if they were empty (so internalize all but main)
|
||||
; Non existent files should be treated as if they were empty (so internalize
|
||||
; everything)
|
||||
; RUN: opt < %s -internalize -internalize-public-api-file /nonexistent/file 2> /dev/null -S | FileCheck --check-prefix=EMPTYFILE %s
|
||||
|
||||
; RUN: opt < %s -S -internalize -internalize-public-api-list bar -internalize-public-api-list foo -internalize-public-api-file /nonexistent/file 2> /dev/null | FileCheck --check-prefix=LIST2 %s
|
||||
@ -26,9 +27,9 @@
|
||||
; MERGE: @j = global
|
||||
@j = global i32 0
|
||||
|
||||
; NOARGS: define void @main
|
||||
; NOARGS: define internal void @main
|
||||
; LIST: define internal void @main
|
||||
; EMPTYFILE: define void @main
|
||||
; EMPTYFILE: define internal void @main
|
||||
; LIST2: define internal void @main
|
||||
; MERGE: define internal void @main
|
||||
define void @main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt < %s -internalize -S | grep internal | count 3
|
||||
; RUN: opt < %s -internalize -internalize-public-api-list main -S | grep internal | count 3
|
||||
|
||||
@A = global i32 0
|
||||
@B = alias i32* @A
|
||||
|
Loading…
Reference in New Issue
Block a user