//===-- ExtractFunction.cpp - Function extraction pass --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass extracts
//
//===----------------------------------------------------------------------===//

#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Support/Compiler.h"
using namespace llvm;

namespace {
  /// @brief A pass to extract specific functions and their dependencies.
  class VISIBILITY_HIDDEN FunctionExtractorPass : public ModulePass {
    Function *Named;
    bool deleteFunc;
    bool reLink;
  public:
    static char ID; // Pass identification, replacement for typeid

    /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the
    /// specified function. Otherwise, it deletes as much of the module as
    /// possible, except for the function specified.
    ///
    explicit FunctionExtractorPass(Function *F = 0, bool deleteFn = true,
                                   bool relinkCallees = false)
      : ModulePass((intptr_t)&ID), Named(F), deleteFunc(deleteFn), 
      reLink(relinkCallees) {}

    bool runOnModule(Module &M) {
      if (Named == 0) {
        Named = M.getFunction("main");
        if (Named == 0) return false;  // No function to extract
      }
      
      if (deleteFunc)
        return deleteFunction();
      M.setModuleInlineAsm("");
      return isolateFunction(M);
    }

    bool deleteFunction() {
      // If we're in relinking mode, set linkage of all internal callees to
      // external. This will allow us extract function, and then - link
      // everything together
      if (reLink) {
        for (Function::iterator B = Named->begin(), BE = Named->end();
             B != BE; ++B) {
          for (BasicBlock::iterator I = B->begin(), E = B->end();
               I != E; ++I) {
            if (CallInst* callInst = dyn_cast<CallInst>(&*I)) {
              Function* Callee = callInst->getCalledFunction();
              if (Callee && Callee->hasInternalLinkage())
                Callee->setLinkage(GlobalValue::ExternalLinkage);
            }
          }
        }
      }
      
      Named->setLinkage(GlobalValue::ExternalLinkage);
      Named->deleteBody();
      assert(Named->isDeclaration() && "This didn't make the function external!");
      return true;
    }

    bool isolateFunction(Module &M) {
      // Make sure our result is globally accessible...
      Named->setLinkage(GlobalValue::ExternalLinkage);

      // Mark all global variables internal
      for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
        if (!I->isDeclaration()) {
          I->setInitializer(0);  // Make all variables external
          I->setLinkage(GlobalValue::ExternalLinkage);
        }

      // All of the functions may be used by global variables or the named
      // function.  Loop through them and create a new, external functions that
      // can be "used", instead of ones with bodies.
      std::vector<Function*> NewFunctions;

      Function *Last = --M.end();  // Figure out where the last real fn is.

      for (Module::iterator I = M.begin(); ; ++I) {
        if (&*I != Named) {
          Function *New = new Function(I->getFunctionType(),
                                       GlobalValue::ExternalLinkage);
          New->setCallingConv(I->getCallingConv());

          // If it's not the named function, delete the body of the function
          I->dropAllReferences();

          M.getFunctionList().push_back(New);
          NewFunctions.push_back(New);
          New->takeName(I);
        }

        if (&*I == Last) break;  // Stop after processing the last function
      }

      // Now that we have replacements all set up, loop through the module,
      // deleting the old functions, replacing them with the newly created
      // functions.
      if (!NewFunctions.empty()) {
        unsigned FuncNum = 0;
        Module::iterator I = M.begin();
        do {
          if (&*I != Named) {
            // Make everything that uses the old function use the new dummy fn
            I->replaceAllUsesWith(NewFunctions[FuncNum++]);

            Function *Old = I;
            ++I;  // Move the iterator to the new function

            // Delete the old function!
            M.getFunctionList().erase(Old);

          } else {
            ++I;  // Skip the function we are extracting
          }
        } while (&*I != NewFunctions[0]);
      }

      return true;
    }
  };

  char FunctionExtractorPass::ID = 0;
  RegisterPass<FunctionExtractorPass> X("extract", "Function Extractor");
}

ModulePass *llvm::createFunctionExtractionPass(Function *F, bool deleteFn,
                                               bool relinkCallees) {
  return new FunctionExtractorPass(F, deleteFn, relinkCallees);
}
