[llvm-commits] CVS: llvm/tools/bugpoint/BugDriver.cpp BugDriver.h CrashDebugger.cpp Makefile OptimizerDriver.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Dec 23 17:51:01 PST 2002


Changes in directory llvm/tools/bugpoint:

BugDriver.cpp updated: 1.1 -> 1.2
BugDriver.h updated: 1.1 -> 1.2
CrashDebugger.cpp updated: 1.1 -> 1.2
Makefile updated: 1.1 -> 1.2
OptimizerDriver.cpp updated: 1.1 -> 1.2

---
Log message:

Implement the start of the miscompilation detection stuff


---
Diffs of the changes:

Index: llvm/tools/bugpoint/BugDriver.cpp
diff -u llvm/tools/bugpoint/BugDriver.cpp:1.1 llvm/tools/bugpoint/BugDriver.cpp:1.2
--- llvm/tools/bugpoint/BugDriver.cpp:1.1	Wed Nov 20 16:28:10 2002
+++ llvm/tools/bugpoint/BugDriver.cpp	Mon Dec 23 17:49:59 2002
@@ -82,19 +82,3 @@
   else
     return debugMiscompilation();
 }
-
-
-/// debugMiscompilation - This method is used when the passes selected are not
-/// crashing, but the generated output is semantically different from the
-/// input.
-///
-bool BugDriver::debugMiscompilation() {
-  std::cout << "*** Debugging miscompilation!\n";
-  std::cerr << "Sorry, bugpoint cannot debug a miscompilation yet!\n";
-
-  // If no reference output was specified, run the program without optimizations
-  // to get a reference output.
-  //
-
-  return true;
-}


Index: llvm/tools/bugpoint/BugDriver.h
diff -u llvm/tools/bugpoint/BugDriver.h:1.1 llvm/tools/bugpoint/BugDriver.h:1.2
--- llvm/tools/bugpoint/BugDriver.h:1.1	Wed Nov 20 16:28:10 2002
+++ llvm/tools/bugpoint/BugDriver.h	Mon Dec 23 17:49:59 2002
@@ -14,13 +14,18 @@
 class PassInfo;
 class Module;
 class Function;
+class AbstractInterpreter;
 
 class BugDriver {
   const std::string ToolName;  // Name of bugpoint
   Module *Program;             // The raw program, linked together
   std::vector<const PassInfo*> PassesToRun;
+  AbstractInterpreter *Interpreter;   // How to run the program
 public:
-  BugDriver(const char *toolname) : ToolName(toolname), Program(0) {}
+  BugDriver(const char *toolname)
+    : ToolName(toolname), Program(0), Interpreter(0) {}
+
+  const std::string &getToolName() const { return ToolName; }
 
   // Set up methods... these methods are used to copy information about the
   // command line arguments into instance variables of BugDriver.
@@ -51,20 +56,25 @@
   /// input.
   bool debugMiscompilation();
 
+  /// debugPassMiscompilation - This method is called when the specified pass
+  /// miscompiles Program as input.  It tries to reduce the testcase to
+  /// something that smaller that still miscompiles the program.
+  /// ReferenceOutput contains the filename of the file containing the output we
+  /// are to match.
+  ///
+  bool debugPassMiscompilation(const PassInfo *ThePass,
+			       const std::string &ReferenceOutput);
+
 private:
   /// ParseInputFile - Given a bytecode or assembly input filename, parse and
   /// return it, or return null if not possible.
   ///
   Module *ParseInputFile(const std::string &InputFilename) const;
 
-  /// removeFile - Delete the specified file
-  ///
-  void removeFile(const std::string &Filename) const;
-
   /// writeProgramToFile - This writes the current "Program" to the named
   /// bytecode file.  If an error occurs, true is returned.
   ///
-  bool writeProgramToFile(const std::string &Filename) const;
+  bool writeProgramToFile(const std::string &Filename, Module *M = 0) const;
 
 
   /// EmitProgressBytecode - This function is used to output the current Program
@@ -78,10 +88,11 @@
   /// otherwise return false.  If DeleteOutput is set to true, the bytecode is
   /// deleted on success, and the filename string is undefined.  This prints to
   /// cout a single line message indicating whether compilation was successful
-  /// or failed.
+  /// or failed, unless Quiet is set.
   ///
   bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
-                 std::string &OutputFilename, bool DeleteOutput = false) const;
+                 std::string &OutputFilename, bool DeleteOutput = false,
+		 bool Quiet = false) const;
 
   /// runPasses - Just like the method above, but this just returns true or
   /// false indicating whether or not the optimizer crashed on the specified
