//===- DomTreeUpdaterTest.cpp - DomTreeUpdater unit 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/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
#include <algorithm>

using namespace llvm;

static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
                                              StringRef ModuleStr) {
  SMDiagnostic Err;
  std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context);
  assert(M && "Bad LLVM IR?");
  return M;
}

TEST(DomTreeUpdater, EagerUpdateBasicOperations) {
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                          define i32 @f(i32 %i, i32 *%p) {
                          bb0:
                             store i32 %i, i32 *%p
                             switch i32 %i, label %bb1 [
                               i32 1, label %bb2
                               i32 2, label %bb3
                             ]
                          bb1:
                             ret i32 1
                          bb2:
                             ret i32 2
                          bb3:
                             ret i32 3
                          })";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DomTreeUpdater.
  DominatorTree DT(*F);
  PostDominatorTree PDT(*F);
  DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);

  ASSERT_TRUE(DTU.hasDomTree());
  ASSERT_TRUE(DTU.hasPostDomTree());
  ASSERT_TRUE(DTU.isEager());
  ASSERT_FALSE(DTU.isLazy());
  ASSERT_TRUE(DTU.getDomTree().verify());
  ASSERT_TRUE(DTU.getPostDomTree().verify());
  ASSERT_FALSE(DTU.hasPendingUpdates());

  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  BasicBlock *BB1 = &*FI++;
  BasicBlock *BB2 = &*FI++;
  BasicBlock *BB3 = &*FI++;
  SwitchInst *SI = dyn_cast<SwitchInst>(BB0->getTerminator());
  ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";

  DTU.applyUpdatesPermissive(
      {{DominatorTree::Insert, BB0, BB0}, {DominatorTree::Delete, BB0, BB0}});
  ASSERT_FALSE(DTU.hasPendingUpdates());

  // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
  // entries are discarded.
  std::vector<DominatorTree::UpdateType> Updates;
  Updates.reserve(4);
  Updates.push_back({DominatorTree::Delete, BB0, BB3});
  Updates.push_back({DominatorTree::Delete, BB0, BB3});

  // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
  Updates.push_back({DominatorTree::Insert, BB1, BB2});
  // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
  Updates.push_back({DominatorTree::Delete, BB0, BB1});

  // CFG Change: remove edge bb0 -> bb3.
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 3u);
  BB3->removePredecessor(BB0);
  for (auto i = SI->case_begin(), e = SI->case_end(); i != e; ++i) {
    if (i->getCaseSuccessor() == BB3) {
      SI->removeCase(i);
      break;
    }
  }
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
  // Deletion of a BasicBlock is an immediate event. We remove all uses to the
  // contained Instructions and change the Terminator to "unreachable" when
  // queued for deletion.
  ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
  EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
  DTU.applyUpdatesPermissive(Updates);
  ASSERT_FALSE(DTU.hasPendingUpdates());

  // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
  // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
  DTU.applyUpdatesPermissive(
      {{DominatorTree::Insert, BB1, BB2}, {DominatorTree::Delete, BB0, BB1}});

  // DTU working with Eager UpdateStrategy does not need to flush.
  ASSERT_TRUE(DT.verify());
  ASSERT_TRUE(PDT.verify());

  // Test callback utils.
  ASSERT_EQ(BB3->getParent(), F);
  DTU.callbackDeleteBB(BB3,
                       [&F](BasicBlock *BB) { ASSERT_NE(BB->getParent(), F); });

  ASSERT_TRUE(DT.verify());
  ASSERT_TRUE(PDT.verify());
  ASSERT_FALSE(DTU.hasPendingUpdates());

  // Unnecessary flush() test
  DTU.flush();
  EXPECT_TRUE(DT.verify());
  EXPECT_TRUE(PDT.verify());

  // Remove all case branch to BB2 to test Eager recalculation.
  // Code section from llvm::ConstantFoldTerminator
  for (auto i = SI->case_begin(), e = SI->case_end(); i != e;) {
    if (i->getCaseSuccessor() == BB2) {
      // Remove this entry.
      BB2->removePredecessor(BB0);
      i = SI->removeCase(i);
      e = SI->case_end();
    } else
      ++i;
  }
  ASSERT_FALSE(DT.verify());
  ASSERT_FALSE(PDT.verify());
  DTU.recalculate(*F);
  ASSERT_TRUE(DT.verify());
  ASSERT_TRUE(PDT.verify());
}

