svn commit: r223650 - in projects/llvm-ia64: contrib/llvm/lib/Target/IA64 contrib/llvm/tools/bugpoint contrib/llvm/tools/llc contrib/llvm/tools/lli contrib/llvm/tools/llvm-ar contrib/llvm/tools/llv...

Marcel Moolenaar marcel at FreeBSD.org
Tue Jun 28 17:51:47 UTC 2011


Author: marcel
Date: Tue Jun 28 17:51:47 2011
New Revision: 223650
URL: http://svn.freebsd.org/changeset/base/223650

Log:
  Add the LLVM extras on this branch.
  
  Obtained from: dim@

Added:
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/BugDriver.cpp
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/BugDriver.h
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/CrashDebugger.cpp
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/ExecutionDriver.cpp
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/ExtractFunction.cpp
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/FindBugs.cpp
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/ListReducer.h
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/Miscompilation.cpp
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/OptimizerDriver.cpp
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/ToolRunner.cpp
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/ToolRunner.h
  projects/llvm-ia64/contrib/llvm/tools/bugpoint/bugpoint.cpp
  projects/llvm-ia64/contrib/llvm/tools/llc/
  projects/llvm-ia64/contrib/llvm/tools/llc/llc.cpp
  projects/llvm-ia64/contrib/llvm/tools/lli/
  projects/llvm-ia64/contrib/llvm/tools/lli/lli.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-ar/
  projects/llvm-ia64/contrib/llvm/tools/llvm-ar/llvm-ar.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-as/
  projects/llvm-ia64/contrib/llvm/tools/llvm-as/llvm-as.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-bcanalyzer/
  projects/llvm-ia64/contrib/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-diff/
  projects/llvm-ia64/contrib/llvm/tools/llvm-diff/DiffConsumer.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-diff/DiffConsumer.h
  projects/llvm-ia64/contrib/llvm/tools/llvm-diff/DiffLog.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-diff/DiffLog.h
  projects/llvm-ia64/contrib/llvm/tools/llvm-diff/DifferenceEngine.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-diff/DifferenceEngine.h
  projects/llvm-ia64/contrib/llvm/tools/llvm-diff/llvm-diff.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-dis/
  projects/llvm-ia64/contrib/llvm/tools/llvm-dis/llvm-dis.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-extract/
  projects/llvm-ia64/contrib/llvm/tools/llvm-extract/llvm-extract.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-ld/
  projects/llvm-ia64/contrib/llvm/tools/llvm-ld/Optimize.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-ld/llvm-ld.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-link/
  projects/llvm-ia64/contrib/llvm/tools/llvm-link/llvm-link.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-mc/
  projects/llvm-ia64/contrib/llvm/tools/llvm-mc/Disassembler.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-mc/Disassembler.h
  projects/llvm-ia64/contrib/llvm/tools/llvm-mc/llvm-mc.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-nm/
  projects/llvm-ia64/contrib/llvm/tools/llvm-nm/llvm-nm.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-objdump/
  projects/llvm-ia64/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-prof/
  projects/llvm-ia64/contrib/llvm/tools/llvm-prof/llvm-prof.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-ranlib/
  projects/llvm-ia64/contrib/llvm/tools/llvm-ranlib/llvm-ranlib.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-rtdyld/
  projects/llvm-ia64/contrib/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
  projects/llvm-ia64/contrib/llvm/tools/llvm-stub/
  projects/llvm-ia64/contrib/llvm/tools/llvm-stub/llvm-stub.c
  projects/llvm-ia64/contrib/llvm/tools/macho-dump/
  projects/llvm-ia64/contrib/llvm/tools/macho-dump/macho-dump.cpp
  projects/llvm-ia64/contrib/llvm/tools/opt/
  projects/llvm-ia64/contrib/llvm/tools/opt/AnalysisWrappers.cpp
  projects/llvm-ia64/contrib/llvm/tools/opt/GraphPrinters.cpp
  projects/llvm-ia64/contrib/llvm/tools/opt/PrintSCC.cpp
  projects/llvm-ia64/contrib/llvm/tools/opt/opt.cpp
  projects/llvm-ia64/lib/clang/libllvmarchive/
  projects/llvm-ia64/lib/clang/libllvmarchive/Makefile
  projects/llvm-ia64/lib/clang/libllvmexecutionengine/
  projects/llvm-ia64/lib/clang/libllvmexecutionengine/Makefile
  projects/llvm-ia64/lib/clang/libllvminterpreter/
  projects/llvm-ia64/lib/clang/libllvminterpreter/Makefile
  projects/llvm-ia64/lib/clang/libllvmjit/
  projects/llvm-ia64/lib/clang/libllvmjit/Makefile
  projects/llvm-ia64/lib/clang/libllvmlinker/
  projects/llvm-ia64/lib/clang/libllvmlinker/Makefile
  projects/llvm-ia64/lib/clang/libllvmmcdisassembler/
  projects/llvm-ia64/lib/clang/libllvmmcdisassembler/Makefile
  projects/llvm-ia64/lib/clang/libllvmmcjit/
  projects/llvm-ia64/lib/clang/libllvmmcjit/Makefile
  projects/llvm-ia64/lib/clang/libllvmobject/
  projects/llvm-ia64/lib/clang/libllvmobject/Makefile
  projects/llvm-ia64/lib/clang/libllvmruntimedyld/
  projects/llvm-ia64/lib/clang/libllvmruntimedyld/Makefile
  projects/llvm-ia64/tools/build/options/WITH_CLANG_EXTRAS
  projects/llvm-ia64/usr.bin/clang/bugpoint/
  projects/llvm-ia64/usr.bin/clang/bugpoint/Makefile
  projects/llvm-ia64/usr.bin/clang/bugpoint/bugpoint.1
  projects/llvm-ia64/usr.bin/clang/llc/
  projects/llvm-ia64/usr.bin/clang/llc/Makefile
  projects/llvm-ia64/usr.bin/clang/llc/llc.1
  projects/llvm-ia64/usr.bin/clang/lli/
  projects/llvm-ia64/usr.bin/clang/lli/Makefile
  projects/llvm-ia64/usr.bin/clang/lli/lli.1
  projects/llvm-ia64/usr.bin/clang/llvm-ar/
  projects/llvm-ia64/usr.bin/clang/llvm-ar/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-ar/llvm-ar.1
  projects/llvm-ia64/usr.bin/clang/llvm-as/
  projects/llvm-ia64/usr.bin/clang/llvm-as/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-as/llvm-as.1
  projects/llvm-ia64/usr.bin/clang/llvm-bcanalyzer/
  projects/llvm-ia64/usr.bin/clang/llvm-bcanalyzer/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-bcanalyzer/llvm-bcanalyzer.1
  projects/llvm-ia64/usr.bin/clang/llvm-diff/
  projects/llvm-ia64/usr.bin/clang/llvm-diff/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-diff/llvm-diff.1
  projects/llvm-ia64/usr.bin/clang/llvm-dis/
  projects/llvm-ia64/usr.bin/clang/llvm-dis/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-dis/llvm-dis.1
  projects/llvm-ia64/usr.bin/clang/llvm-extract/
  projects/llvm-ia64/usr.bin/clang/llvm-extract/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-extract/llvm-extract.1
  projects/llvm-ia64/usr.bin/clang/llvm-ld/
  projects/llvm-ia64/usr.bin/clang/llvm-ld/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-ld/llvm-ld.1
  projects/llvm-ia64/usr.bin/clang/llvm-link/
  projects/llvm-ia64/usr.bin/clang/llvm-link/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-link/llvm-link.1
  projects/llvm-ia64/usr.bin/clang/llvm-mc/
  projects/llvm-ia64/usr.bin/clang/llvm-mc/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-nm/
  projects/llvm-ia64/usr.bin/clang/llvm-nm/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-nm/llvm-nm.1
  projects/llvm-ia64/usr.bin/clang/llvm-objdump/
  projects/llvm-ia64/usr.bin/clang/llvm-objdump/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-prof/
  projects/llvm-ia64/usr.bin/clang/llvm-prof/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-prof/llvm-prof.1
  projects/llvm-ia64/usr.bin/clang/llvm-ranlib/
  projects/llvm-ia64/usr.bin/clang/llvm-ranlib/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-ranlib/llvm-ranlib.1
  projects/llvm-ia64/usr.bin/clang/llvm-rtdyld/
  projects/llvm-ia64/usr.bin/clang/llvm-rtdyld/Makefile
  projects/llvm-ia64/usr.bin/clang/llvm-stub/
  projects/llvm-ia64/usr.bin/clang/llvm-stub/Makefile
  projects/llvm-ia64/usr.bin/clang/macho-dump/
  projects/llvm-ia64/usr.bin/clang/macho-dump/Makefile
  projects/llvm-ia64/usr.bin/clang/opt/
  projects/llvm-ia64/usr.bin/clang/opt/Makefile
  projects/llvm-ia64/usr.bin/clang/opt/opt.1
