LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ExtractFunction.cpp

Go to the documentation of this file.
00001 //===-- ExtractFunction.cpp - Function extraction pass --------------------===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This pass extracts
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Module.h"
00015 #include "llvm/Pass.h"
00016 #include "llvm/Transforms/IPO.h"
00017 using namespace llvm;
00018 
00019 namespace {
00020   class FunctionExtractorPass : public ModulePass {
00021     Function *Named;
00022     bool deleteFunc;
00023   public:
00024     /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the
00025     /// specified function. Otherwise, it deletes as much of the module as
00026     /// possible, except for the function specified.
00027     ///
00028     FunctionExtractorPass(Function *F = 0, bool deleteFn = true) 
00029       : Named(F), deleteFunc(deleteFn) {}
00030 
00031     bool runOnModule(Module &M) {
00032       if (Named == 0) {
00033         Named = M.getMainFunction();
00034         if (Named == 0) return false;  // No function to extract
00035       }
00036 
00037       if (deleteFunc)
00038         return deleteFunction();
00039       else 
00040         return isolateFunction(M);
00041     }
00042 
00043     bool deleteFunction() {
00044       Named->setLinkage(GlobalValue::ExternalLinkage);
00045       Named->deleteBody();
00046       assert(Named->isExternal() && "This didn't make the function external!");
00047       return true;
00048     }
00049 
00050     bool isolateFunction(Module &M) {
00051       // Make sure our result is globally accessible...
00052       Named->setLinkage(GlobalValue::ExternalLinkage);
00053 
00054       // Mark all global variables internal
00055       for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
00056         if (!I->isExternal()) {
00057           I->setInitializer(0);  // Make all variables external
00058           I->setLinkage(GlobalValue::ExternalLinkage);
00059         }
00060       
00061       // All of the functions may be used by global variables or the named
00062       // function.  Loop through them and create a new, external functions that
00063       // can be "used", instead of ones with bodies.
00064       std::vector<Function*> NewFunctions;
00065       
00066       Function *Last = &M.back();  // Figure out where the last real fn is...
00067       
00068       for (Module::iterator I = M.begin(); ; ++I) {
00069         if (&*I != Named) {
00070           Function *New = new Function(I->getFunctionType(),
00071                                        GlobalValue::ExternalLinkage,
00072                                        I->getName());
00073           I->setName("");  // Remove Old name
00074           
00075           // If it's not the named function, delete the body of the function
00076           I->dropAllReferences();
00077           
00078           M.getFunctionList().push_back(New);
00079           NewFunctions.push_back(New);
00080         }
00081         
00082         if (&*I == Last) break;  // Stop after processing the last function
00083       }
00084       
00085       // Now that we have replacements all set up, loop through the module,
00086       // deleting the old functions, replacing them with the newly created
00087       // functions.
00088       if (!NewFunctions.empty()) {
00089         unsigned FuncNum = 0;
00090         Module::iterator I = M.begin();
00091         do {
00092           if (&*I != Named) {
00093             // Make everything that uses the old function use the new dummy fn
00094             I->replaceAllUsesWith(NewFunctions[FuncNum++]);
00095             
00096             Function *Old = I;
00097             ++I;  // Move the iterator to the new function
00098             
00099             // Delete the old function!
00100             M.getFunctionList().erase(Old);
00101             
00102           } else {
00103             ++I;  // Skip the function we are extracting
00104           }
00105         } while (&*I != NewFunctions[0]);
00106       }
00107       
00108       return true;
00109     }
00110   };
00111 
00112   RegisterPass<FunctionExtractorPass> X("extract", "Function Extractor");
00113 }
00114 
00115 ModulePass *llvm::createFunctionExtractionPass(Function *F, bool deleteFn) {
00116   return new FunctionExtractorPass(F, deleteFn);
00117 }