@@ -94,6 +105,7 @@
   }
 
   /// runPass - Run only the specified pass on the program.
+  ///
   bool runPass(const PassInfo *P, bool DeleteOutput = true) const {
     return runPasses(std::vector<const PassInfo*>(1, P), DeleteOutput);
   }
@@ -102,8 +114,27 @@
   /// (non-external) function from the current program, slim down the module,
   /// and then return it.  This does not modify Program at all, it modifies a
   /// copy, which it returns.
+  ///
   Module *extractFunctionFromModule(Function *F) const;
 
+  /// initializeExecutionEnvironment - This method is used to set up the
+  /// environment for executing LLVM programs.
+  ///
+  bool initializeExecutionEnvironment();
+
+  /// executeProgram - This method runs "Program", capturing the output of the
+  /// program to a file, returning the filename of the file.  A recommended
+  /// filename may be optionally specified.
+  ///
+  std::string executeProgram(std::string RequestedOutputFilename = "",
+			     std::string Bytecode = "");
+
+  /// 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 = "");
 };
 
 #endif


Index: llvm/tools/bugpoint/CrashDebugger.cpp
diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.1 llvm/tools/bugpoint/CrashDebugger.cpp:1.2
--- llvm/tools/bugpoint/CrashDebugger.cpp:1.1	Wed Nov 20 16:28:10 2002
+++ llvm/tools/bugpoint/CrashDebugger.cpp	Mon Dec 23 17:49:59 2002
@@ -5,6 +5,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "BugDriver.h"
+#include "SystemUtils.h"
 #include "llvm/Module.h"
 #include "llvm/Bytecode/Writer.h"
 #include "llvm/Pass.h"
@@ -44,8 +45,7 @@
             << "': " << CrashingPass->getPassName() << "\n";
 
   // Compile the program with just the passes that don't crash.
-  if (LastToPass != 0) {
-    // Don't bother doing this if the first pass crashes...
+  if (LastToPass != 0) { // Don't bother doing this if the first pass crashes...
     std::vector<const PassInfo*> P(PassesToRun.begin(), 
                                    PassesToRun.begin()+LastToPass);
     std::string Filename;
@@ -87,7 +87,7 @@
 
   if (CountFunctions(Program) > 1) {
     // Attempt to reduce the input program down to a single function that still
-    // crashes.
+    // crashes.  Do this by removing everything except for that one function...
     //
     std::cout << "\n*** Attempting to reduce the testcase to one function\n";
 
@@ -116,5 +116,16 @@
       }
   }
 
+  if (CountFunctions(Program) > 1) {
+    std::cout << "\n*** Couldn't reduce testcase to one function.\n"
+	      << "    Attempting to remove individual functions.\n";
+    std::cout << "XXX Individual function removal unimplemented!\n";
+  }
+
+  // Now that we have deleted the functions that are unneccesary for the
+  // program, try to remove instructions and basic blocks that are not neccesary
+  // to cause the crash.
+  //
+  
   return false;
 }


Index: llvm/tools/bugpoint/Makefile
diff -u llvm/tools/bugpoint/Makefile:1.1 llvm/tools/bugpoint/Makefile:1.2
--- llvm/tools/bugpoint/Makefile:1.1	Wed Nov 20 16:28:10 2002
+++ llvm/tools/bugpoint/Makefile	Mon Dec 23 17:49:59 2002
@@ -2,10 +2,10 @@
 
 TOOLNAME = bugpoint
 
