//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class contains all of the shared state and information that is used by
// the BugPoint tool to track down errors in optimizations.  This class is the
// main driver class that invokes all sub-functionality.
//
//===----------------------------------------------------------------------===//

#ifndef BUGDRIVER_H
#define BUGDRIVER_H

#include "llvm/ADT/ValueMap.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <vector>
#include <string>

namespace llvm {

class Value;
class PassInfo;
class Module;
class GlobalVariable;
class Function;
class BasicBlock;
class AbstractInterpreter;
class Instruction;
class LLVMContext;

class DebugCrashes;

class GCC;

extern bool DisableSimplifyCFG;

/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
///
extern bool BugpointIsInterrupted;

class BugDriver {
  LLVMContext& Context;
  const char *ToolName;            // argv[0] of bugpoint
  std::string ReferenceOutputFile; // Name of `good' output file
  Module *Program;             // The raw program, linked together
  std::vector<std::string> PassesToRun;
  AbstractInterpreter *Interpreter;   // How to run the program
  AbstractInterpreter *SafeInterpreter;  // To generate reference output, etc.
  GCC *gcc;
  bool run_find_bugs;
  unsigned Timeout;
  unsigned MemoryLimit;
  bool UseValgrind;

  // FIXME: sort out public/private distinctions...
  friend class ReducePassList;
  friend class ReduceMisCodegenFunctions;

public:
  BugDriver(const char *toolname, bool find_bugs,
            unsigned timeout, unsigned memlimit, bool use_valgrind,
            LLVMContext& ctxt);
  ~BugDriver();

  const char *getToolName() const { return ToolName; }

  LLVMContext& getContext() const { return Context; }

  // Set up methods... these methods are used to copy information about the
  // command line arguments into instance variables of BugDriver.
  //
  bool addSources(const std::vector<std::string> &FileNames);
  void addPass(std::string p) { PassesToRun.push_back(p); }
  void setPassesToRun(const std::vector<std::string> &PTR) {
    PassesToRun = PTR;
  }
  const std::vector<std::string> &getPassesToRun() const {
    return PassesToRun;
  }

  /// run - The top level method that is invoked after all of the instance
  /// variables are set up from command line arguments. The \p as_child argument
  /// indicates whether the driver is to run in parent mode or child mode.
  ///
  bool run(std::string &ErrMsg);

  /// debugOptimizerCrash - This method is called when some optimizer pass
  /// crashes on input.  It attempts to prune down the testcase to something
  /// reasonable, and figure out exactly which pass is crashing.
  ///
  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
  /// while still causing the code generator to crash.
  bool debugCodeGeneratorCrash(std::string &Error);

  /// debugMiscompilation - This method is used when the passes selected are not
  /// crashing, but the generated output is semantically different from the
  /// input.
  void debugMiscompilation(std::string *Error);

  /// debugPassMiscompilation - This method is called when the specified pass
  /// miscompiles Program as input.  It tries to reduce the testcase to
  /// something that smaller that still miscompiles the program.
  /// ReferenceOutput contains the filename of the file containing the output we
  /// are to match.
  ///
  bool debugPassMiscompilation(const PassInfo *ThePass,
                               const std::string &ReferenceOutput);

  /// compileSharedObject - This method creates a SharedObject from a given
  /// BitcodeFile for debugging a code generator.
  ///
  std::string compileSharedObject(const std::string &BitcodeFile,
                                  std::string &Error);

  /// debugCodeGenerator - This method narrows down a module to a function or
  /// set of functions, using the CBE as a ``safe'' code generator for other
  /// functions that are not under consideration.
  bool debugCodeGenerator(std::string *Error);

  /// isExecutingJIT - Returns true if bugpoint is currently testing the JIT
  ///
  bool isExecutingJIT();

  /// runPasses - Run all of the passes in the "PassesToRun" list, discard the
  /// output, and return true if any of the passes crashed.
  bool runPasses(Module *M) const {
    return runPasses(M, PassesToRun);
  }

  Module *getProgram() const { return Program; }

  /// swapProgramIn - Set the current module to the specified module, returning
  /// the old one.
  Module *swapProgramIn(Module *M) {
    Module *OldProgram = Program;
    Program = M;
    return OldProgram;
  }

  AbstractInterpreter *switchToSafeInterpreter() {
    AbstractInterpreter *Old = Interpreter;
    Interpreter = (AbstractInterpreter*)SafeInterpreter;
    return Old;
  }

  void switchToInterpreter(AbstractInterpreter *AI) {
    Interpreter = AI;
  }

  /// setNewProgram - If we reduce or update the program somehow, call this
  /// method to update bugdriver with it.  This deletes the old module and sets
  /// the specified one as the current program.
  void setNewProgram(Module *M);

  /// compileProgram - Try to compile the specified module, returning false and
  /// setting Error if an error occurs.  This is used for code generation
  /// crash testing.
  ///
  void compileProgram(Module *M, std::string *Error) const;

  /// executeProgram - This method runs "Program", capturing the output of the
  /// program to a file.  A recommended filename may be optionally specified.
  ///
  std::string executeProgram(const Module *Program,
                             std::string OutputFilename,
                             std::string Bitcode,
                             const std::string &SharedObjects,
                             AbstractInterpreter *AI,
                             std::string *Error) const;

