llvm.org GIT mirror llvm / ef3682a
Simplify internalize pass. Add test case. Patch by Matthijs Kooijman! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51114 91177308-0d34-0410-b5e6-96231b3b80d8 Devang Patel 11 years ago
5 changed file(s) with 62 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
101101
102102 //===----------------------------------------------------------------------===//
103103 /// createInternalizePass - This pass loops over all of the functions in the
104 /// input module, looking for a main function. If a list of symbols is
105 /// specified with the -internalize-public-api-* command line options, those
106 /// symbols are internalized. Otherwise if InternalizeEverything is set and
107 /// the main function is found, all other globals are marked as internal.
104 /// input module, internalizing all globals (functions and variables) not part
105 /// of the api. If a list of symbols is specified with the
106 /// -internalize-public-api-* command line options, those symbols are not
107 /// internalized and all others are. Otherwise if AllButMain is set and the
108 /// main function is found, all other globals are marked as internal.
108109 ///
109110 ModulePass *createInternalizePass(bool InternalizeEverything);
111
112 /// createInternalizePass - This pass loops over all of the functions in the
113 /// input module, internalizing all globals (functions and variables) not in the
114 /// given exportList.
110115 ModulePass *createInternalizePass(const std::vector &exportList);
111116
112117 //===----------------------------------------------------------------------===//
4242 namespace {
4343 class VISIBILITY_HIDDEN InternalizePass : public ModulePass {
4444 std::set ExternalNames;
45 bool DontInternalize;
45 /// If no api symbols were specified and a main function is defined,
46 /// assume the main function is the only API
47 bool AllButMain;
4648 public:
4749 static char ID; // Pass identification, replacement for typeid
4850 explicit InternalizePass(bool InternalizeEverything = true);
5658 static RegisterPass
5759 X("internalize", "Internalize Global Symbols");
5860
59 InternalizePass::InternalizePass(bool InternalizeEverything)
60 : ModulePass((intptr_t)&ID), DontInternalize(false){
61 if (!APIFile.empty()) // If a filename is specified, use it
61 InternalizePass::InternalizePass(bool AllButMain)
62 : ModulePass((intptr_t)&ID), AllButMain(AllButMain){
63 if (!APIFile.empty()) // If a filename is specified, use it.
6264 LoadFile(APIFile.c_str());
63 else if (!APIList.empty()) // Else, if a list is specified, use it.
65 if (!APIList.empty()) // If a list is specified, use it as well.
6466 ExternalNames.insert(APIList.begin(), APIList.end());
65 else if (!InternalizeEverything)
66 // Finally, if we're allowed to, internalize all but main.
67 DontInternalize = true;
6867 }
6968
7069 InternalizePass::InternalizePass(const std::vector&exportList)
71 : ModulePass((intptr_t)&ID), DontInternalize(false){
70 : ModulePass((intptr_t)&ID), AllButMain(false){
7271 for(std::vector::const_iterator itr = exportList.begin();
7372 itr != exportList.end(); itr++) {
7473 ExternalNames.insert(*itr);
7978 // Load the APIFile...
8079 std::ifstream In(Filename);
8180 if (!In.good()) {
82 cerr << "WARNING: Internalize couldn't load file '" << Filename << "'!\n";
83 return; // Do not internalize anything...
81 cerr << "WARNING: Internalize couldn't load file '" << Filename
82 << "'! Continuing as if it's empty.\n";
83 return; // Just continue as if the file were empty
8484 }
8585 while (In) {
8686 std::string Symbol;
9191 }
9292
9393 bool InternalizePass::runOnModule(Module &M) {
94 if (DontInternalize) return false;
95
96 // If no list or file of symbols was specified, check to see if there is a
97 // "main" symbol defined in the module. If so, use it, otherwise do not
98 // internalize the module, it must be a library or something.
99 //
10094 if (ExternalNames.empty()) {
95 // Return if we're not in 'all but main' mode and have no external api
96 if (!AllButMain)
97 return false;
98 // If no list or file of symbols was specified, check to see if there is a
99 // "main" symbol defined in the module. If so, use it, otherwise do not
100 // internalize the module, it must be a library or something.
101 //
101102 Function *MainFunc = M.getFunction("main");
102103 if (MainFunc == 0 || MainFunc->isDeclaration())
103104 return false; // No main found, must be a library...
108109
109110 bool Changed = false;
110111
111 // Found a main function, mark all functions not named main as internal.
112 // Mark all functions not in the api as internal.
112113 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
113114 if (!I->isDeclaration() && // Function must be defined here
114115 !I->hasInternalLinkage() && // Can't already have internal linkage
133134 ExternalNames.insert("llvm.noinline");
134135 ExternalNames.insert("llvm.global.annotations");
135136
136 // Mark all global variables with initializers as internal as well.
137 // Mark all global variables with initializers that are not in the api as
138 // internal as well.
137139 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
138140 I != E; ++I)
139141 if (!I->isDeclaration() && !I->hasInternalLinkage() &&
0 ; No arguments means internalize all but main
1 ; RUN: llvm-as < %s | opt -internalize | llvm-dis | grep internal | count 4
2 ; Internalize all but foo and j
3 ; RUN: llvm-as < %s | opt -internalize -internalize-public-api-list foo -internalize-public-api-list j | llvm-dis | grep internal | count 3
4 ; Non existent files should be treated as if they were empty (so internalize all but main)
5 ; RUN: llvm-as < %s | opt -internalize -internalize-public-api-file /nonexistent/file | llvm-dis | grep internal | count 4
6 ; RUN: llvm-as < %s | opt -internalize -internalize-public-api-list bar -internalize-public-api-list foo -internalize-public-api-file /nonexistent/file | llvm-dis | grep internal | count 3
7 ; -file and -list options should be merged, the .apifile contains foo and j
8 ; RUN: llvm-as < %s | opt -internalize -internalize-public-api-list bar -internalize-public-api-file %s.apifile | llvm-dis | grep internal | count 2
9
10 @i = weak global i32 0 ; [#uses=0]
11 @j = weak global i32 0 ; [#uses=0]
12
13 define void @main(...) {
14 entry:
15 ret void
16 }
17
18 define void @foo(...) {
19 entry:
20 ret void
21 }
22
23 define void @bar(...) {
24 entry:
25 ret void
26 }
0 load_lib llvm.exp
1
2 RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]