//===- llvm/unittest/IR/PassManager.cpp - PassManager tests ---------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/PassManager.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManagerImpl.h"
#include "llvm/Passes/StandardInstrumentations.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

class TestFunctionAnalysis : public AnalysisInfoMixin<TestFunctionAnalysis> {
public:
  struct Result {
    Result(int Count) : InstructionCount(Count) {}
    int InstructionCount;
    bool invalidate(Function &, const PreservedAnalyses &PA,
                    FunctionAnalysisManager::Invalidator &) {
      // Check whether the analysis or all analyses on functions have been
      // preserved.
      auto PAC = PA.getChecker<TestFunctionAnalysis>();
      return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>());
    }
  };

  TestFunctionAnalysis(int &Runs) : Runs(Runs) {}

  /// Run the analysis pass over the function and return a result.
  Result run(Function &F, FunctionAnalysisManager &AM) {
    ++Runs;
    int Count = 0;
    for (Function::iterator BBI = F.begin(), BBE = F.end(); BBI != BBE; ++BBI)
      for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
           ++II)
        ++Count;
    return Result(Count);
  }

private:
  friend AnalysisInfoMixin<TestFunctionAnalysis>;
  static AnalysisKey Key;

  int &Runs;
};

AnalysisKey TestFunctionAnalysis::Key;

class TestModuleAnalysis : public AnalysisInfoMixin<TestModuleAnalysis> {
public:
  struct Result {
    Result(int Count) : FunctionCount(Count) {}
    int FunctionCount;
    bool invalidate(Module &, const PreservedAnalyses &PA,
                    ModuleAnalysisManager::Invalidator &) {
      // Check whether the analysis or all analyses on modules have been
      // preserved.
      auto PAC = PA.getChecker<TestModuleAnalysis>();
      return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Module>>());
    }
  };

  TestModuleAnalysis(int &Runs) : Runs(Runs) {}

  Result run(Module &M, ModuleAnalysisManager &AM) {
    ++Runs;
    int Count = 0;
    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
      ++Count;
    return Result(Count);
  }

private:
  friend AnalysisInfoMixin<TestModuleAnalysis>;
  static AnalysisKey Key;

  int &Runs;
};

AnalysisKey TestModuleAnalysis::Key;

struct TestModulePass : PassInfoMixin<TestModulePass> {
  TestModulePass(int &RunCount) : RunCount(RunCount) {}

  PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
    ++RunCount;
    return PreservedAnalyses::none();
  }

  int &RunCount;
};

struct TestPreservingModulePass : PassInfoMixin<TestPreservingModulePass> {
  PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
    return PreservedAnalyses::all();
  }
};

struct TestFunctionPass : PassInfoMixin<TestFunctionPass> {
  TestFunctionPass(int &RunCount, int &AnalyzedInstrCount,
                   int &AnalyzedFunctionCount, ModuleAnalysisManager &MAM,
                   bool OnlyUseCachedResults = false)
      : RunCount(RunCount), AnalyzedInstrCount(AnalyzedInstrCount),
        AnalyzedFunctionCount(AnalyzedFunctionCount), MAM(MAM),
        OnlyUseCachedResults(OnlyUseCachedResults) {}

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
    ++RunCount;

    // Getting a cached result that isn't stateless through the proxy will
    // trigger an assert:
    // auto &ModuleProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
    // Use MAM, for the purposes of this unittest.
    if (TestModuleAnalysis::Result *TMA =
            MAM.getCachedResult<TestModuleAnalysis>(*F.getParent())) {
      AnalyzedFunctionCount += TMA->FunctionCount;
    }

    if (OnlyUseCachedResults) {
      // Hack to force the use of the cached interface.
      if (TestFunctionAnalysis::Result *AR =
              AM.getCachedResult<TestFunctionAnalysis>(F))
        AnalyzedInstrCount += AR->InstructionCount;
    } else {
      // Typical path just runs the analysis as needed.
      TestFunctionAnalysis::Result &AR = AM.getResult<TestFunctionAnalysis>(F);
      AnalyzedInstrCount += AR.InstructionCount;
    }

