Is the external program part of this generalized? I and others have
cases where we need to run a complex series of programs to test the
correctness of a transform. Namely, we want to take a compiled kernel
start it up in a simulator, check something then return and tell
bugpoint if the output was right or not.
Andrew
On Tue, 2006-08-15 at 11:41 -0500, Patrick Jenkins wrote:
>
> Changes in directory llvm/tools/bugpoint:
>
> BugDriver.cpp updated: 1.46 -> 1.47
> BugDriver.h updated: 1.43 -> 1.44
> CrashDebugger.cpp updated: 1.48 -> 1.49
> ExecutionDriver.cpp updated: 1.62 -> 1.63
> bugpoint.cpp updated: 1.31 -> 1.32
> ---
> Log message:
>
> This commit adds a new feature called find-bugs. The find-bugs option can be
> invoked on a .bc file from the command like with -find-bugs and a list of
> passes you wish to test. This procedure takes the set of optimization passes
> the user specifies, randomizes the passes, runs the passes on the specified
> .bc file, compiles the program, and finally runs the program checking its
> output vs the .bc file with no optimizations. This process repeats until
> either the user kills bugpoint or an error occurs in the optimizations,
> program complitation, or the running of the program. If an error occurs,
> bugpoint attempts to diagnose the error by eliminating passes that are not at
> fault and code that is not needed.
>
>
> ---
> Diffs of the changes: (+73 -26)
>
> BugDriver.cpp | 30 ++++++++++++++----------------
> BugDriver.h | 23 +++++++++++++++++++++--
> CrashDebugger.cpp | 4 ++--
> ExecutionDriver.cpp | 32 +++++++++++++++++++++++++++++---
> bugpoint.cpp | 10 +++++++---
> 5 files changed, 73 insertions(+), 26 deletions(-)
>
>
> Index: llvm/tools/bugpoint/BugDriver.cpp
> diff -u llvm/tools/bugpoint/BugDriver.cpp:1.46
> llvm/tools/bugpoint/BugDriver.cpp:1.47
> --- llvm/tools/bugpoint/BugDriver.cpp:1.46 Mon Jun 12 22:10:48 2006
> +++ llvm/tools/bugpoint/BugDriver.cpp Tue Aug 15 11:40:49 2006
> @@ -62,10 +62,11 @@
> return Result;
> }
>
> -BugDriver::BugDriver(const char *toolname, bool as_child, unsigned timeout)
> +BugDriver::BugDriver(const char *toolname, bool as_child, bool find_bugs,
> + unsigned timeout)
> : ToolName(toolname), ReferenceOutputFile(OutputFile),
> Program(0), Interpreter(0), cbe(0), gcc(0), run_as_child(as_child),
> - Timeout(timeout) {}
> + run_find_bugs(find_bugs), Timeout(timeout) {}
>
>
> /// ParseInputFile - Given a bytecode or assembly input filename, parse and
> @@ -140,6 +141,12 @@
> // Execute the passes
> return runPassesAsChild(PassesToRun);
> }
> +
> + 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);
> + }
>
> // 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
> @@ -175,20 +182,10 @@
> bool CreatedOutput = false;
> if (ReferenceOutputFile.empty()) {
> std::cout << "Generating reference output from raw program: ";
> - try {
> - ReferenceOutputFile = executeProgramWithCBE("bugpoint.reference.out");
> - CreatedOutput = true;
> - std::cout << "Reference output is: " << ReferenceOutputFile << '\n';
> - } catch (ToolExecutionError &TEE) {
> - std::cerr << TEE.what();
> - if (Interpreter != cbe) {
> - std::cerr << "*** There is a bug running the C backend. Either
> debug"
> - << " it (use the -run-cbe bugpoint option), or fix the
> error"
> - << " some other way.\n";
> - return 1;
> - }
> - return debugCodeGeneratorCrash();
> + if(!createReferenceFile(Program)){
> + return debugCodeGeneratorCrash();
> }
> + CreatedOutput = true;
> }
>
> // Make sure the reference output file gets deleted on exit from this
> @@ -197,7 +194,8 @@
> FileRemover RemoverInstance(ROF, CreatedOutput);
>
> // Diff the output of the raw program against the reference output. If it
> - // matches, then we have a miscompilation bug.
> + // matches, then we assume there is a miscompilation bug and try to
> + // diagnose it.
> std::cout << "*** Checking the code generator...\n";
> try {
> if (!diffProgram()) {
>
>
> Index: llvm/tools/bugpoint/BugDriver.h
> diff -u llvm/tools/bugpoint/BugDriver.h:1.43
> llvm/tools/bugpoint/BugDriver.h:1.44
> --- llvm/tools/bugpoint/BugDriver.h:1.43 Mon Jun 12 22:10:48 2006
> +++ llvm/tools/bugpoint/BugDriver.h Tue Aug 15 11:40:49 2006
> @@ -48,6 +48,7 @@
> CBE *cbe;
> GCC *gcc;
> bool run_as_child;
> + bool run_find_bugs;
> unsigned Timeout;
>
> // FIXME: sort out public/private distinctions...
> @@ -55,7 +56,8 @@
> friend class ReduceMisCodegenFunctions;
>
> public:
> - BugDriver(const char *toolname, bool as_child, unsigned timeout);
> + BugDriver(const char *toolname, bool as_child, bool find_bugs,
> + unsigned timeout);
>
> const std::string &getToolName() const { return ToolName; }
>
> @@ -82,7 +84,7 @@
> /// crashes on input. It attempts to prune down the testcase to something
> /// reasonable, and figure out exactly which pass is crashing.
> ///
> - bool debugOptimizerCrash();
> + 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
> @@ -175,6 +177,13 @@
> ///
> std::string executeProgramWithCBE(std::string OutputFile = "");
>
> + /// 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, true is returned. If there is a problem with the code
> @@ -183,6 +192,7 @@
> bool diffProgram(const std::string &BytecodeFile = "",
> const std::string &SharedObj = "",
> bool RemoveBytecode = false);
> +
> /// EmitProgressBytecode - This function is used to output the current
> Program
> /// to a file named "bugpoint-ID.bc".
> ///
> @@ -235,6 +245,15 @@
> bool runPasses(const std::vector<const PassInfo*> &PassesToRun,
> std::string &OutputFilename, bool DeleteOutput = false,
> bool Quiet = false) 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<const PassInfo*> &AllPasses);
>
> /// writeProgramToFile - This writes the current "Program" to the named
> /// bytecode file. If an error occurs, true is returned.
>
>
> Index: llvm/tools/bugpoint/CrashDebugger.cpp
> diff -u llvm/tools/bugpoint/CrashDebugger.cpp:1.48
> llvm/tools/bugpoint/CrashDebugger.cpp:1.49
> --- llvm/tools/bugpoint/CrashDebugger.cpp:1.48 Tue Jun 6 17:30:59 2006
> +++ llvm/tools/bugpoint/CrashDebugger.cpp Tue Aug 15 11:40:49 2006
> @@ -423,7 +423,7 @@
> /// It attempts to prune down the testcase to something reasonable, and
> figure
> /// out exactly which pass is crashing.
> ///
> -bool BugDriver::debugOptimizerCrash() {
> +bool BugDriver::debugOptimizerCrash(const std::string &ID) {
> std::cout << "\n*** Debugging optimizer crash!\n";
>
> // Reduce the list of passes which causes the optimizer to crash...
> @@ -435,7 +435,7 @@
> << (PassesToRun.size() == 1 ? ": " : "es: ")
> << getPassesString(PassesToRun) << '\n';
>
> - EmitProgressBytecode("passinput");
> + EmitProgressBytecode(ID);
>
> return DebugACrash(*this, TestForOptimizerCrash);
> }
>
>
> Index: llvm/tools/bugpoint/ExecutionDriver.cpp
> diff -u llvm/tools/bugpoint/ExecutionDriver.cpp:1.62
> llvm/tools/bugpoint/ExecutionDriver.cpp:1.63
> --- llvm/tools/bugpoint/ExecutionDriver.cpp:1.62 Tue Jun 27 15:35:36 2006
> +++ llvm/tools/bugpoint/ExecutionDriver.cpp Tue Aug 15 11:40:49 2006
> @@ -297,10 +297,36 @@
> return "./" + SharedObjectFile;
> }
>
> +/// 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 BugDriver::createReferenceFile(Module *M, const std::string &Filename){
> + try {
> + compileProgram(Program);
> + } catch (ToolExecutionError &TEE) {
> + return false;
> + }
> + try {
> + ReferenceOutputFile = executeProgramWithCBE(Filename);
> + std::cout << "Reference output is: " << ReferenceOutputFile << "\n\n";
> + } catch (ToolExecutionError &TEE) {
> + std::cerr << TEE.what();
> + if (Interpreter != cbe) {
> + std::cerr << "*** There is a bug running the C backend. Either debug"
> + << " it (use the -run-cbe bugpoint option), or fix the error"
> + << " some other way.\n";
> + }
> + return false;
> + }
> + return true;
> +}
>
> -/// diffProgram - This method executes the specified module and diffs the
> output
> -/// against the file specified by ReferenceOutputFile. If the output is
> -/// different, true is returned.
> +/// diffProgram - This method executes the specified module and diffs the
> +/// output against the file specified by ReferenceOutputFile. If the output
> +/// is different, true is returned. If there is a problem with the code
> +/// generator (e.g., llc crashes), this will throw an exception.
> ///
> bool BugDriver::diffProgram(const std::string &BytecodeFile,
> const std::string &SharedObject,
>
>
> Index: llvm/tools/bugpoint/bugpoint.cpp
> diff -u llvm/tools/bugpoint/bugpoint.cpp:1.31
> llvm/tools/bugpoint/bugpoint.cpp:1.32
> --- llvm/tools/bugpoint/bugpoint.cpp:1.31 Mon Jun 12 22:10:48 2006
> +++ llvm/tools/bugpoint/bugpoint.cpp Tue Aug 15 11:40:49 2006
> @@ -29,8 +29,12 @@
> // from a parent process. It is not intended to be used by users so the
> // option is hidden.
> static cl::opt<bool>
> - AsChild("as-child", cl::desc("Run bugpoint as child process"),
> - cl::ReallyHidden);
> +AsChild("as-child", cl::desc("Run bugpoint as child process"),
> + cl::ReallyHidden);
> +
> +static cl::opt<bool>
> +FindBugs("find-bugs", cl::desc("Run many different optimization sequences"
> + "on program to find bugs"), cl::init(false));
>
> static cl::list<std::string>
> InputFilenames(cl::Positional, cl::OneOrMore,
> @@ -62,7 +66,7 @@
> sys::PrintStackTraceOnErrorSignal();
> sys::SetInterruptFunction(BugpointInterruptFunction);
>
> - BugDriver D(argv[0],AsChild,TimeoutValue);
> + BugDriver D(argv[0],AsChild,FindBugs,TimeoutValue);
> if (D.addSources(InputFilenames)) return 1;
> D.addPasses(PassList.begin(), PassList.end());
>
>
>
>
> _______________________________________________
> llvm-commits mailing list
> [email protected]
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
http://www.lenharth.org/~andrewl/
And without software to do something useful with all that hardware, the
hardware's nothing more than a really complicated space heater.
--Neal Stephenson
_______________________________________________
llvm-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits