ExtractFunction.cpp revision 7c0e022c5c4be4b11e199a53f73bbdd84e34aa80
1//===- ExtractFunction.cpp - Extract a function from Program --------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// 11// This file implements a method that extracts a function from program, cleans 12// it up, and returns it as a new module. 13// 14//===----------------------------------------------------------------------===// 15 16#include "BugDriver.h" 17#include "llvm/Constant.h" 18#include "llvm/Module.h" 19#include "llvm/PassManager.h" 20#include "llvm/Pass.h" 21#include "llvm/Type.h" 22#include "llvm/Analysis/Verifier.h" 23#include "llvm/Transforms/IPO.h" 24#include "llvm/Transforms/Scalar.h" 25#include "llvm/Transforms/Utils/Cloning.h" 26#include "Support/CommandLine.h" 27 28bool DisableSimplifyCFG = false; 29 30namespace { 31 cl::opt<bool> 32 NoADCE("disable-adce", 33 cl::desc("Do not use the -adce pass to reduce testcases")); 34 cl::opt<bool> 35 NoDCE ("disable-dce", 36 cl::desc("Do not use the -dce pass to reduce testcases")); 37 cl::opt<bool, true> 38 NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG), 39 cl::desc("Do not use the -simplifycfg pass to reduce testcases")); 40 cl::opt<bool> 41 NoFinalCleanup("disable-final-cleanup", 42 cl::desc("Disable the final cleanup phase of narrowing")); 43} 44 45/// deleteInstructionFromProgram - This method clones the current Program and 46/// deletes the specified instruction from the cloned module. It then runs a 47/// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code which 48/// depends on the value. The modified module is then returned. 49/// 50Module *BugDriver::deleteInstructionFromProgram(Instruction *I, 51 unsigned Simplification) const { 52 Module *Result = CloneModule(Program); 53 54 BasicBlock *PBB = I->getParent(); 55 Function *PF = PBB->getParent(); 56 57 Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn 58 std::advance(RFI, std::distance(Program->begin(), Module::iterator(PF))); 59 60 Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB 61 std::advance(RBI, std::distance(PF->begin(), Function::iterator(PBB))); 62 63 BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst 64 std::advance(RI, std::distance(PBB->begin(), BasicBlock::iterator(I))); 65 I = RI; // Got the corresponding instruction! 66 67 // If this instruction produces a value, replace any users with null values 68 if (I->getType() != Type::VoidTy) 69 I->replaceAllUsesWith(Constant::getNullValue(I->getType())); 70 71 // Remove the instruction from the program. 72 I->getParent()->getInstList().erase(I); 73 74 // Spiff up the output a little bit. 75 PassManager Passes; 76 if (Simplification > 2 && !NoADCE) 77 Passes.add(createAggressiveDCEPass()); // Remove dead code... 78 //Passes.add(createInstructionCombiningPass()); 79 if (Simplification > 1 && !NoDCE) 80 Passes.add(createDeadCodeEliminationPass()); 81 if (Simplification && !DisableSimplifyCFG) 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(Module *InM) const { 94 Module *M = InM ? InM : CloneModule(Program); 95 96 // Allow disabling these passes if they crash bugpoint. 97 // 98 // FIXME: This should eventually run these passes in a pass list to prevent 99 // them from being able to crash bugpoint at all! 100 // 101 if (NoFinalCleanup) return M; 102 103 // Make all functions external, so GlobalDCE doesn't delete them... 104 for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) 105 I->setLinkage(GlobalValue::ExternalLinkage); 106 107 PassManager CleanupPasses; 108 CleanupPasses.add(createFunctionResolvingPass()); 109 CleanupPasses.add(createGlobalDCEPass()); 110 CleanupPasses.add(createDeadTypeEliminationPass()); 111 CleanupPasses.add(createDeadArgEliminationPass(InM == 0)); 112 CleanupPasses.add(createVerifierPass()); 113 CleanupPasses.run(*M); 114 return M; 115} 116