BugDriver.h revision a0f5b15e1eb8642d92b3141a6b88a5729ea979dc
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
3047ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattnerextern bool DisableSimplifyCFG;
3147ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner
32afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass BugDriver {
33afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  const std::string ToolName;  // Name of bugpoint
34a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  std::string ReferenceOutputFile; // Name of `good' output file
35afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  Module *Program;             // The raw program, linked together
36afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  std::vector<const PassInfo*> PassesToRun;
37218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  AbstractInterpreter *Interpreter;   // How to run the program
38a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  CBE *cbe;
39a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  GCC *gcc;
40640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner
41aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // FIXME: sort out public/private distinctions...
42aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  friend class DebugCrashes;
43640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner  friend class ReduceMiscompilingPasses;
44640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner  friend class ReduceMiscompilingFunctions;
455073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  friend class ReduceMisCodegenFunctions;
46aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  friend class ReduceCrashingFunctions;
47286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  friend class ReduceCrashingBlocks;
485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
49afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerpublic:
505073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  BugDriver(const char *toolname);
51218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
52218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  const std::string &getToolName() const { return ToolName; }
53afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
54afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  // Set up methods... these methods are used to copy information about the
55afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  // command line arguments into instance variables of BugDriver.
56afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  //
57afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool addSources(const std::vector<std::string> &FileNames);
58afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  template<class It>
59afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  void addPasses(It I, It E) { PassesToRun.insert(PassesToRun.end(), I, E); }
60afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
61afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// run - The top level method that is invoked after all of the instance
62afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// variables are set up from command line arguments.
63afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
64afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool run();
65afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
66afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// debugCrash - This method is called when some pass crashes on input.  It
67afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// attempts to prune down the testcase to something reasonable, and figure
68afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// out exactly which pass is crashing.
69afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
70afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool debugCrash();
71afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
72afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// debugMiscompilation - This method is used when the passes selected are not
73afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// crashing, but the generated output is semantically different from the
74afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// input.
75afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool debugMiscompilation();
76afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
77218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// debugPassMiscompilation - This method is called when the specified pass
78218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// miscompiles Program as input.  It tries to reduce the testcase to
79218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// something that smaller that still miscompiles the program.
80218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// ReferenceOutput contains the filename of the file containing the output we
81218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// are to match.
82218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  ///
83218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  bool debugPassMiscompilation(const PassInfo *ThePass,
84218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner			       const std::string &ReferenceOutput);
85218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// compileSharedObject - This method creates a SharedObject from a given
875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// BytecodeFile for debugging a code generator.
88a0f5b15e1eb8642d92b3141a6b88a5729ea979dcChris Lattner  ///
89a0f5b15e1eb8642d92b3141a6b88a5729ea979dcChris Lattner  std::string compileSharedObject(const std::string &BytecodeFile);
905073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
915073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// debugCodeGenerator - This method narrows down a module to a function or
925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// set of functions, using the CBE as a ``safe'' code generator for other
935073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// functions that are not under consideration.
945073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  bool debugCodeGenerator();
955073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
96fe04db890b87d9ac4c4a607e6bd0035e8cc2ad6cMisha Brukman  /// isExecutingJIT - Returns true if bugpoint is currently testing the JIT
97fe04db890b87d9ac4c4a607e6bd0035e8cc2ad6cMisha Brukman  ///
9891eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman  bool isExecutingJIT();
9991eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman
100afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerprivate:
101afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// ParseInputFile - Given a bytecode or assembly input filename, parse and
102afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// return it, or return null if not possible.
103afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
104afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  Module *ParseInputFile(const std::string &InputFilename) const;
105afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
106afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// writeProgramToFile - This writes the current "Program" to the named
107afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// bytecode file.  If an error occurs, true is returned.
108afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
109218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  bool writeProgramToFile(const std::string &Filename, Module *M = 0) const;
110afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
111afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
112afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// EmitProgressBytecode - This function is used to output the current Program
113afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// to a file named "bugpoing-ID.bc".
114afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
115640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner  void EmitProgressBytecode(const std::string &ID, bool NoFlyer = false);
116afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
117afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// runPasses - Run the specified passes on Program, outputting a bytecode
118afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// file and writting the filename into OutputFile if successful.  If the
119afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// optimizations fail for some reason (optimizer crashes), return true,
120afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// otherwise return false.  If DeleteOutput is set to true, the bytecode is
121afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// deleted on success, and the filename string is undefined.  This prints to
122afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// cout a single line message indicating whether compilation was successful
123218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// or failed, unless Quiet is set.
124afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
125afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
126218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner                 std::string &OutputFilename, bool DeleteOutput = false,
127218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner		 bool Quiet = false) const;
128afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
129afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// runPasses - Just like the method above, but this just returns true or
130afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// false indicating whether or not the optimizer crashed on the specified
131afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  /// input (true = crashed).
132afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  ///
133afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
134afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner                 bool DeleteOutput = true) const {
135afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner    std::string Filename;
136afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner    return runPasses(PassesToRun, Filename, DeleteOutput);
137afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner  }
138afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
1395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// PrintFunctionList - prints out list of problematic functions
140a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman  ///
1415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  static void PrintFunctionList(const std::vector<Function*> &Funcs);
1425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
1436520785dcd22012535934098942d57c07c7631c2Chris Lattner  /// deleteInstructionFromProgram - This method clones the current Program and
1446520785dcd22012535934098942d57c07c7631c2Chris Lattner  /// deletes the specified instruction from the cloned module.  It then runs a
1456520785dcd22012535934098942d57c07c7631c2Chris Lattner  /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code
1466520785dcd22012535934098942d57c07c7631c2Chris Lattner  /// which depends on the value.  The modified module is then returned.
1476520785dcd22012535934098942d57c07c7631c2Chris Lattner  ///
1486520785dcd22012535934098942d57c07c7631c2Chris Lattner  Module *deleteInstructionFromProgram(Instruction *I, unsigned Simp) const;
1496520785dcd22012535934098942d57c07c7631c2Chris Lattner
150ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  /// performFinalCleanups - This method clones the current Program and performs
151ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  /// a series of cleanups intended to get rid of extra cruft on the module
152587a6ce4b99346b5e785d0a5c360c6c6687b036aChris Lattner  /// before handing it to the user... if the module parameter is specified, it
153587a6ce4b99346b5e785d0a5c360c6c6687b036aChris Lattner  /// operates directly on the specified Module, modifying it in place.
154ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  ///
155587a6ce4b99346b5e785d0a5c360c6c6687b036aChris Lattner  Module *performFinalCleanups(Module *M = 0) const;
156ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner
157218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// initializeExecutionEnvironment - This method is used to set up the
158218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// environment for executing LLVM programs.
159218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  ///
160218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  bool initializeExecutionEnvironment();
161218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
162218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// executeProgram - This method runs "Program", capturing the output of the
163218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// program to a file, returning the filename of the file.  A recommended
164218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// filename may be optionally specified.
165218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  ///
166218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  std::string executeProgram(std::string RequestedOutputFilename = "",
1675073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                             std::string Bytecode = "",
1685073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                             std::string SharedObject = "",
1695073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                             AbstractInterpreter *AI = 0);
1705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
1715073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// executeProgramWithCBE - Used to create reference output with the C
1725073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  /// backend, if reference output is not provided.
1735073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  std::string executeProgramWithCBE(std::string RequestedOutputFilename = "",
1745073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                                    std::string Bytecode = "",
1755073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                                    std::string SharedObject = "");
176218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
177218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// diffProgram - This method executes the specified module and diffs the
178218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// output against the file specified by ReferenceOutputFile.  If the output
179218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  /// is different, true is returned.
180218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  ///
1815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman  bool diffProgram(const std::string &BytecodeFile = "",
1825073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman                   const std::string &SharedObject = "",
183640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner                   bool RemoveBytecode = false);
184afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner};
185afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
186640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// getPassesString - Turn a list of passes into a string which indicates the
187640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// command line options that must be passed to add the passes.
188640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner///
189640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattnerstd::string getPassesString(const std::vector<const PassInfo*> &Passes);
190640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner
191aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// DeleteFunctionBody - "Remove" the function by deleting all of it's basic
192aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// blocks, making it external.
193aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner//
194aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattnervoid DeleteFunctionBody(Function *F);
195aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
196afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#endif
197