Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be
loaded by the other two code generators.

LLC debugging should be functional now, LLI needs a few more additions to work,
the major one is renaming of external functions to call the JIT lazy function
resolver.

Bugpoint now has a command-line switch -mode with options 'compile' and
'codegen' to debug appropriate portions of tools.

ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and
GCC, broke out common code within other tools, and added ability to generate C
code with CBE individually, without executing the program, and the GCC tool can
generate executables shared objects or executables.

If no reference output is specified to Bugpoint, it will be generated with CBE,
because it is already assumed to be correct for the purposes of debugging using
this method. As a result, many functions now accept as an optional parameter a
shared object to be loaded in, if specified.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7293 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/bugpoint/BugDriver.h b/tools/bugpoint/BugDriver.h
index 05d4108..0c461d1 100644
--- a/tools/bugpoint/BugDriver.h
+++ b/tools/bugpoint/BugDriver.h
@@ -9,8 +9,10 @@
 #ifndef BUGDRIVER_H
 #define BUGDRIVER_H
 
+#include "Support/CommandLine.h"
 #include <vector>
 #include <string>
+
 class PassInfo;
 class Module;
 class Function;
@@ -25,6 +27,7 @@
 
 class BugDriver {
   const std::string ToolName;  // Name of bugpoint
+  cl::opt<std::string> ReferenceOutputFile; // Name of `good' output file
   Module *Program;             // The raw program, linked together
   std::vector<const PassInfo*> PassesToRun;
   AbstractInterpreter *Interpreter;   // How to run the program
@@ -33,11 +36,12 @@
   friend class DebugCrashes;
   friend class ReduceMiscompilingPasses;
   friend class ReduceMiscompilingFunctions;
+  friend class ReduceMisCodegenFunctions;
   friend class ReduceCrashingFunctions;
   friend class ReduceCrashingBlocks;
+
 public:
-  BugDriver(const char *toolname)
-    : ToolName(toolname), Program(0), Interpreter(0) {}
+  BugDriver(const char *toolname);
 
   const std::string &getToolName() const { return ToolName; }
 
@@ -73,6 +77,17 @@
   bool debugPassMiscompilation(const PassInfo *ThePass,
 			       const std::string &ReferenceOutput);
 
+
+  /// compileSharedObject - This method creates a SharedObject from a given
+  /// BytecodeFile for debugging a code generator.
+  int compileSharedObject(const std::string &BytecodeFile,
+                          std::string &SharedObject);
+
+  /// debugCodeGenerator - This method narrows down a module to a function or
+  /// set of functions, using the CBE as a ``safe'' code generator for other
+  /// functions that are not under consideration.
+  bool debugCodeGenerator();
+
 private:
   /// ParseInputFile - Given a bytecode or assembly input filename, parse and
   /// return it, or return null if not possible.
@@ -112,6 +127,9 @@
     return runPasses(PassesToRun, Filename, DeleteOutput);
   }
 
+  /// PrintFunctionList - prints out list of problematic functions
+  static void PrintFunctionList(const std::vector<Function*> &Funcs);
+
   /// 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
@@ -135,14 +153,22 @@
   /// filename may be optionally specified.
   ///
   std::string executeProgram(std::string RequestedOutputFilename = "",
-			     std::string Bytecode = "");
+                             std::string Bytecode = "",
+                             std::string SharedObject = "",
+                             AbstractInterpreter *AI = 0);
+
+  /// executeProgramWithCBE - Used to create reference output with the C
+  /// backend, if reference output is not provided.
+  std::string executeProgramWithCBE(std::string RequestedOutputFilename = "",
+                                    std::string Bytecode = "",
+                                    std::string SharedObject = "");
 
   /// diffProgram - This method executes the specified module and diffs the
   /// output against the file specified by ReferenceOutputFile.  If the output
   /// is different, true is returned.
   ///
-  bool diffProgram(const std::string &ReferenceOutputFile,
-		   const std::string &BytecodeFile = "",
+  bool diffProgram(const std::string &BytecodeFile = "",
+                   const std::string &SharedObject = "",
                    bool RemoveBytecode = false);
 };