X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fbugpoint%2FMiscompilation.cpp;h=b88f87c9b1e2de3c9f609ce5adbb015adc63485d;hb=0c49b892987687c9eb6f855f00d8c24552100b74;hp=333eb13244eff00da726bde99a74c5adb6c76fe7;hpb=bc0e998c497446f5448425b3cbd7f8f19a458764;p=oota-llvm.git diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 333eb13244e..b88f87c9b1e 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -5,27 +5,12 @@ //===----------------------------------------------------------------------===// #include "BugDriver.h" -#include "SystemUtils.h" #include "ListReducer.h" -#include "llvm/Pass.h" #include "llvm/Module.h" +#include "llvm/Pass.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Linker.h" -#include "Support/CommandLine.h" - -// Anonymous namespace to define command line options for miscompilation -// 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 - Output("output", cl::desc("Specify a reference program output " - "(for miscompilation detection)")); -} +#include "Support/FileUtilities.h" class ReduceMiscompilingPasses : public ListReducer { BugDriver &BD; @@ -33,7 +18,7 @@ public: ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {} virtual TestResult doTest(std::vector &Prefix, - std::vector &Kept); + std::vector &Suffix); }; ReduceMiscompilingPasses::TestResult @@ -52,7 +37,7 @@ ReduceMiscompilingPasses::doTest(std::vector &Prefix, } // Check to see if the finished program matches the reference output... - if (BD.diffProgram(Output, BytecodeResult, true /*delete bytecode*/)) { + if (BD.diffProgram(BytecodeResult, "", true /*delete bytecode*/)) { std::cout << "nope.\n"; return KeepSuffix; // Miscompilation detected! } @@ -78,7 +63,7 @@ ReduceMiscompilingPasses::doTest(std::vector &Prefix, } // If the prefix maintains the predicate by itself, only keep the prefix! - if (BD.diffProgram(Output, BytecodeResult)) { + if (BD.diffProgram(BytecodeResult)) { std::cout << "nope.\n"; removeFile(BytecodeResult); return KeepPrefix; @@ -109,7 +94,7 @@ ReduceMiscompilingPasses::doTest(std::vector &Prefix, } // Run the result... - if (BD.diffProgram(Output, BytecodeResult, true/*delete bytecode*/)) { + if (BD.diffProgram(BytecodeResult, "", true/*delete bytecode*/)) { std::cout << "nope.\n"; delete OriginalInput; // We pruned down the original input... return KeepSuffix; @@ -122,14 +107,6 @@ ReduceMiscompilingPasses::doTest(std::vector &Prefix, return NoFailure; } -static void PrintFunctionList(const std::vector &Funcs) { - for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { - if (i) std::cout << ", "; - std::cout << Funcs[i]->getName(); - } -} - - class ReduceMiscompilingFunctions : public ListReducer { BugDriver &BD; public: @@ -137,7 +114,7 @@ public: virtual TestResult doTest(std::vector &Prefix, std::vector &Suffix) { - if (TestFuncs(Suffix, false)) + if (!Suffix.empty() && TestFuncs(Suffix, false)) return KeepSuffix; if (!Prefix.empty() && TestFuncs(Prefix, false)) return KeepPrefix; @@ -154,7 +131,7 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector &Funcs, if (!EmitBytecode) { std::cout << "Checking to see if the program is misoptimized when these " << "functions are run\nthrough the passes: "; - PrintFunctionList(Funcs); + BD.PrintFunctionList(Funcs); std::cout << "\n"; } else { std::cout <<"Outputting reduced bytecode files which expose the problem:\n"; @@ -269,7 +246,7 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector &Funcs, // Eighth step: Execute the program. If it does not match the expected // output, then 'Funcs' are being misoptimized! - bool Broken = BD.diffProgram(Output); + bool Broken = BD.diffProgram(); delete BD.Program; // Delete the hacked up program BD.Program = OldProgram; // Restore the original @@ -284,33 +261,15 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector &Funcs, /// input. /// bool BugDriver::debugMiscompilation() { - std::cout << "*** Debugging 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 whatever produced the input code. - // - bool CreatedOutput = false; - if (Output.empty()) { - std::cout << "Generating reference output from raw program..."; - Output = executeProgram("bugpoint.reference.out"); - CreatedOutput = true; - std::cout << " done! Reference output is: " << Output << "\n"; - } else if (diffProgram(Output)) { + if (diffProgram()) { std::cout << "\n*** Input program does not match reference diff!\n" - << " Must be problem with input source!\n"; + << " Must be problem with input source!\n"; return false; // Problem found } - // Figure out which transformations miscompile the input program. - unsigned OldSize = PassesToRun.size(); - ReduceMiscompilingPasses(*this).reduceList(PassesToRun); - // Make sure something was miscompiled... - if (PassesToRun.size() == OldSize) { + if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun)) { std::cerr << "*** Optimized program matches reference output! No problem " << "detected...\nbugpoint can't help you with your problem!\n"; return false; @@ -321,7 +280,6 @@ bool BugDriver::debugMiscompilation() { << getPassesString(PassesToRun) << "\n"; EmitProgressBytecode("passinput"); - // Okay, now that we have reduced the list of passes which are causing the // failure, see if we can pin down which functions are being // miscompiled... first build a list of all of the non-external functions in @@ -341,6 +299,5 @@ bool BugDriver::debugMiscompilation() { // Output a bunch of bytecode files for the user... ReduceMiscompilingFunctions(*this).TestFuncs(MiscompiledFunctions, true); - if (CreatedOutput) removeFile(Output); return false; }