    return PreservedAnalyses::all();
  }

  int &RunCount;
  int &AnalyzedInstrCount;
  int &AnalyzedFunctionCount;
  ModuleAnalysisManager &MAM;
  bool OnlyUseCachedResults;
};

// A test function pass that invalidates all function analyses for a function
// with a specific name.
struct TestInvalidationFunctionPass
    : PassInfoMixin<TestInvalidationFunctionPass> {
  TestInvalidationFunctionPass(StringRef FunctionName) : Name(FunctionName) {}

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
    return F.getName() == Name ? PreservedAnalyses::none()
                               : PreservedAnalyses::all();
  }

  StringRef Name;
};

std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {
  SMDiagnostic Err;
  return parseAssemblyString(IR, Err, Context);
}

class PassManagerTest : public ::testing::Test {
protected:
  LLVMContext Context;
  std::unique_ptr<Module> M;

public:
  PassManagerTest()
      : M(parseIR(Context, "define void @f() {\n"
                           "entry:\n"
                           "  call void @g()\n"
                           "  call void @h()\n"
                           "  ret void\n"
                           "}\n"
                           "define void @g() {\n"
                           "  ret void\n"
                           "}\n"
                           "define void @h() {\n"
                           "  ret void\n"
                           "}\n")) {}
};

TEST(PreservedAnalysesTest, Basic) {
  PreservedAnalyses PA1 = PreservedAnalyses();
  {
    auto PAC = PA1.getChecker<TestFunctionAnalysis>();
    EXPECT_FALSE(PAC.preserved());
    EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
  }
  {
    auto PAC = PA1.getChecker<TestModuleAnalysis>();
    EXPECT_FALSE(PAC.preserved());
    EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Module>>());
  }
  auto PA2 = PreservedAnalyses::none();
  {
    auto PAC = PA2.getChecker<TestFunctionAnalysis>();
    EXPECT_FALSE(PAC.preserved());
    EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
  }
  auto PA3 = PreservedAnalyses::all();
  {
    auto PAC = PA3.getChecker<TestFunctionAnalysis>();
    EXPECT_TRUE(PAC.preserved());
    EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
  }
  PreservedAnalyses PA4 = PA1;
  {
    auto PAC = PA4.getChecker<TestFunctionAnalysis>();
    EXPECT_FALSE(PAC.preserved());
    EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
  }
  PA4 = PA3;
  {
    auto PAC = PA4.getChecker<TestFunctionAnalysis>();
    EXPECT_TRUE(PAC.preserved());
    EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
  }
  PA4 = std::move(PA2);
  {
    auto PAC = PA4.getChecker<TestFunctionAnalysis>();
    EXPECT_FALSE(PAC.preserved());
    EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Function>>());
  }
  auto PA5 = PreservedAnalyses::allInSet<AllAnalysesOn<Function>>();
  {
    auto PAC = PA5.getChecker<TestFunctionAnalysis>();
    EXPECT_FALSE(PAC.preserved());
    EXPECT_TRUE(PAC.preservedSet<AllAnalysesOn<Function>>());
    EXPECT_FALSE(PAC.preservedSet<AllAnalysesOn<Module>>());
  }
}

TEST(PreservedAnalysesTest, Preserve) {
  auto PA = PreservedAnalyses::none();
  PA.preserve<TestFunctionAnalysis>();
  EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());
  PA.preserve<TestModuleAnalysis>();
  EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());

  // Redundant calls are fine.
  PA.preserve<TestFunctionAnalysis>();
  EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>().preserved());
}

TEST(PreservedAnalysesTest, PreserveSets) {
  auto PA = PreservedAnalyses::none();
  PA.preserveSet<AllAnalysesOn<Function>>();
  EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
                  .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
                   .preservedSet<AllAnalysesOn<Module>>());
  PA.preserveSet<AllAnalysesOn<Module>>();
  EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
                  .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());

  // Mixing is fine.
  PA.preserve<TestFunctionAnalysis>();
  EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
                  .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());

  // Redundant calls are fine.
  PA.preserveSet<AllAnalysesOn<Module>>();
  EXPECT_TRUE(PA.getChecker<TestFunctionAnalysis>()
                  .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_TRUE(PA.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());
}

