Add a new -cbe-bug mode, which works just like -run-llc, except that it uses
authorChris Lattner <sabre@nondot.org>
Fri, 15 Sep 2006 21:29:15 +0000 (21:29 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 15 Sep 2006 21:29:15 +0000 (21:29 +0000)
LLC as the reference compiler to reduce testcases for bugs in GCC.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30400 91177308-0d34-0410-b5e6-96231b3b80d8

tools/bugpoint/BugDriver.h
tools/bugpoint/ExecutionDriver.cpp
tools/bugpoint/ToolRunner.cpp
tools/bugpoint/ToolRunner.h

index f719b64fa2cb2f703f5ac21000c69b95dc3636e6..2029e2da029926c6d4dd5bf005be1283433d71c0 100644 (file)
@@ -30,7 +30,6 @@ class Instruction;
 
 class DebugCrashes;
 
-class CBE;
 class GCC;
 
 extern bool DisableSimplifyCFG;
@@ -45,7 +44,7 @@ class BugDriver {
   Module *Program;             // The raw program, linked together
   std::vector<const PassInfo*> PassesToRun;
   AbstractInterpreter *Interpreter;   // How to run the program
-  CBE *cbe;
+  AbstractInterpreter *cbe;
   GCC *gcc;
   bool run_as_child;
   bool run_find_bugs;
index 2f75f6233810c21af22769756ef86f2a9d16e45c..f71d7bace61568bbe14a8ab2ff2340d8b1e527b0 100644 (file)
@@ -28,7 +28,7 @@ namespace {
   // for miscompilation.
   //
   enum OutputType {
-    AutoPick, RunLLI, RunJIT, RunLLC, RunCBE
+    AutoPick, RunLLI, RunJIT, RunLLC, RunCBE, CBE_bug
   };
 
   cl::opt<double>
@@ -46,6 +46,7 @@ namespace {
                             clEnumValN(RunJIT, "run-jit", "Execute with JIT"),
                             clEnumValN(RunLLC, "run-llc", "Compile with LLC"),
                             clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
+                            clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"),
                             clEnumValEnd),
                  cl::init(AutoPick));
 
@@ -133,8 +134,9 @@ bool BugDriver::initializeExecutionEnvironment() {
                                                  &ToolArgv);
     break;
   case RunCBE:
-    Interpreter = cbe = AbstractInterpreter::createCBE(getToolName(), Message,
-                                                       &ToolArgv);
+  case CBE_bug:
+    Interpreter = AbstractInterpreter::createCBE(getToolName(), Message,
+                                                 &ToolArgv);
     break;
   default:
     Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
@@ -143,10 +145,19 @@ bool BugDriver::initializeExecutionEnvironment() {
   std::cerr << Message;
 
   // Initialize auxiliary tools for debugging
-  if (!cbe) {
+  if (InterpreterSel == RunCBE) {
+    // We already created a CBE, reuse it.
+    cbe = Interpreter;
+  } else if (InterpreterSel == CBE_bug) {
+    // We want to debug the CBE itself.  Use LLC as the 'known-good' compiler.
+    std::vector<std::string> ToolArgs;
+    ToolArgs.push_back("--relocation-model=pic");
+    cbe = AbstractInterpreter::createLLC(getToolName(), Message, &ToolArgs);
+  } else {
     cbe = AbstractInterpreter::createCBE(getToolName(), Message, &ToolArgv);
-    if (!cbe) { std::cout << Message << "\nExiting.\n"; exit(1); }
   }
+  if (!cbe) { std::cout << Message << "\nExiting.\n"; exit(1); }
+  
   gcc = GCC::create(getToolName(), Message);
   if (!gcc) { std::cout << Message << "\nExiting.\n"; exit(1); }
 
@@ -237,7 +248,8 @@ std::string BugDriver::executeProgram(std::string OutputFile,
   // compile the program. If so, we should pass the user's -Xlinker options
   // as the GCCArgs.
   int RetVal = 0;
-  if (InterpreterSel == RunLLC || InterpreterSel == RunCBE)
+  if (InterpreterSel == RunLLC || InterpreterSel == RunCBE ||
+      InterpreterSel == CBE_bug)
     RetVal = AI->ExecuteProgram(BytecodeFile, InputArgv, InputFile,
                                 OutputFile, AdditionalLinkerArgs, SharedObjs, 
                                 Timeout);
@@ -271,8 +283,7 @@ std::string BugDriver::executeProgram(std::string OutputFile,
 ///
 std::string BugDriver::executeProgramWithCBE(std::string OutputFile) {
   bool ProgramExitedNonzero;
-  std::string outFN = executeProgram(OutputFile, "", "",
-                                     (AbstractInterpreter*)cbe,
+  std::string outFN = executeProgram(OutputFile, "", "", cbe,
                                      &ProgramExitedNonzero);
   if (ProgramExitedNonzero) {
     std::cerr
@@ -285,28 +296,18 @@ std::string BugDriver::executeProgramWithCBE(std::string OutputFile) {
 
 std::string BugDriver::compileSharedObject(const std::string &BytecodeFile) {
   assert(Interpreter && "Interpreter should have been created already!");
-  sys::Path OutputCFile;
+  sys::Path OutputFile;
 
   // Using CBE
-  cbe->OutputC(BytecodeFile, OutputCFile);
-
-#if 0 /* This is an alternative, as yet unimplemented */
-  // Using LLC
-  std::string Message;
-  LLC *llc = createLLCtool(Message);
-  if (llc->OutputAsm(BytecodeFile, OutputFile)) {
-    std::cerr << "Could not generate asm code with `llc', exiting.\n";
-    exit(1);
-  }
-#endif
+  GCC::FileType FT = cbe->OutputCode(BytecodeFile, OutputFile);
 
   std::string SharedObjectFile;
-  if (gcc->MakeSharedObject(OutputCFile.toString(), GCC::CFile,
+  if (gcc->MakeSharedObject(OutputFile.toString(), FT,
                             SharedObjectFile, AdditionalLinkerArgs))
     exit(1);
 
   // Remove the intermediate C file
-  OutputCFile.eraseFromDisk();
+  OutputFile.eraseFromDisk();
 
   return "./" + SharedObjectFile;
 }
@@ -316,7 +317,7 @@ std::string BugDriver::compileSharedObject(const std::string &BytecodeFile) {
 /// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
 /// this function.
 ///
-bool BugDriver::createReferenceFile(Module *M, const std::string &Filename){
+bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
   try {
     compileProgram(Program);
   } catch (ToolExecutionError &TEE) {
index 589f5158d141449ded00c1c89d915b77e6a84b11..bcade20e5160f1fc2017a3c17d43be2818afaada 100644 (file)
@@ -37,6 +37,13 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
   redirects[0] = &StdInFile;
   redirects[1] = &StdOutFile;
   redirects[2] = &StdErrFile;
+                                   
+{
+  std::cerr << "RUN:";
+  for (unsigned i = 0; Args[i]; ++i)
+    std::cerr << " " << Args[i];
+  std::cerr << "\n";
+}
 
   return
     sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, NumSeconds);
@@ -155,7 +162,8 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath,
 //===----------------------------------------------------------------------===//
 // LLC Implementation of AbstractIntepreter interface
 //
-void LLC::OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile) {
+GCC::FileType LLC::OutputCode(const std::string &Bytecode, 
+                              sys::Path &OutputAsmFile) {
   sys::Path uniqueFile(Bytecode+".llc.s");
   std::string ErrMsg;
   if (uniqueFile.makeUnique(true, &ErrMsg)) {
@@ -185,11 +193,13 @@ void LLC::OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile) {
   if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
                             sys::Path(), sys::Path(), sys::Path()))
     ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
+
+  return GCC::AsmFile;                              
 }
 
 void LLC::compileProgram(const std::string &Bytecode) {
   sys::Path OutputAsmFile;
-  OutputAsm(Bytecode, OutputAsmFile);
+  OutputCode(Bytecode, OutputAsmFile);
   OutputAsmFile.eraseFromDisk();
 }
 
@@ -202,7 +212,7 @@ int LLC::ExecuteProgram(const std::string &Bytecode,
                         unsigned Timeout) {
 
   sys::Path OutputAsmFile;
-  OutputAsm(Bytecode, OutputAsmFile);
+  OutputCode(Bytecode, OutputAsmFile);
   FileRemover OutFileRemover(OutputAsmFile);
 
   std::vector<std::string> GCCArgs(ArgsForGCC);
@@ -313,7 +323,8 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath,
   return 0;
 }
 
-void CBE::OutputC(const std::string &Bytecode, sys::Path& OutputCFile) {
+GCC::FileType CBE::OutputCode(const std::string &Bytecode,
+                              sys::Path &OutputCFile) {
   sys::Path uniqueFile(Bytecode+".cbe.c");
   std::string ErrMsg;
   if (uniqueFile.makeUnique(true, &ErrMsg)) {
@@ -344,11 +355,12 @@ void CBE::OutputC(const std::string &Bytecode, sys::Path& OutputCFile) {
   if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
                             sys::Path()))
     ProcessFailure(LLCPath, &LLCArgs[0]);
+  return GCC::CFile;
 }
 
 void CBE::compileProgram(const std::string &Bytecode) {
   sys::Path OutputCFile;
-  OutputC(Bytecode, OutputCFile);
+  OutputCode(Bytecode, OutputCFile);
   OutputCFile.eraseFromDisk();
 }
 
@@ -360,7 +372,7 @@ int CBE::ExecuteProgram(const std::string &Bytecode,
                         const std::vector<std::string> &SharedLibs,
                         unsigned Timeout) {
   sys::Path OutputCFile;
-  OutputC(Bytecode, OutputCFile);
+  OutputCode(Bytecode, OutputCFile);
 
   FileRemover CFileRemove(OutputCFile);
 
index 62bf6d2c84e493bb06e3e442deedfe8d144dbd59..e64d0054f0a71c2796bf43dd694786a935cafdc0 100644 (file)
@@ -104,6 +104,15 @@ public:
   /// thrown, otherwise, this function will just return.
   virtual void compileProgram(const std::string &Bytecode) {}
 
+  /// OutputCode - Compile the specified program from bytecode to code
+  /// understood by the GCC driver (either C or asm).  If the code generator
+  /// fails, an exception should be thrown, otherwise, this function returns the
+  /// type of code emitted.
+  virtual GCC::FileType OutputCode(const std::string &Bytecode,
+                                   sys::Path &OutFile) {
+    throw std::string("OutputCode not supported by this AbstractInterpreter!");
+  }
+  
   /// ExecuteProgram - Run the specified bytecode file, emitting output to the
   /// specified filename.  This returns the exit code of the program.
   ///
@@ -149,11 +158,12 @@ public:
                                std::vector<std::string>(),
                              unsigned Timeout = 0);
 
-  // Sometimes we just want to go half-way and only generate the .c file, not
-  // necessarily compile it with GCC and run the program.  This throws an
-  // exception if LLC crashes.
-  //
-  virtual void OutputC(const std::string &Bytecode, sys::Path& OutputCFile);
+  /// OutputCode - Compile the specified program from bytecode to code
+  /// understood by the GCC driver (either C or asm).  If the code generator
+  /// fails, an exception should be thrown, otherwise, this function returns the
+  /// type of code emitted.
+  virtual GCC::FileType OutputCode(const std::string &Bytecode,
+                                   sys::Path &OutFile);
 };
 
 
@@ -188,11 +198,9 @@ public:
                                 std::vector<std::string>(),
                              unsigned Timeout = 0);
 
-  // Sometimes we just want to go half-way and only generate the .s file,
-  // not necessarily compile it all the way and run the program.  This throws
-  // an exception if execution of LLC fails.
-  //
-  void OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile);
+  virtual GCC::FileType OutputCode(const std::string &Bytecode,
+                                   sys::Path &OutFile);
+  
 };
 
 } // End llvm namespace