//===-- Type.cpp - Implement the Type class -------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Type class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "LLVMContextImpl.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Threading.h"
#include <algorithm>
#include <cstdarg>
using namespace llvm;

// DEBUG_MERGE_TYPES - Enable this #define to see how and when derived types are
// created and later destroyed, all in an effort to make sure that there is only
// a single canonical version of a type.
//
// #define DEBUG_MERGE_TYPES 1

AbstractTypeUser::~AbstractTypeUser() {}

void AbstractTypeUser::setType(Value *V, const Type *NewTy) {
  V->VTy = NewTy;
}

//===----------------------------------------------------------------------===//
//                         Type Class Implementation
//===----------------------------------------------------------------------===//

/// Because of the way Type subclasses are allocated, this function is necessary
/// to use the correct kind of "delete" operator to deallocate the Type object.
/// Some type objects (FunctionTy, StructTy) allocate additional space
/// after the space for their derived type to hold the contained types array of
/// PATypeHandles. Using this allocation scheme means all the PATypeHandles are
/// allocated with the type object, decreasing allocations and eliminating the
/// need for a std::vector to be used in the Type class itself. 
/// @brief Type destruction function
void Type::destroy() const {
  // Nothing calls getForwardedType from here on.
  if (ForwardType && ForwardType->isAbstract()) {
    ForwardType->dropRef();
    ForwardType = NULL;
  }

  // Structures and Functions allocate their contained types past the end of
  // the type object itself. These need to be destroyed differently than the
  // other types.
  if (this->isFunctionTy() || this->isStructTy()) {
    // First, make sure we destruct any PATypeHandles allocated by these
    // subclasses.  They must be manually destructed. 
    for (unsigned i = 0; i < NumContainedTys; ++i)
      ContainedTys[i].PATypeHandle::~PATypeHandle();

    // Now call the destructor for the subclass directly because we're going
    // to delete this as an array of char.
    if (this->isFunctionTy())
      static_cast<const FunctionType*>(this)->FunctionType::~FunctionType();
    else {
      assert(isStructTy());
      static_cast<const StructType*>(this)->StructType::~StructType();
    }

    // Finally, remove the memory as an array deallocation of the chars it was
    // constructed from.
    operator delete(const_cast<Type *>(this));

    return;
  } else if (const OpaqueType *opaque_this = dyn_cast<OpaqueType>(this)) {
    LLVMContextImpl *pImpl = this->getContext().pImpl;
    pImpl->OpaqueTypes.erase(opaque_this);
  }

  // For all the other type subclasses, there is either no contained types or 
  // just one (all Sequentials). For Sequentials, the PATypeHandle is not
  // allocated past the type object, its included directly in the SequentialType
  // class. This means we can safely just do "normal" delete of this object and
  // all the destructors that need to run will be run.
  delete this; 
}

const Type *Type::getPrimitiveType(LLVMContext &C, TypeID IDNumber) {
  switch (IDNumber) {
  case VoidTyID      : return getVoidTy(C);
  case FloatTyID     : return getFloatTy(C);
  case DoubleTyID    : return getDoubleTy(C);
  case X86_FP80TyID  : return getX86_FP80Ty(C);
  case FP128TyID     : return getFP128Ty(C);
  case PPC_FP128TyID : return getPPC_FP128Ty(C);
  case LabelTyID     : return getLabelTy(C);
  case MetadataTyID  : return getMetadataTy(C);
  case X86_MMXTyID   : return getX86_MMXTy(C);
  default:
    return 0;
  }
}

const Type *Type::getVAArgsPromotedType(LLVMContext &C) const {
  if (ID == IntegerTyID && getSubclassData() < 32)
    return Type::getInt32Ty(C);
  else if (ID == FloatTyID)
    return Type::getDoubleTy(C);
  else
    return this;
}

/// getScalarType - If this is a vector type, return the element type,
/// otherwise return this.
const Type *Type::getScalarType() const {
  if (const VectorType *VTy = dyn_cast<VectorType>(this))
    return VTy->getElementType();
  return this;
}

/// isIntegerTy - Return true if this is an IntegerType of the specified width.
bool Type::isIntegerTy(unsigned Bitwidth) const {
  return isIntegerTy() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
}

/// isIntOrIntVectorTy - Return true if this is an integer type or a vector of
/// integer types.
///
bool Type::isIntOrIntVectorTy() const {
  if (isIntegerTy())
    return true;
  if (ID != Type::VectorTyID) return false;
  
  return cast<VectorType>(this)->getElementType()->isIntegerTy();
}

/// isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP types.
///
bool Type::isFPOrFPVectorTy() const {
  if (ID == Type::FloatTyID || ID == Type::DoubleTyID || 
      ID == Type::FP128TyID || ID == Type::X86_FP80TyID || 
      ID == Type::PPC_FP128TyID)
    return true;
  if (ID != Type::VectorTyID) return false;
  
  return cast<VectorType>(this)->getElementType()->isFloatingPointTy();
}

