LLVM API Documentation

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::global_iterator I = M.global_begin(), E = M.global_end(); 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.end();  // 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 }