//===- llvm/unittest/ADT/ValueMapTest.cpp - ValueMap unit tests -*- C++ -*-===//
//
// 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/ValueMap.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

// Test fixture
template<typename T>
class ValueMapTest : public testing::Test {
protected:
  LLVMContext Context;
  Constant *ConstantV;
  std::unique_ptr<BitCastInst> BitcastV;
  std::unique_ptr<BinaryOperator> AddV;

  ValueMapTest()
      : ConstantV(ConstantInt::get(Type::getInt32Ty(Context), 0)),
        BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(Context))),
        AddV(BinaryOperator::CreateAdd(ConstantV, ConstantV)) {}
};

// Run everything on Value*, a subtype to make sure that casting works as
// expected, and a const subtype to make sure we cast const correctly.
typedef ::testing::Types<Value, Instruction, const Instruction> KeyTypes;
TYPED_TEST_CASE(ValueMapTest, KeyTypes);

TYPED_TEST(ValueMapTest, Null) {
  ValueMap<TypeParam*, int> VM1;
  VM1[nullptr] = 7;
  EXPECT_EQ(7, VM1.lookup(nullptr));
}

TYPED_TEST(ValueMapTest, FollowsValue) {
  ValueMap<TypeParam*, int> VM;
  VM[this->BitcastV.get()] = 7;
  EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
  EXPECT_EQ(0u, VM.count(this->AddV.get()));
  this->BitcastV->replaceAllUsesWith(this->AddV.get());
  EXPECT_EQ(7, VM.lookup(this->AddV.get()));
  EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
  this->AddV.reset();
  EXPECT_EQ(0u, VM.count(this->AddV.get()));
  EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
  EXPECT_EQ(0U, VM.size());
}

TYPED_TEST(ValueMapTest, OperationsWork) {
  ValueMap<TypeParam*, int> VM;
  ValueMap<TypeParam*, int> VM2(16);  (void)VM2;
  typename ValueMapConfig<TypeParam*>::ExtraData Data;
  ValueMap<TypeParam*, int> VM3(Data, 16);  (void)VM3;
  EXPECT_TRUE(VM.empty());

  VM[this->BitcastV.get()] = 7;

  // Find:
  typename ValueMap<TypeParam*, int>::iterator I =
    VM.find(this->BitcastV.get());
  ASSERT_TRUE(I != VM.end());
  EXPECT_EQ(this->BitcastV.get(), I->first);
  EXPECT_EQ(7, I->second);
  EXPECT_TRUE(VM.find(this->AddV.get()) == VM.end());

  // Const find:
  const ValueMap<TypeParam*, int> &CVM = VM;
  typename ValueMap<TypeParam*, int>::const_iterator CI =
    CVM.find(this->BitcastV.get());
  ASSERT_TRUE(CI != CVM.end());
  EXPECT_EQ(this->BitcastV.get(), CI->first);
  EXPECT_EQ(7, CI->second);
  EXPECT_TRUE(CVM.find(this->AddV.get()) == CVM.end());

  // Insert:
  std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult1 =
    VM.insert(std::make_pair(this->AddV.get(), 3));
  EXPECT_EQ(this->AddV.get(), InsertResult1.first->first);
  EXPECT_EQ(3, InsertResult1.first->second);
  EXPECT_TRUE(InsertResult1.second);
  EXPECT_EQ(1u, VM.count(this->AddV.get()));
  std::pair<typename ValueMap<TypeParam*, int>::iterator, bool> InsertResult2 =
    VM.insert(std::make_pair(this->AddV.get(), 5));
  EXPECT_EQ(this->AddV.get(), InsertResult2.first->first);
  EXPECT_EQ(3, InsertResult2.first->second);
  EXPECT_FALSE(InsertResult2.second);

  // Erase:
  VM.erase(InsertResult2.first);
  EXPECT_EQ(0U, VM.count(this->AddV.get()));
  EXPECT_EQ(1U, VM.count(this->BitcastV.get()));
  VM.erase(this->BitcastV.get());
  EXPECT_EQ(0U, VM.count(this->BitcastV.get()));
  EXPECT_EQ(0U, VM.size());

  // Range insert:
  SmallVector<std::pair<Instruction*, int>, 2> Elems;
  Elems.push_back(std::make_pair(this->AddV.get(), 1));
  Elems.push_back(std::make_pair(this->BitcastV.get(), 2));
  VM.insert(Elems.begin(), Elems.end());
  EXPECT_EQ(1, VM.lookup(this->AddV.get()));
  EXPECT_EQ(2, VM.lookup(this->BitcastV.get()));
}