// canLosslesslyBitCastTo - Return true if this type can be converted to
// 'Ty' without any reinterpretation of bits.  For example, i8* to i32*.
//
bool Type::canLosslesslyBitCastTo(const Type *Ty) const {
  // Identity cast means no change so return true
  if (this == Ty) 
    return true;
  
  // They are not convertible unless they are at least first class types
  if (!this->isFirstClassType() || !Ty->isFirstClassType())
    return false;

  // Vector -> Vector conversions are always lossless if the two vector types
  // have the same size, otherwise not.  Also, 64-bit vector types can be
  // converted to x86mmx.
  if (const VectorType *thisPTy = dyn_cast<VectorType>(this)) {
    if (const VectorType *thatPTy = dyn_cast<VectorType>(Ty))
      return thisPTy->getBitWidth() == thatPTy->getBitWidth();
    if (Ty->getTypeID() == Type::X86_MMXTyID &&
        thisPTy->getBitWidth() == 64)
      return true;
  }

  if (this->getTypeID() == Type::X86_MMXTyID)
    if (const VectorType *thatPTy = dyn_cast<VectorType>(Ty))
      if (thatPTy->getBitWidth() == 64)
        return true;

  // At this point we have only various mismatches of the first class types
  // remaining and ptr->ptr. Just select the lossless conversions. Everything
  // else is not lossless.
  if (this->isPointerTy())
    return Ty->isPointerTy();
  return false;  // Other types have no identity values
}

unsigned Type::getPrimitiveSizeInBits() const {
  switch (getTypeID()) {
  case Type::FloatTyID: return 32;
  case Type::DoubleTyID: return 64;
  case Type::X86_FP80TyID: return 80;
  case Type::FP128TyID: return 128;
  case Type::PPC_FP128TyID: return 128;
  case Type::X86_MMXTyID: return 64;
  case Type::IntegerTyID: return cast<IntegerType>(this)->getBitWidth();
  case Type::VectorTyID:  return cast<VectorType>(this)->getBitWidth();
  default: return 0;
  }
}

/// getScalarSizeInBits - If this is a vector type, return the
/// getPrimitiveSizeInBits value for the element type. Otherwise return the
/// getPrimitiveSizeInBits value for this type.
unsigned Type::getScalarSizeInBits() const {
  return getScalarType()->getPrimitiveSizeInBits();
}

/// getFPMantissaWidth - Return the width of the mantissa of this type.  This
/// is only valid on floating point types.  If the FP type does not
/// have a stable mantissa (e.g. ppc long double), this method returns -1.
int Type::getFPMantissaWidth() const {
  if (const VectorType *VTy = dyn_cast<VectorType>(this))
    return VTy->getElementType()->getFPMantissaWidth();
  assert(isFloatingPointTy() && "Not a floating point type!");
  if (ID == FloatTyID) return 24;
  if (ID == DoubleTyID) return 53;
  if (ID == X86_FP80TyID) return 64;
  if (ID == FP128TyID) return 113;
  assert(ID == PPC_FP128TyID && "unknown fp type");
  return -1;
}

/// isSizedDerivedType - Derived types like structures and arrays are sized
/// iff all of the members of the type are sized as well.  Since asking for
/// their size is relatively uncommon, move this operation out of line.
bool Type::isSizedDerivedType() const {
  if (this->isIntegerTy())
    return true;

  if (const ArrayType *ATy = dyn_cast<ArrayType>(this))
    return ATy->getElementType()->isSized();

  if (const VectorType *PTy = dyn_cast<VectorType>(this))
    return PTy->getElementType()->isSized();

  if (!this->isStructTy()) 
    return false;

  // Okay, our struct is sized if all of the elements are...
  for (subtype_iterator I = subtype_begin(), E = subtype_end(); I != E; ++I)
    if (!(*I)->isSized()) 
      return false;

  return true;
}

/// getForwardedTypeInternal - This method is used to implement the union-find
/// algorithm for when a type is being forwarded to another type.
const Type *Type::getForwardedTypeInternal() const {
  assert(ForwardType && "This type is not being forwarded to another type!");

  // Check to see if the forwarded type has been forwarded on.  If so, collapse
  // the forwarding links.
  const Type *RealForwardedType = ForwardType->getForwardedType();
  if (!RealForwardedType)
    return ForwardType;  // No it's not forwarded again

  // Yes, it is forwarded again.  First thing, add the reference to the new
  // forward type.
  if (RealForwardedType->isAbstract())
    RealForwardedType->addRef();

  // Now drop the old reference.  This could cause ForwardType to get deleted.
  // ForwardType must be abstract because only abstract types can have their own
  // ForwardTypes.
  ForwardType->dropRef();

  // Return the updated type.
  ForwardType = RealForwardedType;
  return ForwardType;
}

void Type::refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
  llvm_unreachable("Attempting to refine a derived type!");
}
void Type::typeBecameConcrete(const DerivedType *AbsTy) {
  llvm_unreachable("DerivedType is already a concrete type!");
}


std::string Type::getDescription() const {
  LLVMContextImpl *pImpl = getContext().pImpl;
  TypePrinting &Map =
    isAbstract() ?
      pImpl->AbstractTypeDescriptions :
      pImpl->ConcreteTypeDescriptions;
  
  std::string DescStr;
  raw_string_ostream DescOS(DescStr);
  Map.print(this, DescOS);
  return DescOS.str();
}


bool StructType::indexValid(const Value *V) const {
  // Structure indexes require 32-bit integer constants.
  if (V->getType()->isIntegerTy(32))
    if (const ConstantInt *CU = dyn_cast<ConstantInt>(V))
      return indexValid(CU->getZExtValue());
  return false;
}

bool StructType::indexValid(unsigned V) const {
  return V < NumContainedTys;
}

