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