//===-- ConstantsContext.h - Constants-related Context Interals -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines various helper methods and classes used by
// LLVMContextImpl for creating and managing constants.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CONSTANTSCONTEXT_H
#define LLVM_CONSTANTSCONTEXT_H

#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Operator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <map>

namespace llvm {
template<class ValType>
struct ConstantTraits;

/// UnaryConstantExpr - This class is private to Constants.cpp, and is used
/// behind the scenes to implement unary constant exprs.
class UnaryConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
public:
  // allocate space for exactly one operand
  void *operator new(size_t s) {
    return User::operator new(s, 1);
  }
  UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
    : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
    Op<0>() = C;
  }
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

/// BinaryConstantExpr - This class is private to Constants.cpp, and is used
/// behind the scenes to implement binary constant exprs.
class BinaryConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
public:
  // allocate space for exactly two operands
  void *operator new(size_t s) {
    return User::operator new(s, 2);
  }
  BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
                     unsigned Flags)
    : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
    Op<0>() = C1;
    Op<1>() = C2;
    SubclassOptionalData = Flags;
  }
  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

/// SelectConstantExpr - This class is private to Constants.cpp, and is used
/// behind the scenes to implement select constant exprs.
class SelectConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
public:
  // allocate space for exactly three operands
  void *operator new(size_t s) {
    return User::operator new(s, 3);
  }
  SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
    : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
    Op<0>() = C1;
    Op<1>() = C2;
    Op<2>() = C3;
  }
  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

/// ExtractElementConstantExpr - This class is private to
/// Constants.cpp, and is used behind the scenes to implement
/// extractelement constant exprs.
class ExtractElementConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
public:
  // allocate space for exactly two operands
  void *operator new(size_t s) {
    return User::operator new(s, 2);
  }
  ExtractElementConstantExpr(Constant *C1, Constant *C2)
    : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), 
                   Instruction::ExtractElement, &Op<0>(), 2) {
    Op<0>() = C1;
    Op<1>() = C2;
  }
  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

/// InsertElementConstantExpr - This class is private to
/// Constants.cpp, and is used behind the scenes to implement
/// insertelement constant exprs.
class InsertElementConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
public:
  // allocate space for exactly three operands
  void *operator new(size_t s) {
    return User::operator new(s, 3);
  }
  InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
    : ConstantExpr(C1->getType(), Instruction::InsertElement, 
                   &Op<0>(), 3) {
    Op<0>() = C1;
    Op<1>() = C2;
    Op<2>() = C3;
  }
  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

/// ShuffleVectorConstantExpr - This class is private to
/// Constants.cpp, and is used behind the scenes to implement
/// shufflevector constant exprs.
class ShuffleVectorConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
public:
  // allocate space for exactly three operands
  void *operator new(size_t s) {
    return User::operator new(s, 3);
  }
  ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
  : ConstantExpr(VectorType::get(
                   cast<VectorType>(C1->getType())->getElementType(),
                   cast<VectorType>(C3->getType())->getNumElements()),
                 Instruction::ShuffleVector, 
                 &Op<0>(), 3) {
    Op<0>() = C1;
    Op<1>() = C2;
    Op<2>() = C3;
  }
  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

/// ExtractValueConstantExpr - This class is private to
/// Constants.cpp, and is used behind the scenes to implement
/// extractvalue constant exprs.
class ExtractValueConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
public:
  // allocate space for exactly one operand
  void *operator new(size_t s) {
    return User::operator new(s, 1);
  }
  ExtractValueConstantExpr(Constant *Agg,
                           const SmallVector<unsigned, 4> &IdxList,
                           Type *DestTy)
    : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
      Indices(IdxList) {
    Op<0>() = Agg;
  }

  /// Indices - These identify which value to extract.
  const SmallVector<unsigned, 4> Indices;

  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

