//===- ImmutableSetIteratorBM.cpp - Benchmark ImmutableSet iterators ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Benchmarks in-order traversal of the ImutAVLTree backing ImmutableSet using
// only its public iterator API. It does not compare iterator implementations
// directly; instead, run the binary before and after a change to the iterator
// and compare the two reports (e.g. with llvm/utils/compare.py) to see the
// effect of that change.
//
// Two access patterns are measured:
//   * Iterate - a plain forward walk over ImmutableSet::iterator, the common
//               client usage.
//   * Skip    - a walk that calls skipSubTree on the tree iterator at every
//               other node, the pattern used by ImutAVLTree::isEqual and the
//               tree canonicalization that the clang static analyzer relies on.
//
// It also measures tree canonicalization directly:
//   * CanonicalizeSharedEqual - re-canonicalize a freshly built tree that is
//               structurally equal to, and shares subtrees with, a tree already
//               in the factory's cache. This is the clang static analyzer's hot
//               path when equivalent ProgramStates are re-derived on many
//               paths, and it exercises ImutAVLFactory::getCanonicalTree ->
//               ImutAVLTree::isEqual.
//
//===----------------------------------------------------------------------===//

#include "benchmark/benchmark.h"
#include "llvm/ADT/ImmutableSet.h"
#include <algorithm>
#include <cstdint>
#include <numeric>
#include <random>
#include <vector>

using namespace llvm;

namespace {

// Non-canonicalizing set (matches the dataflow analyses' usage).
using IntSet =
    ImmutableSet<int, ImutContainerInfo<int>, /*Canonicalize=*/false>;
using Tree = IntSet::TreeTy;

// Holds a factory plus a built set so the (non-trivial) tree construction is
// kept out of the timed region. The factory must outlive the tree.
struct Fixture {
  IntSet::Factory F;
  IntSet Set = F.getEmptySet();

  explicit Fixture(size_t N) {
    std::vector<int> Vals(N);
    std::iota(Vals.begin(), Vals.end(), 0);
    std::mt19937 Rng(0xC0FFEE);
    std::shuffle(Vals.begin(), Vals.end(), Rng);
    for (int V : Vals)
      Set = F.add(Set, V);
  }
};

// Plain forward iteration over the public ImmutableSet::iterator.
static void BM_Iterate(benchmark::State &State) {
  const size_t N = State.range(0);
  Fixture Fix(N);
  const IntSet &S = Fix.Set;
  benchmark::DoNotOptimize(S.getRootWithoutRetain());

  for (auto _ : State) {
    int64_t Sum = 0;
    for (int V : S)
      Sum += V;
    benchmark::DoNotOptimize(Sum);
  }
  State.SetItemsProcessed(State.iterations() * N);
}

// Iterate while skipping every other subtree, exercising skipSubTree (the
// pattern behind ImutAVLTree::isEqual / canonicalization) rather than plain ++.
static void BM_IterateWithSkips(benchmark::State &State) {
  const size_t N = State.range(0);
  Fixture Fix(N);
  const Tree *Root = Fix.Set.getRootWithoutRetain();
  benchmark::DoNotOptimize(Root);

  for (auto _ : State) {
    int64_t Sum = 0;
    unsigned K = 0;
    for (Tree::iterator I(Root), E; I != E; ++K) {
      Sum += I->getValue();
      if (K & 1)
        I.skipSubTree();
      else
        ++I;
    }
    benchmark::DoNotOptimize(Sum);
  }
}

// Compare two iterators positioned at the same (non-end) node on every step.
// This isolates operator==: it is the case that differs between comparing the
// current node only (O(1)) and comparing the whole ancestor path (O(depth)).
// It is a microbenchmark of the comparison itself, not a typical client loop
// (those compare against end(), which is O(1) either way).
static void BM_CompareSamePosition(benchmark::State &State) {
  const size_t N = State.range(0);
  Fixture Fix(N);
  const Tree *Root = Fix.Set.getRootWithoutRetain();
  benchmark::DoNotOptimize(Root);

  for (auto _ : State) {
    bool R = false;
    Tree::iterator E;
    for (Tree::iterator A(Root), B(Root); A != E; ++A, ++B)
      R ^= (A == B);
    benchmark::DoNotOptimize(R);
  }
  State.SetItemsProcessed(State.iterations() * N);
}

// Re-canonicalize a freshly built tree that is structurally equal to a tree
// already in the factory's cache and shares most of its subtrees. This mirrors
// the clang static analyzer, where equivalent ProgramStates re-derived on many
// paths are canonicalized against ones already cached. Adding then removing an
// absent (largest) key rebuilds only the right spine while sharing the rest of
// Base's subtrees, so getCanonicalTree confirms equality against a structurally
// shared equal tree -- exactly where isEqual's subtree pointer skipping
// matters.
static void BM_CanonicalizeSharedEqual(benchmark::State &State) {
  const size_t N = State.range(0);
  // This case exercises canonicalization, so it uses a canonicalizing factory.
  ImmutableSet<int>::Factory F;
  ImmutableSet<int> Base = F.getEmptySet();
  std::vector<int> Vals(N);
  std::iota(Vals.begin(), Vals.end(), 0);
  std::mt19937 Rng(0xC0FFEE);
  std::shuffle(Vals.begin(), Vals.end(), Rng);
  for (int V : Vals)
    Base = F.add(Base, V); // Base is canonical and lives in the factory cache.
  const int Absent = static_cast<int>(N) + 1;

  for (auto _ : State) {
    ImmutableSet<int> Tmp = F.add(Base, Absent);
    ImmutableSet<int> Eq = F.remove(Tmp, Absent); // structurally equal to Base
    benchmark::DoNotOptimize(Eq.getRootWithoutRetain());
  }
  State.SetItemsProcessed(State.iterations());
}

} // namespace

#define ITER_SIZES Arg(16)->Arg(256)->Arg(4096)->Arg(65536)

BENCHMARK(BM_Iterate)->Name("Iterate")->ITER_SIZES;
BENCHMARK(BM_IterateWithSkips)->Name("Skip")->ITER_SIZES;
BENCHMARK(BM_CompareSamePosition)->Name("CompareSamePos")->ITER_SIZES;
BENCHMARK(BM_CanonicalizeSharedEqual)
    ->Name("CanonicalizeSharedEqual")
    ->ITER_SIZES;

BENCHMARK_MAIN();
