mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-23 16:19:52 +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:
@@ -82,7 +82,7 @@ namespace {
|
|||||||
(void) llvm::createIPSCCPPass();
|
(void) llvm::createIPSCCPPass();
|
||||||
(void) llvm::createIndVarSimplifyPass();
|
(void) llvm::createIndVarSimplifyPass();
|
||||||
(void) llvm::createInstructionCombiningPass();
|
(void) llvm::createInstructionCombiningPass();
|
||||||
(void) llvm::createInternalizePass(false);
|
(void) llvm::createInternalizePass();
|
||||||
(void) llvm::createLCSSAPass();
|
(void) llvm::createLCSSAPass();
|
||||||
(void) llvm::createLICMPass();
|
(void) llvm::createLICMPass();
|
||||||
(void) llvm::createLazyValueInfoPass();
|
(void) llvm::createLazyValueInfoPass();
|
||||||
|
|||||||
@@ -103,24 +103,15 @@ Pass *createAlwaysInlinerPass(bool InsertLifetime);
|
|||||||
Pass *createPruneEHPass();
|
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
|
/// createInternalizePass - This pass loops over all of the functions in the
|
||||||
/// input module, internalizing all globals (functions and variables) not in the
|
/// input module, internalizing all globals (functions and variables) not in the
|
||||||
/// given exportList.
|
/// given exportList.
|
||||||
///
|
///
|
||||||
/// Note that commandline options that are used with the above function are not
|
/// 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);
|
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
|
/// createDeadArgEliminationPass - This pass removes arguments from functions
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ void LLVMAddIPSCCPPass(LLVMPassManagerRef PM) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LLVMAddInternalizePass(LLVMPassManagerRef PM, unsigned AllButMain) {
|
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) {
|
void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM) {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This pass loops over all of the functions in the input module, looking for a
|
// This pass loops over all of the functions and variables in the input module.
|
||||||
// main function. If a main function is found, all other functions and all
|
// If the function or variable is not in the list of external names given to
|
||||||
// global variables with initializers are marked as internal.
|
// the pass it is marked as internal.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@@ -45,12 +45,9 @@ APIList("internalize-public-api-list", cl::value_desc("list"),
|
|||||||
namespace {
|
namespace {
|
||||||
class InternalizePass : public ModulePass {
|
class InternalizePass : public ModulePass {
|
||||||
std::set<std::string> ExternalNames;
|
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:
|
public:
|
||||||
static char ID; // Pass identification, replacement for typeid
|
static char ID; // Pass identification, replacement for typeid
|
||||||
explicit InternalizePass(bool AllButMain = true);
|
explicit InternalizePass();
|
||||||
explicit InternalizePass(const std::vector <const char *>& exportList);
|
explicit InternalizePass(const std::vector <const char *>& exportList);
|
||||||
void LoadFile(const char *Filename);
|
void LoadFile(const char *Filename);
|
||||||
virtual bool runOnModule(Module &M);
|
virtual bool runOnModule(Module &M);
|
||||||
@@ -66,8 +63,8 @@ char InternalizePass::ID = 0;
|
|||||||
INITIALIZE_PASS(InternalizePass, "internalize",
|
INITIALIZE_PASS(InternalizePass, "internalize",
|
||||||
"Internalize Global Symbols", false, false)
|
"Internalize Global Symbols", false, false)
|
||||||
|
|
||||||
InternalizePass::InternalizePass(bool AllButMain)
|
InternalizePass::InternalizePass()
|
||||||
: ModulePass(ID), AllButMain(AllButMain){
|
: ModulePass(ID) {
|
||||||
initializeInternalizePassPass(*PassRegistry::getPassRegistry());
|
initializeInternalizePassPass(*PassRegistry::getPassRegistry());
|
||||||
if (!APIFile.empty()) // If a filename is specified, use it.
|
if (!APIFile.empty()) // If a filename is specified, use it.
|
||||||
LoadFile(APIFile.c_str());
|
LoadFile(APIFile.c_str());
|
||||||
@@ -76,7 +73,7 @@ InternalizePass::InternalizePass(bool AllButMain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
InternalizePass::InternalizePass(const std::vector<const char *>&exportList)
|
InternalizePass::InternalizePass(const std::vector<const char *>&exportList)
|
||||||
: ModulePass(ID), AllButMain(false){
|
: ModulePass(ID){
|
||||||
initializeInternalizePassPass(*PassRegistry::getPassRegistry());
|
initializeInternalizePassPass(*PassRegistry::getPassRegistry());
|
||||||
for(std::vector<const char *>::const_iterator itr = exportList.begin();
|
for(std::vector<const char *>::const_iterator itr = exportList.begin();
|
||||||
itr != exportList.end(); itr++) {
|
itr != exportList.end(); itr++) {
|
||||||
@@ -103,23 +100,6 @@ void InternalizePass::LoadFile(const char *Filename) {
|
|||||||
bool InternalizePass::runOnModule(Module &M) {
|
bool InternalizePass::runOnModule(Module &M) {
|
||||||
CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
|
CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
|
||||||
CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
|
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;
|
bool Changed = false;
|
||||||
|
|
||||||
// Never internalize functions which code-gen might insert.
|
// Never internalize functions which code-gen might insert.
|
||||||
@@ -189,8 +169,8 @@ bool InternalizePass::runOnModule(Module &M) {
|
|||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModulePass *llvm::createInternalizePass(bool AllButMain) {
|
ModulePass *llvm::createInternalizePass() {
|
||||||
return new InternalizePass(AllButMain);
|
return new InternalizePass();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModulePass *llvm::createInternalizePass(const std::vector <const char *> &el) {
|
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
|
// Now that composite has been compiled, scan through the module, looking
|
||||||
// for a main function. If main is defined, mark all other functions
|
// for a main function. If main is defined, mark all other functions
|
||||||
// internal.
|
// internal.
|
||||||
if (Internalize)
|
if (Internalize) {
|
||||||
PM.add(createInternalizePass(true));
|
std::vector<const char*> E;
|
||||||
|
E.push_back("main");
|
||||||
|
PM.add(createInternalizePass(E));
|
||||||
|
}
|
||||||
|
|
||||||
// Propagate constants at call sites into the functions they call. This
|
// Propagate constants at call sites into the functions they call. This
|
||||||
// opens opportunities for globalopt (and inlining) by substituting function
|
// 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
|
; RUN: opt < %s -internalize -S | FileCheck --check-prefix=NOARGS %s
|
||||||
|
|
||||||
; Internalize all but foo and j
|
; 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
|
; 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 -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
|
; 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
|
; MERGE: @j = global
|
||||||
@j = global i32 0
|
@j = global i32 0
|
||||||
|
|
||||||
; NOARGS: define void @main
|
; NOARGS: define internal void @main
|
||||||
; LIST: define internal void @main
|
; LIST: define internal void @main
|
||||||
; EMPTYFILE: define void @main
|
; EMPTYFILE: define internal void @main
|
||||||
; LIST2: define internal void @main
|
; LIST2: define internal void @main
|
||||||
; MERGE: define internal void @main
|
; MERGE: define internal void @main
|
||||||
define 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
|
@A = global i32 0
|
||||||
@B = alias i32* @A
|
@B = alias i32* @A
|
||||||
|
|||||||
Reference in New Issue
Block a user