Modified:
  projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64FrameLowering.cpp
  projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64FrameLowering.h
  projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64TargetLowering.cpp
  projects/llvm-ia64/lib/clang/Makefile
  projects/llvm-ia64/lib/clang/libllvmanalysis/Makefile
  projects/llvm-ia64/lib/clang/libllvmarmdisassembler/Makefile
  projects/llvm-ia64/lib/clang/libllvmia64codegen/Makefile
  projects/llvm-ia64/lib/clang/libllvmipa/Makefile
  projects/llvm-ia64/lib/clang/libllvmipo/Makefile
  projects/llvm-ia64/lib/clang/libllvmmc/Makefile
  projects/llvm-ia64/lib/clang/libllvmscalaropts/Makefile
  projects/llvm-ia64/lib/clang/libllvmsupport/Makefile
  projects/llvm-ia64/lib/clang/libllvmtransformutils/Makefile
  projects/llvm-ia64/lib/clang/libllvmx86disassembler/Makefile
  projects/llvm-ia64/share/mk/bsd.own.mk
  projects/llvm-ia64/usr.bin/clang/Makefile

Modified: projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64FrameLowering.cpp
==============================================================================
--- projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64FrameLowering.cpp	Tue Jun 28 16:44:02 2011	(r223649)
+++ projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64FrameLowering.cpp	Tue Jun 28 17:51:47 2011	(r223650)
@@ -1,3 +1,5 @@
+#define DEBUG_TYPE "ia64-frame-lowering"
+
 #include "IA64FrameLowering.h"
 #include "IA64InstrInfo.h"
 #include "IA64MachineFunctionInfo.h"
@@ -11,6 +13,7 @@
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
 
 using namespace llvm;
 
@@ -23,14 +26,15 @@ IA64FrameLowering::emitPrologue(MachineF
   const IA64InstrInfo &TII =
         *static_cast<const IA64InstrInfo*>(MF.getTarget().getInstrInfo());
 
-  llvm_unreachable(__func__);
+  DEBUG(dbgs() << "XXX: IA64FrameLowering::" << __func__ << "\n");
 }
 
 void
 IA64FrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB)
     const
 {
-  llvm_unreachable(__func__);
+
+  DEBUG(dbgs() << "XXX: IA64FrameLowering::" << __func__ << "\n");
 }
 
 bool

