summaryrefslogtreecommitdiff
path: root/tools/bugpoint/BugDriver.cpp
diff options
context:
space:
mode:
authorMisha Brukman <brukman+llvm@gmail.com>2003-07-24 18:17:43 +0000
committerMisha Brukman <brukman+llvm@gmail.com>2003-07-24 18:17:43 +0000
commit5073336cd4da5df4ae13a167582d1dc90f32e4e0 (patch)
tree1d91677c5c7dbdbad402706b99ce7fe10f0637c2 /tools/bugpoint/BugDriver.cpp
parent08fd7abb42cadf2d14a3ca8103b73a358468391f (diff)
downloadllvm-5073336cd4da5df4ae13a167582d1dc90f32e4e0.tar.gz
llvm-5073336cd4da5df4ae13a167582d1dc90f32e4e0.tar.bz2
llvm-5073336cd4da5df4ae13a167582d1dc90f32e4e0.tar.xz
Major addition to bugpoint: ability to debug code generators (LLC and LLI).
The C backend is assumed correct and is used to generate shared objects to be loaded by the other two code generators. LLC debugging should be functional now, LLI needs a few more additions to work, the major one is renaming of external functions to call the JIT lazy function resolver. Bugpoint now has a command-line switch -mode with options 'compile' and 'codegen' to debug appropriate portions of tools. ExecutionDriver.cpp: Added implementations of AbstractInterpreter for LLC and GCC, broke out common code within other tools, and added ability to generate C code with CBE individually, without executing the program, and the GCC tool can generate executables shared objects or executables. If no reference output is specified to Bugpoint, it will be generated with CBE, because it is already assumed to be correct for the purposes of debugging using this method. As a result, many functions now accept as an optional parameter a shared object to be loaded in, if specified. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7293 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/bugpoint/BugDriver.cpp')
-rw-r--r--tools/bugpoint/BugDriver.cpp70
1 files changed, 68 insertions, 2 deletions
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp
index ed1a135125..53a8395aaf 100644
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -7,13 +7,36 @@
//===----------------------------------------------------------------------===//
#include "BugDriver.h"
+#include "SystemUtils.h"
#include "llvm/Module.h"
#include "llvm/Bytecode/Reader.h"
#include "llvm/Assembly/Parser.h"
#include "llvm/Transforms/Utils/Linker.h"
#include "llvm/Pass.h"
+#include "Support/CommandLine.h"
#include <memory>
+// 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)"));
+
+ enum DebugType { DebugCompile, DebugCodegen };
+ cl::opt<DebugType>
+ DebugMode("mode", cl::desc("Debug mode for bugpoint:"), cl::Prefix,
+ cl::values(clEnumValN(DebugCompile, "compile", " Compilation"),
+ clEnumValN(DebugCodegen, "codegen", " Code generation"),
+ 0),
+ cl::init(DebugCompile));
+}
+
/// getPassesString - Turn a list of passes into a string which indicates the
/// command line options that must be passed to add the passes.
///
@@ -41,6 +64,11 @@ void DeleteFunctionBody(Function *F) {
assert(F->isExternal() && "This didn't make the function external!");
}
+BugDriver::BugDriver(const char *toolname)
+ : ToolName(toolname), ReferenceOutputFile(OutputFile),
+ Program(0), Interpreter(0) {}
+
+
/// ParseInputFile - Given a bytecode or assembly input filename, parse and
/// return it, or return null if not possible.
///
@@ -108,6 +136,44 @@ bool BugDriver::run() {
std::cout << "Running selected passes on program to test for crash: ";
if (runPasses(PassesToRun))
return debugCrash();
- else
- return debugMiscompilation();
+
+ std::cout << "Checking for a miscompilation...\n";
+
+ // Set up the execution environment, selecting a method to run LLVM bytecode.
+ if (initializeExecutionEnvironment()) return true;
+
+ // 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, Result;
+ if (ReferenceOutputFile.empty()) {
+ std::cout << "Generating reference output from raw program...";
+ if (DebugCodegen) {
+ ReferenceOutputFile = executeProgramWithCBE("bugpoint.reference.out");
+ } else {
+ ReferenceOutputFile = executeProgram("bugpoint.reference.out");
+ }
+ CreatedOutput = true;
+ std::cout << "Reference output is: " << ReferenceOutputFile << "\n";
+ }
+
+ if (DebugMode == DebugCompile) {
+ std::cout << "\n*** Debugging miscompilation!\n";
+ Result = debugMiscompilation();
+ } else if (DebugMode == DebugCodegen) {
+ std::cout << "Debugging code generator problem!\n";
+ Result = debugCodeGenerator();
+ }
+
+ if (CreatedOutput) removeFile(ReferenceOutputFile);
+ return Result;
+}
+
+void BugDriver::PrintFunctionList(const std::vector<Function*> &Funcs)
+{
+ for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
+ if (i) std::cout << ", ";
+ std::cout << Funcs[i]->getName();
+ }
}