template<typename ExpectedType, typename VarType>
void CompileAssertHasType(VarType) {
  static_assert(std::is_same<ExpectedType, VarType>::value,
                "Not the same type");
}

TYPED_TEST(ValueMapTest, Iteration) {
  ValueMap<TypeParam*, int> VM;
  VM[this->BitcastV.get()] = 2;
  VM[this->AddV.get()] = 3;
  size_t size = 0;
  for (typename ValueMap<TypeParam*, int>::iterator I = VM.begin(), E = VM.end();
       I != E; ++I) {
    ++size;
    std::pair<TypeParam*, int> value = *I; (void)value;
    CompileAssertHasType<TypeParam*>(I->first);
    if (I->second == 2) {
      EXPECT_EQ(this->BitcastV.get(), I->first);
      I->second = 5;
    } else if (I->second == 3) {
      EXPECT_EQ(this->AddV.get(), I->first);
      I->second = 6;
    } else {
      ADD_FAILURE() << "Iterated through an extra value.";
    }
  }
  EXPECT_EQ(2U, size);
  EXPECT_EQ(5, VM[this->BitcastV.get()]);
  EXPECT_EQ(6, VM[this->AddV.get()]);

  size = 0;
  // Cast to const ValueMap to avoid a bug in DenseMap's iterators.
  const ValueMap<TypeParam*, int>& CVM = VM;
  for (typename ValueMap<TypeParam*, int>::const_iterator I = CVM.begin(),
         E = CVM.end(); I != E; ++I) {
    ++size;
    std::pair<TypeParam*, int> value = *I;  (void)value;
    CompileAssertHasType<TypeParam*>(I->first);
    if (I->second == 5) {
      EXPECT_EQ(this->BitcastV.get(), I->first);
    } else if (I->second == 6) {
      EXPECT_EQ(this->AddV.get(), I->first);
    } else {
      ADD_FAILURE() << "Iterated through an extra value.";
    }
  }
  EXPECT_EQ(2U, size);
}

TYPED_TEST(ValueMapTest, DefaultCollisionBehavior) {
  // By default, we overwrite the old value with the replaced value.
  ValueMap<TypeParam*, int> VM;
  VM[this->BitcastV.get()] = 7;
  VM[this->AddV.get()] = 9;
  this->BitcastV->replaceAllUsesWith(this->AddV.get());
  EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
  EXPECT_EQ(9, VM.lookup(this->AddV.get()));
}

TYPED_TEST(ValueMapTest, ConfiguredCollisionBehavior) {
  // TODO: Implement this when someone needs it.
}

template<typename KeyT, typename MutexT>
struct LockMutex : ValueMapConfig<KeyT, MutexT> {
  struct ExtraData {
    MutexT *M;
    bool *CalledRAUW;
    bool *CalledDeleted;
  };
  static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
    *Data.CalledRAUW = true;
    EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
  }
  static void onDelete(const ExtraData &Data, KeyT Old) {
    *Data.CalledDeleted = true;
    EXPECT_FALSE(Data.M->try_lock()) << "Mutex should already be locked.";
  }
  static MutexT *getMutex(const ExtraData &Data) { return Data.M; }
};
// FIXME: These tests started failing on Windows.
#if LLVM_ENABLE_THREADS && !defined(_WIN32)
TYPED_TEST(ValueMapTest, LocksMutex) {
  std::mutex M;
  bool CalledRAUW = false, CalledDeleted = false;
  typedef LockMutex<TypeParam*, std::mutex> ConfigType;
  typename ConfigType::ExtraData Data = {&M, &CalledRAUW, &CalledDeleted};
  ValueMap<TypeParam*, int, ConfigType> VM(Data);
  VM[this->BitcastV.get()] = 7;
  this->BitcastV->replaceAllUsesWith(this->AddV.get());
  this->AddV.reset();
  EXPECT_TRUE(CalledRAUW);
  EXPECT_TRUE(CalledDeleted);
}
#endif