// getTypeAtIndex - Given an index value into the type, return the type of the
// element.  For a structure type, this must be a constant value...
//
const Type *StructType::getTypeAtIndex(const Value *V) const {
  unsigned Idx = (unsigned)cast<ConstantInt>(V)->getZExtValue();
  return getTypeAtIndex(Idx);
}

const Type *StructType::getTypeAtIndex(unsigned Idx) const {
  assert(indexValid(Idx) && "Invalid structure index!");
  return ContainedTys[Idx];
}


//===----------------------------------------------------------------------===//
//                          Primitive 'Type' data
//===----------------------------------------------------------------------===//

const Type *Type::getVoidTy(LLVMContext &C) {
  return &C.pImpl->VoidTy;
}

const Type *Type::getLabelTy(LLVMContext &C) {
  return &C.pImpl->LabelTy;
}

const Type *Type::getFloatTy(LLVMContext &C) {
  return &C.pImpl->FloatTy;
}

const Type *Type::getDoubleTy(LLVMContext &C) {
  return &C.pImpl->DoubleTy;
}

const Type *Type::getMetadataTy(LLVMContext &C) {
  return &C.pImpl->MetadataTy;
}

const Type *Type::getX86_FP80Ty(LLVMContext &C) {
  return &C.pImpl->X86_FP80Ty;
}

const Type *Type::getFP128Ty(LLVMContext &C) {
  return &C.pImpl->FP128Ty;
}

const Type *Type::getPPC_FP128Ty(LLVMContext &C) {
  return &C.pImpl->PPC_FP128Ty;
}

const Type *Type::getX86_MMXTy(LLVMContext &C) {
  return &C.pImpl->X86_MMXTy;
}

const IntegerType *Type::getIntNTy(LLVMContext &C, unsigned N) {
  return IntegerType::get(C, N);
}

const IntegerType *Type::getInt1Ty(LLVMContext &C) {
  return &C.pImpl->Int1Ty;
}

const IntegerType *Type::getInt8Ty(LLVMContext &C) {
  return &C.pImpl->Int8Ty;
}

const IntegerType *Type::getInt16Ty(LLVMContext &C) {
  return &C.pImpl->Int16Ty;
}

const IntegerType *Type::getInt32Ty(LLVMContext &C) {
  return &C.pImpl->Int32Ty;
}

const IntegerType *Type::getInt64Ty(LLVMContext &C) {
  return &C.pImpl->Int64Ty;
}

const PointerType *Type::getFloatPtrTy(LLVMContext &C, unsigned AS) {
  return getFloatTy(C)->getPointerTo(AS);
}

const PointerType *Type::getDoublePtrTy(LLVMContext &C, unsigned AS) {
  return getDoubleTy(C)->getPointerTo(AS);
}

const PointerType *Type::getX86_FP80PtrTy(LLVMContext &C, unsigned AS) {
  return getX86_FP80Ty(C)->getPointerTo(AS);
}

const PointerType *Type::getFP128PtrTy(LLVMContext &C, unsigned AS) {
  return getFP128Ty(C)->getPointerTo(AS);
}

const PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) {
  return getPPC_FP128Ty(C)->getPointerTo(AS);
}

const PointerType *Type::getX86_MMXPtrTy(LLVMContext &C, unsigned AS) {
  return getX86_MMXTy(C)->getPointerTo(AS);
}

const PointerType *Type::getIntNPtrTy(LLVMContext &C, unsigned N, unsigned AS) {
  return getIntNTy(C, N)->getPointerTo(AS);
}

const PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) {
  return getInt1Ty(C)->getPointerTo(AS);
}

const PointerType *Type::getInt8PtrTy(LLVMContext &C, unsigned AS) {
  return getInt8Ty(C)->getPointerTo(AS);
}

const PointerType *Type::getInt16PtrTy(LLVMContext &C, unsigned AS) {
  return getInt16Ty(C)->getPointerTo(AS);
}

const PointerType *Type::getInt32PtrTy(LLVMContext &C, unsigned AS) {
  return getInt32Ty(C)->getPointerTo(AS);
}

const PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) {
  return getInt64Ty(C)->getPointerTo(AS);
}

//===----------------------------------------------------------------------===//
//                          Derived Type Constructors
//===----------------------------------------------------------------------===//

/// isValidReturnType - Return true if the specified type is valid as a return
/// type.
bool FunctionType::isValidReturnType(const Type *RetTy) {
  return !RetTy->isFunctionTy() && !RetTy->isLabelTy() &&
         !RetTy->isMetadataTy();
}

/// isValidArgumentType - Return true if the specified type is valid as an
/// argument type.
bool FunctionType::isValidArgumentType(const Type *ArgTy) {
  return ArgTy->isFirstClassType() || ArgTy->isOpaqueTy();
}

FunctionType::FunctionType(const Type *Result,
                           const std::vector<const Type*> &Params,
                           bool IsVarArgs)
  : DerivedType(Result->getContext(), FunctionTyID), isVarArgs(IsVarArgs) {
  ContainedTys = reinterpret_cast<PATypeHandle*>(this+1);
  NumContainedTys = Params.size() + 1; // + 1 for result type
  assert(isValidReturnType(Result) && "invalid return type for function");


  bool isAbstract = Result->isAbstract();
  new (&ContainedTys[0]) PATypeHandle(Result, this);

  for (unsigned i = 0; i != Params.size(); ++i) {
    assert(isValidArgumentType(Params[i]) &&
           "Not a valid type for function argument!");
    new (&ContainedTys[i+1]) PATypeHandle(Params[i], this);
    isAbstract |= Params[i]->isAbstract();
  }

  // Calculate whether or not this type is abstract
  setAbstract(isAbstract);
}