TEST(DomTreeUpdater, EagerUpdateReplaceEntryBB) {
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                           define i32 @f() {
                           bb0:
                              br label %bb1
                            bb1:
                              ret i32 1
                           }
                           )";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DTU.
  DominatorTree DT(*F);
  PostDominatorTree PDT(*F);
  DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Eager);
  ASSERT_TRUE(DTU.hasDomTree());
  ASSERT_TRUE(DTU.hasPostDomTree());
  ASSERT_TRUE(DTU.isEager());
  ASSERT_FALSE(DTU.isLazy());
  ASSERT_TRUE(DT.verify());
  ASSERT_TRUE(PDT.verify());

  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  BasicBlock *BB1 = &*FI++;

  // Add a block as the new function entry BB. We also link it to BB0.
  BasicBlock *NewEntry =
      BasicBlock::Create(F->getContext(), "new_entry", F, BB0);
  BranchInst::Create(BB0, NewEntry);
  EXPECT_EQ(F->begin()->getName(), NewEntry->getName());
  EXPECT_TRUE(&F->getEntryBlock() == NewEntry);

  DTU.applyUpdates({{DominatorTree::Insert, NewEntry, BB0}});

  // Changing the Entry BB requires a full recalculation of DomTree.
  DTU.recalculate(*F);
  ASSERT_TRUE(DT.verify());
  ASSERT_TRUE(PDT.verify());

  // CFG Change: remove new_edge -> bb0 and redirect to new_edge -> bb1.
  EXPECT_EQ(NewEntry->getTerminator()->getNumSuccessors(), 1u);
  NewEntry->getTerminator()->eraseFromParent();
  BranchInst::Create(BB1, NewEntry);
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);

  // Update the DTU. At this point bb0 now has no predecessors but is still a
  // Child of F.
  DTU.applyUpdates({{DominatorTree::Delete, NewEntry, BB0},
                    {DominatorTree::Insert, NewEntry, BB1}});
  ASSERT_TRUE(DT.verify());
  ASSERT_TRUE(PDT.verify());

  // Now remove bb0 from F.
  ASSERT_FALSE(isa<UnreachableInst>(BB0->getTerminator()));
  EXPECT_FALSE(DTU.isBBPendingDeletion(BB0));
  DTU.deleteBB(BB0);
  ASSERT_TRUE(DT.verify());
  ASSERT_TRUE(PDT.verify());
}