Modified: projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64FrameLowering.h
==============================================================================
--- projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64FrameLowering.h	Tue Jun 28 16:44:02 2011	(r223649)
+++ projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64FrameLowering.h	Tue Jun 28 17:51:47 2011	(r223650)
@@ -15,7 +15,7 @@ namespace llvm {
 
   public:
     explicit IA64FrameLowering(const IA64Subtarget &sti) :
-	TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 16, -8, 16),
+	TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 16, 0, 16),
 	STI(sti) {}
 
     void emitPrologue(MachineFunction &MF) const;

Modified: projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64TargetLowering.cpp
==============================================================================
--- projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64TargetLowering.cpp	Tue Jun 28 16:44:02 2011	(r223649)
+++ projects/llvm-ia64/contrib/llvm/lib/Target/IA64/IA64TargetLowering.cpp	Tue Jun 28 17:51:47 2011	(r223650)
@@ -60,6 +60,8 @@ IA64TargetLowering::LowerFormalArguments
   MachineFunction &MF = DAG.getMachineFunction();
   SDValue Val;
 
+  DEBUG(dbgs() << "XXX: IA64TargetLowering::" << __func__ << "\n");
+
   for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
     EVT vt = Ins[ArgNo].VT;
 
@@ -82,5 +84,9 @@ IA64TargetLowering::LowerReturn(SDValue 
     const SmallVectorImpl<SDValue> &OutVals, DebugLoc dl,
     SelectionDAG &DAG) const
 {
+  MachineFunction &MF = DAG.getMachineFunction();
+
+  DEBUG(dbgs() << "XXX: IA64TargetLowering::" <<__func__ << "\n");
+
   return Chain;
 }

Added: projects/llvm-ia64/contrib/llvm/tools/bugpoint/BugDriver.cpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/llvm-ia64/contrib/llvm/tools/bugpoint/BugDriver.cpp	Tue Jun 28 17:51:47 2011	(r223650)
@@ -0,0 +1,246 @@
+//===- BugDriver.cpp - Top-Level BugPoint class implementation ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class contains all of the shared state and information that is used by
+// the BugPoint tool to track down errors in optimizations.  This class is the
+// main driver class that invokes all sub-functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "ToolRunner.h"
+#include "llvm/Linker.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/IRReader.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Host.h"
+#include <memory>
+using namespace llvm;
+
+namespace llvm {
+  Triple TargetTriple;
+}
+
+// Anonymous namespace to define command line options for debugging.
+//
+namespace {
+  // Output - The user can specify a file containing the expected output of the
+  // program.  If this filename is set, it is used as the reference diff source,
+  // otherwise the raw input run through an interpreter is used as the reference
+  // source.
+  //
+  cl::opt<std::string>
+  OutputFile("output", cl::desc("Specify a reference program output "
+                                "(for miscompilation detection)"));
+}
+
+/// setNewProgram - If we reduce or update the program somehow, call this method
+/// to update bugdriver with it.  This deletes the old module and sets the
+/// specified one as the current program.
+void BugDriver::setNewProgram(Module *M) {
+  delete Program;
+  Program = M;
+}
+
+
+/// getPassesString - Turn a list of passes into a string which indicates the
+/// command line options that must be passed to add the passes.
+///
+std::string llvm::getPassesString(const std::vector<std::string> &Passes) {
+  std::string Result;
+  for (unsigned i = 0, e = Passes.size(); i != e; ++i) {
+    if (i) Result += " ";
+    Result += "-";
+    Result += Passes[i];
+  }
+  return Result;
+}
+
+BugDriver::BugDriver(const char *toolname, bool find_bugs,
+                     unsigned timeout, unsigned memlimit, bool use_valgrind,
+                     LLVMContext& ctxt)
+  : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile),
+    Program(0), Interpreter(0), SafeInterpreter(0), gcc(0),
+    run_find_bugs(find_bugs), Timeout(timeout),
+    MemoryLimit(memlimit), UseValgrind(use_valgrind) {}
+
+BugDriver::~BugDriver() {
+  delete Program;
+}
+
+
+/// ParseInputFile - Given a bitcode or assembly input filename, parse and
+/// return it, or return null if not possible.
+///
+Module *llvm::ParseInputFile(const std::string &Filename,
+                             LLVMContext& Ctxt) {
+  SMDiagnostic Err;
+  Module *Result = ParseIRFile(Filename, Err, Ctxt);
+  if (!Result)
+    Err.Print("bugpoint", errs());
+
+  // If we don't have an override triple, use the first one to configure
+  // bugpoint, or use the host triple if none provided.
+  if (Result) {
+    if (TargetTriple.getTriple().empty()) {
+      Triple TheTriple(Result->getTargetTriple());
+
+      if (TheTriple.getTriple().empty())
+        TheTriple.setTriple(sys::getHostTriple());
+
+      TargetTriple.setTriple(TheTriple.getTriple());
+    }
+
+    Result->setTargetTriple(TargetTriple.getTriple());  // override the triple
+  }
+  return Result;
+}
+
+// This method takes the specified list of LLVM input files, attempts to load
+// them, either as assembly or bitcode, then link them together. It returns
+// true on failure (if, for example, an input bitcode file could not be
+// parsed), and false on success.
+//
+bool BugDriver::addSources(const std::vector<std::string> &Filenames) {
+  assert(Program == 0 && "Cannot call addSources multiple times!");
+  assert(!Filenames.empty() && "Must specify at least on input filename!");
+
+  // Load the first input file.
+  Program = ParseInputFile(Filenames[0], Context);
+  if (Program == 0) return true;
+
+  outs() << "Read input file      : '" << Filenames[0] << "'\n";
+
+  for (unsigned i = 1, e = Filenames.size(); i != e; ++i) {
+    std::auto_ptr<Module> M(ParseInputFile(Filenames[i], Context));
+    if (M.get() == 0) return true;
+
+    outs() << "Linking in input file: '" << Filenames[i] << "'\n";
+    std::string ErrorMessage;
+    if (Linker::LinkModules(Program, M.get(), &ErrorMessage)) {
+      errs() << ToolName << ": error linking in '" << Filenames[i] << "': "
+             << ErrorMessage << '\n';
+      return true;
+    }
+  }
+
+  outs() << "*** All input ok\n";
+
+  // All input files read successfully!
+  return false;
+}
+
+
+
+/// run - The top level method that is invoked after all of the instance
+/// variables are set up from command line arguments.
+///
+bool BugDriver::run(std::string &ErrMsg) {
+  if (run_find_bugs) {
+    // Rearrange the passes and apply them to the program. Repeat this process
+    // until the user kills the program or we find a bug.
+    return runManyPasses(PassesToRun, ErrMsg);
+  }
+
+  // If we're not running as a child, the first thing that we must do is
+  // determine what the problem is. Does the optimization series crash the
+  // compiler, or does it produce illegal code?  We make the top-level
+  // decision by trying to run all of the passes on the the input program,
+  // which should generate a bitcode file.  If it does generate a bitcode
+  // file, then we know the compiler didn't crash, so try to diagnose a
+  // miscompilation.
+  if (!PassesToRun.empty()) {
+    outs() << "Running selected passes on program to test for crash: ";
+    if (runPasses(Program, PassesToRun))
+      return debugOptimizerCrash();
+  }
+
+  // Set up the execution environment, selecting a method to run LLVM bitcode.
+  if (initializeExecutionEnvironment()) return true;
+
+  // Test to see if we have a code generator crash.
+  outs() << "Running the code generator to test for a crash: ";
+  std::string Error;
+  compileProgram(Program, &Error);
+  if (!Error.empty()) {
+    outs() << Error;
+    return debugCodeGeneratorCrash(ErrMsg);
+  }
+  outs() << '\n';
+
+  // Run the raw input to see where we are coming from.  If a reference output
+  // was specified, make sure that the raw output matches it.  If not, it's a
+  // problem in the front-end or the code generator.
+  //
+  bool CreatedOutput = false;
+  if (ReferenceOutputFile.empty()) {
+    outs() << "Generating reference output from raw program: ";
+    if (!createReferenceFile(Program)) {
+      return debugCodeGeneratorCrash(ErrMsg);
+    }
+    CreatedOutput = true;
+  }
+
+  // Make sure the reference output file gets deleted on exit from this
+  // function, if appropriate.
+  sys::Path ROF(ReferenceOutputFile);
+  FileRemover RemoverInstance(ROF.str(), CreatedOutput && !SaveTemps);
+
+  // Diff the output of the raw program against the reference output.  If it
+  // matches, then we assume there is a miscompilation bug and try to
+  // diagnose it.
+  outs() << "*** Checking the code generator...\n";
+  bool Diff = diffProgram(Program, "", "", false, &Error);
+  if (!Error.empty()) {
+    errs() << Error;
+    return debugCodeGeneratorCrash(ErrMsg);
+  }
+  if (!Diff) {
+    outs() << "\n*** Output matches: Debugging miscompilation!\n";
+    debugMiscompilation(&Error);
+    if (!Error.empty()) {
+      errs() << Error;
+      return debugCodeGeneratorCrash(ErrMsg);
+    }
+    return false;
+  }
+
+  outs() << "\n*** Input program does not match reference diff!\n";
+  outs() << "Debugging code generator problem!\n";
+  bool Failure = debugCodeGenerator(&Error);
+  if (!Error.empty()) {
+    errs() << Error;
+    return debugCodeGeneratorCrash(ErrMsg);
+  }
+  return Failure;
+}
+
+void llvm::PrintFunctionList(const std::vector<Function*> &Funcs) {
+  unsigned NumPrint = Funcs.size();
+  if (NumPrint > 10) NumPrint = 10;
+  for (unsigned i = 0; i != NumPrint; ++i)
+    outs() << " " << Funcs[i]->getName();
+  if (NumPrint < Funcs.size())
+    outs() << "... <" << Funcs.size() << " total>";
+  outs().flush();
+}
+
+void llvm::PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs) {
+  unsigned NumPrint = GVs.size();
+  if (NumPrint > 10) NumPrint = 10;
+  for (unsigned i = 0; i != NumPrint; ++i)
+    outs() << " " << GVs[i]->getName();
+  if (NumPrint < GVs.size())
+    outs() << "... <" << GVs.size() << " total>";
+  outs().flush();
+}

