<commit_before>//===- CrashDebugger.cpp - Debug compilation crashes ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the bugpoint internals that narrow down compilation crashes
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ListReducer.h"
#include "llvm/Constant.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/SymbolTable.h"
#include "llvm/Type.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bytecode/Writer.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/ToolRunner.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Support/FileUtilities.h"
#include <fstream>
#include <set>
using namespace llvm;

namespace llvm {
  class ReducePassList : public ListReducer<const PassInfo*> {
    BugDriver &BD;
  public:
    ReducePassList(BugDriver &bd) : BD(bd) {}

    // doTest - Return true iff running the "removed" passes succeeds, and
    // running the "Kept" passes fail when run on the output of the "removed"
    // passes.  If we return true, we update the current module of bugpoint.
    //
    virtual TestResult doTest(std::vector<const PassInfo*> &Removed,
                              std::vector<const PassInfo*> &Kept);
  };
}

ReducePassList::TestResult
ReducePassList::doTest(std::vector<const PassInfo*> &Prefix,
                       std::vector<const PassInfo*> &Suffix) {
  sys::Path PrefixOutput;
  Module *OrigProgram = 0;
  if (!Prefix.empty()) {
    std::cout << "Checking to see if these passes crash: "
              << getPassesString(Prefix) << ": ";
    std::string PfxOutput;
    if (BD.runPasses(Prefix, PfxOutput))
      return KeepPrefix;

    PrefixOutput.set(PfxOutput);
    OrigProgram = BD.Program;

    BD.Program = ParseInputFile(PrefixOutput.toString());
    if (BD.Program == 0) {
      std::cerr << BD.getToolName() << ": Error reading bytecode file '"
                << PrefixOutput << "'!\n";
      exit(1);
    }
    PrefixOutput.eraseFromDisk();
  }

  std::cout << "Checking to see if these passes crash: "
            << getPassesString(Suffix) << ": ";

  if (BD.runPasses(Suffix)) {
    delete OrigProgram;            // The suffix crashes alone...
    return KeepSuffix;
  }

  // Nothing failed, restore state...
  if (OrigProgram) {
    delete BD.Program;
    BD.Program = OrigProgram;
  }
  return NoFailure;
}

namespace llvm {
  class ReduceCrashingFunctions : public ListReducer<Function*> {
    BugDriver &BD;
    bool (*TestFn)(BugDriver &, Module *);
  public:
    ReduceCrashingFunctions(BugDriver &bd,
                            bool (*testFn)(BugDriver &, Module *))
      : BD(bd), TestFn(testFn) {}

    virtual TestResult doTest(std::vector<Function*> &Prefix,
                              std::vector<Function*> &Kept) {
      if (!Kept.empty() && TestFuncs(Kept))
        return KeepSuffix;
      if (!Prefix.empty() && TestFuncs(Prefix))
        return KeepPrefix;
      return NoFailure;
    }

    bool TestFuncs(std::vector<Function*> &Prefix);
  };
}

bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
  // Clone the program to try hacking it apart...
  Module *M = CloneModule(BD.getProgram());

  // Convert list to set for fast lookup...
  std::set<Function*> Functions;
  for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
    Function *CMF = M->getFunction(Funcs[i]->getName(),
                                   Funcs[i]->getFunctionType());
    assert(CMF && "Function not in module?!");
    Functions.insert(CMF);
  }

  std::cout << "Checking for crash with only these functions: ";
  PrintFunctionList(Funcs);
  std::cout << ": ";

  // Loop over and delete any functions which we aren't supposed to be playing
  // with...
  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
    if (!I->isExternal() && !Functions.count(I))
      DeleteFunctionBody(I);
<commit_msg>For transforms the behave differently if main goes away, add an option to prevent bugpoint from removing main<commit_after>//===- CrashDebugger.cpp - Debug compilation crashes ----------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the bugpoint internals that narrow down compilation crashes
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ListReducer.h"
#include "llvm/Constant.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/PassManager.h"
#include "llvm/SymbolTable.h"
#include "llvm/Type.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bytecode/Writer.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/ToolRunner.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/CommandLine.h"
#include <fstream>
#include <set>
using namespace llvm;

