blob: c99c8f32b5ff316220d3bf4e9f4169bcfbbff6af [file] [log] [blame]
Chris Lattnerafade922002-11-20 22:28:10 +00001//===- 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"
Chris Lattner65207852003-01-23 02:48:33 +000012#include "llvm/Transforms/Scalar.h"
Chris Lattnerafade922002-11-20 22:28:10 +000013#include "llvm/Transforms/Utils/Cloning.h"
Chris Lattner65207852003-01-23 02:48:33 +000014#include "llvm/Type.h"
15#include "llvm/Constant.h"
Chris Lattnerafade922002-11-20 22:28:10 +000016
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.
21Module *BugDriver::extractFunctionFromModule(Function *F) const {
22 Module *Result = CloneModule(Program);
23
24 // Translate from the old module to the new copied module...
Chris Lattner65207852003-01-23 02:48:33 +000025 Module::iterator RFI = Result->begin(); // Get iterator to corresponding fn
26 std::advance(RFI, std::distance(Program->begin(), Module::iterator(F)));
Chris Lattnerafade922002-11-20 22:28:10 +000027
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;
Chris Lattner65207852003-01-23 02:48:33 +000032 Passes.add(createFunctionExtractionPass(RFI)); // Extract the function
Chris Lattnerafade922002-11-20 22:28:10 +000033 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}
Chris Lattner65207852003-01-23 02:48:33 +000039
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///
46Module *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}
Chris Lattnerba386d92003-02-28 16:13:20 +000084
85/// performFinalCleanups - This method clones the current Program and performs
86/// a series of cleanups intended to get rid of extra cruft on the module
87/// before handing it to the user...
88///
89Module *BugDriver::performFinalCleanups() const {
90 PassManager CleanupPasses;
91 CleanupPasses.add(createFunctionResolvingPass());
92 CleanupPasses.add(createGlobalDCEPass());
93 Module *M = CloneModule(Program);
94 CleanupPasses.run(*M);
95 return M;
96}