StructType::StructType(LLVMContext &C, 
                       const std::vector<const Type*> &Types, bool isPacked)
  : CompositeType(C, StructTyID) {
  ContainedTys = reinterpret_cast<PATypeHandle*>(this + 1);
  NumContainedTys = Types.size();
  setSubclassData(isPacked);
  bool isAbstract = false;
  for (unsigned i = 0; i < Types.size(); ++i) {
    assert(Types[i] && "<null> type for structure field!");
    assert(isValidElementType(Types[i]) &&
           "Invalid type for structure element!");
    new (&ContainedTys[i]) PATypeHandle(Types[i], this);
    isAbstract |= Types[i]->isAbstract();
  }

  // Calculate whether or not this type is abstract
  setAbstract(isAbstract);
}

ArrayType::ArrayType(const Type *ElType, uint64_t NumEl)
  : SequentialType(ArrayTyID, ElType) {
  NumElements = NumEl;

  // Calculate whether or not this type is abstract
  setAbstract(ElType->isAbstract());
}

VectorType::VectorType(const Type *ElType, unsigned NumEl)
  : SequentialType(VectorTyID, ElType) {
  NumElements = NumEl;
  setAbstract(ElType->isAbstract());
  assert(NumEl > 0 && "NumEl of a VectorType must be greater than 0");
  assert(isValidElementType(ElType) &&
         "Elements of a VectorType must be a primitive type");

}


PointerType::PointerType(const Type *E, unsigned AddrSpace)
  : SequentialType(PointerTyID, E) {
  AddressSpace = AddrSpace;
  // Calculate whether or not this type is abstract
  setAbstract(E->isAbstract());
}

OpaqueType::OpaqueType(LLVMContext &C) : DerivedType(C, OpaqueTyID) {
  setAbstract(true);
#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "Derived new type: " << *this << "\n");
#endif
}

void PATypeHolder::destroy() {
  Ty = 0;
}

// dropAllTypeUses - When this (abstract) type is resolved to be equal to
// another (more concrete) type, we must eliminate all references to other
// types, to avoid some circular reference problems.
void DerivedType::dropAllTypeUses() {
  if (NumContainedTys != 0) {
    // The type must stay abstract.  To do this, we insert a pointer to a type
    // that will never get resolved, thus will always be abstract.
    ContainedTys[0] = getContext().pImpl->AlwaysOpaqueTy;

    // Change the rest of the types to be Int32Ty's.  It doesn't matter what we
    // pick so long as it doesn't point back to this type.  We choose something
    // concrete to avoid overhead for adding to AbstractTypeUser lists and
    // stuff.
    const Type *ConcreteTy = Type::getInt32Ty(getContext());
    for (unsigned i = 1, e = NumContainedTys; i != e; ++i)
      ContainedTys[i] = ConcreteTy;
  }
}


namespace {

/// TypePromotionGraph and graph traits - this is designed to allow us to do
/// efficient SCC processing of type graphs.  This is the exact same as
/// GraphTraits<Type*>, except that we pretend that concrete types have no
/// children to avoid processing them.
struct TypePromotionGraph {
  Type *Ty;
  TypePromotionGraph(Type *T) : Ty(T) {}
};

}

namespace llvm {
  template <> struct GraphTraits<TypePromotionGraph> {
    typedef Type NodeType;
    typedef Type::subtype_iterator ChildIteratorType;

    static inline NodeType *getEntryNode(TypePromotionGraph G) { return G.Ty; }
    static inline ChildIteratorType child_begin(NodeType *N) {
      if (N->isAbstract())
        return N->subtype_begin();
      // No need to process children of concrete types.
      return N->subtype_end();
    }
    static inline ChildIteratorType child_end(NodeType *N) {
      return N->subtype_end();
    }
  };
}


// PromoteAbstractToConcrete - This is a recursive function that walks a type
// graph calculating whether or not a type is abstract.
//
void Type::PromoteAbstractToConcrete() {
  if (!isAbstract()) return;

  scc_iterator<TypePromotionGraph> SI = scc_begin(TypePromotionGraph(this));
  scc_iterator<TypePromotionGraph> SE = scc_end  (TypePromotionGraph(this));

  for (; SI != SE; ++SI) {
    std::vector<Type*> &SCC = *SI;

    // Concrete types are leaves in the tree.  Since an SCC will either be all
    // abstract or all concrete, we only need to check one type.
    if (!SCC[0]->isAbstract()) continue;
    
    if (SCC[0]->isOpaqueTy())
      return;     // Not going to be concrete, sorry.

    // If all of the children of all of the types in this SCC are concrete,
    // then this SCC is now concrete as well.  If not, neither this SCC, nor
    // any parent SCCs will be concrete, so we might as well just exit.
    for (unsigned i = 0, e = SCC.size(); i != e; ++i)
      for (Type::subtype_iterator CI = SCC[i]->subtype_begin(),
             E = SCC[i]->subtype_end(); CI != E; ++CI)
        if ((*CI)->isAbstract())
          // If the child type is in our SCC, it doesn't make the entire SCC
          // abstract unless there is a non-SCC abstract type.
          if (std::find(SCC.begin(), SCC.end(), *CI) == SCC.end())
            return;               // Not going to be concrete, sorry.

    // Okay, we just discovered this whole SCC is now concrete, mark it as
    // such!
    for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
      assert(SCC[i]->isAbstract() && "Why are we processing concrete types?");

      SCC[i]->setAbstract(false);
    }

    for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
      assert(!SCC[i]->isAbstract() && "Concrete type became abstract?");
      // The type just became concrete, notify all users!
      cast<DerivedType>(SCC[i])->notifyUsesThatTypeBecameConcrete();
    }
  }
}