TEST(PreservedAnalysisTest, Intersect) {
  // Setup the initial sets.
  auto PA1 = PreservedAnalyses::none();
  PA1.preserve<TestFunctionAnalysis>();
  PA1.preserveSet<AllAnalysesOn<Module>>();
  auto PA2 = PreservedAnalyses::none();
  PA2.preserve<TestFunctionAnalysis>();
  PA2.preserveSet<AllAnalysesOn<Function>>();
  PA2.preserve<TestModuleAnalysis>();
  PA2.preserveSet<AllAnalysesOn<Module>>();
  auto PA3 = PreservedAnalyses::none();
  PA3.preserve<TestModuleAnalysis>();
  PA3.preserveSet<AllAnalysesOn<Function>>();

  // Self intersection is a no-op.
  auto Intersected = PA1;
  Intersected.intersect(PA1);
  EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());

  // Intersecting with all is a no-op.
  Intersected.intersect(PreservedAnalyses::all());
  EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());

  // Intersecting a narrow set with a more broad set is the narrow set.
  Intersected.intersect(PA2);
  EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());

  // Intersecting a broad set with a more narrow set is the narrow set.
  Intersected = PA2;
  Intersected.intersect(PA1);
  EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());

  // Intersecting with empty clears.
  Intersected.intersect(PreservedAnalyses::none());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
                   .preservedSet<AllAnalysesOn<Module>>());

  // Intersecting non-overlapping clears.
  Intersected = PA1;
  Intersected.intersect(PA3);
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>()
                   .preservedSet<AllAnalysesOn<Module>>());

  // Intersecting with moves works in when there is storage on both sides.
  Intersected = PA1;
  auto Tmp = PA2;
  Intersected.intersect(std::move(Tmp));
  EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());

  // Intersecting with move works for incoming all and existing all.
  auto Tmp2 = PreservedAnalyses::all();
  Intersected.intersect(std::move(Tmp2));
  EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());
  Intersected = PreservedAnalyses::all();
  auto Tmp3 = PA1;
  Intersected.intersect(std::move(Tmp3));
  EXPECT_TRUE(Intersected.getChecker<TestFunctionAnalysis>().preserved());
  EXPECT_FALSE(Intersected.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(Intersected.getChecker<TestModuleAnalysis>().preserved());
  EXPECT_TRUE(Intersected.getChecker<TestModuleAnalysis>()
                  .preservedSet<AllAnalysesOn<Module>>());
}

TEST(PreservedAnalysisTest, Abandon) {
  auto PA = PreservedAnalyses::none();

  // We can abandon things after they are preserved.
  PA.preserve<TestFunctionAnalysis>();
  PA.abandon<TestFunctionAnalysis>();
  EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());

  // Repeated is fine, and abandoning if they were never preserved is fine.
  PA.abandon<TestFunctionAnalysis>();
  EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>().preserved());
  PA.abandon<TestModuleAnalysis>();
  EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>().preserved());

  // Even if the sets are preserved, the abandoned analyses' checker won't
  // return true for those sets.
  PA.preserveSet<AllAnalysesOn<Function>>();
  PA.preserveSet<AllAnalysesOn<Module>>();
  EXPECT_FALSE(PA.getChecker<TestFunctionAnalysis>()
                   .preservedSet<AllAnalysesOn<Function>>());
  EXPECT_FALSE(PA.getChecker<TestModuleAnalysis>()
                   .preservedSet<AllAnalysesOn<Module>>());

  // But an arbitrary (opaque) analysis will still observe the sets as
  // preserved. This also checks that we can use an explicit ID rather than
  // a type.
  AnalysisKey FakeKey, *FakeID = &FakeKey;
  EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Function>>());
  EXPECT_TRUE(PA.getChecker(FakeID).preservedSet<AllAnalysesOn<Module>>());
}

