diff options
Diffstat (limited to 'llvm/tools/bugpoint/ExtractFunction.cpp')
-rw-r--r-- | llvm/tools/bugpoint/ExtractFunction.cpp | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/llvm/tools/bugpoint/ExtractFunction.cpp b/llvm/tools/bugpoint/ExtractFunction.cpp index 76b2258f8a7..9b5440c0d4e 100644 --- a/llvm/tools/bugpoint/ExtractFunction.cpp +++ b/llvm/tools/bugpoint/ExtractFunction.cpp @@ -9,7 +9,10 @@ #include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Type.h" +#include "llvm/Constant.h" /// extractFunctionFromModule - This method is used to extract the specified /// (non-external) function from the current program, slim down the module, and @@ -19,16 +22,62 @@ Module *BugDriver::extractFunctionFromModule(Function *F) const { Module *Result = CloneModule(Program); // Translate from the old module to the new copied module... - F = Result->getFunction(F->getName(), F->getFunctionType()); + Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn + std::advance(RFI, std::distance(Program->begin(), Module::iterator(F))); // In addition to just parsing the input from GCC, we also want to spiff it up // a little bit. Do this now. // PassManager Passes; - Passes.add(createFunctionExtractionPass(F)); // Extract the function + Passes.add(createFunctionExtractionPass(RFI)); // Extract the function Passes.add(createGlobalDCEPass()); // Delete unreachable globals Passes.add(createFunctionResolvingPass()); // Delete prototypes Passes.add(createDeadTypeEliminationPass()); // Remove dead types... Passes.run(*Result); return Result; } + + +/// deleteInstructionFromProgram - This method clones the current Program and +/// deletes the specified instruction from the cloned module. It then runs a +/// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code which +/// depends on the value. The modified module is then returned. +/// +Module *BugDriver::deleteInstructionFromProgram(Instruction *I, + unsigned Simplification) const { + Module *Result = CloneModule(Program); + + BasicBlock *PBB = I->getParent(); + Function *PF = PBB->getParent(); + + Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn + std::advance(RFI, std::distance(Program->begin(), Module::iterator(PF))); + + Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB + std::advance(RBI, std::distance(PF->begin(), Function::iterator(PBB))); + + BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst + std::advance(RI, std::distance(PBB->begin(), BasicBlock::iterator(I))); + I = RI; // Got the corresponding instruction! + + // If this instruction produces a value, replace any users with null values + if (I->getType() != Type::VoidTy) + I->replaceAllUsesWith(Constant::getNullValue(I->getType())); + + // Remove the instruction from the program. + I->getParent()->getInstList().erase(I); + + // In addition to just parsing the input from GCC, we also want to spiff it up + // a little bit. Do this now. + // + PassManager Passes; + if (Simplification > 2) + Passes.add(createAggressiveDCEPass()); // Remove dead code... + //Passes.add(createInstructionCombiningPass()); + if (Simplification > 1) + Passes.add(createDeadCodeEliminationPass()); + if (Simplification) + Passes.add(createCFGSimplificationPass()); // Delete dead control flow + Passes.run(*Result); + return Result; +} |