TEST(DomTreeUpdater, LazyUpdateDTBasicOperations) {
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                           define i32 @f(i32 %i, i32 *%p) {
                            bb0:
                              store i32 %i, i32 *%p
                              switch i32 %i, label %bb1 [
                                i32 0, label %bb2
                                i32 1, label %bb2
                                i32 2, label %bb3
                              ]
                            bb1:
                              ret i32 1
                            bb2:
                              ret i32 2
                            bb3:
                              ret i32 3
                           }
                           )";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DTU.
  DominatorTree DT(*F);
  PostDominatorTree *PDT = nullptr;
  DomTreeUpdater DTU(&DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  ASSERT_TRUE(DTU.hasDomTree());
  ASSERT_FALSE(DTU.hasPostDomTree());
  ASSERT_FALSE(DTU.isEager());
  ASSERT_TRUE(DTU.isLazy());
  ASSERT_TRUE(DTU.getDomTree().verify());

  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  BasicBlock *BB1 = &*FI++;
  BasicBlock *BB2 = &*FI++;
  BasicBlock *BB3 = &*FI++;

  // Test discards of self-domination update.
  DTU.applyUpdatesPermissive({{DominatorTree::Insert, BB0, BB0}});
  ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());

  // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
  // entries are discarded.
  std::vector<DominatorTree::UpdateType> Updates;
  Updates.reserve(4);
  Updates.push_back({DominatorTree::Delete, BB0, BB3});
  Updates.push_back({DominatorTree::Delete, BB0, BB3});

  // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
  Updates.push_back({DominatorTree::Insert, BB1, BB2});
  // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
  Updates.push_back({DominatorTree::Delete, BB0, BB1});

  // CFG Change: remove edge bb0 -> bb3 and one duplicate edge bb0 -> bb2.
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 4u);
  BB0->getTerminator()->eraseFromParent();
  BranchInst::Create(BB1, BB2, ConstantInt::getTrue(F->getContext()), BB0);
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);

  // Verify. Updates to DTU must be applied *after* all changes to the CFG
  // (including block deletion).
  DTU.applyUpdatesPermissive(Updates);
  ASSERT_TRUE(DTU.getDomTree().verify());

  // Deletion of a BasicBlock is an immediate event. We remove all uses to the
  // contained Instructions and change the Terminator to "unreachable" when
  // queued for deletion. Its parent is still F until all the pending updates
  // are applied to all trees held by the DomTreeUpdater (DomTree/PostDomTree).
  // We don't defer this action because it can cause problems for other
  // transforms or analysis as it's part of the actual CFG. We only defer
  // updates to the DominatorTrees. This code will crash if it is placed before
  // the BranchInst::Create() call above. After a deletion of a BasicBlock. Only
  // an explicit flush event can trigger the flushing of deleteBBs. Because some
  // passes using Lazy UpdateStrategy rely on this behavior.

  ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
  EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
  EXPECT_FALSE(DTU.hasPendingDeletedBB());
  DTU.deleteBB(BB3);
  EXPECT_TRUE(DTU.isBBPendingDeletion(BB3));
  EXPECT_TRUE(DTU.hasPendingDeletedBB());
  ASSERT_TRUE(isa<UnreachableInst>(BB3->getTerminator()));
  EXPECT_EQ(BB3->getParent(), F);
  DTU.recalculate(*F);
  EXPECT_FALSE(DTU.hasPendingDeletedBB());
}