TEST_F(PassManagerTest, Basic) {
  FunctionAnalysisManager FAM;
  int FunctionAnalysisRuns = 0;
  FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });

  ModuleAnalysisManager MAM;
  int ModuleAnalysisRuns = 0;
  MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
  MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
  FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });

  MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
  FAM.registerPass([&] { return PassInstrumentationAnalysis(); });

  ModulePassManager MPM;

  // Count the runs over a Function.
  int FunctionPassRunCount1 = 0;
  int AnalyzedInstrCount1 = 0;
  int AnalyzedFunctionCount1 = 0;
  {
    // Pointless scoped copy to test move assignment.
    ModulePassManager NestedMPM;
    FunctionPassManager FPM;
    {
      // Pointless scope to test move assignment.
      FunctionPassManager NestedFPM;
      NestedFPM.addPass(TestFunctionPass(FunctionPassRunCount1,
                                         AnalyzedInstrCount1,
                                         AnalyzedFunctionCount1, MAM));
      FPM = std::move(NestedFPM);
    }
    NestedMPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
    MPM = std::move(NestedMPM);
  }

  // Count the runs over a module.
  int ModulePassRunCount = 0;
  MPM.addPass(TestModulePass(ModulePassRunCount));

  // Count the runs over a Function in a separate manager.
  int FunctionPassRunCount2 = 0;
  int AnalyzedInstrCount2 = 0;
  int AnalyzedFunctionCount2 = 0;
  {
    FunctionPassManager FPM;
    FPM.addPass(TestFunctionPass(FunctionPassRunCount2, AnalyzedInstrCount2,
                                 AnalyzedFunctionCount2, MAM));
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  }

  // A third function pass manager but with only preserving intervening passes
  // and with a function pass that invalidates exactly one analysis.
  MPM.addPass(TestPreservingModulePass());
  int FunctionPassRunCount3 = 0;
  int AnalyzedInstrCount3 = 0;
  int AnalyzedFunctionCount3 = 0;
  {
    FunctionPassManager FPM;
    FPM.addPass(TestFunctionPass(FunctionPassRunCount3, AnalyzedInstrCount3,
                                 AnalyzedFunctionCount3, MAM));
    FPM.addPass(TestInvalidationFunctionPass("f"));
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  }

  // A fourth function pass manager but with only preserving intervening
  // passes but triggering the module analysis.
  MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
  int FunctionPassRunCount4 = 0;
  int AnalyzedInstrCount4 = 0;
  int AnalyzedFunctionCount4 = 0;
  {
    FunctionPassManager FPM;
    FPM.addPass(TestFunctionPass(FunctionPassRunCount4, AnalyzedInstrCount4,
                                 AnalyzedFunctionCount4, MAM));
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  }

  // A fifth function pass manager which invalidates one function first but
  // uses only cached results.
  int FunctionPassRunCount5 = 0;
  int AnalyzedInstrCount5 = 0;
  int AnalyzedFunctionCount5 = 0;
  {
    FunctionPassManager FPM;
    FPM.addPass(TestInvalidationFunctionPass("f"));
    FPM.addPass(TestFunctionPass(FunctionPassRunCount5, AnalyzedInstrCount5,
                                 AnalyzedFunctionCount5, MAM,
                                 /*OnlyUseCachedResults=*/true));
    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  }

  MPM.run(*M, MAM);

  // Validate module pass counters.
  EXPECT_EQ(1, ModulePassRunCount);

  // Validate all function pass counter sets are the same.
  EXPECT_EQ(3, FunctionPassRunCount1);
  EXPECT_EQ(5, AnalyzedInstrCount1);
  EXPECT_EQ(0, AnalyzedFunctionCount1);
  EXPECT_EQ(3, FunctionPassRunCount2);
  EXPECT_EQ(5, AnalyzedInstrCount2);
  EXPECT_EQ(0, AnalyzedFunctionCount2);
  EXPECT_EQ(3, FunctionPassRunCount3);
  EXPECT_EQ(5, AnalyzedInstrCount3);
  EXPECT_EQ(0, AnalyzedFunctionCount3);
  EXPECT_EQ(3, FunctionPassRunCount4);
  EXPECT_EQ(5, AnalyzedInstrCount4);
  EXPECT_EQ(9, AnalyzedFunctionCount4);
  EXPECT_EQ(3, FunctionPassRunCount5);
  EXPECT_EQ(2, AnalyzedInstrCount5); // Only 'g' and 'h' were cached.
  EXPECT_EQ(9, AnalyzedFunctionCount5);

  // Validate the analysis counters:
  //   first run over 3 functions, then module pass invalidates
  //   second run over 3 functions, nothing invalidates
  //   third run over 0 functions, but 1 function invalidated
  //   fourth run over 1 function
  //   fifth run invalidates 1 function first, but runs over 0 functions
  EXPECT_EQ(7, FunctionAnalysisRuns);

  EXPECT_EQ(1, ModuleAnalysisRuns);
}

