LLVM  mainline
ConstantsContext.h
Go to the documentation of this file.
00001 //===-- ConstantsContext.h - Constants-related Context Interals -----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines various helper methods and classes used by
00011 // LLVMContextImpl for creating and managing constants.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_LIB_IR_CONSTANTSCONTEXT_H
00016 #define LLVM_LIB_IR_CONSTANTSCONTEXT_H
00017 
00018 #include "llvm/ADT/DenseMap.h"
00019 #include "llvm/ADT/Hashing.h"
00020 #include "llvm/IR/InlineAsm.h"
00021 #include "llvm/IR/Instructions.h"
00022 #include "llvm/IR/Operator.h"
00023 #include "llvm/Support/Debug.h"
00024 #include "llvm/Support/ErrorHandling.h"
00025 #include "llvm/Support/raw_ostream.h"
00026 #include <map>
00027 #include <tuple>
00028 
00029 #define DEBUG_TYPE "ir"
00030 
00031 namespace llvm {
00032 
00033 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
00034 /// behind the scenes to implement unary constant exprs.
00035 class UnaryConstantExpr : public ConstantExpr {
00036   void anchor() override;
00037   void *operator new(size_t, unsigned) = delete;
00038 public:
00039   // allocate space for exactly one operand
00040   void *operator new(size_t s) {
00041     return User::operator new(s, 1);
00042   }
00043   UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
00044     : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
00045     Op<0>() = C;
00046   }
00047   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00048 };
00049 
00050 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
00051 /// behind the scenes to implement binary constant exprs.
00052 class BinaryConstantExpr : public ConstantExpr {
00053   void anchor() override;
00054   void *operator new(size_t, unsigned) = delete;
00055 public:
00056   // allocate space for exactly two operands
00057   void *operator new(size_t s) {
00058     return User::operator new(s, 2);
00059   }
00060   BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
00061                      unsigned Flags)
00062     : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
00063     Op<0>() = C1;
00064     Op<1>() = C2;
00065     SubclassOptionalData = Flags;
00066   }
00067   /// Transparently provide more efficient getOperand methods.
00068   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00069 };
00070 
00071 /// SelectConstantExpr - This class is private to Constants.cpp, and is used
00072 /// behind the scenes to implement select constant exprs.
00073 class SelectConstantExpr : public ConstantExpr {
00074   void anchor() override;
00075   void *operator new(size_t, unsigned) = delete;
00076 public:
00077   // allocate space for exactly three operands
00078   void *operator new(size_t s) {
00079     return User::operator new(s, 3);
00080   }
00081   SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
00082     : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
00083     Op<0>() = C1;
00084     Op<1>() = C2;
00085     Op<2>() = C3;
00086   }
00087   /// Transparently provide more efficient getOperand methods.
00088   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00089 };
00090 
00091 /// ExtractElementConstantExpr - This class is private to
00092 /// Constants.cpp, and is used behind the scenes to implement
00093 /// extractelement constant exprs.
00094 class ExtractElementConstantExpr : public ConstantExpr {
00095   void anchor() override;
00096   void *operator new(size_t, unsigned) = delete;
00097 public:
00098   // allocate space for exactly two operands
00099   void *operator new(size_t s) {
00100     return User::operator new(s, 2);
00101   }
00102   ExtractElementConstantExpr(Constant *C1, Constant *C2)
00103     : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
00104                    Instruction::ExtractElement, &Op<0>(), 2) {
00105     Op<0>() = C1;
00106     Op<1>() = C2;
00107   }
00108   /// Transparently provide more efficient getOperand methods.
00109   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00110 };
00111 
00112 /// InsertElementConstantExpr - This class is private to
00113 /// Constants.cpp, and is used behind the scenes to implement
00114 /// insertelement constant exprs.
00115 class InsertElementConstantExpr : public ConstantExpr {
00116   void anchor() override;
00117   void *operator new(size_t, unsigned) = delete;
00118 public:
00119   // allocate space for exactly three operands
00120   void *operator new(size_t s) {
00121     return User::operator new(s, 3);
00122   }
00123   InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
00124     : ConstantExpr(C1->getType(), Instruction::InsertElement,
00125                    &Op<0>(), 3) {
00126     Op<0>() = C1;
00127     Op<1>() = C2;
00128     Op<2>() = C3;
00129   }
00130   /// Transparently provide more efficient getOperand methods.
00131   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00132 };
00133 
00134 /// ShuffleVectorConstantExpr - This class is private to
00135 /// Constants.cpp, and is used behind the scenes to implement
00136 /// shufflevector constant exprs.
00137 class ShuffleVectorConstantExpr : public ConstantExpr {
00138   void anchor() override;
00139   void *operator new(size_t, unsigned) = delete;
00140 public:
00141   // allocate space for exactly three operands
00142   void *operator new(size_t s) {
00143     return User::operator new(s, 3);
00144   }
00145   ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
00146   : ConstantExpr(VectorType::get(
00147                    cast<VectorType>(C1->getType())->getElementType(),
00148                    cast<VectorType>(C3->getType())->getNumElements()),
00149                  Instruction::ShuffleVector,
00150                  &Op<0>(), 3) {
00151     Op<0>() = C1;
00152     Op<1>() = C2;
00153     Op<2>() = C3;
00154   }
00155   /// Transparently provide more efficient getOperand methods.
00156   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00157 };
00158 
00159 /// ExtractValueConstantExpr - This class is private to
00160 /// Constants.cpp, and is used behind the scenes to implement
00161 /// extractvalue constant exprs.
00162 class ExtractValueConstantExpr : public ConstantExpr {
00163   void anchor() override;
00164   void *operator new(size_t, unsigned) = delete;
00165 public:
00166   // allocate space for exactly one operand
00167   void *operator new(size_t s) {
00168     return User::operator new(s, 1);
00169   }
00170   ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList,
00171                            Type *DestTy)
00172       : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
00173         Indices(IdxList.begin(), IdxList.end()) {
00174     Op<0>() = Agg;
00175   }
00176 
00177   /// Indices - These identify which value to extract.
00178   const SmallVector<unsigned, 4> Indices;
00179 
00180   /// Transparently provide more efficient getOperand methods.
00181   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00182 };
00183 
00184 /// InsertValueConstantExpr - This class is private to
00185 /// Constants.cpp, and is used behind the scenes to implement
00186 /// insertvalue constant exprs.
00187 class InsertValueConstantExpr : public ConstantExpr {
00188   void anchor() override;
00189   void *operator new(size_t, unsigned) = delete;
00190 public:
00191   // allocate space for exactly one operand
00192   void *operator new(size_t s) {
00193     return User::operator new(s, 2);
00194   }
00195   InsertValueConstantExpr(Constant *Agg, Constant *Val,
00196                           ArrayRef<unsigned> IdxList, Type *DestTy)
00197       : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
00198         Indices(IdxList.begin(), IdxList.end()) {
00199     Op<0>() = Agg;
00200     Op<1>() = Val;
00201   }
00202 
00203   /// Indices - These identify the position for the insertion.
00204   const SmallVector<unsigned, 4> Indices;
00205 
00206   /// Transparently provide more efficient getOperand methods.
00207   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00208 };
00209 
00210 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
00211 /// used behind the scenes to implement getelementpr constant exprs.
00212 class GetElementPtrConstantExpr : public ConstantExpr {
00213   Type *SrcElementTy;
00214   void anchor() override;
00215   GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
00216                             ArrayRef<Constant *> IdxList, Type *DestTy);
00217 
00218 public:
00219   static GetElementPtrConstantExpr *Create(Constant *C,
00220                                            ArrayRef<Constant*> IdxList,
00221                                            Type *DestTy,
00222                                            unsigned Flags) {
00223     return Create(
00224         cast<PointerType>(C->getType()->getScalarType())->getElementType(), C,
00225         IdxList, DestTy, Flags);
00226   }
00227   static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C,
00228                                            ArrayRef<Constant *> IdxList,
00229                                            Type *DestTy, unsigned Flags) {
00230     GetElementPtrConstantExpr *Result = new (IdxList.size() + 1)
00231         GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy);
00232     Result->SubclassOptionalData = Flags;
00233     return Result;
00234   }
00235   Type *getSourceElementType() const;
00236   /// Transparently provide more efficient getOperand methods.
00237   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00238 };
00239 
00240 // CompareConstantExpr - This class is private to Constants.cpp, and is used
00241 // behind the scenes to implement ICmp and FCmp constant expressions. This is
00242 // needed in order to store the predicate value for these instructions.
00243 class CompareConstantExpr : public ConstantExpr {
00244   void anchor() override;
00245   void *operator new(size_t, unsigned) = delete;
00246 public:
00247   // allocate space for exactly two operands
00248   void *operator new(size_t s) {
00249     return User::operator new(s, 2);
00250   }
00251   unsigned short predicate;
00252   CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
00253                       unsigned short pred,  Constant* LHS, Constant* RHS)
00254     : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
00255     Op<0>() = LHS;
00256     Op<1>() = RHS;
00257   }
00258   /// Transparently provide more efficient getOperand methods.
00259   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
00260 };
00261 
00262 template <>
00263 struct OperandTraits<UnaryConstantExpr>
00264     : public FixedNumOperandTraits<UnaryConstantExpr, 1> {};
00265 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
00266 
00267 template <>
00268 struct OperandTraits<BinaryConstantExpr>
00269     : public FixedNumOperandTraits<BinaryConstantExpr, 2> {};
00270 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
00271 
00272 template <>
00273 struct OperandTraits<SelectConstantExpr>
00274     : public FixedNumOperandTraits<SelectConstantExpr, 3> {};
00275 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
00276 
00277 template <>
00278 struct OperandTraits<ExtractElementConstantExpr>
00279     : public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {};
00280 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
00281 
00282 template <>
00283 struct OperandTraits<InsertElementConstantExpr>
00284     : public FixedNumOperandTraits<InsertElementConstantExpr, 3> {};
00285 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
00286 
00287 template <>
00288 struct OperandTraits<ShuffleVectorConstantExpr>
00289     : public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {};
00290 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
00291 
00292 template <>
00293 struct OperandTraits<ExtractValueConstantExpr>
00294     : public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {};
00295 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
00296 
00297 template <>
00298 struct OperandTraits<InsertValueConstantExpr>
00299     : public FixedNumOperandTraits<InsertValueConstantExpr, 2> {};
00300 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
00301 
00302 template <>
00303 struct OperandTraits<GetElementPtrConstantExpr>
00304     : public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {};
00305 
00306 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
00307 
00308 template <>
00309 struct OperandTraits<CompareConstantExpr>
00310     : public FixedNumOperandTraits<CompareConstantExpr, 2> {};
00311 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
00312 
00313 template <class ConstantClass> struct ConstantAggrKeyType;
00314 struct InlineAsmKeyType;
00315 struct ConstantExprKeyType;
00316 
00317 template <class ConstantClass> struct ConstantInfo;
00318 template <> struct ConstantInfo<ConstantExpr> {
00319   typedef ConstantExprKeyType ValType;
00320   typedef Type TypeClass;
00321 };
00322 template <> struct ConstantInfo<InlineAsm> {
00323   typedef InlineAsmKeyType ValType;
00324   typedef PointerType TypeClass;
00325 };
00326 template <> struct ConstantInfo<ConstantArray> {
00327   typedef ConstantAggrKeyType<ConstantArray> ValType;
00328   typedef ArrayType TypeClass;
00329 };
00330 template <> struct ConstantInfo<ConstantStruct> {
00331   typedef ConstantAggrKeyType<ConstantStruct> ValType;
00332   typedef StructType TypeClass;
00333 };
00334 template <> struct ConstantInfo<ConstantVector> {
00335   typedef ConstantAggrKeyType<ConstantVector> ValType;
00336   typedef VectorType TypeClass;
00337 };
00338 
00339 template <class ConstantClass> struct ConstantAggrKeyType {
00340   ArrayRef<Constant *> Operands;
00341   ConstantAggrKeyType(ArrayRef<Constant *> Operands) : Operands(Operands) {}
00342   ConstantAggrKeyType(ArrayRef<Constant *> Operands, const ConstantClass *)
00343       : Operands(Operands) {}
00344   ConstantAggrKeyType(const ConstantClass *C,
00345                       SmallVectorImpl<Constant *> &Storage) {
00346     assert(Storage.empty() && "Expected empty storage");
00347     for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I)
00348       Storage.push_back(C->getOperand(I));
00349     Operands = Storage;
00350   }
00351 
00352   bool operator==(const ConstantAggrKeyType &X) const {
00353     return Operands == X.Operands;
00354   }
00355   bool operator==(const ConstantClass *C) const {
00356     if (Operands.size() != C->getNumOperands())
00357       return false;
00358     for (unsigned I = 0, E = Operands.size(); I != E; ++I)
00359       if (Operands[I] != C->getOperand(I))
00360         return false;
00361     return true;
00362   }
00363   unsigned getHash() const {
00364     return hash_combine_range(Operands.begin(), Operands.end());
00365   }
00366 
00367   typedef typename ConstantInfo<ConstantClass>::TypeClass TypeClass;
00368   ConstantClass *create(TypeClass *Ty) const {
00369     return new (Operands.size()) ConstantClass(Ty, Operands);
00370   }
00371 };
00372 
00373 struct InlineAsmKeyType {
00374   StringRef AsmString;
00375   StringRef Constraints;
00376   bool HasSideEffects;
00377   bool IsAlignStack;
00378   InlineAsm::AsmDialect AsmDialect;
00379 
00380   InlineAsmKeyType(StringRef AsmString, StringRef Constraints,
00381                    bool HasSideEffects, bool IsAlignStack,
00382                    InlineAsm::AsmDialect AsmDialect)
00383       : AsmString(AsmString), Constraints(Constraints),
00384         HasSideEffects(HasSideEffects), IsAlignStack(IsAlignStack),
00385         AsmDialect(AsmDialect) {}
00386   InlineAsmKeyType(const InlineAsm *Asm, SmallVectorImpl<Constant *> &)
00387       : AsmString(Asm->getAsmString()), Constraints(Asm->getConstraintString()),
00388         HasSideEffects(Asm->hasSideEffects()),
00389         IsAlignStack(Asm->isAlignStack()), AsmDialect(Asm->getDialect()) {}
00390 
00391   bool operator==(const InlineAsmKeyType &X) const {
00392     return HasSideEffects == X.HasSideEffects &&
00393            IsAlignStack == X.IsAlignStack && AsmDialect == X.AsmDialect &&
00394            AsmString == X.AsmString && Constraints == X.Constraints;
00395   }
00396   bool operator==(const InlineAsm *Asm) const {
00397     return HasSideEffects == Asm->hasSideEffects() &&
00398            IsAlignStack == Asm->isAlignStack() &&
00399            AsmDialect == Asm->getDialect() &&
00400            AsmString == Asm->getAsmString() &&
00401            Constraints == Asm->getConstraintString();
00402   }
00403   unsigned getHash() const {
00404     return hash_combine(AsmString, Constraints, HasSideEffects, IsAlignStack,
00405                         AsmDialect);
00406   }
00407 
00408   typedef ConstantInfo<InlineAsm>::TypeClass TypeClass;
00409   InlineAsm *create(TypeClass *Ty) const {
00410     return new InlineAsm(Ty, AsmString, Constraints, HasSideEffects,
00411                          IsAlignStack, AsmDialect);
00412   }
00413 };
00414 
00415 struct ConstantExprKeyType {
00416   uint8_t Opcode;
00417   uint8_t SubclassOptionalData;
00418   uint16_t SubclassData;
00419   ArrayRef<Constant *> Ops;
00420   ArrayRef<unsigned> Indexes;
00421   Type *ExplicitTy;
00422 
00423   ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops,
00424                       unsigned short SubclassData = 0,
00425                       unsigned short SubclassOptionalData = 0,
00426                       ArrayRef<unsigned> Indexes = None,
00427                       Type *ExplicitTy = nullptr)
00428       : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData),
00429         SubclassData(SubclassData), Ops(Ops), Indexes(Indexes),
00430         ExplicitTy(ExplicitTy) {}
00431   ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE)
00432       : Opcode(CE->getOpcode()),
00433         SubclassOptionalData(CE->getRawSubclassOptionalData()),
00434         SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands),
00435         Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {}
00436   ConstantExprKeyType(const ConstantExpr *CE,
00437                       SmallVectorImpl<Constant *> &Storage)
00438       : Opcode(CE->getOpcode()),
00439         SubclassOptionalData(CE->getRawSubclassOptionalData()),
00440         SubclassData(CE->isCompare() ? CE->getPredicate() : 0),
00441         Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {
00442     assert(Storage.empty() && "Expected empty storage");
00443     for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I)
00444       Storage.push_back(CE->getOperand(I));
00445     Ops = Storage;
00446   }
00447 
00448   bool operator==(const ConstantExprKeyType &X) const {
00449     return Opcode == X.Opcode && SubclassData == X.SubclassData &&
00450            SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops &&
00451            Indexes == X.Indexes;
00452   }
00453 
00454   bool operator==(const ConstantExpr *CE) const {
00455     if (Opcode != CE->getOpcode())
00456       return false;
00457     if (SubclassOptionalData != CE->getRawSubclassOptionalData())
00458       return false;
00459     if (Ops.size() != CE->getNumOperands())
00460       return false;
00461     if (SubclassData != (CE->isCompare() ? CE->getPredicate() : 0))
00462       return false;
00463     for (unsigned I = 0, E = Ops.size(); I != E; ++I)
00464       if (Ops[I] != CE->getOperand(I))
00465         return false;
00466     if (Indexes != (CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()))
00467       return false;
00468     return true;
00469   }
00470 
00471   unsigned getHash() const {
00472     return hash_combine(Opcode, SubclassOptionalData, SubclassData,
00473                         hash_combine_range(Ops.begin(), Ops.end()),
00474                         hash_combine_range(Indexes.begin(), Indexes.end()));
00475   }
00476 
00477   typedef ConstantInfo<ConstantExpr>::TypeClass TypeClass;
00478   ConstantExpr *create(TypeClass *Ty) const {
00479     switch (Opcode) {
00480     default:
00481       if (Instruction::isCast(Opcode))
00482         return new UnaryConstantExpr(Opcode, Ops[0], Ty);
00483       if ((Opcode >= Instruction::BinaryOpsBegin &&
00484            Opcode < Instruction::BinaryOpsEnd))
00485         return new BinaryConstantExpr(Opcode, Ops[0], Ops[1],
00486                                       SubclassOptionalData);
00487       llvm_unreachable("Invalid ConstantExpr!");
00488     case Instruction::Select:
00489       return new SelectConstantExpr(Ops[0], Ops[1], Ops[2]);
00490     case Instruction::ExtractElement:
00491       return new ExtractElementConstantExpr(Ops[0], Ops[1]);
00492     case Instruction::InsertElement:
00493       return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]);
00494     case Instruction::ShuffleVector:
00495       return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]);
00496     case Instruction::InsertValue:
00497       return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty);
00498     case Instruction::ExtractValue:
00499       return new ExtractValueConstantExpr(Ops[0], Indexes, Ty);
00500     case Instruction::GetElementPtr:
00501       return GetElementPtrConstantExpr::Create(
00502           ExplicitTy ? ExplicitTy
00503                      : cast<PointerType>(Ops[0]->getType()->getScalarType())
00504                            ->getElementType(),
00505           Ops[0], Ops.slice(1), Ty, SubclassOptionalData);
00506     case Instruction::ICmp:
00507       return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData,
00508                                      Ops[0], Ops[1]);
00509     case Instruction::FCmp:
00510       return new CompareConstantExpr(Ty, Instruction::FCmp, SubclassData,
00511                                      Ops[0], Ops[1]);
00512     }
00513   }
00514 };
00515 
00516 template <class ConstantClass> class ConstantUniqueMap {
00517 public:
00518   typedef typename ConstantInfo<ConstantClass>::ValType ValType;
00519   typedef typename ConstantInfo<ConstantClass>::TypeClass TypeClass;
00520   typedef std::pair<TypeClass *, ValType> LookupKey;
00521 
00522 private:
00523   struct MapInfo {
00524     typedef DenseMapInfo<ConstantClass *> ConstantClassInfo;
00525     static inline ConstantClass *getEmptyKey() {
00526       return ConstantClassInfo::getEmptyKey();
00527     }
00528     static inline ConstantClass *getTombstoneKey() {
00529       return ConstantClassInfo::getTombstoneKey();
00530     }
00531     static unsigned getHashValue(const ConstantClass *CP) {
00532       SmallVector<Constant *, 8> Storage;
00533       return getHashValue(LookupKey(CP->getType(), ValType(CP, Storage)));
00534     }
00535     static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) {
00536       return LHS == RHS;
00537     }
00538     static unsigned getHashValue(const LookupKey &Val) {
00539       return hash_combine(Val.first, Val.second.getHash());
00540     }
00541     static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) {
00542       if (RHS == getEmptyKey() || RHS == getTombstoneKey())
00543         return false;
00544       if (LHS.first != RHS->getType())
00545         return false;
00546       return LHS.second == RHS;
00547     }
00548   };
00549 
00550 public:
00551   typedef DenseMap<ConstantClass *, char, MapInfo> MapTy;
00552 
00553 private:
00554   MapTy Map;
00555 
00556 public:
00557   typename MapTy::iterator map_begin() { return Map.begin(); }
00558   typename MapTy::iterator map_end() { return Map.end(); }
00559 
00560   void freeConstants() {
00561     for (auto &I : Map)
00562       // Asserts that use_empty().
00563       delete I.first;
00564   }
00565 
00566 private:
00567   ConstantClass *create(TypeClass *Ty, ValType V) {
00568     ConstantClass *Result = V.create(Ty);
00569 
00570     assert(Result->getType() == Ty && "Type specified is not correct!");
00571     insert(Result);
00572 
00573     return Result;
00574   }
00575 
00576 public:
00577   /// Return the specified constant from the map, creating it if necessary.
00578   ConstantClass *getOrCreate(TypeClass *Ty, ValType V) {
00579     LookupKey Lookup(Ty, V);
00580     ConstantClass *Result = nullptr;
00581 
00582     auto I = find(Lookup);
00583     if (I == Map.end())
00584       Result = create(Ty, V);
00585     else
00586       Result = I->first;
00587     assert(Result && "Unexpected nullptr");
00588 
00589     return Result;
00590   }
00591 
00592   /// Find the constant by lookup key.
00593   typename MapTy::iterator find(LookupKey Lookup) {
00594     return Map.find_as(Lookup);
00595   }
00596 
00597   /// Insert the constant into its proper slot.
00598   void insert(ConstantClass *CP) { Map[CP] = '\0'; }
00599 
00600   /// Remove this constant from the map
00601   void remove(ConstantClass *CP) {
00602     typename MapTy::iterator I = Map.find(CP);
00603     assert(I != Map.end() && "Constant not found in constant table!");
00604     assert(I->first == CP && "Didn't find correct element?");
00605     Map.erase(I);
00606   }
00607 
00608   ConstantClass *replaceOperandsInPlace(ArrayRef<Constant *> Operands,
00609                                         ConstantClass *CP, Value *From,
00610                                         Constant *To, unsigned NumUpdated = 0,
00611                                         unsigned OperandNo = ~0u) {
00612     LookupKey Lookup(CP->getType(), ValType(Operands, CP));
00613     auto I = find(Lookup);
00614     if (I != Map.end())
00615       return I->first;
00616 
00617     // Update to the new value.  Optimize for the case when we have a single
00618     // operand that we're changing, but handle bulk updates efficiently.
00619     remove(CP);
00620     if (NumUpdated == 1) {
00621       assert(OperandNo < CP->getNumOperands() && "Invalid index");
00622       assert(CP->getOperand(OperandNo) != To && "I didn't contain From!");
00623       CP->setOperand(OperandNo, To);
00624     } else {
00625       for (unsigned I = 0, E = CP->getNumOperands(); I != E; ++I)
00626         if (CP->getOperand(I) == From)
00627           CP->setOperand(I, To);
00628     }
00629     insert(CP);
00630     return nullptr;
00631   }
00632 
00633   void dump() const { DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); }
00634 };
00635 
00636 } // end namespace llvm
00637 
00638 #endif