//===----------------------------------------------------------------------===//
//                      Type Structural Equality Testing
//===----------------------------------------------------------------------===//

// TypesEqual - Two types are considered structurally equal if they have the
// same "shape": Every level and element of the types have identical primitive
// ID's, and the graphs have the same edges/nodes in them.  Nodes do not have to
// be pointer equals to be equivalent though.  This uses an optimistic algorithm
// that assumes that two graphs are the same until proven otherwise.
//
static bool TypesEqual(const Type *Ty, const Type *Ty2,
                       std::map<const Type *, const Type *> &EqTypes) {
  if (Ty == Ty2) return true;
  if (Ty->getTypeID() != Ty2->getTypeID()) return false;
  if (Ty->isOpaqueTy())
    return false;  // Two unequal opaque types are never equal

  std::map<const Type*, const Type*>::iterator It = EqTypes.find(Ty);
  if (It != EqTypes.end())
    return It->second == Ty2;    // Looping back on a type, check for equality

  // Otherwise, add the mapping to the table to make sure we don't get
  // recursion on the types...
  EqTypes.insert(It, std::make_pair(Ty, Ty2));

  // Two really annoying special cases that breaks an otherwise nice simple
  // algorithm is the fact that arraytypes have sizes that differentiates types,
  // and that function types can be varargs or not.  Consider this now.
  //
  if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty)) {
    const IntegerType *ITy2 = cast<IntegerType>(Ty2);
    return ITy->getBitWidth() == ITy2->getBitWidth();
  }
  
  if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
    const PointerType *PTy2 = cast<PointerType>(Ty2);
    return PTy->getAddressSpace() == PTy2->getAddressSpace() &&
           TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes);
  }
  
  if (const StructType *STy = dyn_cast<StructType>(Ty)) {
    const StructType *STy2 = cast<StructType>(Ty2);
    if (STy->getNumElements() != STy2->getNumElements()) return false;
    if (STy->isPacked() != STy2->isPacked()) return false;
    for (unsigned i = 0, e = STy2->getNumElements(); i != e; ++i)
      if (!TypesEqual(STy->getElementType(i), STy2->getElementType(i), EqTypes))
        return false;
    return true;
  }
  
  if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
    const ArrayType *ATy2 = cast<ArrayType>(Ty2);
    return ATy->getNumElements() == ATy2->getNumElements() &&
           TypesEqual(ATy->getElementType(), ATy2->getElementType(), EqTypes);
  }
  
  if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) {
    const VectorType *PTy2 = cast<VectorType>(Ty2);
    return PTy->getNumElements() == PTy2->getNumElements() &&
           TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes);
  }
  
  if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
    const FunctionType *FTy2 = cast<FunctionType>(Ty2);
    if (FTy->isVarArg() != FTy2->isVarArg() ||
        FTy->getNumParams() != FTy2->getNumParams() ||
        !TypesEqual(FTy->getReturnType(), FTy2->getReturnType(), EqTypes))
      return false;
    for (unsigned i = 0, e = FTy2->getNumParams(); i != e; ++i) {
      if (!TypesEqual(FTy->getParamType(i), FTy2->getParamType(i), EqTypes))
        return false;
    }
    return true;
  }
  
  llvm_unreachable("Unknown derived type!");
  return false;
}

namespace llvm { // in namespace llvm so findable by ADL
static bool TypesEqual(const Type *Ty, const Type *Ty2) {
  std::map<const Type *, const Type *> EqTypes;
  return ::TypesEqual(Ty, Ty2, EqTypes);
}
}

// AbstractTypeHasCycleThrough - Return true there is a path from CurTy to
// TargetTy in the type graph.  We know that Ty is an abstract type, so if we
// ever reach a non-abstract type, we know that we don't need to search the
// subgraph.
static bool AbstractTypeHasCycleThrough(const Type *TargetTy, const Type *CurTy,
                                SmallPtrSet<const Type*, 128> &VisitedTypes) {
  if (TargetTy == CurTy) return true;
  if (!CurTy->isAbstract()) return false;

  if (!VisitedTypes.insert(CurTy))
    return false;  // Already been here.

  for (Type::subtype_iterator I = CurTy->subtype_begin(),
       E = CurTy->subtype_end(); I != E; ++I)
    if (AbstractTypeHasCycleThrough(TargetTy, *I, VisitedTypes))
      return true;
  return false;
}

static bool ConcreteTypeHasCycleThrough(const Type *TargetTy, const Type *CurTy,
                                SmallPtrSet<const Type*, 128> &VisitedTypes) {
  if (TargetTy == CurTy) return true;

  if (!VisitedTypes.insert(CurTy))
    return false;  // Already been here.

  for (Type::subtype_iterator I = CurTy->subtype_begin(),
       E = CurTy->subtype_end(); I != E; ++I)
    if (ConcreteTypeHasCycleThrough(TargetTy, *I, VisitedTypes))
      return true;
  return false;
}

