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

Reply via email to