// A customized pass manager that passes extra arguments through the
// infrastructure.
typedef AnalysisManager<Function, int> CustomizedAnalysisManager;
typedef PassManager<Function, CustomizedAnalysisManager, int, int &>
    CustomizedPassManager;

class CustomizedAnalysis : public AnalysisInfoMixin<CustomizedAnalysis> {
public:
  struct Result {
    Result(int I) : I(I) {}
    int I;
  };

  Result run(Function &F, CustomizedAnalysisManager &AM, int I) {
    return Result(I);
  }

private:
  friend AnalysisInfoMixin<CustomizedAnalysis>;
  static AnalysisKey Key;
};

AnalysisKey CustomizedAnalysis::Key;

struct CustomizedPass : PassInfoMixin<CustomizedPass> {
  std::function<void(CustomizedAnalysis::Result &, int &)> Callback;

  template <typename CallbackT>
  CustomizedPass(CallbackT Callback) : Callback(Callback) {}

  PreservedAnalyses run(Function &F, CustomizedAnalysisManager &AM, int I,
                        int &O) {
    Callback(AM.getResult<CustomizedAnalysis>(F, I), O);
    return PreservedAnalyses::none();
  }
};

TEST_F(PassManagerTest, CustomizedPassManagerArgs) {
  CustomizedAnalysisManager AM;
  AM.registerPass([&] { return CustomizedAnalysis(); });
  PassInstrumentationCallbacks PIC;
  AM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });

  CustomizedPassManager PM;

  // Add an instance of the customized pass that just accumulates the input
  // after it is round-tripped through the analysis.
  int Result = 0;
  PM.addPass(
      CustomizedPass([](CustomizedAnalysis::Result &R, int &O) { O += R.I; }));

  // Run this over every function with the input of 42.
  for (Function &F : *M)
    PM.run(F, AM, 42, Result);

  // And ensure that we accumulated the correct result.
  EXPECT_EQ(42 * (int)M->size(), Result);
}

/// A test analysis pass which caches in its result another analysis pass and
/// uses it to serve queries. This requires the result to invalidate itself
/// when its dependency is invalidated.
struct TestIndirectFunctionAnalysis
    : public AnalysisInfoMixin<TestIndirectFunctionAnalysis> {
  struct Result {
    Result(TestFunctionAnalysis::Result &FDep, TestModuleAnalysis::Result &MDep)
        : FDep(FDep), MDep(MDep) {}
    TestFunctionAnalysis::Result &FDep;
    TestModuleAnalysis::Result &MDep;

    bool invalidate(Function &F, const PreservedAnalyses &PA,
                    FunctionAnalysisManager::Invalidator &Inv) {
      auto PAC = PA.getChecker<TestIndirectFunctionAnalysis>();
      return !(PAC.preserved() ||
               PAC.preservedSet<AllAnalysesOn<Function>>()) ||
             Inv.invalidate<TestFunctionAnalysis>(F, PA);
    }
  };

  TestIndirectFunctionAnalysis(int &Runs, ModuleAnalysisManager &MAM)
      : Runs(Runs), MAM(MAM) {}

  /// Run the analysis pass over the function and return a result.
  Result run(Function &F, FunctionAnalysisManager &AM) {
    ++Runs;
    auto &FDep = AM.getResult<TestFunctionAnalysis>(F);
    auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
    // For the test, we insist that the module analysis starts off in the
    // cache. Getting a cached result that isn't stateless trigger an assert.
    // Use MAM, for the purposes of this unittest.
    auto &MDep = *MAM.getCachedResult<TestModuleAnalysis>(*F.getParent());
    // And register the dependency as module analysis dependencies have to be
    // pre-registered on the proxy.
    MAMProxy.registerOuterAnalysisInvalidation<TestModuleAnalysis,
                                               TestIndirectFunctionAnalysis>();
    return Result(FDep, MDep);
  }

private:
  friend AnalysisInfoMixin<TestIndirectFunctionAnalysis>;
  static AnalysisKey Key;

  int &Runs;
  ModuleAnalysisManager &MAM;
};