/// TypeHasCycleThroughItself - Return true if the specified type has
/// a cycle back to itself.

namespace llvm { // in namespace llvm so it's findable by ADL
static bool TypeHasCycleThroughItself(const Type *Ty) {
  SmallPtrSet<const Type*, 128> VisitedTypes;

  if (Ty->isAbstract()) {  // Optimized case for abstract types.
    for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
         I != E; ++I)
      if (AbstractTypeHasCycleThrough(Ty, *I, VisitedTypes))
        return true;
  } else {
    for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
         I != E; ++I)
      if (ConcreteTypeHasCycleThrough(Ty, *I, VisitedTypes))
        return true;
  }
  return false;
}
}

//===----------------------------------------------------------------------===//
// Function Type Factory and Value Class...
//
const IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) {
  assert(NumBits >= MIN_INT_BITS && "bitwidth too small");
  assert(NumBits <= MAX_INT_BITS && "bitwidth too large");

  // Check for the built-in integer types
  switch (NumBits) {
  case  1: return cast<IntegerType>(Type::getInt1Ty(C));
  case  8: return cast<IntegerType>(Type::getInt8Ty(C));
  case 16: return cast<IntegerType>(Type::getInt16Ty(C));
  case 32: return cast<IntegerType>(Type::getInt32Ty(C));
  case 64: return cast<IntegerType>(Type::getInt64Ty(C));
  default: 
    break;
  }

  LLVMContextImpl *pImpl = C.pImpl;
  
  IntegerValType IVT(NumBits);
  IntegerType *ITy = 0;
  
  // First, see if the type is already in the table, for which
  // a reader lock suffices.
  ITy = pImpl->IntegerTypes.get(IVT);
    
  if (!ITy) {
    // Value not found.  Derive a new type!
    ITy = new IntegerType(C, NumBits);
    pImpl->IntegerTypes.add(IVT, ITy);
  }
#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "Derived new type: " << *ITy << "\n");
#endif
  return ITy;
}

bool IntegerType::isPowerOf2ByteWidth() const {
  unsigned BitWidth = getBitWidth();
  return (BitWidth > 7) && isPowerOf2_32(BitWidth);
}

APInt IntegerType::getMask() const {
  return APInt::getAllOnesValue(getBitWidth());
}

FunctionValType FunctionValType::get(const FunctionType *FT) {
  // Build up a FunctionValType
  std::vector<const Type *> ParamTypes;
  ParamTypes.reserve(FT->getNumParams());
  for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i)
    ParamTypes.push_back(FT->getParamType(i));
  return FunctionValType(FT->getReturnType(), ParamTypes, FT->isVarArg());
}


// FunctionType::get - The factory function for the FunctionType class...
FunctionType *FunctionType::get(const Type *ReturnType,
                                const std::vector<const Type*> &Params,
                                bool isVarArg) {
  FunctionValType VT(ReturnType, Params, isVarArg);
  FunctionType *FT = 0;
  
  LLVMContextImpl *pImpl = ReturnType->getContext().pImpl;
  
  FT = pImpl->FunctionTypes.get(VT);
  
  if (!FT) {
    FT = (FunctionType*) operator new(sizeof(FunctionType) +
                                    sizeof(PATypeHandle)*(Params.size()+1));
    new (FT) FunctionType(ReturnType, Params, isVarArg);
    pImpl->FunctionTypes.add(VT, FT);
  }

#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "Derived new type: " << FT << "\n");
#endif
  return FT;
}

ArrayType *ArrayType::get(const Type *ElementType, uint64_t NumElements) {
  assert(ElementType && "Can't get array of <null> types!");
  assert(isValidElementType(ElementType) && "Invalid type for array element!");

  ArrayValType AVT(ElementType, NumElements);
  ArrayType *AT = 0;

  LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
  
  AT = pImpl->ArrayTypes.get(AVT);
      
  if (!AT) {
    // Value not found.  Derive a new type!
    pImpl->ArrayTypes.add(AVT, AT = new ArrayType(ElementType, NumElements));
  }
#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "Derived new type: " << *AT << "\n");
#endif
  return AT;
}

bool ArrayType::isValidElementType(const Type *ElemTy) {
  return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
         !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
}

VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) {
  assert(ElementType && "Can't get vector of <null> types!");

  VectorValType PVT(ElementType, NumElements);
  VectorType *PT = 0;
  
  LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
  
  PT = pImpl->VectorTypes.get(PVT);
    
  if (!PT) {
    pImpl->VectorTypes.add(PVT, PT = new VectorType(ElementType, NumElements));
  }
#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "Derived new type: " << *PT << "\n");
#endif
  return PT;
}

bool VectorType::isValidElementType(const Type *ElemTy) {
  return ElemTy->isIntegerTy() || ElemTy->isFloatingPointTy() ||
         ElemTy->isOpaqueTy();
}

//===----------------------------------------------------------------------===//
// Struct Type Factory...
//

