Added LLVM project notice to the top of every C++ source file.
[oota-llvm.git] / lib / Transforms / IPO / ExtractFunction.cpp
1
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/IPO.h"
10 #include "llvm/Pass.h"
11 #include "llvm/Module.h"
12
13 namespace {
14   class FunctionExtractorPass : public Pass {
15     Function *Named;
16   public:
17     FunctionExtractorPass(Function *F = 0) : Named(F) {}
18
19     bool run(Module &M) {
20       if (Named == 0) {
21         Named = M.getMainFunction();
22         if (Named == 0) return false;  // No function to extract
23       }
24
25       // Make sure our result is globally accessible...
26       Named->setLinkage(GlobalValue::ExternalLinkage);
27
28       // Mark all global variables internal
29       for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
30         if (!I->isExternal()) {
31           I->setInitializer(0);  // Make all variables external
32           I->setLinkage(GlobalValue::ExternalLinkage);
33         }
34       
35       // All of the functions may be used by global variables or the named
36       // function.  Loop through them and create a new, external functions that
37       // can be "used", instead of ones with bodies.
38       //
39       std::vector<Function*> NewFunctions;
40       
41       Function *Last = &M.back();  // Figure out where the last real fn is...
42       
43       for (Module::iterator I = M.begin(); ; ++I) {
44         if (&*I != Named) {
45           Function *New = new Function(I->getFunctionType(),
46                                        GlobalValue::ExternalLinkage,
47                                        I->getName());
48           I->setName("");  // Remove Old name
49           
50           // If it's not the named function, delete the body of the function
51           I->dropAllReferences();
52           
53           M.getFunctionList().push_back(New);
54           NewFunctions.push_back(New);
55         }
56         
57         if (&*I == Last) break;  // Stop after processing the last function
58       }
59       
60       // Now that we have replacements all set up, loop through the module,
61       // deleting the old functions, replacing them with the newly created
62       // functions.
63       if (!NewFunctions.empty()) {
64         unsigned FuncNum = 0;
65         Module::iterator I = M.begin();
66         do {
67           if (&*I != Named) {
68             // Make everything that uses the old function use the new dummy fn
69             I->replaceAllUsesWith(NewFunctions[FuncNum++]);
70             
71             Function *Old = I;
72             ++I;  // Move the iterator to the new function
73             
74             // Delete the old function!
75             M.getFunctionList().erase(Old);
76             
77           } else {
78             ++I;  // Skip the function we are extracting
79           }
80         } while (&*I != NewFunctions[0]);
81       }
82       
83       return true;
84     }
85   };
86
87   RegisterPass<FunctionExtractorPass> X("extract", "Function Extractor");
88 }
89
90 Pass *createFunctionExtractionPass(Function *F) {
91   return new FunctionExtractorPass(F);
92 }