AnalysisKey TestIndirectFunctionAnalysis::Key;

/// A test analysis pass which chaches in its result the result from the above
/// indirect analysis pass.
///
/// This allows us to ensure that whenever an analysis pass is invalidated due
/// to dependencies (especially dependencies across IR units that trigger
/// asynchronous invalidation) we correctly detect that this may in turn cause
/// other analysis to be invalidated.
struct TestDoublyIndirectFunctionAnalysis
    : public AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis> {
  struct Result {
    Result(TestIndirectFunctionAnalysis::Result &IDep) : IDep(IDep) {}
    TestIndirectFunctionAnalysis::Result &IDep;

    bool invalidate(Function &F, const PreservedAnalyses &PA,
                    FunctionAnalysisManager::Invalidator &Inv) {
      auto PAC = PA.getChecker<TestDoublyIndirectFunctionAnalysis>();
      return !(PAC.preserved() ||
               PAC.preservedSet<AllAnalysesOn<Function>>()) ||
             Inv.invalidate<TestIndirectFunctionAnalysis>(F, PA);
    }
  };

  TestDoublyIndirectFunctionAnalysis(int &Runs) : Runs(Runs) {}

  /// Run the analysis pass over the function and return a result.
  Result run(Function &F, FunctionAnalysisManager &AM) {
    ++Runs;
    auto &IDep = AM.getResult<TestIndirectFunctionAnalysis>(F);
    return Result(IDep);
  }

private:
  friend AnalysisInfoMixin<TestDoublyIndirectFunctionAnalysis>;
  static AnalysisKey Key;

  int &Runs;
};

AnalysisKey TestDoublyIndirectFunctionAnalysis::Key;

struct LambdaPass : public PassInfoMixin<LambdaPass> {
  using FuncT = std::function<PreservedAnalyses(Function &, FunctionAnalysisManager &)>;

  LambdaPass(FuncT Func) : Func(std::move(Func)) {}

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
    return Func(F, AM);
  }

  FuncT Func;
};