TEST(DomTreeUpdater, LazyUpdateDTInheritedPreds) {
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                           define i32 @f(i32 %i, i32 *%p) {
                            bb0:
                              store i32 %i, i32 *%p
                              switch i32 %i, label %bb1 [
                                i32 2, label %bb2
                                i32 3, label %bb3
                              ]
                            bb1:
                              br label %bb3
                            bb2:
                              br label %bb3
                            bb3:
                              ret i32 3
                           }
                           )";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DTU.
  DominatorTree DT(*F);
  PostDominatorTree *PDT = nullptr;
  DomTreeUpdater DTU(&DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  ASSERT_TRUE(DTU.hasDomTree());
  ASSERT_FALSE(DTU.hasPostDomTree());
  ASSERT_FALSE(DTU.isEager());
  ASSERT_TRUE(DTU.isLazy());
  ASSERT_TRUE(DTU.getDomTree().verify());

  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  BasicBlock *BB1 = &*FI++;
  BasicBlock *BB2 = &*FI++;
  BasicBlock *BB3 = &*FI++;

  // There are several CFG locations where we have:
  //
  //   pred1..predN
  //    |        |
  //    +> curr <+    converted into:   pred1..predN curr
  //        |                            |        |
  //        v                            +> succ <+
  //       succ
  //
  // There is a specific shape of this we have to be careful of:
  //
  //   pred1..predN
  //   ||        |
  //   |+> curr <+    converted into:   pred1..predN curr
  //   |    |                            |        |
  //   |    v                            +> succ <+
  //   +-> succ
  //
  // While the final CFG form is functionally identical the updates to
  // DTU are not. In the first case we must have
  // DTU.applyUpdates({{DominatorTree::Insert, Pred1, Succ}}) while in
  // the latter case we must *NOT* have
  // DTU.applyUpdates({{DominatorTree::Insert, Pred1, Succ}}).

  // CFG Change: bb0 now only has bb0 -> bb1 and bb0 -> bb3. We are preparing to
  // remove bb2.
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 3u);
  BB0->getTerminator()->eraseFromParent();
  BranchInst::Create(BB1, BB3, ConstantInt::getTrue(F->getContext()), BB0);
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);

  // Test callback utils.
  std::vector<BasicBlock *> BasicBlocks;
  BasicBlocks.push_back(BB1);
  BasicBlocks.push_back(BB2);
  auto Eraser = [&](BasicBlock *BB) {
    BasicBlocks.erase(
        std::remove_if(BasicBlocks.begin(), BasicBlocks.end(),
                       [&](const BasicBlock *i) { return i == BB; }),
        BasicBlocks.end());
  };
  ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
  // Remove bb2 from F. This has to happen before the call to
  // applyUpdates() for DTU to detect there is no longer an edge between
  // bb2 -> bb3. The deleteBB() method converts bb2's TI into "unreachable".
  ASSERT_FALSE(isa<UnreachableInst>(BB2->getTerminator()));
  EXPECT_FALSE(DTU.isBBPendingDeletion(BB2));
  DTU.callbackDeleteBB(BB2, Eraser);
  EXPECT_TRUE(DTU.isBBPendingDeletion(BB2));
  ASSERT_TRUE(isa<UnreachableInst>(BB2->getTerminator()));
  EXPECT_EQ(BB2->getParent(), F);

  // Queue up the DTU updates.
  std::vector<DominatorTree::UpdateType> Updates;
  Updates.reserve(4);
  Updates.push_back({DominatorTree::Delete, BB0, BB2});
  Updates.push_back({DominatorTree::Delete, BB2, BB3});

  // Handle the specific shape case next.
  // CFG Change: bb0 now only branches to bb3. We are preparing to remove bb1.
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);
  BB0->getTerminator()->eraseFromParent();
  BranchInst::Create(BB3, BB0);
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);

  // Remove bb1 from F. This has to happen before the call to
  // applyUpdates() for DTU to detect there is no longer an edge between
  // bb1 -> bb3. The deleteBB() method converts bb1's TI into "unreachable".
  ASSERT_FALSE(isa<UnreachableInst>(BB1->getTerminator()));
  EXPECT_FALSE(DTU.isBBPendingDeletion(BB1));
  DTU.callbackDeleteBB(BB1, Eraser);
  EXPECT_TRUE(DTU.isBBPendingDeletion(BB1));
  ASSERT_TRUE(isa<UnreachableInst>(BB1->getTerminator()));
  EXPECT_EQ(BB1->getParent(), F);

  // Update the DTU. In this case we don't submit {DominatorTree::Insert, BB0,
  // BB3} because the edge previously existed at the start of this test when DT
  // was first created.
  Updates.push_back({DominatorTree::Delete, BB0, BB1});
  Updates.push_back({DominatorTree::Delete, BB1, BB3});

  // Verify everything.
  DTU.applyUpdatesPermissive(Updates);
  ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(2));
  DTU.flush();
  ASSERT_EQ(BasicBlocks.size(), static_cast<size_t>(0));
  ASSERT_TRUE(DT.verify());
}