namespace {
  cl::opt<bool>
  KeepMain("keep-main",
           cl::desc("Force function reduction to keep main"),
           cl::init(false));
}

namespace llvm {
  class ReducePassList : public ListReducer<const PassInfo*> {
    BugDriver &BD;
  public:
    ReducePassList(BugDriver &bd) : BD(bd) {}

    // doTest - Return true iff running the "removed" passes succeeds, and
    // running the "Kept" passes fail when run on the output of the "removed"
    // passes.  If we return true, we update the current module of bugpoint.
    //
    virtual TestResult doTest(std::vector<const PassInfo*> &Removed,
                              std::vector<const PassInfo*> &Kept);
  };
}

ReducePassList::TestResult
ReducePassList::doTest(std::vector<const PassInfo*> &Prefix,
                       std::vector<const PassInfo*> &Suffix) {
  sys::Path PrefixOutput;
  Module *OrigProgram = 0;
  if (!Prefix.empty()) {
    std::cout << "Checking to see if these passes crash: "
              << getPassesString(Prefix) << ": ";
    std::string PfxOutput;
    if (BD.runPasses(Prefix, PfxOutput))
      return KeepPrefix;

    PrefixOutput.set(PfxOutput);
    OrigProgram = BD.Program;

    BD.Program = ParseInputFile(PrefixOutput.toString());
    if (BD.Program == 0) {
      std::cerr << BD.getToolName() << ": Error reading bytecode file '"
                << PrefixOutput << "'!\n";
      exit(1);
    }
    PrefixOutput.eraseFromDisk();
  }

  std::cout << "Checking to see if these passes crash: "
            << getPassesString(Suffix) << ": ";

  if (BD.runPasses(Suffix)) {
    delete OrigProgram;            // The suffix crashes alone...
    return KeepSuffix;
  }

  // Nothing failed, restore state...
  if (OrigProgram) {
    delete BD.Program;
    BD.Program = OrigProgram;
  }
  return NoFailure;
}

namespace llvm {
  class ReduceCrashingFunctions : public ListReducer<Function*> {
    BugDriver &BD;
    bool (*TestFn)(BugDriver &, Module *);
  public:
    ReduceCrashingFunctions(BugDriver &bd,
                            bool (*testFn)(BugDriver &, Module *))
      : BD(bd), TestFn(testFn) {}

    virtual TestResult doTest(std::vector<Function*> &Prefix,
                              std::vector<Function*> &Kept) {
      if (!Kept.empty() && TestFuncs(Kept))
        return KeepSuffix;
      if (!Prefix.empty() && TestFuncs(Prefix))
        return KeepPrefix;
      return NoFailure;
    }

    bool TestFuncs(std::vector<Function*> &Prefix);
  };
}

bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {

  //if main isn't present, claim there is no problem
  if (KeepMain && find(Funcs.begin(), Funcs.end(), BD.getProgram()->getMainFunction()) == Funcs.end())
    return false;

  // Clone the program to try hacking it apart...
  Module *M = CloneModule(BD.getProgram());

  // Convert list to set for fast lookup...
  std::set<Function*> Functions;
  for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
    Function *CMF = M->getFunction(Funcs[i]->getName(),
                                   Funcs[i]->getFunctionType());
    assert(CMF && "Function not in module?!");
    Functions.insert(CMF);
  }

  std::cout << "Checking for crash with only these functions: ";
  PrintFunctionList(Funcs);
  std::cout << ": ";

  // Loop over and delete any functions which we aren't supposed to be playing
  // with...
  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
    if (!I->isExternal() && !Functions.count(I))
      DeleteFunctionBody(I);

{'fraction_non_alphanumeric': 0.17566674013665418, 'fraction_numerical': 0.0008816398501212255, 'mean_word_length': 2.599761999206664, 'pattern_counts': {'":': 8, '<': 78, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1986731', 'n_tokens_mistral': 2759, 'n_tokens_neox': 2671, 'n_words': 720}