TEST_F(PassManagerTest, IndirectAnalysisInvalidation) {
  FunctionAnalysisManager FAM;
  ModuleAnalysisManager MAM;
  int FunctionAnalysisRuns = 0, ModuleAnalysisRuns = 0,
      IndirectAnalysisRuns = 0, DoublyIndirectAnalysisRuns = 0;
  FAM.registerPass([&] { return TestFunctionAnalysis(FunctionAnalysisRuns); });
  FAM.registerPass(
      [&] { return TestIndirectFunctionAnalysis(IndirectAnalysisRuns, MAM); });
  FAM.registerPass([&] {
    return TestDoublyIndirectFunctionAnalysis(DoublyIndirectAnalysisRuns);
  });

  MAM.registerPass([&] { return TestModuleAnalysis(ModuleAnalysisRuns); });
  MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
  FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });

  PassInstrumentationCallbacks PIC;
  MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
  FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });

  int InstrCount = 0, FunctionCount = 0;
  ModulePassManager MPM;
  FunctionPassManager FPM;
  // First just use the analysis to get the instruction count, and preserve
  // everything.
  FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
    auto &DoublyIndirectResult =
        AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
    auto &IndirectResult = DoublyIndirectResult.IDep;
    InstrCount += IndirectResult.FDep.InstructionCount;
    FunctionCount += IndirectResult.MDep.FunctionCount;
    return PreservedAnalyses::all();
  }));
  // Next, invalidate
  //   - both analyses for "f",
  //   - just the underlying (indirect) analysis for "g", and
  //   - just the direct analysis for "h".
  FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
    auto &DoublyIndirectResult =
        AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
    auto &IndirectResult = DoublyIndirectResult.IDep;
    InstrCount += IndirectResult.FDep.InstructionCount;
    FunctionCount += IndirectResult.MDep.FunctionCount;
    auto PA = PreservedAnalyses::none();
    if (F.getName() == "g")
      PA.preserve<TestFunctionAnalysis>();
    else if (F.getName() == "h")
      PA.preserve<TestIndirectFunctionAnalysis>();
    return PA;
  }));
  // Finally, use the analysis again on each function, forcing re-computation
  // for all of them.
  FPM.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
    auto &DoublyIndirectResult =
        AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
    auto &IndirectResult = DoublyIndirectResult.IDep;
    InstrCount += IndirectResult.FDep.InstructionCount;
    FunctionCount += IndirectResult.MDep.FunctionCount;
    return PreservedAnalyses::all();
  }));

  // Create a second function pass manager. This will cause the module-level
  // invalidation to occur, which will force yet another invalidation of the
  // indirect function-level analysis as the module analysis it depends on gets
  // invalidated.
  FunctionPassManager FPM2;
  FPM2.addPass(LambdaPass([&](Function &F, FunctionAnalysisManager &AM) {
    auto &DoublyIndirectResult =
        AM.getResult<TestDoublyIndirectFunctionAnalysis>(F);
    auto &IndirectResult = DoublyIndirectResult.IDep;
    InstrCount += IndirectResult.FDep.InstructionCount;
    FunctionCount += IndirectResult.MDep.FunctionCount;
    return PreservedAnalyses::all();
  }));

  // Add a requires pass to populate the module analysis and then our function
  // pass pipeline.
  MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
  // Now require the module analysis again (it will have been invalidated once)
  // and then use it again from a function pass manager.
  MPM.addPass(RequireAnalysisPass<TestModuleAnalysis, Module>());
  MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM2)));
  MPM.run(*M, MAM);

  // There are generally two possible runs for each of the three functions. But
  // for one function, we only invalidate the indirect analysis so the base one
  // only gets run five times.
  EXPECT_EQ(5, FunctionAnalysisRuns);
  // The module analysis pass should be run twice here.
  EXPECT_EQ(2, ModuleAnalysisRuns);
  // The indirect analysis is invalidated for each function (either directly or
  // indirectly) and run twice for each.
  EXPECT_EQ(9, IndirectAnalysisRuns);
  EXPECT_EQ(9, DoublyIndirectAnalysisRuns);

  // There are five instructions in the module and we add the count four
  // times.
  EXPECT_EQ(5 * 4, InstrCount);

  // There are three functions and we count them four times for each of the
  // three functions.
  EXPECT_EQ(3 * 4 * 3, FunctionCount);
}

// Run SimplifyCFGPass that makes CFG changes and reports PreservedAnalyses
// without CFGAnalyses. So the CFGChecker does not complain.
TEST_F(PassManagerTest, FunctionPassCFGChecker) {
  LLVMContext Context;
  // SimplifyCFG changes this function to
  // define void @foo {next: ret void}
  auto M = parseIR(Context, "define void @foo() {\n"
                            "  br label %next\n"
                            "next:\n"
                            "  br label %exit\n"
                            "exit:\n"
                            "  ret void\n"
                            "}\n");

  auto *F = M->getFunction("foo");
  FunctionAnalysisManager FAM;
  FunctionPassManager FPM;
  PassInstrumentationCallbacks PIC;
  StandardInstrumentations SI(/*DebugLogging*/ true);
  SI.registerCallbacks(PIC, &FAM);
  FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
  FAM.registerPass([&] { return DominatorTreeAnalysis(); });
  FAM.registerPass([&] { return AssumptionAnalysis(); });
  FAM.registerPass([&] { return TargetIRAnalysis(); });

  FPM.addPass(SimplifyCFGPass());
  FPM.run(*F, FAM);
}

// FunctionPass that manually invalidates analyses and always returns
// PreservedAnalyses::all().
struct TestSimplifyCFGInvalidatingAnalysisPass
    : PassInfoMixin<TestSimplifyCFGInvalidatingAnalysisPass> {
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
    // Run SimplifyCFG and if it changes CFG then invalidate the CFG analysis.
    // This allows to return PreserveAnalysis::all().
    PreservedAnalyses PA = CFGSimplifier.run(F, FAM);
    FAM.invalidate(F, PA);
    return PreservedAnalyses::all();
  }

  SimplifyCFGPass CFGSimplifier;
};