StructType *StructType::get(LLVMContext &Context,
                            const std::vector<const Type*> &ETypes, 
                            bool isPacked) {
  StructValType STV(ETypes, isPacked);
  StructType *ST = 0;
  
  LLVMContextImpl *pImpl = Context.pImpl;
  
  ST = pImpl->StructTypes.get(STV);
    
  if (!ST) {
    // Value not found.  Derive a new type!
    ST = (StructType*) operator new(sizeof(StructType) +
                                    sizeof(PATypeHandle) * ETypes.size());
    new (ST) StructType(Context, ETypes, isPacked);
    pImpl->StructTypes.add(STV, ST);
  }
#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "Derived new type: " << *ST << "\n");
#endif
  return ST;
}

StructType *StructType::get(LLVMContext &Context, const Type *type, ...) {
  va_list ap;
  std::vector<const llvm::Type*> StructFields;
  va_start(ap, type);
  while (type) {
    StructFields.push_back(type);
    type = va_arg(ap, llvm::Type*);
  }
  return llvm::StructType::get(Context, StructFields);
}

bool StructType::isValidElementType(const Type *ElemTy) {
  return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
         !ElemTy->isMetadataTy() && !ElemTy->isFunctionTy();
}


//===----------------------------------------------------------------------===//
// Pointer Type Factory...
//

PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) {
  assert(ValueType && "Can't get a pointer to <null> type!");
  assert(ValueType->getTypeID() != VoidTyID &&
         "Pointer to void is not valid, use i8* instead!");
  assert(isValidElementType(ValueType) && "Invalid type for pointer element!");
  PointerValType PVT(ValueType, AddressSpace);

  PointerType *PT = 0;
  
  LLVMContextImpl *pImpl = ValueType->getContext().pImpl;
  
  PT = pImpl->PointerTypes.get(PVT);
  
  if (!PT) {
    // Value not found.  Derive a new type!
    pImpl->PointerTypes.add(PVT, PT = new PointerType(ValueType, AddressSpace));
  }
#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "Derived new type: " << *PT << "\n");
#endif
  return PT;
}

const PointerType *Type::getPointerTo(unsigned addrs) const {
  return PointerType::get(this, addrs);
}

bool PointerType::isValidElementType(const Type *ElemTy) {
  return !ElemTy->isVoidTy() && !ElemTy->isLabelTy() &&
         !ElemTy->isMetadataTy();
}


//===----------------------------------------------------------------------===//
// Opaque Type Factory...
//

OpaqueType *OpaqueType::get(LLVMContext &C) {
  OpaqueType *OT = new OpaqueType(C);       // All opaque types are distinct.
  LLVMContextImpl *pImpl = C.pImpl;
  pImpl->OpaqueTypes.insert(OT);
  return OT;
}



//===----------------------------------------------------------------------===//
//                     Derived Type Refinement Functions
//===----------------------------------------------------------------------===//

// addAbstractTypeUser - Notify an abstract type that there is a new user of
// it.  This function is called primarily by the PATypeHandle class.
void Type::addAbstractTypeUser(AbstractTypeUser *U) const {
  assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
  AbstractTypeUsers.push_back(U);
}


// removeAbstractTypeUser - Notify an abstract type that a user of the class
// no longer has a handle to the type.  This function is called primarily by
// the PATypeHandle class.  When there are no users of the abstract type, it
// is annihilated, because there is no way to get a reference to it ever again.
//
void Type::removeAbstractTypeUser(AbstractTypeUser *U) const {
  
  // Search from back to front because we will notify users from back to
  // front.  Also, it is likely that there will be a stack like behavior to
  // users that register and unregister users.
  //
  unsigned i;
  for (i = AbstractTypeUsers.size(); AbstractTypeUsers[i-1] != U; --i)
    assert(i != 0 && "AbstractTypeUser not in user list!");

  --i;  // Convert to be in range 0 <= i < size()
  assert(i < AbstractTypeUsers.size() && "Index out of range!");  // Wraparound?

  AbstractTypeUsers.erase(AbstractTypeUsers.begin()+i);

#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "  remAbstractTypeUser[" << (void*)this << ", "
               << *this << "][" << i << "] User = " << U << "\n");
#endif

  if (AbstractTypeUsers.empty() && getRefCount() == 0 && isAbstract()) {
#ifdef DEBUG_MERGE_TYPES
    DEBUG(dbgs() << "DELETEing unused abstract type: <" << *this
                 << ">[" << (void*)this << "]" << "\n");
#endif
  
    this->destroy();
  }
}

// refineAbstractTypeTo - This function is used when it is discovered
// that the 'this' abstract type is actually equivalent to the NewType
// specified. This causes all users of 'this' to switch to reference the more 
// concrete type NewType and for 'this' to be deleted.  Only used for internal
// callers.
//
void DerivedType::refineAbstractTypeTo(const Type *NewType) {
  assert(isAbstract() && "refineAbstractTypeTo: Current type is not abstract!");
  assert(this != NewType && "Can't refine to myself!");
  assert(ForwardType == 0 && "This type has already been refined!");

  LLVMContextImpl *pImpl = getContext().pImpl;

  // The descriptions may be out of date.  Conservatively clear them all!
  pImpl->AbstractTypeDescriptions.clear();

#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "REFINING abstract type [" << (void*)this << " "
               << *this << "] to [" << (void*)NewType << " "
               << *NewType << "]!\n");
