//===- ListReducer.h - Trim down list while retaining property --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class is to be used as a base class for operations that want to zero in
// on a subset of the input which still causes the bug we are tracking.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_BUGPOINT_LISTREDUCER_H
#define LLVM_TOOLS_BUGPOINT_LISTREDUCER_H

#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdlib>
#include <random>
#include <vector>

namespace llvm {

extern bool BugpointIsInterrupted;

template <typename ElTy> struct ListReducer {
  enum TestResult {
    NoFailure,  // No failure of the predicate was detected
    KeepSuffix, // The suffix alone satisfies the predicate
    KeepPrefix  // The prefix alone satisfies the predicate
  };

  virtual ~ListReducer() {}

  /// This virtual function should be overriden by subclasses to implement the
  /// test desired.  The testcase is only required to test to see if the Kept
  /// list still satisfies the property, but if it is going to check the prefix
  /// anyway, it can.
  virtual Expected<TestResult> doTest(std::vector<ElTy> &Prefix,
                                      std::vector<ElTy> &Kept) = 0;

  /// This function attempts to reduce the length of the specified list while
  /// still maintaining the "test" property.  This is the core of the "work"
  /// that bugpoint does.
  Expected<bool> reduceList(std::vector<ElTy> &TheList) {
    std::vector<ElTy> empty;
    std::mt19937 randomness(0x6e5ea738);  // Seed the random number generator
    Expected<TestResult> Result = doTest(TheList, empty);
    if (Error E = Result.takeError())
      return std::move(E);
    switch (*Result) {
    case KeepPrefix:
      if (TheList.size() == 1) // we are done, it's the base case and it fails
        return true;
      else
        break; // there's definitely an error, but we need to narrow it down

    case KeepSuffix:
      // cannot be reached!
      llvm_unreachable("bugpoint ListReducer internal error: "
                       "selected empty set.");

    case NoFailure:
      return false; // there is no failure with the full set of passes/funcs!
    }

    // Maximal number of allowed splitting iterations,
    // before the elements are randomly shuffled.
    const unsigned MaxIterationsWithoutProgress = 3;

    // Maximal number of allowed single-element trim iterations. We add a
    // threshold here as single-element reductions may otherwise take a
    // very long time to complete.
    const unsigned MaxTrimIterationsWithoutBackJump = 3;
    bool ShufflingEnabled = true;

  Backjump:
    unsigned MidTop = TheList.size();
    unsigned MaxIterations = MaxIterationsWithoutProgress;
    unsigned NumOfIterationsWithoutProgress = 0;
    while (MidTop > 1) { // Binary split reduction loop
      // Halt if the user presses ctrl-c.
      if (BugpointIsInterrupted) {
        errs() << "\n\n*** Reduction Interrupted, cleaning up...\n\n";
        return true;
      }

      // If the loop doesn't make satisfying progress, try shuffling.
      // The purpose of shuffling is to avoid the heavy tails of the
      // distribution (improving the speed of convergence).
      if (ShufflingEnabled && NumOfIterationsWithoutProgress > MaxIterations) {
        std::vector<ElTy> ShuffledList(TheList);
        std::shuffle(ShuffledList.begin(), ShuffledList.end(), randomness);
        errs() << "\n\n*** Testing shuffled set...\n\n";
        // Check that random shuffle doesn't lose the bug
        Expected<TestResult> Result = doTest(ShuffledList, empty);
        // TODO: Previously, this error was ignored and we treated it as if
        // shuffling hid the bug. This should really either be consumeError if
        // that behaviour was sensible, or we should propagate the error.
        assert(!Result.takeError() && "Shuffling caused internal error?");

        if (*Result == KeepPrefix) {
          // If the bug is still here, use the shuffled list.
          TheList.swap(ShuffledList);
          MidTop = TheList.size();
          // Must increase the shuffling treshold to avoid the small
          // probability of infinite looping without making progress.
          MaxIterations += 2;
          errs() << "\n\n*** Shuffling does not hide the bug...\n\n";
        } else {
          ShufflingEnabled = false; // Disable shuffling further on
          errs() << "\n\n*** Shuffling hides the bug...\n\n";
        }
        NumOfIterationsWithoutProgress = 0;
      }

      unsigned Mid = MidTop / 2;
      std::vector<ElTy> Prefix(TheList.begin(), TheList.begin() + Mid);
      std::vector<ElTy> Suffix(TheList.begin() + Mid, TheList.end());

      Expected<TestResult> Result = doTest(Prefix, Suffix);
      if (Error E = Result.takeError())
        return std::move(E);
      switch (*Result) {
      case KeepSuffix:
        // The property still holds.  We can just drop the prefix elements, and
        // shorten the list to the "kept" elements.
        TheList.swap(Suffix);
        MidTop = TheList.size();
        // Reset progress treshold and progress counter
        MaxIterations = MaxIterationsWithoutProgress;
        NumOfIterationsWithoutProgress = 0;
        break;
      case KeepPrefix:
        // The predicate still holds, shorten the list to the prefix elements.
        TheList.swap(Prefix);
        MidTop = TheList.size();
        // Reset progress treshold and progress counter
        MaxIterations = MaxIterationsWithoutProgress;
        NumOfIterationsWithoutProgress = 0;
        break;
      case NoFailure:
        // Otherwise the property doesn't hold.  Some of the elements we removed
        // must be necessary to maintain the property.
        MidTop = Mid;
        NumOfIterationsWithoutProgress++;
        break;
      }
    }

    // Probability of backjumping from the trimming loop back to the binary
    // split reduction loop.
    const int BackjumpProbability = 10;

    // Okay, we trimmed as much off the top and the bottom of the list as we
    // could.  If there is more than two elements in the list, try deleting
    // interior elements and testing that.
    //
    if (TheList.size() > 2) {
      bool Changed = true;
      std::vector<ElTy> EmptyList;
      unsigned TrimIterations = 0;
      while (Changed) { // Trimming loop.
        Changed = false;

        // If the binary split reduction loop made an unfortunate sequence of
        // splits, the trimming loop might be left off with a huge number of
        // remaining elements (large search space). Backjumping out of that
        // search space and attempting a different split can significantly
        // improve the convergence speed.
        if (std::rand() % 100 < BackjumpProbability)
          goto Backjump;

        for (unsigned i = 1; i < TheList.size() - 1; ++i) {
          // Check interior elts
          if (BugpointIsInterrupted) {
            errs() << "\n\n*** Reduction Interrupted, cleaning up...\n\n";
            return true;
          }

          std::vector<ElTy> TestList(TheList);
          TestList.erase(TestList.begin() + i);

          Expected<TestResult> Result = doTest(EmptyList, TestList);
          if (Error E = Result.takeError())
            return std::move(E);
          if (*Result == KeepSuffix) {
            // We can trim down the list!
            TheList.swap(TestList);
            --i; // Don't skip an element of the list
            Changed = true;
          }
        }
        if (TrimIterations >= MaxTrimIterationsWithoutBackJump)
          break;
        TrimIterations++;
      }
    }

    return true; // there are some failure and we've narrowed them down
  }
};

} // End llvm namespace

#endif