-OPTLIBS  = instrument profpaths scalaropts ipo
-ANALIBS  = datastructure ipa target.a analysis
+#OPTLIBS  = instrument profpaths 
+ANALIBS  = datastructure ipa target.a 
 
-USEDLIBS = ipo scalaropts $(ANALIBS) \
+USEDLIBS = ipo scalaropts analysis $(OPTLIBS) $(ANALIBS) \
            transformutils asmparser bcreader bcwriter vmcore support
 
 TOOLLINKOPTS = -ldl


Index: llvm/tools/bugpoint/OptimizerDriver.cpp
diff -u llvm/tools/bugpoint/OptimizerDriver.cpp:1.1 llvm/tools/bugpoint/OptimizerDriver.cpp:1.2
--- llvm/tools/bugpoint/OptimizerDriver.cpp:1.1	Wed Nov 20 16:28:10 2002
+++ llvm/tools/bugpoint/OptimizerDriver.cpp	Mon Dec 23 17:49:59 2002
@@ -9,6 +9,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "BugDriver.h"
+#include "SystemUtils.h"
 #include "llvm/PassManager.h"
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Bytecode/WriteBytecodePass.h"
@@ -18,20 +19,14 @@
 #include <stdlib.h>
 #include <fstream>
 
-/// removeFile - Delete the specified file
-///
-void BugDriver::removeFile(const std::string &Filename) const {
-  unlink(Filename.c_str());
-}
-
 /// writeProgramToFile - This writes the current "Program" to the named bytecode
 /// file.  If an error occurs, true is returned.
 ///
-bool BugDriver::writeProgramToFile(const std::string &Filename) const {
+bool BugDriver::writeProgramToFile(const std::string &Filename,
+				   Module *M) const {
   std::ofstream Out(Filename.c_str());
   if (!Out.good()) return true;
-
-  WriteBytecodeToFile(Program, Out);
+  WriteBytecodeToFile(M ? M : Program, Out);
   return false;
 }
 
@@ -50,7 +45,7 @@
     return;
   }
 
-  std::cout << "Emitted bytecode to 'bugpoint-" << Filename << ".bc'\n";
+  std::cout << "Emitted bytecode to '" << Filename << "'\n";
   std::cout << "\n*** You can reproduce the problem with: ";
 
   unsigned PassType = Pass->getPassType();
@@ -101,23 +96,11 @@
 /// failed.
 ///
 bool BugDriver::runPasses(const std::vector<const PassInfo*> &Passes,
-                          std::string &OutputFilename, bool DeleteOutput) const{
+                          std::string &OutputFilename, bool DeleteOutput,
+			  bool Quiet) const{
   std::cout << std::flush;
+  OutputFilename = getUniqueFilename("bugpoint-output.bc");
 
-  // Agree on a temporary file name to use....
-  char FNBuffer[] = "bugpoint-output.bc-XXXXXX";
-  int TempFD;
-  if ((TempFD = mkstemp(FNBuffer)) == -1) {
-    std::cerr << ToolName << ": ERROR: Cannot create temporary"
-              << " file in the current directory!\n";
-    exit(1);
-  }
-  OutputFilename = FNBuffer;
-
-  // We don't need to hold the temp file descriptor... we will trust that noone
-  // will overwrite/delete the file while we are working on it...
-  close(TempFD);
-  
   pid_t child_pid;
   switch (child_pid = fork()) {
   case -1:    // Error occurred
@@ -143,7 +126,7 @@
   if (DeleteOutput)
     removeFile(OutputFilename);
 
-  std::cout << (Status ? "Crashed!\n" : "Success!\n");
+  if (!Quiet) std::cout << (Status ? "Crashed!\n" : "Success!\n");
 
   // Was the child successful?
   return Status != 0;





More information about the llvm-commits mailing list