ExtractFunction.cpp revision 44be25716628941b4cccccf56a28ee0ba2606850
1//===- ExtractFunction.cpp - Extract a function from Program --------------===// 2// 3// This file implements a method that extracts a function from program, cleans 4// it up, and returns it as a new module. 5// 6//===----------------------------------------------------------------------===// 7 8#include "BugDriver.h" 9#include "llvm/Module.h" 10#include "llvm/PassManager.h" 11#include "llvm/Transforms/IPO.h" 12#include "llvm/Transforms/Scalar.h" 13#include "llvm/Transforms/Utils/Cloning.h" 14#include "llvm/Analysis/Verifier.h" 15#include "llvm/Type.h" 16#include "llvm/Constant.h" 17 18/// deleteInstructionFromProgram - This method clones the current Program and 19/// deletes the specified instruction from the cloned module. It then runs a 20/// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code which 21/// depends on the value. The modified module is then returned. 22/// 23Module *BugDriver::deleteInstructionFromProgram(Instruction *I, 24 unsigned Simplification) const { 25 Module *Result = CloneModule(Program); 26 27 BasicBlock *PBB = I->getParent(); 28 Function *PF = PBB->getParent(); 29 30 Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn 31 std::advance(RFI, std::distance(Program->begin(), Module::iterator(PF))); 32 33 Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB 34 std::advance(RBI, std::distance(PF->begin(), Function::iterator(PBB))); 35 36 BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst 37 std::advance(RI, std::distance(PBB->begin(), BasicBlock::iterator(I))); 38 I = RI; // Got the corresponding instruction! 39 40 // If this instruction produces a value, replace any users with null values 41 if (I->getType() != Type::VoidTy) 42 I->replaceAllUsesWith(Constant::getNullValue(I->getType())); 43 44 // Remove the instruction from the program. 45 I->getParent()->getInstList().erase(I); 46 47 // Spiff up the output a little bit. 48 PassManager Passes; 49 if (Simplification > 2) 50 Passes.add(createAggressiveDCEPass()); // Remove dead code... 51 //Passes.add(createInstructionCombiningPass()); 52 if (Simplification > 1) 53 Passes.add(createDeadCodeEliminationPass()); 54 if (Simplification) 55 Passes.add(createCFGSimplificationPass()); // Delete dead control flow 56 57 Passes.add(createVerifierPass()); 58 Passes.run(*Result); 59 return Result; 60} 61 62/// performFinalCleanups - This method clones the current Program and performs 63/// a series of cleanups intended to get rid of extra cruft on the module 64/// before handing it to the user... 65/// 66Module *BugDriver::performFinalCleanups() const { 67 PassManager CleanupPasses; 68 CleanupPasses.add(createFunctionResolvingPass()); 69 CleanupPasses.add(createGlobalDCEPass()); 70 CleanupPasses.add(createVerifierPass()); 71 Module *M = CloneModule(Program); 72 CleanupPasses.run(*M); 73 return M; 74} 75