/// InsertValueConstantExpr - This class is private to
/// Constants.cpp, and is used behind the scenes to implement
/// insertvalue constant exprs.
class InsertValueConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
public:
  // allocate space for exactly one operand
  void *operator new(size_t s) {
    return User::operator new(s, 2);
  }
  InsertValueConstantExpr(Constant *Agg, Constant *Val,
                          const SmallVector<unsigned, 4> &IdxList,
                          Type *DestTy)
    : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
      Indices(IdxList) {
    Op<0>() = Agg;
    Op<1>() = Val;
  }

  /// Indices - These identify the position for the insertion.
  const SmallVector<unsigned, 4> Indices;

  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};


/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
/// used behind the scenes to implement getelementpr constant exprs.
class GetElementPtrConstantExpr : public ConstantExpr {
  GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
                            Type *DestTy);
public:
  static GetElementPtrConstantExpr *Create(Constant *C,
                                           const std::vector<Constant*>&IdxList,
                                           Type *DestTy,
                                           unsigned Flags) {
    GetElementPtrConstantExpr *Result =
      new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
    Result->SubclassOptionalData = Flags;
    return Result;
  }
  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

// CompareConstantExpr - This class is private to Constants.cpp, and is used
// behind the scenes to implement ICmp and FCmp constant expressions. This is
// needed in order to store the predicate value for these instructions.
struct CompareConstantExpr : public ConstantExpr {
  void *operator new(size_t, unsigned);  // DO NOT IMPLEMENT
  // allocate space for exactly two operands
  void *operator new(size_t s) {
    return User::operator new(s, 2);
  }
  unsigned short predicate;
  CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
                      unsigned short pred,  Constant* LHS, Constant* RHS)
    : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
    Op<0>() = LHS;
    Op<1>() = RHS;
  }
  /// Transparently provide more efficient getOperand methods.
  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
};

template <>
struct OperandTraits<UnaryConstantExpr> :
  public FixedNumOperandTraits<UnaryConstantExpr, 1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)

template <>
struct OperandTraits<BinaryConstantExpr> :
  public FixedNumOperandTraits<BinaryConstantExpr, 2> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)

template <>
struct OperandTraits<SelectConstantExpr> :
  public FixedNumOperandTraits<SelectConstantExpr, 3> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)

template <>
struct OperandTraits<ExtractElementConstantExpr> :
  public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)

template <>
struct OperandTraits<InsertElementConstantExpr> :
  public FixedNumOperandTraits<InsertElementConstantExpr, 3> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)

template <>
struct OperandTraits<ShuffleVectorConstantExpr> :
    public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)

template <>
struct OperandTraits<ExtractValueConstantExpr> :
  public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)

template <>
struct OperandTraits<InsertValueConstantExpr> :
  public FixedNumOperandTraits<InsertValueConstantExpr, 2> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)

template <>
struct OperandTraits<GetElementPtrConstantExpr> :
  public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {
};

DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)


template <>
struct OperandTraits<CompareConstantExpr> :
  public FixedNumOperandTraits<CompareConstantExpr, 2> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)

struct ExprMapKeyType {
  ExprMapKeyType(unsigned opc,
      ArrayRef<Constant*> ops,
      unsigned short flags = 0,
      unsigned short optionalflags = 0,
      ArrayRef<unsigned> inds = ArrayRef<unsigned>())
        : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
        operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {}
  uint8_t opcode;
  uint8_t subclassoptionaldata;
  uint16_t subclassdata;
  std::vector<Constant*> operands;
  SmallVector<unsigned, 4> indices;
  bool operator==(const ExprMapKeyType& that) const {
    return this->opcode == that.opcode &&
           this->subclassdata == that.subclassdata &&
           this->subclassoptionaldata == that.subclassoptionaldata &&
           this->operands == that.operands &&
           this->indices == that.indices;
  }
  bool operator<(const ExprMapKeyType & that) const {
    if (this->opcode != that.opcode) return this->opcode < that.opcode;
    if (this->operands != that.operands) return this->operands < that.operands;
    if (this->subclassdata != that.subclassdata)
      return this->subclassdata < that.subclassdata;
    if (this->subclassoptionaldata != that.subclassoptionaldata)
      return this->subclassoptionaldata < that.subclassoptionaldata;
    if (this->indices != that.indices) return this->indices < that.indices;
    return false;
  }