  /// executeProgramSafely - Used to create reference output with the "safe"
  /// backend, if reference output is not provided.  If there is a problem with
  /// the code generator (e.g., llc crashes), this will return false and set
  /// Error.
  ///
  std::string executeProgramSafely(const Module *Program,
                                   std::string OutputFile,
                                   std::string *Error) const;

  /// 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, 1 is returned.  If there is a problem with the code
  /// generator (e.g., llc crashes), this will return -1 and set Error.
  ///
  bool diffProgram(const Module *Program,
                   const std::string &BitcodeFile = "",
                   const std::string &SharedObj = "",
                   bool RemoveBitcode = false,
                   std::string *Error = 0) const;

  /// EmitProgressBitcode - This function is used to output M to a file named
  /// "bugpoint-ID.bc".
  ///
  void EmitProgressBitcode(const Module *M, const std::string &ID,
                           bool NoFlyer = false) const;

  /// deleteInstructionFromProgram - This method clones the current Program and
  /// deletes the specified instruction from the cloned module.  It then runs a
  /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code
  /// which depends on the value.  The modified module is then returned.
  ///
  Module *deleteInstructionFromProgram(const Instruction *I, unsigned Simp);

  /// performFinalCleanups - This method clones the current Program and performs
  /// a series of cleanups intended to get rid of extra cruft on the module.  If
  /// the MayModifySemantics argument is true, then the cleanups is allowed to
  /// modify how the code behaves.
  ///
  Module *performFinalCleanups(Module *M, bool MayModifySemantics = false);

  /// ExtractLoop - Given a module, extract up to one loop from it into a new
  /// function.  This returns null if there are no extractable loops in the
  /// program or if the loop extractor crashes.
  Module *ExtractLoop(Module *M);

  /// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks
  /// into their own functions.  The only detail is that M is actually a module
  /// cloned from the one the BBs are in, so some mapping needs to be performed.
  /// If this operation fails for some reason (ie the implementation is buggy),
  /// this function should return null, otherwise it returns a new Module.
  Module *ExtractMappedBlocksFromModule(const std::vector<BasicBlock*> &BBs,
                                        Module *M);

  /// runPassesOn - Carefully run the specified set of pass on the specified
  /// module, returning the transformed module on success, or a null pointer on
  /// failure.  If AutoDebugCrashes is set to true, then bugpoint will
  /// automatically attempt to track down a crashing pass if one exists, and
  /// this method will never return null.
  Module *runPassesOn(Module *M, const std::vector<std::string> &Passes,
                      bool AutoDebugCrashes = false, unsigned NumExtraArgs = 0,
                      const char * const *ExtraArgs = NULL);

  /// runPasses - Run the specified passes on Program, outputting a bitcode
  /// file and writting the filename into OutputFile if successful.  If the
  /// optimizations fail for some reason (optimizer crashes), return true,
  /// otherwise return false.  If DeleteOutput is set to true, the bitcode is
  /// deleted on success, and the filename string is undefined.  This prints to
  /// outs() a single line message indicating whether compilation was successful
  /// or failed, unless Quiet is set.  ExtraArgs specifies additional arguments
  /// to pass to the child bugpoint instance.
  ///
  bool runPasses(Module *Program,
                 const std::vector<std::string> &PassesToRun,
                 std::string &OutputFilename, bool DeleteOutput = false,
                 bool Quiet = false, unsigned NumExtraArgs = 0,
                 const char * const *ExtraArgs = NULL) 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<std::string> &AllPasses,
                     std::string &ErrMsg);

  /// writeProgramToFile - This writes the current "Program" to the named
  /// bitcode file.  If an error occurs, true is returned.
  ///
  bool writeProgramToFile(const std::string &Filename, const Module *M) const;

private:
  /// runPasses - Just like the method above, but this just returns true or
  /// false indicating whether or not the optimizer crashed on the specified
  /// input (true = crashed).
  ///
  bool runPasses(Module *M,
                 const std::vector<std::string> &PassesToRun,
                 bool DeleteOutput = true) const {
    std::string Filename;
    return runPasses(M, PassesToRun, Filename, DeleteOutput);
  }

  /// initializeExecutionEnvironment - This method is used to set up the
  /// environment for executing LLVM programs.
  ///
  bool initializeExecutionEnvironment();
};

/// ParseInputFile - Given a bitcode or assembly input filename, parse and
/// return it, or return null if not possible.
///
Module *ParseInputFile(const std::string &InputFilename,
                       LLVMContext& ctxt);


/// getPassesString - Turn a list of passes into a string which indicates the
/// command line options that must be passed to add the passes.
///
std::string getPassesString(const std::vector<std::string> &Passes);

/// PrintFunctionList - prints out list of problematic functions
///
void PrintFunctionList(const std::vector<Function*> &Funcs);

/// PrintGlobalVariableList - prints out list of problematic global variables
///
void PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs);

// DeleteFunctionBody - "Remove" the function by deleting all of it's basic
// blocks, making it external.
//
void DeleteFunctionBody(Function *F);

/// SplitFunctionsOutOfModule - Given a module and a list of functions in the
/// module, split the functions OUT of the specified module, and place them in
/// the new module.
Module *SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F,
                                  ValueToValueMapTy &VMap);

} // End llvm namespace

#endif