TEST(DomTreeUpdater, LazyUpdateBasicOperations) {
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                           define i32 @f(i32 %i, i32 *%p) {
                            bb0:
                              store i32 %i, i32 *%p
                              switch i32 %i, label %bb1 [
                                i32 0, label %bb2
                                i32 1, label %bb2
                                i32 2, label %bb3
                              ]
                            bb1:
                              ret i32 1
                            bb2:
                              ret i32 2
                            bb3:
                              ret i32 3
                           }
                           )";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DTU.
  DominatorTree DT(*F);
  PostDominatorTree PDT(*F);
  DomTreeUpdater DTU(&DT, &PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  ASSERT_TRUE(DTU.hasDomTree());
  ASSERT_TRUE(DTU.hasPostDomTree());
  ASSERT_FALSE(DTU.isEager());
  ASSERT_TRUE(DTU.isLazy());
  ASSERT_TRUE(DTU.getDomTree().verify());
  ASSERT_TRUE(DTU.getPostDomTree().verify());

  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  BasicBlock *BB1 = &*FI++;
  BasicBlock *BB2 = &*FI++;
  BasicBlock *BB3 = &*FI++;
  // Test discards of self-domination update.
  DTU.applyUpdates({{DominatorTree::Delete, BB0, BB0}});

  // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
  // entries are discarded.
  std::vector<DominatorTree::UpdateType> Updates;
  Updates.reserve(4);
  Updates.push_back({DominatorTree::Delete, BB0, BB3});
  Updates.push_back({DominatorTree::Delete, BB0, BB3});

  // Unnecessary Insert: no edge bb1 -> bb2 after change to bb0.
  Updates.push_back({DominatorTree::Insert, BB1, BB2});
  // Unnecessary Delete: edge exists bb0 -> bb1 after change to bb0.
  Updates.push_back({DominatorTree::Delete, BB0, BB1});

  // CFG Change: remove edge bb0 -> bb3 and one duplicate edge bb0 -> bb2.
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 4u);
  BB0->getTerminator()->eraseFromParent();
  BranchInst::Create(BB1, BB2, ConstantInt::getTrue(F->getContext()), BB0);
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u);

  // Deletion of a BasicBlock is an immediate event. We remove all uses to the
  // contained Instructions and change the Terminator to "unreachable" when
  // queued for deletion. Its parent is still F until DTU.flushDomTree is
  // called. We don't defer this action because it can cause problems for other
  // transforms or analysis as it's part of the actual CFG. We only defer
  // updates to the DominatorTree. This code will crash if it is placed before
  // the BranchInst::Create() call above.
  bool CallbackFlag = false;
  ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
  EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
  DTU.callbackDeleteBB(BB3, [&](BasicBlock *) { CallbackFlag = true; });
  EXPECT_TRUE(DTU.isBBPendingDeletion(BB3));
  ASSERT_TRUE(isa<UnreachableInst>(BB3->getTerminator()));
  EXPECT_EQ(BB3->getParent(), F);

  // Verify. Updates to DTU must be applied *after* all changes to the CFG
  // (including block deletion).
  DTU.applyUpdatesPermissive(Updates);
  ASSERT_TRUE(DTU.getDomTree().verify());
  ASSERT_TRUE(DTU.hasPendingUpdates());
  ASSERT_TRUE(DTU.hasPendingPostDomTreeUpdates());
  ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
  ASSERT_TRUE(DTU.hasPendingDeletedBB());
  ASSERT_TRUE(DTU.getPostDomTree().verify());
  ASSERT_FALSE(DTU.hasPendingUpdates());
  ASSERT_FALSE(DTU.hasPendingPostDomTreeUpdates());
  ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());
  ASSERT_FALSE(DTU.hasPendingDeletedBB());
  ASSERT_EQ(CallbackFlag, true);
}

TEST(DomTreeUpdater, LazyUpdateReplaceEntryBB) {
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                           define i32 @f() {
                           bb0:
                              br label %bb1
                            bb1:
                              ret i32 1
                           }
                           )";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DTU.
  DominatorTree DT(*F);
  PostDominatorTree PDT(*F);
  DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
  ASSERT_TRUE(DTU.hasDomTree());
  ASSERT_TRUE(DTU.hasPostDomTree());
  ASSERT_FALSE(DTU.isEager());
  ASSERT_TRUE(DTU.isLazy());
  ASSERT_TRUE(DTU.getDomTree().verify());
  ASSERT_TRUE(DTU.getPostDomTree().verify());

  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  BasicBlock *BB1 = &*FI++;

  // Add a block as the new function entry BB. We also link it to BB0.
  BasicBlock *NewEntry =
      BasicBlock::Create(F->getContext(), "new_entry", F, BB0);
  BranchInst::Create(BB0, NewEntry);
  EXPECT_EQ(F->begin()->getName(), NewEntry->getName());
  EXPECT_TRUE(&F->getEntryBlock() == NewEntry);

  // Insert the new edge between new_entry -> bb0. Without this the
  // recalculate() call below will not actually recalculate the DT as there
  // are no changes pending and no blocks deleted.
  DTU.applyUpdates({{DominatorTree::Insert, NewEntry, BB0}});

  // Changing the Entry BB requires a full recalculation.
  DTU.recalculate(*F);
  ASSERT_TRUE(DTU.getDomTree().verify());
  ASSERT_TRUE(DTU.getPostDomTree().verify());

  // CFG Change: remove new_edge -> bb0 and redirect to new_edge -> bb1.
  EXPECT_EQ(NewEntry->getTerminator()->getNumSuccessors(), 1u);
  NewEntry->getTerminator()->eraseFromParent();
  BranchInst::Create(BB1, NewEntry);
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);

  // Update the DTU. At this point bb0 now has no predecessors but is still a
  // Child of F.
  DTU.applyUpdates({{DominatorTree::Delete, NewEntry, BB0},
                    {DominatorTree::Insert, NewEntry, BB1}});
  DTU.flush();
  ASSERT_TRUE(DT.verify());
  ASSERT_TRUE(PDT.verify());

  // Now remove bb0 from F.
  ASSERT_FALSE(isa<UnreachableInst>(BB0->getTerminator()));
  EXPECT_FALSE(DTU.isBBPendingDeletion(BB0));
  DTU.deleteBB(BB0);
  EXPECT_TRUE(DTU.isBBPendingDeletion(BB0));
  ASSERT_TRUE(isa<UnreachableInst>(BB0->getTerminator()));
  EXPECT_EQ(BB0->getParent(), F);

  // Perform a full recalculation of the DTU. It is not necessary here but we
  // do this to test the case when there are no pending DT updates but there are
  // pending deleted BBs.
  ASSERT_TRUE(DTU.hasPendingDeletedBB());
  DTU.recalculate(*F);
  ASSERT_FALSE(DTU.hasPendingDeletedBB());
}