Added: projects/llvm-ia64/contrib/llvm/tools/bugpoint/BugDriver.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/llvm-ia64/contrib/llvm/tools/bugpoint/BugDriver.h	Tue Jun 28 17:51:47 2011	(r223650)
@@ -0,0 +1,330 @@
+//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class contains all of the shared state and information that is used by
+// the BugPoint tool to track down errors in optimizations.  This class is the
+// main driver class that invokes all sub-functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BUGDRIVER_H
+#define BUGDRIVER_H
+
+#include "llvm/ADT/ValueMap.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
+#include <vector>
+#include <string>
+
+namespace llvm {
+
+class Value;
+class PassInfo;
+class Module;
+class GlobalVariable;
+class Function;
+class BasicBlock;
+class AbstractInterpreter;
+class Instruction;
+class LLVMContext;
+
+class DebugCrashes;
+
+class GCC;
+
+extern bool DisableSimplifyCFG;
+
+/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
+///
+extern bool BugpointIsInterrupted;
+
+class BugDriver {
+  LLVMContext& Context;
+  const char *ToolName;            // argv[0] of bugpoint
+  std::string ReferenceOutputFile; // Name of `good' output file
+  Module *Program;             // The raw program, linked together
+  std::vector<std::string> PassesToRun;
+  AbstractInterpreter *Interpreter;   // How to run the program
+  AbstractInterpreter *SafeInterpreter;  // To generate reference output, etc.
+  GCC *gcc;
+  bool run_find_bugs;
+  unsigned Timeout;
+  unsigned MemoryLimit;
+  bool UseValgrind;
+
+  // FIXME: sort out public/private distinctions...
+  friend class ReducePassList;
+  friend class ReduceMisCodegenFunctions;
+
+public:
+  BugDriver(const char *toolname, bool find_bugs,
+            unsigned timeout, unsigned memlimit, bool use_valgrind,
+            LLVMContext& ctxt);
+  ~BugDriver();
+
+  const char *getToolName() const { return ToolName; }
+
+  LLVMContext& getContext() const { return Context; }
+
+  // Set up methods... these methods are used to copy information about the
+  // command line arguments into instance variables of BugDriver.
+  //
+  bool addSources(const std::vector<std::string> &FileNames);
+  void addPass(std::string p) { PassesToRun.push_back(p); }
+  void setPassesToRun(const std::vector<std::string> &PTR) {
+    PassesToRun = PTR;
+  }
+  const std::vector<std::string> &getPassesToRun() const {
+    return PassesToRun;
+  }
+
+  /// run - The top level method that is invoked after all of the instance
+  /// variables are set up from command line arguments. The \p as_child argument
+  /// indicates whether the driver is to run in parent mode or child mode.
+  ///
+  bool run(std::string &ErrMsg);
+
+  /// debugOptimizerCrash - This method is called when some optimizer pass
+  /// crashes on input.  It attempts to prune down the testcase to something
+  /// reasonable, and figure out exactly which pass is crashing.
+  ///
+  bool debugOptimizerCrash(const std::string &ID = "passes");
+
+  /// debugCodeGeneratorCrash - This method is called when the code generator
+  /// crashes on an input.  It attempts to reduce the input as much as possible
+  /// while still causing the code generator to crash.
+  bool debugCodeGeneratorCrash(std::string &Error);
+
+  /// debugMiscompilation - This method is used when the passes selected are not
+  /// crashing, but the generated output is semantically different from the
+  /// input.
+  void debugMiscompilation(std::string *Error);
+
+  /// 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);
+
+  /// compileSharedObject - This method creates a SharedObject from a given
+  /// BitcodeFile for debugging a code generator.
+  ///
+  std::string compileSharedObject(const std::string &BitcodeFile,
+                                  std::string &Error);
+
+  /// 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(std::string *Error);
+
+  /// isExecutingJIT - Returns true if bugpoint is currently testing the JIT
+  ///
+  bool isExecutingJIT();
+
+  /// runPasses - Run all of the passes in the "PassesToRun" list, discard the
+  /// output, and return true if any of the passes crashed.
+  bool runPasses(Module *M) const {
+    return runPasses(M, PassesToRun);
+  }
+
+  Module *getProgram() const { return Program; }
+
+  /// swapProgramIn - Set the current module to the specified module, returning
+  /// the old one.
+  Module *swapProgramIn(Module *M) {
+    Module *OldProgram = Program;
+    Program = M;
+    return OldProgram;
+  }
+
+  AbstractInterpreter *switchToSafeInterpreter() {
+    AbstractInterpreter *Old = Interpreter;
+    Interpreter = (AbstractInterpreter*)SafeInterpreter;
+    return Old;
+  }
+
+  void switchToInterpreter(AbstractInterpreter *AI) {
+    Interpreter = AI;
+  }
+
+  /// setNewProgram - If we reduce or update the program somehow, call this
+  /// method to update bugdriver with it.  This deletes the old module and sets
+  /// the specified one as the current program.
+  void setNewProgram(Module *M);
+
+  /// compileProgram - Try to compile the specified module, returning false and
+  /// setting Error if an error occurs.  This is used for code generation
+  /// crash testing.
+  ///
+  void compileProgram(Module *M, std::string *Error) const;
+
+  /// executeProgram - This method runs "Program", capturing the output of the
+  /// program to a file.  A recommended filename may be optionally specified.
+  ///
+  std::string executeProgram(const Module *Program,
+                             std::string OutputFilename,
+                             std::string Bitcode,
+                             const std::string &SharedObjects,
+                             AbstractInterpreter *AI,
+                             std::string *Error) const;
+
+  /// executeProgramSafely - Used to create reference output with the "safe"
+  /// backend, if reference output is not provided.  If there is a problem with
+  /// the code generator (e.g., llc crashes), this will return false and set
+  /// Error.
+  ///
+  std::string executeProgramSafely(const Module *Program,
+                                   std::string OutputFile,
+                                   std::string *Error) const;
+
+  /// createReferenceFile - calls compileProgram and then records the output
+  /// into ReferenceOutputFile. Returns true if reference file created, false 
+  /// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
+  /// this function.
+  ///
+  bool createReferenceFile(Module *M, const std::string &Filename
+                                            = "bugpoint.reference.out");
+
+  /// diffProgram - This method executes the specified module and diffs the
+  /// output against the file specified by ReferenceOutputFile.  If the output
+  /// is different, 1 is returned.  If there is a problem with the code
+  /// generator (e.g., llc crashes), this will return -1 and set Error.
+  ///
+  bool diffProgram(const Module *Program,
+                   const std::string &BitcodeFile = "",
+                   const std::string &SharedObj = "",
+                   bool RemoveBitcode = false,
+                   std::string *Error = 0) const;
+
+  /// EmitProgressBitcode - This function is used to output M to a file named
+  /// "bugpoint-ID.bc".
+  ///
+  void EmitProgressBitcode(const Module *M, const std::string &ID,
+                           bool NoFlyer = false) const;
+
+  /// 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
+  /// which depends on the value.  The modified module is then returned.
+  ///
+  Module *deleteInstructionFromProgram(const Instruction *I, unsigned Simp);
+
+  /// performFinalCleanups - This method clones the current Program and performs
+  /// a series of cleanups intended to get rid of extra cruft on the module.  If
+  /// the MayModifySemantics argument is true, then the cleanups is allowed to
+  /// modify how the code behaves.
+  ///
+  Module *performFinalCleanups(Module *M, bool MayModifySemantics = false);
+
+  /// ExtractLoop - Given a module, extract up to one loop from it into a new
+  /// function.  This returns null if there are no extractable loops in the
+  /// program or if the loop extractor crashes.
+  Module *ExtractLoop(Module *M);
+
+  /// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks
+  /// into their own functions.  The only detail is that M is actually a module
+  /// cloned from the one the BBs are in, so some mapping needs to be performed.
+  /// If this operation fails for some reason (ie the implementation is buggy),
+  /// this function should return null, otherwise it returns a new Module.
+  Module *ExtractMappedBlocksFromModule(const std::vector<BasicBlock*> &BBs,
+                                        Module *M);
+
+  /// runPassesOn - Carefully run the specified set of pass on the specified
+  /// module, returning the transformed module on success, or a null pointer on
+  /// failure.  If AutoDebugCrashes is set to true, then bugpoint will
+  /// automatically attempt to track down a crashing pass if one exists, and
+  /// this method will never return null.
+  Module *runPassesOn(Module *M, const std::vector<std::string> &Passes,
+                      bool AutoDebugCrashes = false, unsigned NumExtraArgs = 0,
+                      const char * const *ExtraArgs = NULL);
+
+  /// runPasses - Run the specified passes on Program, outputting a bitcode
+  /// file and writting the filename into OutputFile if successful.  If the
+  /// optimizations fail for some reason (optimizer crashes), return true,
+  /// otherwise return false.  If DeleteOutput is set to true, the bitcode is
+  /// deleted on success, and the filename string is undefined.  This prints to
+  /// outs() a single line message indicating whether compilation was successful
+  /// or failed, unless Quiet is set.  ExtraArgs specifies additional arguments
+  /// to pass to the child bugpoint instance.
+  ///
+  bool runPasses(Module *Program,
+                 const std::vector<std::string> &PassesToRun,
+                 std::string &OutputFilename, bool DeleteOutput = false,
+                 bool Quiet = false, unsigned NumExtraArgs = 0,
+                 const char * const *ExtraArgs = NULL) const;
+                 
+  /// runManyPasses - Take the specified pass list and create different 
+  /// combinations of passes to compile the program with. Compile the program with
+  /// each set and mark test to see if it compiled correctly. If the passes 
+  /// compiled correctly output nothing and rearrange the passes into a new order.
+  /// If the passes did not compile correctly, output the command required to 
+  /// recreate the failure. This returns true if a compiler error is found.
+  ///
+  bool runManyPasses(const std::vector<std::string> &AllPasses,
+                     std::string &ErrMsg);
+
+  /// writeProgramToFile - This writes the current "Program" to the named
+  /// bitcode file.  If an error occurs, true is returned.
+  ///
+  bool writeProgramToFile(const std::string &Filename, const Module *M) const;
+
+private:
+  /// runPasses - Just like the method above, but this just returns true or
+  /// false indicating whether or not the optimizer crashed on the specified
+  /// input (true = crashed).
+  ///
+  bool runPasses(Module *M,
+                 const std::vector<std::string> &PassesToRun,
+                 bool DeleteOutput = true) const {
+    std::string Filename;
+    return runPasses(M, PassesToRun, Filename, DeleteOutput);
+  }
+
+  /// initializeExecutionEnvironment - This method is used to set up the
+  /// environment for executing LLVM programs.
+  ///
+  bool initializeExecutionEnvironment();
+};
+
+/// ParseInputFile - Given a bitcode or assembly input filename, parse and
+/// return it, or return null if not possible.
+///
+Module *ParseInputFile(const std::string &InputFilename,
+                       LLVMContext& ctxt);
+
+
+/// getPassesString - Turn a list of passes into a string which indicates the
+/// command line options that must be passed to add the passes.
+///
+std::string getPassesString(const std::vector<std::string> &Passes);
+
+/// PrintFunctionList - prints out list of problematic functions
+///
+void PrintFunctionList(const std::vector<Function*> &Funcs);
+
+/// PrintGlobalVariableList - prints out list of problematic global variables
+///
+void PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs);
+
+// DeleteFunctionBody - "Remove" the function by deleting all of it's basic
+// blocks, making it external.
+//
+void DeleteFunctionBody(Function *F);
+
+/// SplitFunctionsOutOfModule - Given a module and a list of functions in the
+/// module, split the functions OUT of the specified module, and place them in
+/// the new module.
+Module *SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F,
+                                  ValueToValueMapTy &VMap);
+
+} // End llvm namespace
+
+#endif