  bool operator!=(const ExprMapKeyType& that) const {
    return !(*this == that);
  }
};

struct InlineAsmKeyType {
  InlineAsmKeyType(StringRef AsmString,
                   StringRef Constraints, bool hasSideEffects,
                   bool isAlignStack)
    : asm_string(AsmString), constraints(Constraints),
      has_side_effects(hasSideEffects), is_align_stack(isAlignStack) {}
  std::string asm_string;
  std::string constraints;
  bool has_side_effects;
  bool is_align_stack;
  bool operator==(const InlineAsmKeyType& that) const {
    return this->asm_string == that.asm_string &&
           this->constraints == that.constraints &&
           this->has_side_effects == that.has_side_effects &&
           this->is_align_stack == that.is_align_stack;
  }
  bool operator<(const InlineAsmKeyType& that) const {
    if (this->asm_string != that.asm_string)
      return this->asm_string < that.asm_string;
    if (this->constraints != that.constraints)
      return this->constraints < that.constraints;
    if (this->has_side_effects != that.has_side_effects)
      return this->has_side_effects < that.has_side_effects;
    if (this->is_align_stack != that.is_align_stack)
      return this->is_align_stack < that.is_align_stack;
    return false;
  }

  bool operator!=(const InlineAsmKeyType& that) const {
    return !(*this == that);
  }
};

// The number of operands for each ConstantCreator::create method is
// determined by the ConstantTraits template.
// ConstantCreator - A class that is used to create constants by
// ConstantUniqueMap*.  This class should be partially specialized if there is
// something strange that needs to be done to interface to the ctor for the
// constant.
//
template<typename T, typename Alloc>
struct ConstantTraits< std::vector<T, Alloc> > {
  static unsigned uses(const std::vector<T, Alloc>& v) {
    return v.size();
  }
};

template<>
struct ConstantTraits<Constant *> {
  static unsigned uses(Constant * const & v) {
    return 1;
  }
};

template<class ConstantClass, class TypeClass, class ValType>
struct ConstantCreator {
  static ConstantClass *create(TypeClass *Ty, const ValType &V) {
    return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V);
  }
};

template<class ConstantClass>
struct ConstantKeyData {
  typedef void ValType;
  static ValType getValType(ConstantClass *C) {
    llvm_unreachable("Unknown Constant type!");
  }
};

template<>
struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
  static ConstantExpr *create(Type *Ty, const ExprMapKeyType &V,
      unsigned short pred = 0) {
    if (Instruction::isCast(V.opcode))
      return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
    if ((V.opcode >= Instruction::BinaryOpsBegin &&
         V.opcode < Instruction::BinaryOpsEnd))
      return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
                                    V.subclassoptionaldata);
    if (V.opcode == Instruction::Select)
      return new SelectConstantExpr(V.operands[0], V.operands[1], 
                                    V.operands[2]);
    if (V.opcode == Instruction::ExtractElement)
      return new ExtractElementConstantExpr(V.operands[0], V.operands[1]);
    if (V.opcode == Instruction::InsertElement)
      return new InsertElementConstantExpr(V.operands[0], V.operands[1],
                                           V.operands[2]);
    if (V.opcode == Instruction::ShuffleVector)
      return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
                                           V.operands[2]);
    if (V.opcode == Instruction::InsertValue)
      return new InsertValueConstantExpr(V.operands[0], V.operands[1],
                                         V.indices, Ty);
    if (V.opcode == Instruction::ExtractValue)
      return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
    if (V.opcode == Instruction::GetElementPtr) {
      std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
      return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
                                               V.subclassoptionaldata);
    }

    // The compare instructions are weird. We have to encode the predicate
    // value and it is combined with the instruction opcode by multiplying
    // the opcode by one hundred. We must decode this to get the predicate.
    if (V.opcode == Instruction::ICmp)
      return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata,
                                     V.operands[0], V.operands[1]);
    if (V.opcode == Instruction::FCmp) 
      return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata,
                                     V.operands[0], V.operands[1]);
    llvm_unreachable("Invalid ConstantExpr!");
    return 0;
  }
};