TEST(DomTreeUpdater, LazyUpdateStepTest) {
  // This test focus on testing a DTU holding both trees applying multiple
  // updates and DT/PDT not flushed together.
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                           define i32 @f(i32 %i, i32 *%p) {
                            bb0:
                              store i32 %i, i32 *%p
                              switch i32 %i, label %bb1 [
                                i32 0, label %bb1
                                i32 1, label %bb2
                                i32 2, label %bb3
                                i32 3, label %bb1
                              ]
                            bb1:
                              ret i32 1
                            bb2:
                              ret i32 2
                            bb3:
                              ret i32 3
                           }
                           )";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DomTreeUpdater.
  DominatorTree DT(*F);
  PostDominatorTree PDT(*F);
  DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);

  ASSERT_TRUE(DTU.hasDomTree());
  ASSERT_TRUE(DTU.hasPostDomTree());
  ASSERT_FALSE(DTU.isEager());
  ASSERT_TRUE(DTU.isLazy());
  ASSERT_TRUE(DTU.getDomTree().verify());
  ASSERT_TRUE(DTU.getPostDomTree().verify());
  ASSERT_FALSE(DTU.hasPendingUpdates());

  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  FI++;
  BasicBlock *BB2 = &*FI++;
  BasicBlock *BB3 = &*FI++;
  SwitchInst *SI = dyn_cast<SwitchInst>(BB0->getTerminator());
  ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";

  // Delete edge bb0 -> bb3.
  std::vector<DominatorTree::UpdateType> Updates;
  Updates.reserve(1);
  Updates.push_back({DominatorTree::Delete, BB0, BB3});

  // CFG Change: remove edge bb0 -> bb3.
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 5u);
  BB3->removePredecessor(BB0);
  for (auto i = SI->case_begin(), e = SI->case_end(); i != e; ++i) {
    if (i->getCaseIndex() == 2) {
      SI->removeCase(i);
      break;
    }
  }
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 4u);
  // Deletion of a BasicBlock is an immediate event. We remove all uses to the
  // contained Instructions and change the Terminator to "unreachable" when
  // queued for deletion.
  ASSERT_FALSE(isa<UnreachableInst>(BB3->getTerminator()));
  EXPECT_FALSE(DTU.isBBPendingDeletion(BB3));
  DTU.applyUpdates(Updates);

  // Only flush DomTree.
  ASSERT_TRUE(DTU.getDomTree().verify());
  ASSERT_TRUE(DTU.hasPendingPostDomTreeUpdates());
  ASSERT_FALSE(DTU.hasPendingDomTreeUpdates());

  ASSERT_EQ(BB3->getParent(), F);
  DTU.deleteBB(BB3);

  Updates.clear();

  // Remove all case branch to BB2 to test Eager recalculation.
  // Code section from llvm::ConstantFoldTerminator
  for (auto i = SI->case_begin(), e = SI->case_end(); i != e;) {
    if (i->getCaseSuccessor() == BB2) {
      // Remove this entry.
      BB2->removePredecessor(BB0);
      i = SI->removeCase(i);
      e = SI->case_end();
      Updates.push_back({DominatorTree::Delete, BB0, BB2});
    } else
      ++i;
  }

  DTU.applyUpdatesPermissive(Updates);
  // flush PostDomTree
  ASSERT_TRUE(DTU.getPostDomTree().verify());
  ASSERT_FALSE(DTU.hasPendingPostDomTreeUpdates());
  ASSERT_TRUE(DTU.hasPendingDomTreeUpdates());
  // flush both trees
  DTU.flush();
  ASSERT_TRUE(DT.verify());
}

