Use isNull instead of getNode() to test for existence of a node, this is cheaper.
[oota-llvm.git] / tools / bugpoint / Miscompilation.cpp
index 6ef9fc26c11d684843c9c5f9d7e71188b5860e3e..98e299d76d82ddce5d5677e024ddf90ddf2ab21d 100644 (file)
@@ -1,4 +1,11 @@
 //===- Miscompilation.cpp - Debug program miscompilations -----------------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // This file implements program miscompilation debugging support.
 //
 #include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Transforms/Utils/Linker.h"
 #include "Support/FileUtilities.h"
+using namespace llvm;
 
-class ReduceMiscompilingPasses : public ListReducer<const PassInfo*> {
-  BugDriver &BD;
-public:
-  ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}
+namespace llvm {
 
-  virtual TestResult doTest(std::vector<const PassInfo*> &Prefix,
-                            std::vector<const PassInfo*> &Suffix);
-};
+  class ReduceMiscompilingPasses : public ListReducer<const PassInfo*> {
+    BugDriver &BD;
+  public:
+    ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}
+    
+    virtual TestResult doTest(std::vector<const PassInfo*> &Prefix,
+                              std::vector<const PassInfo*> &Suffix);
+  };
+}
 
 ReduceMiscompilingPasses::TestResult
 ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
@@ -35,7 +46,7 @@ ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
               << " on the input program!\n";
     BD.setPassesToRun(Suffix);
     BD.EmitProgressBytecode("pass-error",  false);
-    exit(1);
+    exit(BD.debugOptimizerCrash());
   }
 
   // Check to see if the finished program matches the reference output...
@@ -63,7 +74,7 @@ ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
               << " on the input program!\n";
     BD.setPassesToRun(Prefix);
     BD.EmitProgressBytecode("pass-error",  false);
-    exit(1);
+    exit(BD.debugOptimizerCrash());
   }
 
   // If the prefix maintains the predicate by itself, only keep the prefix!
@@ -96,7 +107,7 @@ ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
               << " on the input program!\n";
     BD.setPassesToRun(Suffix);
     BD.EmitProgressBytecode("pass-error",  false);
-    exit(1);
+    exit(BD.debugOptimizerCrash());
   }
 
   // Run the result...
@@ -113,30 +124,34 @@ ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix,
   return NoFailure;
 }
 
-class ReduceMiscompilingFunctions : public ListReducer<Function*> {
-  BugDriver &BD;
-public:
-  ReduceMiscompilingFunctions(BugDriver &bd) : BD(bd) {}
-
-  virtual TestResult doTest(std::vector<Function*> &Prefix,
-                            std::vector<Function*> &Suffix) {
-    if (!Suffix.empty() && TestFuncs(Suffix, false))
-      return KeepSuffix;
-    if (!Prefix.empty() && TestFuncs(Prefix, false))
-      return KeepPrefix;
-    return NoFailure;
-  }
-  
-  bool TestFuncs(const std::vector<Function*> &Prefix, bool EmitBytecode);
-};
+namespace llvm {
+  class ReduceMiscompilingFunctions : public ListReducer<Function*> {
+    BugDriver &BD;
+  public:
+    ReduceMiscompilingFunctions(BugDriver &bd) : BD(bd) {}
+    
+    virtual TestResult doTest(std::vector<Function*> &Prefix,
+                              std::vector<Function*> &Suffix) {
+      if (!Suffix.empty() && TestFuncs(Suffix, false))
+        return KeepSuffix;
+      if (!Prefix.empty() && TestFuncs(Prefix, false))
+        return KeepPrefix;
+      return NoFailure;
+    }
+    
+    bool TestFuncs(const std::vector<Function*> &Prefix, bool EmitBytecode);
+  };
+}
 
 bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
                                             bool EmitBytecode) {
   // Test to see if the function is misoptimized if we ONLY run it on the
   // functions listed in Funcs.
   if (!EmitBytecode) {
-    std::cout << "Checking to see if the program is misoptimized when these "
-              << "functions are run\nthrough the passes: ";
+    std::cout << "Checking to see if the program is misoptimized when "
+              << (Funcs.size()==1 ? "this function is" : "these functions are")
+              << " run through the pass"
+              << (BD.PassesToRun.size() == 1 ? "" : "es") << ": ";
     BD.PrintFunctionList(Funcs);
     std::cout << "\n";
   } else {
@@ -144,7 +159,7 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
   }
 
   // First step: clone the module for the two halves of the program we want.
-  Module *ToOptimize = CloneModule(BD.Program);
+  Module *ToOptimize = CloneModule(BD.getProgram());
 
   // Second step: Make sure functions & globals are all external so that linkage
   // between the two modules will work.
@@ -210,13 +225,13 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
     std::cerr << " Error running this sequence of passes" 
               << " on the input program!\n";
     BD.EmitProgressBytecode("pass-error",  false);
-    exit(1);
+    exit(BD.debugOptimizerCrash());
   }
 
   if (!EmitBytecode)
     std::cout << "done.\n";
 
-  delete BD.Program;   // Delete the old "ToOptimize" module
+  delete BD.getProgram();   // Delete the old "ToOptimize" module
   BD.Program = BD.ParseInputFile(BytecodeResult);
 
   if (EmitBytecode) {
@@ -255,10 +270,10 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
   // output, then 'Funcs' are being misoptimized!
   bool Broken = BD.diffProgram();
 
-  delete BD.Program;  // Delete the hacked up program
+  delete BD.Program;         // Delete the hacked up program
   BD.Program = OldProgram;   // Restore the original
 
-  std::cout << (Broken ? "nope.\n" : "yup.\n");
+  std::cout << (Broken ? " nope.\n" : " yup.\n");
   return Broken;
 }
 
@@ -292,7 +307,9 @@ bool BugDriver::debugMiscompilation() {
   // Do the reduction...
   ReduceMiscompilingFunctions(*this).reduceList(MiscompiledFunctions);
 
-  std::cout << "\n*** The following functions are being miscompiled: ";
+  std::cout << "\n*** The following function"
+            << (MiscompiledFunctions.size() == 1 ? " is" : "s are")
+            << " being miscompiled: ";
   PrintFunctionList(MiscompiledFunctions);
   std::cout << "\n";
 
@@ -301,3 +318,4 @@ bool BugDriver::debugMiscompilation() {
 
   return false;
 }
+