template<>
struct ConstantKeyData<ConstantExpr> {
  typedef ExprMapKeyType ValType;
  static ValType getValType(ConstantExpr *CE) {
    std::vector<Constant*> Operands;
    Operands.reserve(CE->getNumOperands());
    for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
      Operands.push_back(cast<Constant>(CE->getOperand(i)));
    return ExprMapKeyType(CE->getOpcode(), Operands,
        CE->isCompare() ? CE->getPredicate() : 0,
        CE->getRawSubclassOptionalData(),
        CE->hasIndices() ?
          CE->getIndices() : ArrayRef<unsigned>());
  }
};

// ConstantAggregateZero does not take extra "value" argument...
template<class ValType>
struct ConstantCreator<ConstantAggregateZero, Type, ValType> {
  static ConstantAggregateZero *create(Type *Ty, const ValType &V){
    return new ConstantAggregateZero(Ty);
  }
};

template<>
struct ConstantKeyData<ConstantVector> {
  typedef std::vector<Constant*> ValType;
  static ValType getValType(ConstantVector *CP) {
    std::vector<Constant*> Elements;
    Elements.reserve(CP->getNumOperands());
    for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
      Elements.push_back(CP->getOperand(i));
    return Elements;
  }
};

template<>
struct ConstantKeyData<ConstantAggregateZero> {
  typedef char ValType;
  static ValType getValType(ConstantAggregateZero *C) {
    return 0;
  }
};

template<>
struct ConstantKeyData<ConstantArray> {
  typedef std::vector<Constant*> ValType;
  static ValType getValType(ConstantArray *CA) {
    std::vector<Constant*> Elements;
    Elements.reserve(CA->getNumOperands());
    for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
      Elements.push_back(cast<Constant>(CA->getOperand(i)));
    return Elements;
  }
};

template<>
struct ConstantKeyData<ConstantStruct> {
  typedef std::vector<Constant*> ValType;
  static ValType getValType(ConstantStruct *CS) {
    std::vector<Constant*> Elements;
    Elements.reserve(CS->getNumOperands());
    for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i)
      Elements.push_back(cast<Constant>(CS->getOperand(i)));
    return Elements;
  }
};

// ConstantPointerNull does not take extra "value" argument...
template<class ValType>
struct ConstantCreator<ConstantPointerNull, PointerType, ValType> {
  static ConstantPointerNull *create(PointerType *Ty, const ValType &V){
    return new ConstantPointerNull(Ty);
  }
};

template<>
struct ConstantKeyData<ConstantPointerNull> {
  typedef char ValType;
  static ValType getValType(ConstantPointerNull *C) {
    return 0;
  }
};

// UndefValue does not take extra "value" argument...
template<class ValType>
struct ConstantCreator<UndefValue, Type, ValType> {
  static UndefValue *create(Type *Ty, const ValType &V) {
    return new UndefValue(Ty);
  }
};

template<>
struct ConstantKeyData<UndefValue> {
  typedef char ValType;
  static ValType getValType(UndefValue *C) {
    return 0;
  }
};

template<>
struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
  static InlineAsm *create(PointerType *Ty, const InlineAsmKeyType &Key) {
    return new InlineAsm(Ty, Key.asm_string, Key.constraints,
                         Key.has_side_effects, Key.is_align_stack);
  }
};

template<>
struct ConstantKeyData<InlineAsm> {
  typedef InlineAsmKeyType ValType;
  static ValType getValType(InlineAsm *Asm) {
    return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(),
                            Asm->hasSideEffects(), Asm->isAlignStack());
  }
};

template<class ValType, class ValRefType, class TypeClass, class ConstantClass,
         bool HasLargeKey = false /*true for arrays and structs*/ >
class ConstantUniqueMap {
public:
  typedef std::pair<TypeClass*, ValType> MapKey;
  typedef std::map<MapKey, ConstantClass *> MapTy;
  typedef std::map<ConstantClass *, typename MapTy::iterator> InverseMapTy;
private:
  /// Map - This is the main map from the element descriptor to the Constants.
  /// This is the primary way we avoid creating two of the same shape
  /// constant.
  MapTy Map;
    
