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 > llvm-commits@cs.uiuc.edu > 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 llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits