| //===-- 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 |