BugDriver.h revision 91eabc13d3a456cc4b387d3d7fdb041d976732c7
1afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===//
2afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//
3afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This class contains all of the shared state and information that is used by
4afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// the BugPoint tool to track down errors in optimizations.  This class is the
5afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// main driver class that invokes all sub-functionality.
6afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//
7afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===----------------------------------------------------------------------===//
8afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
9afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#ifndef BUGDRIVER_H
10afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#define BUGDRIVER_H
11afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
12afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <vector>
13afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <string>
145073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
15afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass PassInfo;
16afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass Module;
17afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass Function;
18218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattnerclass AbstractInterpreter;
196520785dcd22012535934098942d57c07c7631c2Chris Lattnerclass Instruction;
20afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
21aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattnerclass DebugCrashes;
22640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattnerclass ReduceMiscompilingPasses;
23640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattnerclass ReduceMiscompilingFunctions;
24aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattnerclass ReduceCrashingFunctions;
25286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattnerclass ReduceCrashingBlocks;
26640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner
27a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukmanclass CBE;
28a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukmanclass GCC;
29a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman
30afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass BugDriver {
31afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  const std::string ToolName;  // Name of bugpoint
32a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  std::string ReferenceOutputFile; // Name of `good' output file
33afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  Module *Program;             // The raw program, linked together
34afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  std::vector<const PassInfo*> PassesToRun;
35218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  AbstractInterpreter *Interpreter;   // How to run the program
36a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  CBE *cbe;
37a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  GCC *gcc;
38640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner
39aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // FIXME: sort out public/private distinctions...
40aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  friend class DebugCrashes;
41640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner  friend class ReduceMiscompilingPasses;
42640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner  friend class ReduceMiscompilingFunctions;
435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  friend class ReduceMisCodegenFunctions;
44aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  friend class ReduceCrashingFunctions;
45286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  friend class ReduceCrashingBlocks;
465073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
47afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerpublic:
485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  BugDriver(const char *toolname);
49218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
50218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  const std::string &getToolName() const { return ToolName; }
51afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
52afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  // Set up methods... these methods are used to copy information about the
53afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  // command line arguments into instance variables of BugDriver.
54afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  //
55afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool addSources(const std::vector<std::string> &FileNames);
56afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  template<class It>
57afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  void addPasses(It I, It E) { PassesToRun.insert(PassesToRun.end(), I, E); }
58afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
59afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// run - The top level method that is invoked after all of the instance
60afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// variables are set up from command line arguments.
61afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
62afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool run();
63afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
64afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// debugCrash - This method is called when some pass crashes on input.  It
65afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// attempts to prune down the testcase to something reasonable, and figure
66afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// out exactly which pass is crashing.
67afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
68afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool debugCrash();
69afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
70afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// debugMiscompilation - This method is used when the passes selected are not
71afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// crashing, but the generated output is semantically different from the
72afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// input.
73afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool debugMiscompilation();
74afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
75218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// debugPassMiscompilation - This method is called when the specified pass
76218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// miscompiles Program as input.  It tries to reduce the testcase to
77218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// something that smaller that still miscompiles the program.
78218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// ReferenceOutput contains the filename of the file containing the output we
79218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// are to match.
80218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  ///
81218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  bool debugPassMiscompilation(const PassInfo *ThePass,
82218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner			       const std::string &ReferenceOutput);
83218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
845073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// compileSharedObject - This method creates a SharedObject from a given
855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// BytecodeFile for debugging a code generator.
865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  int compileSharedObject(const std::string &BytecodeFile,
875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                          std::string &SharedObject);
885073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
895073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// debugCodeGenerator - This method narrows down a module to a function or
905073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// set of functions, using the CBE as a ``safe'' code generator for other
915073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// functions that are not under consideration.
925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  bool debugCodeGenerator();
935073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
9491eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman  bool isExecutingJIT();
9591eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman
96afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerprivate:
97afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// ParseInputFile - Given a bytecode or assembly input filename, parse and
98afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// return it, or return null if not possible.
99afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
100afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  Module *ParseInputFile(const std::string &InputFilename) const;
101afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
102afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// writeProgramToFile - This writes the current "Program" to the named
103afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// bytecode file.  If an error occurs, true is returned.
104afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
105218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  bool writeProgramToFile(const std::string &Filename, Module *M = 0) const;
106afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
107afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
108afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// EmitProgressBytecode - This function is used to output the current Program
109afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// to a file named "bugpoing-ID.bc".
110afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
111640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner  void EmitProgressBytecode(const std::string &ID, bool NoFlyer = false);
112afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
113afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// runPasses - Run the specified passes on Program, outputting a bytecode
114afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// file and writting the filename into OutputFile if successful.  If the
115afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// optimizations fail for some reason (optimizer crashes), return true,
116afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// otherwise return false.  If DeleteOutput is set to true, the bytecode is
117afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// deleted on success, and the filename string is undefined.  This prints to
118afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// cout a single line message indicating whether compilation was successful
119218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// or failed, unless Quiet is set.
120afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
121afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
122218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner                 std::string &OutputFilename, bool DeleteOutput = false,
123218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner		 bool Quiet = false) const;
124afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
125afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// runPasses - Just like the method above, but this just returns true or
126afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// false indicating whether or not the optimizer crashed on the specified
127afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// input (true = crashed).
128afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
129afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
130afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner                 bool DeleteOutput = true) const {
131afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner    std::string Filename;
132afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner    return runPasses(PassesToRun, Filename, DeleteOutput);
133afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  }
134afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
1355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// PrintFunctionList - prints out list of problematic functions
136a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  ///
1375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  static void PrintFunctionList(const std::vector<Function*> &Funcs);
1385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
1396520785dcd22012535934098942d57c07c7631c2Chris Lattner  /// deleteInstructionFromProgram - This method clones the current Program and
1406520785dcd22012535934098942d57c07c7631c2Chris Lattner  /// deletes the specified instruction from the cloned module.  It then runs a
1416520785dcd22012535934098942d57c07c7631c2Chris Lattner  /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code
1426520785dcd22012535934098942d57c07c7631c2Chris Lattner  /// which depends on the value.  The modified module is then returned.
1436520785dcd22012535934098942d57c07c7631c2Chris Lattner  ///
1446520785dcd22012535934098942d57c07c7631c2Chris Lattner  Module *deleteInstructionFromProgram(Instruction *I, unsigned Simp) const;
1456520785dcd22012535934098942d57c07c7631c2Chris Lattner
146ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  /// performFinalCleanups - This method clones the current Program and performs
147ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  /// a series of cleanups intended to get rid of extra cruft on the module
148ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  /// before handing it to the user...
149ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  ///
150ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  Module *performFinalCleanups() const;
151ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner
152218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// initializeExecutionEnvironment - This method is used to set up the
153218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// environment for executing LLVM programs.
154218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  ///
155218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  bool initializeExecutionEnvironment();
156218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
157218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// executeProgram - This method runs "Program", capturing the output of the
158218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// program to a file, returning the filename of the file.  A recommended
159218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// filename may be optionally specified.
160218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  ///
161218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  std::string executeProgram(std::string RequestedOutputFilename = "",
1625073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                             std::string Bytecode = "",
1635073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                             std::string SharedObject = "",
1645073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                             AbstractInterpreter *AI = 0);
1655073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
1665073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// executeProgramWithCBE - Used to create reference output with the C
1675073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// backend, if reference output is not provided.
1685073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  std::string executeProgramWithCBE(std::string RequestedOutputFilename = "",
1695073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                                    std::string Bytecode = "",
1705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                                    std::string SharedObject = "");
171218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
172218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// diffProgram - This method executes the specified module and diffs the
173218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// output against the file specified by ReferenceOutputFile.  If the output
174218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// is different, true is returned.
175218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  ///
1765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  bool diffProgram(const std::string &BytecodeFile = "",
1775073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                   const std::string &SharedObject = "",
178640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner                   bool RemoveBytecode = false);
179afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner};
180afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
181640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// getPassesString - Turn a list of passes into a string which indicates the
182640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// command line options that must be passed to add the passes.
183640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner///
184640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattnerstd::string getPassesString(const std::vector<const PassInfo*> &Passes);
185640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner
186aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// DeleteFunctionBody - "Remove" the function by deleting all of it's basic
187aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// blocks, making it external.
188aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner//
189aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattnervoid DeleteFunctionBody(Function *F);
190aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
191afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#endif
192