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