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