#endif

  // Make sure to put the type to be refined to into a holder so that if IT gets
  // refined, that we will not continue using a dead reference...
  //
  PATypeHolder NewTy(NewType);
  // Any PATypeHolders referring to this type will now automatically forward to
  // the type we are resolved to.
  ForwardType = NewType;
  if (ForwardType->isAbstract())
    ForwardType->addRef();

  // Add a self use of the current type so that we don't delete ourself until
  // after the function exits.
  //
  PATypeHolder CurrentTy(this);

  // To make the situation simpler, we ask the subclass to remove this type from
  // the type map, and to replace any type uses with uses of non-abstract types.
  // This dramatically limits the amount of recursive type trouble we can find
  // ourselves in.
  dropAllTypeUses();

  // Iterate over all of the uses of this type, invoking callback.  Each user
  // should remove itself from our use list automatically.  We have to check to
  // make sure that NewTy doesn't _become_ 'this'.  If it does, resolving types
  // will not cause users to drop off of the use list.  If we resolve to ourself
  // we succeed!
  //
  while (!AbstractTypeUsers.empty() && NewTy != this) {
    AbstractTypeUser *User = AbstractTypeUsers.back();

    unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize;
#ifdef DEBUG_MERGE_TYPES
    DEBUG(dbgs() << " REFINING user " << OldSize-1 << "[" << (void*)User
                 << "] of abstract type [" << (void*)this << " "
                 << *this << "] to [" << (void*)NewTy.get() << " "
                 << *NewTy << "]!\n");
#endif
    User->refineAbstractType(this, NewTy);

    assert(AbstractTypeUsers.size() != OldSize &&
           "AbsTyUser did not remove self from user list!");
  }

  // If we were successful removing all users from the type, 'this' will be
  // deleted when the last PATypeHolder is destroyed or updated from this type.
  // This may occur on exit of this function, as the CurrentTy object is
  // destroyed.
}

// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type that
// the current type has transitioned from being abstract to being concrete.
//
void DerivedType::notifyUsesThatTypeBecameConcrete() {
#ifdef DEBUG_MERGE_TYPES
  DEBUG(dbgs() << "typeIsREFINED type: " << (void*)this << " " << *this <<"\n");
#endif

  unsigned OldSize = AbstractTypeUsers.size(); (void)OldSize;
  while (!AbstractTypeUsers.empty()) {
    AbstractTypeUser *ATU = AbstractTypeUsers.back();
    ATU->typeBecameConcrete(this);

    assert(AbstractTypeUsers.size() < OldSize-- &&
           "AbstractTypeUser did not remove itself from the use list!");
  }
}

// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
void FunctionType::refineAbstractType(const DerivedType *OldType,
                                      const Type *NewType) {
  LLVMContextImpl *pImpl = OldType->getContext().pImpl;
  pImpl->FunctionTypes.RefineAbstractType(this, OldType, NewType);
}

void FunctionType::typeBecameConcrete(const DerivedType *AbsTy) {
  LLVMContextImpl *pImpl = AbsTy->getContext().pImpl;
  pImpl->FunctionTypes.TypeBecameConcrete(this, AbsTy);
}


// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
void ArrayType::refineAbstractType(const DerivedType *OldType,
                                   const Type *NewType) {
  LLVMContextImpl *pImpl = OldType->getContext().pImpl;
  pImpl->ArrayTypes.RefineAbstractType(this, OldType, NewType);
}

void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) {
  LLVMContextImpl *pImpl = AbsTy->getContext().pImpl;
  pImpl->ArrayTypes.TypeBecameConcrete(this, AbsTy);
}

// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
void VectorType::refineAbstractType(const DerivedType *OldType,
                                   const Type *NewType) {
  LLVMContextImpl *pImpl = OldType->getContext().pImpl;
  pImpl->VectorTypes.RefineAbstractType(this, OldType, NewType);
}

void VectorType::typeBecameConcrete(const DerivedType *AbsTy) {
  LLVMContextImpl *pImpl = AbsTy->getContext().pImpl;
  pImpl->VectorTypes.TypeBecameConcrete(this, AbsTy);
}

// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
void StructType::refineAbstractType(const DerivedType *OldType,
                                    const Type *NewType) {
  LLVMContextImpl *pImpl = OldType->getContext().pImpl;
  pImpl->StructTypes.RefineAbstractType(this, OldType, NewType);
}

void StructType::typeBecameConcrete(const DerivedType *AbsTy) {
  LLVMContextImpl *pImpl = AbsTy->getContext().pImpl;
  pImpl->StructTypes.TypeBecameConcrete(this, AbsTy);
}

// refineAbstractType - Called when a contained type is found to be more
// concrete - this could potentially change us from an abstract type to a
// concrete type.
//
void PointerType::refineAbstractType(const DerivedType *OldType,
                                     const Type *NewType) {
  LLVMContextImpl *pImpl = OldType->getContext().pImpl;
  pImpl->PointerTypes.RefineAbstractType(this, OldType, NewType);
}

void PointerType::typeBecameConcrete(const DerivedType *AbsTy) {
  LLVMContextImpl *pImpl = AbsTy->getContext().pImpl;
  pImpl->PointerTypes.TypeBecameConcrete(this, AbsTy);
}

bool SequentialType::indexValid(const Value *V) const {
  if (V->getType()->isIntegerTy()) 
    return true;
  return false;
}

namespace llvm {
raw_ostream &operator<<(raw_ostream &OS, const Type &T) {
  T.print(OS);
  return OS;
}
}