template<typename KeyT>
struct NoFollow : ValueMapConfig<KeyT> {
  enum { FollowRAUW = false };
};

TYPED_TEST(ValueMapTest, NoFollowRAUW) {
  ValueMap<TypeParam*, int, NoFollow<TypeParam*> > VM;
  VM[this->BitcastV.get()] = 7;
  EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
  EXPECT_EQ(0u, VM.count(this->AddV.get()));
  this->BitcastV->replaceAllUsesWith(this->AddV.get());
  EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
  EXPECT_EQ(0, VM.lookup(this->AddV.get()));
  this->AddV.reset();
  EXPECT_EQ(7, VM.lookup(this->BitcastV.get()));
  EXPECT_EQ(0, VM.lookup(this->AddV.get()));
  this->BitcastV.reset();
  EXPECT_EQ(0, VM.lookup(this->BitcastV.get()));
  EXPECT_EQ(0, VM.lookup(this->AddV.get()));
  EXPECT_EQ(0U, VM.size());
}

template<typename KeyT>
struct CountOps : ValueMapConfig<KeyT> {
  struct ExtraData {
    int *Deletions;
    int *RAUWs;
  };

  static void onRAUW(const ExtraData &Data, KeyT Old, KeyT New) {
    ++*Data.RAUWs;
  }
  static void onDelete(const ExtraData &Data, KeyT Old) {
    ++*Data.Deletions;
  }
};

TYPED_TEST(ValueMapTest, CallsConfig) {
  int Deletions = 0, RAUWs = 0;
  typename CountOps<TypeParam*>::ExtraData Data = {&Deletions, &RAUWs};
  ValueMap<TypeParam*, int, CountOps<TypeParam*> > VM(Data);
  VM[this->BitcastV.get()] = 7;
  this->BitcastV->replaceAllUsesWith(this->AddV.get());
  EXPECT_EQ(0, Deletions);
  EXPECT_EQ(1, RAUWs);
  this->AddV.reset();
  EXPECT_EQ(1, Deletions);
  EXPECT_EQ(1, RAUWs);
  this->BitcastV.reset();
  EXPECT_EQ(1, Deletions);
  EXPECT_EQ(1, RAUWs);
}

template<typename KeyT>
struct ModifyingConfig : ValueMapConfig<KeyT> {
  // We'll put a pointer here back to the ValueMap this key is in, so
  // that we can modify it (and clobber *this) before the ValueMap
  // tries to do the same modification.  In previous versions of
  // ValueMap, that exploded.
  typedef ValueMap<KeyT, int, ModifyingConfig<KeyT> > **ExtraData;

  static void onRAUW(ExtraData Map, KeyT Old, KeyT New) {
    (*Map)->erase(Old);
  }
  static void onDelete(ExtraData Map, KeyT Old) {
    (*Map)->erase(Old);
  }
};
TYPED_TEST(ValueMapTest, SurvivesModificationByConfig) {
  ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > *MapAddress;
  ValueMap<TypeParam*, int, ModifyingConfig<TypeParam*> > VM(&MapAddress);
  MapAddress = &VM;
  // Now the ModifyingConfig can modify the Map inside a callback.
  VM[this->BitcastV.get()] = 7;
  this->BitcastV->replaceAllUsesWith(this->AddV.get());
  EXPECT_EQ(0u, VM.count(this->BitcastV.get()));
  EXPECT_EQ(0u, VM.count(this->AddV.get()));
  VM[this->AddV.get()] = 7;
  this->AddV.reset();
  EXPECT_EQ(0u, VM.count(this->AddV.get()));
}

} // end namespace