TEST(DomTreeUpdater, NoTreeTest) {
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                           define i32 @f() {
                           bb0:
                              ret i32 0
                           }
                           )";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DTU.
  DomTreeUpdater DTU(nullptr, nullptr, DomTreeUpdater::UpdateStrategy::Lazy);
  ASSERT_FALSE(DTU.hasDomTree());
  ASSERT_FALSE(DTU.hasPostDomTree());
  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  // Test whether PendingDeletedBB is flushed after the recalculation.
  DTU.deleteBB(BB0);
  ASSERT_TRUE(DTU.hasPendingDeletedBB());
  DTU.recalculate(*F);
  ASSERT_FALSE(DTU.hasPendingDeletedBB());
}

TEST(DomTreeUpdater, LazyUpdateDeduplicationTest) {
  StringRef FuncName = "f";
  StringRef ModuleString = R"(
                           define i32 @f() {
                           bb0:
                              br label %bb1
                           bb1:
                              ret i32 1
                           bb2:
                              ret i32 1
                           }
                           )";
  // Make the module.
  LLVMContext Context;
  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
  Function *F = M->getFunction(FuncName);

  // Make the DTU.
  DominatorTree DT(*F);
  DomTreeUpdater DTU(&DT, nullptr, DomTreeUpdater::UpdateStrategy::Lazy);
  ASSERT_TRUE(DTU.getDomTree().verify());

  Function::iterator FI = F->begin();
  BasicBlock *BB0 = &*FI++;
  BasicBlock *BB1 = &*FI++;
  BasicBlock *BB2 = &*FI++;

  // CFG Change: remove bb0 -> bb1 and add back bb0 -> bb1.
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
  BB0->getTerminator()->eraseFromParent();
  BranchInst::Create(BB1, BB0);
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);

  // Update the DTU and simulate duplicates.
  DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1},
                              {DominatorTree::Delete, BB0, BB1},
                              {DominatorTree::Insert, BB0, BB1},
                              {DominatorTree::Insert, BB0, BB1},
                              {DominatorTree::Insert, BB0, BB1}});

  // The above operations result in a no-op.
  ASSERT_FALSE(DTU.hasPendingUpdates());

  // Update the DTU. Simulate an invalid update.
  DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1}});
  ASSERT_FALSE(DTU.hasPendingUpdates());

  // CFG Change: remove bb0 -> bb1.
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
  BB0->getTerminator()->eraseFromParent();

  // Update the DTU and simulate invalid updates.
  DTU.applyUpdatesPermissive({{DominatorTree::Delete, BB0, BB1},
                              {DominatorTree::Insert, BB0, BB1},
                              {DominatorTree::Delete, BB0, BB1},
                              {DominatorTree::Insert, BB0, BB1},
                              {DominatorTree::Insert, BB0, BB1}});
  ASSERT_TRUE(DTU.hasPendingUpdates());

  // CFG Change: add bb0 -> bb2.
  BranchInst::Create(BB2, BB0);
  EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u);
  DTU.applyUpdates({{DominatorTree::Insert, BB0, BB2}});
  ASSERT_TRUE(DTU.getDomTree().verify());
}