// Run TestSimplifyCFGInvalidatingAnalysisPass which changes CFG by running
// SimplifyCFGPass then manually invalidates analyses and always returns
// PreservedAnalyses::all(). CFGChecker does not complain because it resets
// its saved CFG snapshot when the analyses are invalidated manually.
TEST_F(PassManagerTest, FunctionPassCFGCheckerInvalidateAnalysis) {
  LLVMContext Context;
  // SimplifyCFG changes this function to
  // define void @foo {next: ret void}
  auto M = parseIR(Context, "define void @foo() {\n"
                            "  br label %next\n"
                            "next:\n"
                            "  br label %exit\n"
                            "exit:\n"
                            "  ret void\n"
                            "}\n");

  auto *F = M->getFunction("foo");
  FunctionAnalysisManager FAM;
  FunctionPassManager FPM;
  PassInstrumentationCallbacks PIC;
  StandardInstrumentations SI(/*DebugLogging*/ true);
  SI.registerCallbacks(PIC, &FAM);
  FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
  FAM.registerPass([&] { return DominatorTreeAnalysis(); });
  FAM.registerPass([&] { return AssumptionAnalysis(); });
  FAM.registerPass([&] { return TargetIRAnalysis(); });

  FPM.addPass(TestSimplifyCFGInvalidatingAnalysisPass());
  FPM.run(*F, FAM);
}

// Wrap a FunctionPassManager running SimplifyCFG pass with another
// FunctionPassManager.
struct TestSimplifyCFGWrapperPass : PassInfoMixin<TestSimplifyCFGWrapperPass> {
  TestSimplifyCFGWrapperPass(FunctionPassManager &InnerPM) : InnerPM(InnerPM) {}

  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
    // Here we simulate exactly what FunctionPassManager::run() does but
    // instead of running all passes from InnerPM.Passes we run them in bulk
    // by calling InnerPM.run().
    PreservedAnalyses PA = PreservedAnalyses::all();
    PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(F);

    if (!PI.runBeforePass<Function>(InnerPM, F))
      return PreservedAnalyses::all();

    PreservedAnalyses PassPA = InnerPM.run(F, FAM);
    PI.runAfterPass(InnerPM, F, PassPA);
    FAM.invalidate(F, PassPA);
    PA.intersect(PassPA);
    PA.preserveSet<AllAnalysesOn<Function>>();
    return PA;
  }

  FunctionPassManager &InnerPM;
};

// Run TestSimplifyCFGWrapperPass which simulates behavior of
// FunctionPassManager::run() except that it runs all passes at once by calling
// an inner pass manager's passes with PassManager::run(). This is how one pass
// manager is expected to wrap another pass manager.
// SimplifyCFGPass, which is called by the inner pass manager, changes the CFG.
// The CFGChecker's AfterPassCallback, run right after SimplifyCFGPass, does not
// complain because CFGAnalyses is not in the PreservedAnalises set returned by
// SimplifyCFGPass. Then the CFG analysis is invalidated by the analysis manager
// according to the PreservedAnalises set. Further calls to CFGChecker's
// AfterPassCallback see that all analyses for the current function are
// preserved but there is no CFG snapshot available (i.e.
// AM.getCachedResult<PreservedCFGCheckerAnalysis>(F) returns nullptr).
TEST_F(PassManagerTest, FunctionPassCFGCheckerWrapped) {
  LLVMContext Context;
  // SimplifyCFG changes this function to
  // define void @foo {next: ret void}
  auto M = parseIR(Context, "define void @foo() {\n"
                            "  br label %next\n"
                            "next:\n"
                            "  br label %exit\n"
                            "exit:\n"
                            "  ret void\n"
                            "}\n");

  auto *F = M->getFunction("foo");
  FunctionAnalysisManager FAM;
  FunctionPassManager FPM;
  PassInstrumentationCallbacks PIC;
  StandardInstrumentations SI(/*DebugLogging*/ true);
  SI.registerCallbacks(PIC, &FAM);
  FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
  FAM.registerPass([&] { return DominatorTreeAnalysis(); });
  FAM.registerPass([&] { return AssumptionAnalysis(); });
  FAM.registerPass([&] { return TargetIRAnalysis(); });

  FunctionPassManager InnerFPM;
  InnerFPM.addPass(SimplifyCFGPass());

  FPM.addPass(TestSimplifyCFGWrapperPass(InnerFPM));
  FPM.run(*F, FAM);
}
}
