]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/IR/ConstantsContext.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / IR / ConstantsContext.h
1 //===-- ConstantsContext.h - Constants-related Context Interals -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines various helper methods and classes used by
11 // LLVMContextImpl for creating and managing constants.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_LIB_IR_CONSTANTSCONTEXT_H
16 #define LLVM_LIB_IR_CONSTANTSCONTEXT_H
17
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/DenseMapInfo.h"
20 #include "llvm/ADT/DenseSet.h"
21 #include "llvm/ADT/Hashing.h"
22 #include "llvm/ADT/None.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/IR/Constant.h"
26 #include "llvm/IR/Constants.h"
27 #include "llvm/IR/DerivedTypes.h"
28 #include "llvm/IR/InlineAsm.h"
29 #include "llvm/IR/Instruction.h"
30 #include "llvm/IR/OperandTraits.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/raw_ostream.h"
35 #include <cassert>
36 #include <cstddef>
37 #include <cstdint>
38 #include <utility>
39
40 #define DEBUG_TYPE "ir"
41
42 namespace llvm {
43
44 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
45 /// behind the scenes to implement unary constant exprs.
46 class UnaryConstantExpr : public ConstantExpr {
47 public:
48   UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
49     : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
50     Op<0>() = C;
51   }
52
53   // allocate space for exactly one operand
54   void *operator new(size_t s) {
55     return User::operator new(s, 1);
56   }
57
58   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
59 };
60
61 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
62 /// behind the scenes to implement binary constant exprs.
63 class BinaryConstantExpr : public ConstantExpr {
64 public:
65   BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
66                      unsigned Flags)
67     : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
68     Op<0>() = C1;
69     Op<1>() = C2;
70     SubclassOptionalData = Flags;
71   }
72
73   // allocate space for exactly two operands
74   void *operator new(size_t s) {
75     return User::operator new(s, 2);
76   }
77
78   /// Transparently provide more efficient getOperand methods.
79   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
80 };
81
82 /// SelectConstantExpr - This class is private to Constants.cpp, and is used
83 /// behind the scenes to implement select constant exprs.
84 class SelectConstantExpr : public ConstantExpr {
85 public:
86   SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
87     : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
88     Op<0>() = C1;
89     Op<1>() = C2;
90     Op<2>() = C3;
91   }
92
93   // allocate space for exactly three operands
94   void *operator new(size_t s) {
95     return User::operator new(s, 3);
96   }
97
98   /// Transparently provide more efficient getOperand methods.
99   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
100 };
101
102 /// ExtractElementConstantExpr - This class is private to
103 /// Constants.cpp, and is used behind the scenes to implement
104 /// extractelement constant exprs.
105 class ExtractElementConstantExpr : public ConstantExpr {
106 public:
107   ExtractElementConstantExpr(Constant *C1, Constant *C2)
108     : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
109                    Instruction::ExtractElement, &Op<0>(), 2) {
110     Op<0>() = C1;
111     Op<1>() = C2;
112   }
113
114   // allocate space for exactly two operands
115   void *operator new(size_t s) {
116     return User::operator new(s, 2);
117   }
118
119   /// Transparently provide more efficient getOperand methods.
120   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
121 };
122
123 /// InsertElementConstantExpr - This class is private to
124 /// Constants.cpp, and is used behind the scenes to implement
125 /// insertelement constant exprs.
126 class InsertElementConstantExpr : public ConstantExpr {
127 public:
128   InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
129     : ConstantExpr(C1->getType(), Instruction::InsertElement,
130                    &Op<0>(), 3) {
131     Op<0>() = C1;
132     Op<1>() = C2;
133     Op<2>() = C3;
134   }
135
136   // allocate space for exactly three operands
137   void *operator new(size_t s) {
138     return User::operator new(s, 3);
139   }
140
141   /// Transparently provide more efficient getOperand methods.
142   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
143 };
144
145 /// ShuffleVectorConstantExpr - This class is private to
146 /// Constants.cpp, and is used behind the scenes to implement
147 /// shufflevector constant exprs.
148 class ShuffleVectorConstantExpr : public ConstantExpr {
149 public:
150   ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
151   : ConstantExpr(VectorType::get(
152                    cast<VectorType>(C1->getType())->getElementType(),
153                    cast<VectorType>(C3->getType())->getNumElements()),
154                  Instruction::ShuffleVector,
155                  &Op<0>(), 3) {
156     Op<0>() = C1;
157     Op<1>() = C2;
158     Op<2>() = C3;
159   }
160
161   // allocate space for exactly three operands
162   void *operator new(size_t s) {
163     return User::operator new(s, 3);
164   }
165
166   /// Transparently provide more efficient getOperand methods.
167   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
168 };
169
170 /// ExtractValueConstantExpr - This class is private to
171 /// Constants.cpp, and is used behind the scenes to implement
172 /// extractvalue constant exprs.
173 class ExtractValueConstantExpr : public ConstantExpr {
174 public:
175   ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList,
176                            Type *DestTy)
177       : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
178         Indices(IdxList.begin(), IdxList.end()) {
179     Op<0>() = Agg;
180   }
181
182   // allocate space for exactly one operand
183   void *operator new(size_t s) {
184     return User::operator new(s, 1);
185   }
186
187   /// Indices - These identify which value to extract.
188   const SmallVector<unsigned, 4> Indices;
189
190   /// Transparently provide more efficient getOperand methods.
191   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
192
193   static bool classof(const ConstantExpr *CE) {
194     return CE->getOpcode() == Instruction::ExtractValue;
195   }
196   static bool classof(const Value *V) {
197     return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
198   }
199 };
200
201 /// InsertValueConstantExpr - This class is private to
202 /// Constants.cpp, and is used behind the scenes to implement
203 /// insertvalue constant exprs.
204 class InsertValueConstantExpr : public ConstantExpr {
205 public:
206   InsertValueConstantExpr(Constant *Agg, Constant *Val,
207                           ArrayRef<unsigned> IdxList, Type *DestTy)
208       : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
209         Indices(IdxList.begin(), IdxList.end()) {
210     Op<0>() = Agg;
211     Op<1>() = Val;
212   }
213
214   // allocate space for exactly one operand
215   void *operator new(size_t s) {
216     return User::operator new(s, 2);
217   }
218
219   /// Indices - These identify the position for the insertion.
220   const SmallVector<unsigned, 4> Indices;
221
222   /// Transparently provide more efficient getOperand methods.
223   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
224
225   static bool classof(const ConstantExpr *CE) {
226     return CE->getOpcode() == Instruction::InsertValue;
227   }
228   static bool classof(const Value *V) {
229     return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
230   }
231 };
232
233 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
234 /// used behind the scenes to implement getelementpr constant exprs.
235 class GetElementPtrConstantExpr : public ConstantExpr {
236   Type *SrcElementTy;
237   Type *ResElementTy;
238
239   GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
240                             ArrayRef<Constant *> IdxList, Type *DestTy);
241
242 public:
243   static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C,
244                                            ArrayRef<Constant *> IdxList,
245                                            Type *DestTy, unsigned Flags) {
246     GetElementPtrConstantExpr *Result = new (IdxList.size() + 1)
247         GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy);
248     Result->SubclassOptionalData = Flags;
249     return Result;
250   }
251
252   Type *getSourceElementType() const;
253   Type *getResultElementType() const;
254
255   /// Transparently provide more efficient getOperand methods.
256   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
257
258   static bool classof(const ConstantExpr *CE) {
259     return CE->getOpcode() == Instruction::GetElementPtr;
260   }
261   static bool classof(const Value *V) {
262     return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
263   }
264 };
265
266 // CompareConstantExpr - This class is private to Constants.cpp, and is used
267 // behind the scenes to implement ICmp and FCmp constant expressions. This is
268 // needed in order to store the predicate value for these instructions.
269 class CompareConstantExpr : public ConstantExpr {
270 public:
271   unsigned short predicate;
272   CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
273                       unsigned short pred,  Constant* LHS, Constant* RHS)
274     : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
275     Op<0>() = LHS;
276     Op<1>() = RHS;
277   }
278
279   // allocate space for exactly two operands
280   void *operator new(size_t s) {
281     return User::operator new(s, 2);
282   }
283
284   /// Transparently provide more efficient getOperand methods.
285   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
286
287   static bool classof(const ConstantExpr *CE) {
288     return CE->getOpcode() == Instruction::ICmp ||
289            CE->getOpcode() == Instruction::FCmp;
290   }
291   static bool classof(const Value *V) {
292     return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
293   }
294 };
295
296 template <>
297 struct OperandTraits<UnaryConstantExpr>
298     : public FixedNumOperandTraits<UnaryConstantExpr, 1> {};
299 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
300
301 template <>
302 struct OperandTraits<BinaryConstantExpr>
303     : public FixedNumOperandTraits<BinaryConstantExpr, 2> {};
304 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
305
306 template <>
307 struct OperandTraits<SelectConstantExpr>
308     : public FixedNumOperandTraits<SelectConstantExpr, 3> {};
309 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
310
311 template <>
312 struct OperandTraits<ExtractElementConstantExpr>
313     : public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {};
314 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
315
316 template <>
317 struct OperandTraits<InsertElementConstantExpr>
318     : public FixedNumOperandTraits<InsertElementConstantExpr, 3> {};
319 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
320
321 template <>
322 struct OperandTraits<ShuffleVectorConstantExpr>
323     : public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {};
324 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
325
326 template <>
327 struct OperandTraits<ExtractValueConstantExpr>
328     : public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {};
329 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
330
331 template <>
332 struct OperandTraits<InsertValueConstantExpr>
333     : public FixedNumOperandTraits<InsertValueConstantExpr, 2> {};
334 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
335
336 template <>
337 struct OperandTraits<GetElementPtrConstantExpr>
338     : public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {};
339
340 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
341
342 template <>
343 struct OperandTraits<CompareConstantExpr>
344     : public FixedNumOperandTraits<CompareConstantExpr, 2> {};
345 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
346
347 template <class ConstantClass> struct ConstantAggrKeyType;
348 struct InlineAsmKeyType;
349 struct ConstantExprKeyType;
350
351 template <class ConstantClass> struct ConstantInfo;
352 template <> struct ConstantInfo<ConstantExpr> {
353   using ValType = ConstantExprKeyType;
354   using TypeClass = Type;
355 };
356 template <> struct ConstantInfo<InlineAsm> {
357   using ValType = InlineAsmKeyType;
358   using TypeClass = PointerType;
359 };
360 template <> struct ConstantInfo<ConstantArray> {
361   using ValType = ConstantAggrKeyType<ConstantArray>;
362   using TypeClass = ArrayType;
363 };
364 template <> struct ConstantInfo<ConstantStruct> {
365   using ValType = ConstantAggrKeyType<ConstantStruct>;
366   using TypeClass = StructType;
367 };
368 template <> struct ConstantInfo<ConstantVector> {
369   using ValType = ConstantAggrKeyType<ConstantVector>;
370   using TypeClass = VectorType;
371 };
372
373 template <class ConstantClass> struct ConstantAggrKeyType {
374   ArrayRef<Constant *> Operands;
375
376   ConstantAggrKeyType(ArrayRef<Constant *> Operands) : Operands(Operands) {}
377
378   ConstantAggrKeyType(ArrayRef<Constant *> Operands, const ConstantClass *)
379       : Operands(Operands) {}
380
381   ConstantAggrKeyType(const ConstantClass *C,
382                       SmallVectorImpl<Constant *> &Storage) {
383     assert(Storage.empty() && "Expected empty storage");
384     for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I)
385       Storage.push_back(C->getOperand(I));
386     Operands = Storage;
387   }
388
389   bool operator==(const ConstantAggrKeyType &X) const {
390     return Operands == X.Operands;
391   }
392
393   bool operator==(const ConstantClass *C) const {
394     if (Operands.size() != C->getNumOperands())
395       return false;
396     for (unsigned I = 0, E = Operands.size(); I != E; ++I)
397       if (Operands[I] != C->getOperand(I))
398         return false;
399     return true;
400   }
401
402   unsigned getHash() const {
403     return hash_combine_range(Operands.begin(), Operands.end());
404   }
405
406   using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
407
408   ConstantClass *create(TypeClass *Ty) const {
409     return new (Operands.size()) ConstantClass(Ty, Operands);
410   }
411 };
412
413 struct InlineAsmKeyType {
414   StringRef AsmString;
415   StringRef Constraints;
416   FunctionType *FTy;
417   bool HasSideEffects;
418   bool IsAlignStack;
419   InlineAsm::AsmDialect AsmDialect;
420
421   InlineAsmKeyType(StringRef AsmString, StringRef Constraints,
422                    FunctionType *FTy, bool HasSideEffects, bool IsAlignStack,
423                    InlineAsm::AsmDialect AsmDialect)
424       : AsmString(AsmString), Constraints(Constraints), FTy(FTy),
425         HasSideEffects(HasSideEffects), IsAlignStack(IsAlignStack),
426         AsmDialect(AsmDialect) {}
427
428   InlineAsmKeyType(const InlineAsm *Asm, SmallVectorImpl<Constant *> &)
429       : AsmString(Asm->getAsmString()), Constraints(Asm->getConstraintString()),
430         FTy(Asm->getFunctionType()), HasSideEffects(Asm->hasSideEffects()),
431         IsAlignStack(Asm->isAlignStack()), AsmDialect(Asm->getDialect()) {}
432
433   bool operator==(const InlineAsmKeyType &X) const {
434     return HasSideEffects == X.HasSideEffects &&
435            IsAlignStack == X.IsAlignStack && AsmDialect == X.AsmDialect &&
436            AsmString == X.AsmString && Constraints == X.Constraints &&
437            FTy == X.FTy;
438   }
439
440   bool operator==(const InlineAsm *Asm) const {
441     return HasSideEffects == Asm->hasSideEffects() &&
442            IsAlignStack == Asm->isAlignStack() &&
443            AsmDialect == Asm->getDialect() &&
444            AsmString == Asm->getAsmString() &&
445            Constraints == Asm->getConstraintString() &&
446            FTy == Asm->getFunctionType();
447   }
448
449   unsigned getHash() const {
450     return hash_combine(AsmString, Constraints, HasSideEffects, IsAlignStack,
451                         AsmDialect, FTy);
452   }
453
454   using TypeClass = ConstantInfo<InlineAsm>::TypeClass;
455
456   InlineAsm *create(TypeClass *Ty) const {
457     assert(PointerType::getUnqual(FTy) == Ty);
458     return new InlineAsm(FTy, AsmString, Constraints, HasSideEffects,
459                          IsAlignStack, AsmDialect);
460   }
461 };
462
463 struct ConstantExprKeyType {
464   uint8_t Opcode;
465   uint8_t SubclassOptionalData;
466   uint16_t SubclassData;
467   ArrayRef<Constant *> Ops;
468   ArrayRef<unsigned> Indexes;
469   Type *ExplicitTy;
470
471   ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops,
472                       unsigned short SubclassData = 0,
473                       unsigned short SubclassOptionalData = 0,
474                       ArrayRef<unsigned> Indexes = None,
475                       Type *ExplicitTy = nullptr)
476       : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData),
477         SubclassData(SubclassData), Ops(Ops), Indexes(Indexes),
478         ExplicitTy(ExplicitTy) {}
479
480   ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE)
481       : Opcode(CE->getOpcode()),
482         SubclassOptionalData(CE->getRawSubclassOptionalData()),
483         SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands),
484         Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {}
485
486   ConstantExprKeyType(const ConstantExpr *CE,
487                       SmallVectorImpl<Constant *> &Storage)
488       : Opcode(CE->getOpcode()),
489         SubclassOptionalData(CE->getRawSubclassOptionalData()),
490         SubclassData(CE->isCompare() ? CE->getPredicate() : 0),
491         Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {
492     assert(Storage.empty() && "Expected empty storage");
493     for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I)
494       Storage.push_back(CE->getOperand(I));
495     Ops = Storage;
496   }
497
498   bool operator==(const ConstantExprKeyType &X) const {
499     return Opcode == X.Opcode && SubclassData == X.SubclassData &&
500            SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops &&
501            Indexes == X.Indexes;
502   }
503
504   bool operator==(const ConstantExpr *CE) const {
505     if (Opcode != CE->getOpcode())
506       return false;
507     if (SubclassOptionalData != CE->getRawSubclassOptionalData())
508       return false;
509     if (Ops.size() != CE->getNumOperands())
510       return false;
511     if (SubclassData != (CE->isCompare() ? CE->getPredicate() : 0))
512       return false;
513     for (unsigned I = 0, E = Ops.size(); I != E; ++I)
514       if (Ops[I] != CE->getOperand(I))
515         return false;
516     if (Indexes != (CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()))
517       return false;
518     return true;
519   }
520
521   unsigned getHash() const {
522     return hash_combine(Opcode, SubclassOptionalData, SubclassData,
523                         hash_combine_range(Ops.begin(), Ops.end()),
524                         hash_combine_range(Indexes.begin(), Indexes.end()));
525   }
526
527   using TypeClass = ConstantInfo<ConstantExpr>::TypeClass;
528
529   ConstantExpr *create(TypeClass *Ty) const {
530     switch (Opcode) {
531     default:
532       if (Instruction::isCast(Opcode) ||
533           (Opcode >= Instruction::UnaryOpsBegin &&
534            Opcode < Instruction::UnaryOpsEnd))
535         return new UnaryConstantExpr(Opcode, Ops[0], Ty);
536       if ((Opcode >= Instruction::BinaryOpsBegin &&
537            Opcode < Instruction::BinaryOpsEnd))
538         return new BinaryConstantExpr(Opcode, Ops[0], Ops[1],
539                                       SubclassOptionalData);
540       llvm_unreachable("Invalid ConstantExpr!");
541     case Instruction::Select:
542       return new SelectConstantExpr(Ops[0], Ops[1], Ops[2]);
543     case Instruction::ExtractElement:
544       return new ExtractElementConstantExpr(Ops[0], Ops[1]);
545     case Instruction::InsertElement:
546       return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]);
547     case Instruction::ShuffleVector:
548       return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]);
549     case Instruction::InsertValue:
550       return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty);
551     case Instruction::ExtractValue:
552       return new ExtractValueConstantExpr(Ops[0], Indexes, Ty);
553     case Instruction::GetElementPtr:
554       return GetElementPtrConstantExpr::Create(
555           ExplicitTy ? ExplicitTy
556                      : cast<PointerType>(Ops[0]->getType()->getScalarType())
557                            ->getElementType(),
558           Ops[0], Ops.slice(1), Ty, SubclassOptionalData);
559     case Instruction::ICmp:
560       return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData,
561                                      Ops[0], Ops[1]);
562     case Instruction::FCmp:
563       return new CompareConstantExpr(Ty, Instruction::FCmp, SubclassData,
564                                      Ops[0], Ops[1]);
565     }
566   }
567 };
568
569 template <class ConstantClass> class ConstantUniqueMap {
570 public:
571   using ValType = typename ConstantInfo<ConstantClass>::ValType;
572   using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
573   using LookupKey = std::pair<TypeClass *, ValType>;
574
575   /// Key and hash together, so that we compute the hash only once and reuse it.
576   using LookupKeyHashed = std::pair<unsigned, LookupKey>;
577
578 private:
579   struct MapInfo {
580     using ConstantClassInfo = DenseMapInfo<ConstantClass *>;
581
582     static inline ConstantClass *getEmptyKey() {
583       return ConstantClassInfo::getEmptyKey();
584     }
585
586     static inline ConstantClass *getTombstoneKey() {
587       return ConstantClassInfo::getTombstoneKey();
588     }
589
590     static unsigned getHashValue(const ConstantClass *CP) {
591       SmallVector<Constant *, 32> Storage;
592       return getHashValue(LookupKey(CP->getType(), ValType(CP, Storage)));
593     }
594
595     static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) {
596       return LHS == RHS;
597     }
598
599     static unsigned getHashValue(const LookupKey &Val) {
600       return hash_combine(Val.first, Val.second.getHash());
601     }
602
603     static unsigned getHashValue(const LookupKeyHashed &Val) {
604       return Val.first;
605     }
606
607     static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) {
608       if (RHS == getEmptyKey() || RHS == getTombstoneKey())
609         return false;
610       if (LHS.first != RHS->getType())
611         return false;
612       return LHS.second == RHS;
613     }
614
615     static bool isEqual(const LookupKeyHashed &LHS, const ConstantClass *RHS) {
616       return isEqual(LHS.second, RHS);
617     }
618   };
619
620 public:
621   using MapTy = DenseSet<ConstantClass *, MapInfo>;
622
623 private:
624   MapTy Map;
625
626 public:
627   typename MapTy::iterator begin() { return Map.begin(); }
628   typename MapTy::iterator end() { return Map.end(); }
629
630   void freeConstants() {
631     for (auto &I : Map)
632       delete I; // Asserts that use_empty().
633   }
634
635 private:
636   ConstantClass *create(TypeClass *Ty, ValType V, LookupKeyHashed &HashKey) {
637     ConstantClass *Result = V.create(Ty);
638
639     assert(Result->getType() == Ty && "Type specified is not correct!");
640     Map.insert_as(Result, HashKey);
641
642     return Result;
643   }
644
645 public:
646   /// Return the specified constant from the map, creating it if necessary.
647   ConstantClass *getOrCreate(TypeClass *Ty, ValType V) {
648     LookupKey Key(Ty, V);
649     /// Hash once, and reuse it for the lookup and the insertion if needed.
650     LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
651
652     ConstantClass *Result = nullptr;
653
654     auto I = Map.find_as(Lookup);
655     if (I == Map.end())
656       Result = create(Ty, V, Lookup);
657     else
658       Result = *I;
659     assert(Result && "Unexpected nullptr");
660
661     return Result;
662   }
663
664   /// Remove this constant from the map
665   void remove(ConstantClass *CP) {
666     typename MapTy::iterator I = Map.find(CP);
667     assert(I != Map.end() && "Constant not found in constant table!");
668     assert(*I == CP && "Didn't find correct element?");
669     Map.erase(I);
670   }
671
672   ConstantClass *replaceOperandsInPlace(ArrayRef<Constant *> Operands,
673                                         ConstantClass *CP, Value *From,
674                                         Constant *To, unsigned NumUpdated = 0,
675                                         unsigned OperandNo = ~0u) {
676     LookupKey Key(CP->getType(), ValType(Operands, CP));
677     /// Hash once, and reuse it for the lookup and the insertion if needed.
678     LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
679
680     auto I = Map.find_as(Lookup);
681     if (I != Map.end())
682       return *I;
683
684     // Update to the new value.  Optimize for the case when we have a single
685     // operand that we're changing, but handle bulk updates efficiently.
686     remove(CP);
687     if (NumUpdated == 1) {
688       assert(OperandNo < CP->getNumOperands() && "Invalid index");
689       assert(CP->getOperand(OperandNo) != To && "I didn't contain From!");
690       CP->setOperand(OperandNo, To);
691     } else {
692       for (unsigned I = 0, E = CP->getNumOperands(); I != E; ++I)
693         if (CP->getOperand(I) == From)
694           CP->setOperand(I, To);
695     }
696     Map.insert_as(CP, Lookup);
697     return nullptr;
698   }
699
700   void dump() const {
701     LLVM_DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
702   }
703 };
704
705 } // end namespace llvm
706
707 #endif // LLVM_LIB_IR_CONSTANTSCONTEXT_H