  /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping
  /// from the constants to their element in Map.  This is important for
  /// removal of constants from the array, which would otherwise have to scan
  /// through the map with very large keys.
  InverseMapTy InverseMap;

public:
  typename MapTy::iterator map_begin() { return Map.begin(); }
  typename MapTy::iterator map_end() { return Map.end(); }

  void freeConstants() {
    for (typename MapTy::iterator I=Map.begin(), E=Map.end();
         I != E; ++I) {
      // Asserts that use_empty().
      delete I->second;
    }
  }
    
  /// InsertOrGetItem - Return an iterator for the specified element.
  /// If the element exists in the map, the returned iterator points to the
  /// entry and Exists=true.  If not, the iterator points to the newly
  /// inserted entry and returns Exists=false.  Newly inserted entries have
  /// I->second == 0, and should be filled in.
  typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, ConstantClass *>
                                 &InsertVal,
                                 bool &Exists) {
    std::pair<typename MapTy::iterator, bool> IP = Map.insert(InsertVal);
    Exists = !IP.second;
    return IP.first;
  }
    
private:
  typename MapTy::iterator FindExistingElement(ConstantClass *CP) {
    if (HasLargeKey) {
      typename InverseMapTy::iterator IMI = InverseMap.find(CP);
      assert(IMI != InverseMap.end() && IMI->second != Map.end() &&
             IMI->second->second == CP &&
             "InverseMap corrupt!");
      return IMI->second;
    }
      
    typename MapTy::iterator I =
      Map.find(MapKey(static_cast<TypeClass*>(CP->getType()),
                      ConstantKeyData<ConstantClass>::getValType(CP)));
    if (I == Map.end() || I->second != CP) {
      // FIXME: This should not use a linear scan.  If this gets to be a
      // performance problem, someone should look at this.
      for (I = Map.begin(); I != Map.end() && I->second != CP; ++I)
        /* empty */;
    }
    return I;
  }

  ConstantClass *Create(TypeClass *Ty, ValRefType V,
                        typename MapTy::iterator I) {
    ConstantClass* Result =
      ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V);

    assert(Result->getType() == Ty && "Type specified is not correct!");
    I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result));

    if (HasLargeKey)  // Remember the reverse mapping if needed.
      InverseMap.insert(std::make_pair(Result, I));

    return Result;
  }
public:
    
  /// getOrCreate - Return the specified constant from the map, creating it if
  /// necessary.
  ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) {
    MapKey Lookup(Ty, V);
    ConstantClass* Result = 0;
    
    typename MapTy::iterator I = Map.find(Lookup);
    // Is it in the map?  
    if (I != Map.end())
      Result = I->second;
        
    if (!Result) {
      // If no preexisting value, create one now...
      Result = Create(Ty, V, I);
    }
        
    return Result;
  }

  void remove(ConstantClass *CP) {
    typename MapTy::iterator I = FindExistingElement(CP);
    assert(I != Map.end() && "Constant not found in constant table!");
    assert(I->second == CP && "Didn't find correct element?");

    if (HasLargeKey)  // Remember the reverse mapping if needed.
      InverseMap.erase(CP);

    Map.erase(I);
  }

  /// MoveConstantToNewSlot - If we are about to change C to be the element
  /// specified by I, update our internal data structures to reflect this
  /// fact.
  void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) {
    // First, remove the old location of the specified constant in the map.
    typename MapTy::iterator OldI = FindExistingElement(C);
    assert(OldI != Map.end() && "Constant not found in constant table!");
    assert(OldI->second == C && "Didn't find correct element?");
      
     // Remove the old entry from the map.
    Map.erase(OldI);
    
    // Update the inverse map so that we know that this constant is now
    // located at descriptor I.
    if (HasLargeKey) {
      assert(I->second == C && "Bad inversemap entry!");
      InverseMap[C] = I;
    }
  }

  void dump() const {
    DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
  }
};

}

#endif