Added: projects/llvm-ia64/contrib/llvm/tools/bugpoint/CrashDebugger.cpp
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/llvm-ia64/contrib/llvm/tools/bugpoint/CrashDebugger.cpp	Tue Jun 28 17:51:47 2011	(r223650)
@@ -0,0 +1,667 @@
+//===- CrashDebugger.cpp - Debug compilation crashes ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the bugpoint internals that narrow down compilation crashes
+//
+//===----------------------------------------------------------------------===//
+
+#include "BugDriver.h"
+#include "ToolRunner.h"
+#include "ListReducer.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/PassManager.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/CommandLine.h"
+#include <set>
+using namespace llvm;
+
+namespace {
+  cl::opt<bool>
+  KeepMain("keep-main",
+           cl::desc("Force function reduction to keep main"),
+           cl::init(false));
+  cl::opt<bool>
+  NoGlobalRM ("disable-global-remove",
+         cl::desc("Do not remove global variables"),
+         cl::init(false));
+}
+
+namespace llvm {
+  class ReducePassList : public ListReducer<std::string> {
+    BugDriver &BD;
+  public:
+    ReducePassList(BugDriver &bd) : BD(bd) {}
+
+    // doTest - Return true iff running the "removed" passes succeeds, and
+    // running the "Kept" passes fail when run on the output of the "removed"
+    // passes.  If we return true, we update the current module of bugpoint.
+    //
+    virtual TestResult doTest(std::vector<std::string> &Removed,
+                              std::vector<std::string> &Kept,
+                              std::string &Error);
+  };
+}
+
+ReducePassList::TestResult
+ReducePassList::doTest(std::vector<std::string> &Prefix,
+                       std::vector<std::string> &Suffix,
+                       std::string &Error) {
+  sys::Path PrefixOutput;
+  Module *OrigProgram = 0;
+  if (!Prefix.empty()) {
+    outs() << "Checking to see if these passes crash: "
+           << getPassesString(Prefix) << ": ";
+    std::string PfxOutput;
+    if (BD.runPasses(BD.getProgram(), Prefix, PfxOutput))
+      return KeepPrefix;
+
+    PrefixOutput.set(PfxOutput);
+    OrigProgram = BD.Program;
+
+    BD.Program = ParseInputFile(PrefixOutput.str(), BD.getContext());
+    if (BD.Program == 0) {
+      errs() << BD.getToolName() << ": Error reading bitcode file '"
+             << PrefixOutput.str() << "'!\n";
+      exit(1);
+    }
+    PrefixOutput.eraseFromDisk();
+  }
+
+  outs() << "Checking to see if these passes crash: "
+         << getPassesString(Suffix) << ": ";
+
+  if (BD.runPasses(BD.getProgram(), Suffix)) {
+    delete OrigProgram;            // The suffix crashes alone...
+    return KeepSuffix;
+  }
+
+  // Nothing failed, restore state...
+  if (OrigProgram) {
+    delete BD.Program;
+    BD.Program = OrigProgram;
+  }
+  return NoFailure;
+}
+
+namespace {
+  /// ReduceCrashingGlobalVariables - This works by removing the global
+  /// variable's initializer and seeing if the program still crashes. If it
+  /// does, then we keep that program and try again.
+  ///
+  class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable*> {
+    BugDriver &BD;
+    bool (*TestFn)(const BugDriver &, Module *);
+  public:
+    ReduceCrashingGlobalVariables(BugDriver &bd,
+                                  bool (*testFn)(const BugDriver &, Module *))
+      : BD(bd), TestFn(testFn) {}
+
+    virtual TestResult doTest(std::vector<GlobalVariable*> &Prefix,
+                              std::vector<GlobalVariable*> &Kept,
+                              std::string &Error) {
+      if (!Kept.empty() && TestGlobalVariables(Kept))
+        return KeepSuffix;
+      if (!Prefix.empty() && TestGlobalVariables(Prefix))
+        return KeepPrefix;
+      return NoFailure;
+    }
+
+    bool TestGlobalVariables(std::vector<GlobalVariable*> &GVs);
+  };
+}
+
+bool
+ReduceCrashingGlobalVariables::TestGlobalVariables(
+                              std::vector<GlobalVariable*> &GVs) {
+  // Clone the program to try hacking it apart...
+  ValueToValueMapTy VMap;
+  Module *M = CloneModule(BD.getProgram(), VMap);
+
+  // Convert list to set for fast lookup...
+  std::set<GlobalVariable*> GVSet;
+
+  for (unsigned i = 0, e = GVs.size(); i != e; ++i) {
+    GlobalVariable* CMGV = cast<GlobalVariable>(VMap[GVs[i]]);
+    assert(CMGV && "Global Variable not in module?!");
+    GVSet.insert(CMGV);
+  }
+
+  outs() << "Checking for crash with only these global variables: ";
+  PrintGlobalVariableList(GVs);
+  outs() << ": ";
+
+  // Loop over and delete any global variables which we aren't supposed to be
+  // playing with...
+  for (Module::global_iterator I = M->global_begin(), E = M->global_end();
+       I != E; ++I)
+    if (I->hasInitializer() && !GVSet.count(I)) {
+      I->setInitializer(0);
+      I->setLinkage(GlobalValue::ExternalLinkage);
+    }
+
+  // Try running the hacked up program...
+  if (TestFn(BD, M)) {
+    BD.setNewProgram(M);        // It crashed, keep the trimmed version...
+
+    // Make sure to use global variable pointers that point into the now-current
+    // module.
+    GVs.assign(GVSet.begin(), GVSet.end());
+    return true;
+  }
+
+  delete M;
+  return false;
+}
+
+namespace llvm {
+  /// ReduceCrashingFunctions reducer - This works by removing functions and
+  /// seeing if the program still crashes. If it does, then keep the newer,
+  /// smaller program.
+  ///
+  class ReduceCrashingFunctions : public ListReducer<Function*> {
+    BugDriver &BD;
+    bool (*TestFn)(const BugDriver &, Module *);
+  public:
+    ReduceCrashingFunctions(BugDriver &bd,
+                            bool (*testFn)(const BugDriver &, Module *))
+      : BD(bd), TestFn(testFn) {}
+
+    virtual TestResult doTest(std::vector<Function*> &Prefix,
+                              std::vector<Function*> &Kept,
+                              std::string &Error) {
+      if (!Kept.empty() && TestFuncs(Kept))
+        return KeepSuffix;
+      if (!Prefix.empty() && TestFuncs(Prefix))
+        return KeepPrefix;
+      return NoFailure;
+    }
+
+    bool TestFuncs(std::vector<Function*> &Prefix);
+  };
+}
+
+bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
+
+  //if main isn't present, claim there is no problem
+  if (KeepMain && find(Funcs.begin(), Funcs.end(),
+                       BD.getProgram()->getFunction("main")) == Funcs.end())
+    return false;
+
+  // Clone the program to try hacking it apart...
+  ValueToValueMapTy VMap;
+  Module *M = CloneModule(BD.getProgram(), VMap);
+
+  // Convert list to set for fast lookup...
+  std::set<Function*> Functions;
+  for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
+    Function *CMF = cast<Function>(VMap[Funcs[i]]);
+    assert(CMF && "Function not in module?!");
+    assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty");
+    assert(CMF->getName() == Funcs[i]->getName() && "wrong name");
+    Functions.insert(CMF);
+  }
+
+  outs() << "Checking for crash with only these functions: ";
+  PrintFunctionList(Funcs);
+  outs() << ": ";
+
+  // Loop over and delete any functions which we aren't supposed to be playing
+  // with...
+  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+    if (!I->isDeclaration() && !Functions.count(I))
+      DeleteFunctionBody(I);
+
+  // Try running the hacked up program...
+  if (TestFn(BD, M)) {
+    BD.setNewProgram(M);        // It crashed, keep the trimmed version...
+
+    // Make sure to use function pointers that point into the now-current
+    // module.
+    Funcs.assign(Functions.begin(), Functions.end());
+    return true;
+  }
+  delete M;
+  return false;
+}
+
+
+namespace {
+  /// ReduceCrashingBlocks reducer - This works by setting the terminators of
+  /// all terminators except the specified basic blocks to a 'ret' instruction,
+  /// then running the simplify-cfg pass.  This has the effect of chopping up
+  /// the CFG really fast which can reduce large functions quickly.
+  ///
+  class ReduceCrashingBlocks : public ListReducer<const BasicBlock*> {
+    BugDriver &BD;
+    bool (*TestFn)(const BugDriver &, Module *);
+  public:
+    ReduceCrashingBlocks(BugDriver &bd,
+                         bool (*testFn)(const BugDriver &, Module *))
+      : BD(bd), TestFn(testFn) {}
+
+    virtual TestResult doTest(std::vector<const BasicBlock*> &Prefix,
+                              std::vector<const BasicBlock*> &Kept,
+                              std::string &Error) {
+      if (!Kept.empty() && TestBlocks(Kept))
+        return KeepSuffix;
+      if (!Prefix.empty() && TestBlocks(Prefix))
+        return KeepPrefix;
+      return NoFailure;
+    }
+
+    bool TestBlocks(std::vector<const BasicBlock*> &Prefix);
+  };
+}
+
+bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
+  // Clone the program to try hacking it apart...
+  ValueToValueMapTy VMap;
+  Module *M = CloneModule(BD.getProgram(), VMap);
+
+  // Convert list to set for fast lookup...
+  SmallPtrSet<BasicBlock*, 8> Blocks;
+  for (unsigned i = 0, e = BBs.size(); i != e; ++i)
+    Blocks.insert(cast<BasicBlock>(VMap[BBs[i]]));
+
+  outs() << "Checking for crash with only these blocks:";
+  unsigned NumPrint = Blocks.size();
+  if (NumPrint > 10) NumPrint = 10;
+  for (unsigned i = 0, e = NumPrint; i != e; ++i)
+    outs() << " " << BBs[i]->getName();
+  if (NumPrint < Blocks.size())
+    outs() << "... <" << Blocks.size() << " total>";
+  outs() << ": ";
+
+  // Loop over and delete any hack up any blocks that are not listed...
+  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
+    for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB)
+      if (!Blocks.count(BB) && BB->getTerminator()->getNumSuccessors()) {
+        // Loop over all of the successors of this block, deleting any PHI nodes
+        // that might include it.
+        for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
+          (*SI)->removePredecessor(BB);
+
+        TerminatorInst *BBTerm = BB->getTerminator();
+        
+        if (!BB->getTerminator()->getType()->isVoidTy())
+          BBTerm->replaceAllUsesWith(Constant::getNullValue(BBTerm->getType()));
+
+        // Replace the old terminator instruction.
+        BB->getInstList().pop_back();
+        new UnreachableInst(BB->getContext(), BB);
+      }
+
+  // The CFG Simplifier pass may delete one of the basic blocks we are
+  // interested in.  If it does we need to take the block out of the list.  Make
+  // a "persistent mapping" by turning basic blocks into <function, name> pairs.
+  // This won't work well if blocks are unnamed, but that is just the risk we
+  // have to take.
+  std::vector<std::pair<std::string, std::string> > BlockInfo;
+
+  for (SmallPtrSet<BasicBlock*, 8>::iterator I = Blocks.begin(),
+         E = Blocks.end(); I != E; ++I)
+    BlockInfo.push_back(std::make_pair((*I)->getParent()->getName(),
+                                       (*I)->getName()));
+
+  // Now run the CFG simplify pass on the function...
+  std::vector<std::string> Passes;
+  Passes.push_back("simplifycfg");
+  Passes.push_back("verify");
+  Module *New = BD.runPassesOn(M, Passes);
+  delete M;
+  if (!New) {
+    errs() << "simplifycfg failed!\n";
+    exit(1);
+  }
+  M = New;
+
+  // Try running on the hacked up program...
+  if (TestFn(BD, M)) {
+    BD.setNewProgram(M);      // It crashed, keep the trimmed version...
+
+    // Make sure to use basic block pointers that point into the now-current
+    // module, and that they don't include any deleted blocks.
+    BBs.clear();
+    const ValueSymbolTable &GST = M->getValueSymbolTable();
+    for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
+      Function *F = cast<Function>(GST.lookup(BlockInfo[i].first));
+      ValueSymbolTable &ST = F->getValueSymbolTable();
+      Value* V = ST.lookup(BlockInfo[i].second);
+      if (V && V->getType() == Type::getLabelTy(V->getContext()))
+        BBs.push_back(cast<BasicBlock>(V));
+    }
+    return true;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list