ExtractFunction.cpp revision 10f22cb1a0f2755050218cd0e07221a0985c6b63
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/// extractFunctionFromModule - This method is used to extract the specified 19/// (non-external) function from the current program, slim down the module, and 20/// then return it. This does not modify Program at all, it modifies a copy, 21/// which it returns. 22Module *BugDriver::extractFunctionFromModule(Function *F) const { 23 Module *Result = CloneModule(Program); 24 25 // Translate from the old module to the new copied module... 26 Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn 27 std::advance(RFI, std::distance(Program->begin(), Module::iterator(F))); 28 29 // In addition to just parsing the input from GCC, we also want to spiff it up 30 // a little bit. Do this now. 31 // 32 PassManager Passes; 33 Passes.add(createFunctionExtractionPass(RFI)); // Extract the function 34 Passes.add(createGlobalDCEPass()); // Delete unreachable globals 35 Passes.add(createFunctionResolvingPass()); // Delete prototypes 36 Passes.add(createDeadTypeEliminationPass()); // Remove dead types... 37 Passes.add(createVerifierPass()); 38 Passes.run(*Result); 39 return Result; 40} 41 42 43/// deleteInstructionFromProgram - This method clones the current Program and 44/// deletes the specified instruction from the cloned module. It then runs a 45/// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code which 46/// depends on the value. The modified module is then returned. 47/// 48Module *BugDriver::deleteInstructionFromProgram(Instruction *I, 49 unsigned Simplification) const { 50 Module *Result = CloneModule(Program); 51 52 BasicBlock *PBB = I->getParent(); 53 Function *PF = PBB->getParent(); 54 55 Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn 56 std::advance(RFI, std::distance(Program->begin(), Module::iterator(PF))); 57 58 Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB 59 std::advance(RBI, std::distance(PF->begin(), Function::iterator(PBB))); 60 61 BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst 62 std::advance(RI, std::distance(PBB->begin(), BasicBlock::iterator(I))); 63 I = RI; // Got the corresponding instruction! 64 65 // If this instruction produces a value, replace any users with null values 66 if (I->getType() != Type::VoidTy) 67 I->replaceAllUsesWith(Constant::getNullValue(I->getType())); 68 69 // Remove the instruction from the program. 70 I->getParent()->getInstList().erase(I); 71 72 // In addition to just parsing the input from GCC, we also want to spiff it up 73 // a little bit. Do this now. 74 // 75 PassManager Passes; 76 if (Simplification > 2) 77 Passes.add(createAggressiveDCEPass()); // Remove dead code... 78 //Passes.add(createInstructionCombiningPass()); 79 if (Simplification > 1) 80 Passes.add(createDeadCodeEliminationPass()); 81 if (Simplification) 82 Passes.add(createCFGSimplificationPass()); // Delete dead control flow 83 84 Passes.add(createVerifierPass()); 85 Passes.run(*Result); 86 return Result; 87} 88 89/// performFinalCleanups - This method clones the current Program and performs 90/// a series of cleanups intended to get rid of extra cruft on the module 91/// before handing it to the user... 92/// 93Module *BugDriver::performFinalCleanups() const { 94 PassManager CleanupPasses; 95 CleanupPasses.add(createFunctionResolvingPass()); 96 CleanupPasses.add(createGlobalDCEPass()); 97 CleanupPasses.add(createVerifierPass()); 98 Module *M = CloneModule(Program); 99 CleanupPasses.run(*M); 100 return M; 101} 102