Date: Tue, 28 Jun 2011 17:51:47 +0000 (UTC) From: Marcel Moolenaar <marcel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: 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... Message-ID: <201106281751.p5SHplJC059483@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106281751.p5SHplJC059483>