1 //===-- ConstantsContext.h - Constants-related Context Interals -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines various helper methods and classes used by
11 // LLVMContextImpl for creating and managing constants.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_IR_CONSTANTSCONTEXT_H
16 #define LLVM_LIB_IR_CONSTANTSCONTEXT_H
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"
40 #define DEBUG_TYPE "ir"
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 {
48 UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty)
49 : ConstantExpr(Ty, Opcode, &Op<0>(), 1) {
53 // allocate space for exactly one operand
54 void *operator new(size_t s) {
55 return User::operator new(s, 1);
58 void *operator new(size_t, unsigned) = delete;
60 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
63 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
64 /// behind the scenes to implement binary constant exprs.
65 class BinaryConstantExpr : public ConstantExpr {
67 BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
69 : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
72 SubclassOptionalData = Flags;
75 // allocate space for exactly two operands
76 void *operator new(size_t s) {
77 return User::operator new(s, 2);
80 void *operator new(size_t, unsigned) = delete;
82 /// Transparently provide more efficient getOperand methods.
83 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
86 /// SelectConstantExpr - This class is private to Constants.cpp, and is used
87 /// behind the scenes to implement select constant exprs.
88 class SelectConstantExpr : public ConstantExpr {
90 SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3)
91 : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) {
97 // allocate space for exactly three operands
98 void *operator new(size_t s) {
99 return User::operator new(s, 3);
102 void *operator new(size_t, unsigned) = delete;
104 /// Transparently provide more efficient getOperand methods.
105 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
108 /// ExtractElementConstantExpr - This class is private to
109 /// Constants.cpp, and is used behind the scenes to implement
110 /// extractelement constant exprs.
111 class ExtractElementConstantExpr : public ConstantExpr {
113 ExtractElementConstantExpr(Constant *C1, Constant *C2)
114 : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(),
115 Instruction::ExtractElement, &Op<0>(), 2) {
120 // allocate space for exactly two operands
121 void *operator new(size_t s) {
122 return User::operator new(s, 2);
125 void *operator new(size_t, unsigned) = delete;
127 /// Transparently provide more efficient getOperand methods.
128 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
131 /// InsertElementConstantExpr - This class is private to
132 /// Constants.cpp, and is used behind the scenes to implement
133 /// insertelement constant exprs.
134 class InsertElementConstantExpr : public ConstantExpr {
136 InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3)
137 : ConstantExpr(C1->getType(), Instruction::InsertElement,
144 // allocate space for exactly three operands
145 void *operator new(size_t s) {
146 return User::operator new(s, 3);
149 void *operator new(size_t, unsigned) = delete;
151 /// Transparently provide more efficient getOperand methods.
152 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
155 /// ShuffleVectorConstantExpr - This class is private to
156 /// Constants.cpp, and is used behind the scenes to implement
157 /// shufflevector constant exprs.
158 class ShuffleVectorConstantExpr : public ConstantExpr {
160 ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3)
161 : ConstantExpr(VectorType::get(
162 cast<VectorType>(C1->getType())->getElementType(),
163 cast<VectorType>(C3->getType())->getNumElements()),
164 Instruction::ShuffleVector,
171 // allocate space for exactly three operands
172 void *operator new(size_t s) {
173 return User::operator new(s, 3);
176 void *operator new(size_t, unsigned) = delete;
178 /// Transparently provide more efficient getOperand methods.
179 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
182 /// ExtractValueConstantExpr - This class is private to
183 /// Constants.cpp, and is used behind the scenes to implement
184 /// extractvalue constant exprs.
185 class ExtractValueConstantExpr : public ConstantExpr {
187 ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList,
189 : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1),
190 Indices(IdxList.begin(), IdxList.end()) {
194 // allocate space for exactly one operand
195 void *operator new(size_t s) {
196 return User::operator new(s, 1);
199 void *operator new(size_t, unsigned) = delete;
201 /// Indices - These identify which value to extract.
202 const SmallVector<unsigned, 4> Indices;
204 /// Transparently provide more efficient getOperand methods.
205 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
207 static bool classof(const ConstantExpr *CE) {
208 return CE->getOpcode() == Instruction::ExtractValue;
210 static bool classof(const Value *V) {
211 return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
215 /// InsertValueConstantExpr - This class is private to
216 /// Constants.cpp, and is used behind the scenes to implement
217 /// insertvalue constant exprs.
218 class InsertValueConstantExpr : public ConstantExpr {
220 InsertValueConstantExpr(Constant *Agg, Constant *Val,
221 ArrayRef<unsigned> IdxList, Type *DestTy)
222 : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2),
223 Indices(IdxList.begin(), IdxList.end()) {
228 // allocate space for exactly one operand
229 void *operator new(size_t s) {
230 return User::operator new(s, 2);
233 void *operator new(size_t, unsigned) = delete;
235 /// Indices - These identify the position for the insertion.
236 const SmallVector<unsigned, 4> Indices;
238 /// Transparently provide more efficient getOperand methods.
239 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
241 static bool classof(const ConstantExpr *CE) {
242 return CE->getOpcode() == Instruction::InsertValue;
244 static bool classof(const Value *V) {
245 return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
249 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
250 /// used behind the scenes to implement getelementpr constant exprs.
251 class GetElementPtrConstantExpr : public ConstantExpr {
255 GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C,
256 ArrayRef<Constant *> IdxList, Type *DestTy);
259 static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C,
260 ArrayRef<Constant *> IdxList,
261 Type *DestTy, unsigned Flags) {
262 GetElementPtrConstantExpr *Result = new (IdxList.size() + 1)
263 GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy);
264 Result->SubclassOptionalData = Flags;
268 Type *getSourceElementType() const;
269 Type *getResultElementType() const;
271 /// Transparently provide more efficient getOperand methods.
272 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
274 static bool classof(const ConstantExpr *CE) {
275 return CE->getOpcode() == Instruction::GetElementPtr;
277 static bool classof(const Value *V) {
278 return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
282 // CompareConstantExpr - This class is private to Constants.cpp, and is used
283 // behind the scenes to implement ICmp and FCmp constant expressions. This is
284 // needed in order to store the predicate value for these instructions.
285 class CompareConstantExpr : public ConstantExpr {
287 unsigned short predicate;
288 CompareConstantExpr(Type *ty, Instruction::OtherOps opc,
289 unsigned short pred, Constant* LHS, Constant* RHS)
290 : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
295 // allocate space for exactly two operands
296 void *operator new(size_t s) {
297 return User::operator new(s, 2);
300 void *operator new(size_t, unsigned) = delete;
302 /// Transparently provide more efficient getOperand methods.
303 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
305 static bool classof(const ConstantExpr *CE) {
306 return CE->getOpcode() == Instruction::ICmp ||
307 CE->getOpcode() == Instruction::FCmp;
309 static bool classof(const Value *V) {
310 return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V));
315 struct OperandTraits<UnaryConstantExpr>
316 : public FixedNumOperandTraits<UnaryConstantExpr, 1> {};
317 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value)
320 struct OperandTraits<BinaryConstantExpr>
321 : public FixedNumOperandTraits<BinaryConstantExpr, 2> {};
322 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value)
325 struct OperandTraits<SelectConstantExpr>
326 : public FixedNumOperandTraits<SelectConstantExpr, 3> {};
327 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value)
330 struct OperandTraits<ExtractElementConstantExpr>
331 : public FixedNumOperandTraits<ExtractElementConstantExpr, 2> {};
332 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value)
335 struct OperandTraits<InsertElementConstantExpr>
336 : public FixedNumOperandTraits<InsertElementConstantExpr, 3> {};
337 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value)
340 struct OperandTraits<ShuffleVectorConstantExpr>
341 : public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {};
342 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value)
345 struct OperandTraits<ExtractValueConstantExpr>
346 : public FixedNumOperandTraits<ExtractValueConstantExpr, 1> {};
347 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value)
350 struct OperandTraits<InsertValueConstantExpr>
351 : public FixedNumOperandTraits<InsertValueConstantExpr, 2> {};
352 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value)
355 struct OperandTraits<GetElementPtrConstantExpr>
356 : public VariadicOperandTraits<GetElementPtrConstantExpr, 1> {};
358 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value)
361 struct OperandTraits<CompareConstantExpr>
362 : public FixedNumOperandTraits<CompareConstantExpr, 2> {};
363 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value)
365 template <class ConstantClass> struct ConstantAggrKeyType;
366 struct InlineAsmKeyType;
367 struct ConstantExprKeyType;
369 template <class ConstantClass> struct ConstantInfo;
370 template <> struct ConstantInfo<ConstantExpr> {
371 using ValType = ConstantExprKeyType;
372 using TypeClass = Type;
374 template <> struct ConstantInfo<InlineAsm> {
375 using ValType = InlineAsmKeyType;
376 using TypeClass = PointerType;
378 template <> struct ConstantInfo<ConstantArray> {
379 using ValType = ConstantAggrKeyType<ConstantArray>;
380 using TypeClass = ArrayType;
382 template <> struct ConstantInfo<ConstantStruct> {
383 using ValType = ConstantAggrKeyType<ConstantStruct>;
384 using TypeClass = StructType;
386 template <> struct ConstantInfo<ConstantVector> {
387 using ValType = ConstantAggrKeyType<ConstantVector>;
388 using TypeClass = VectorType;
391 template <class ConstantClass> struct ConstantAggrKeyType {
392 ArrayRef<Constant *> Operands;
394 ConstantAggrKeyType(ArrayRef<Constant *> Operands) : Operands(Operands) {}
396 ConstantAggrKeyType(ArrayRef<Constant *> Operands, const ConstantClass *)
397 : Operands(Operands) {}
399 ConstantAggrKeyType(const ConstantClass *C,
400 SmallVectorImpl<Constant *> &Storage) {
401 assert(Storage.empty() && "Expected empty storage");
402 for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I)
403 Storage.push_back(C->getOperand(I));
407 bool operator==(const ConstantAggrKeyType &X) const {
408 return Operands == X.Operands;
411 bool operator==(const ConstantClass *C) const {
412 if (Operands.size() != C->getNumOperands())
414 for (unsigned I = 0, E = Operands.size(); I != E; ++I)
415 if (Operands[I] != C->getOperand(I))
420 unsigned getHash() const {
421 return hash_combine_range(Operands.begin(), Operands.end());
424 using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
426 ConstantClass *create(TypeClass *Ty) const {
427 return new (Operands.size()) ConstantClass(Ty, Operands);
431 struct InlineAsmKeyType {
433 StringRef Constraints;
437 InlineAsm::AsmDialect AsmDialect;
439 InlineAsmKeyType(StringRef AsmString, StringRef Constraints,
440 FunctionType *FTy, bool HasSideEffects, bool IsAlignStack,
441 InlineAsm::AsmDialect AsmDialect)
442 : AsmString(AsmString), Constraints(Constraints), FTy(FTy),
443 HasSideEffects(HasSideEffects), IsAlignStack(IsAlignStack),
444 AsmDialect(AsmDialect) {}
446 InlineAsmKeyType(const InlineAsm *Asm, SmallVectorImpl<Constant *> &)
447 : AsmString(Asm->getAsmString()), Constraints(Asm->getConstraintString()),
448 FTy(Asm->getFunctionType()), HasSideEffects(Asm->hasSideEffects()),
449 IsAlignStack(Asm->isAlignStack()), AsmDialect(Asm->getDialect()) {}
451 bool operator==(const InlineAsmKeyType &X) const {
452 return HasSideEffects == X.HasSideEffects &&
453 IsAlignStack == X.IsAlignStack && AsmDialect == X.AsmDialect &&
454 AsmString == X.AsmString && Constraints == X.Constraints &&
458 bool operator==(const InlineAsm *Asm) const {
459 return HasSideEffects == Asm->hasSideEffects() &&
460 IsAlignStack == Asm->isAlignStack() &&
461 AsmDialect == Asm->getDialect() &&
462 AsmString == Asm->getAsmString() &&
463 Constraints == Asm->getConstraintString() &&
464 FTy == Asm->getFunctionType();
467 unsigned getHash() const {
468 return hash_combine(AsmString, Constraints, HasSideEffects, IsAlignStack,
472 using TypeClass = ConstantInfo<InlineAsm>::TypeClass;
474 InlineAsm *create(TypeClass *Ty) const {
475 assert(PointerType::getUnqual(FTy) == Ty);
476 return new InlineAsm(FTy, AsmString, Constraints, HasSideEffects,
477 IsAlignStack, AsmDialect);
481 struct ConstantExprKeyType {
483 uint8_t SubclassOptionalData;
484 uint16_t SubclassData;
485 ArrayRef<Constant *> Ops;
486 ArrayRef<unsigned> Indexes;
489 ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops,
490 unsigned short SubclassData = 0,
491 unsigned short SubclassOptionalData = 0,
492 ArrayRef<unsigned> Indexes = None,
493 Type *ExplicitTy = nullptr)
494 : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData),
495 SubclassData(SubclassData), Ops(Ops), Indexes(Indexes),
496 ExplicitTy(ExplicitTy) {}
498 ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE)
499 : Opcode(CE->getOpcode()),
500 SubclassOptionalData(CE->getRawSubclassOptionalData()),
501 SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands),
502 Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {}
504 ConstantExprKeyType(const ConstantExpr *CE,
505 SmallVectorImpl<Constant *> &Storage)
506 : Opcode(CE->getOpcode()),
507 SubclassOptionalData(CE->getRawSubclassOptionalData()),
508 SubclassData(CE->isCompare() ? CE->getPredicate() : 0),
509 Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {
510 assert(Storage.empty() && "Expected empty storage");
511 for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I)
512 Storage.push_back(CE->getOperand(I));
516 bool operator==(const ConstantExprKeyType &X) const {
517 return Opcode == X.Opcode && SubclassData == X.SubclassData &&
518 SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops &&
519 Indexes == X.Indexes;
522 bool operator==(const ConstantExpr *CE) const {
523 if (Opcode != CE->getOpcode())
525 if (SubclassOptionalData != CE->getRawSubclassOptionalData())
527 if (Ops.size() != CE->getNumOperands())
529 if (SubclassData != (CE->isCompare() ? CE->getPredicate() : 0))
531 for (unsigned I = 0, E = Ops.size(); I != E; ++I)
532 if (Ops[I] != CE->getOperand(I))
534 if (Indexes != (CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()))
539 unsigned getHash() const {
540 return hash_combine(Opcode, SubclassOptionalData, SubclassData,
541 hash_combine_range(Ops.begin(), Ops.end()),
542 hash_combine_range(Indexes.begin(), Indexes.end()));
545 using TypeClass = ConstantInfo<ConstantExpr>::TypeClass;
547 ConstantExpr *create(TypeClass *Ty) const {
550 if (Instruction::isCast(Opcode))
551 return new UnaryConstantExpr(Opcode, Ops[0], Ty);
552 if ((Opcode >= Instruction::BinaryOpsBegin &&
553 Opcode < Instruction::BinaryOpsEnd))
554 return new BinaryConstantExpr(Opcode, Ops[0], Ops[1],
555 SubclassOptionalData);
556 llvm_unreachable("Invalid ConstantExpr!");
557 case Instruction::Select:
558 return new SelectConstantExpr(Ops[0], Ops[1], Ops[2]);
559 case Instruction::ExtractElement:
560 return new ExtractElementConstantExpr(Ops[0], Ops[1]);
561 case Instruction::InsertElement:
562 return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]);
563 case Instruction::ShuffleVector:
564 return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]);
565 case Instruction::InsertValue:
566 return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty);
567 case Instruction::ExtractValue:
568 return new ExtractValueConstantExpr(Ops[0], Indexes, Ty);
569 case Instruction::GetElementPtr:
570 return GetElementPtrConstantExpr::Create(
571 ExplicitTy ? ExplicitTy
572 : cast<PointerType>(Ops[0]->getType()->getScalarType())
574 Ops[0], Ops.slice(1), Ty, SubclassOptionalData);
575 case Instruction::ICmp:
576 return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData,
578 case Instruction::FCmp:
579 return new CompareConstantExpr(Ty, Instruction::FCmp, SubclassData,
585 template <class ConstantClass> class ConstantUniqueMap {
587 using ValType = typename ConstantInfo<ConstantClass>::ValType;
588 using TypeClass = typename ConstantInfo<ConstantClass>::TypeClass;
589 using LookupKey = std::pair<TypeClass *, ValType>;
591 /// Key and hash together, so that we compute the hash only once and reuse it.
592 using LookupKeyHashed = std::pair<unsigned, LookupKey>;
596 using ConstantClassInfo = DenseMapInfo<ConstantClass *>;
598 static inline ConstantClass *getEmptyKey() {
599 return ConstantClassInfo::getEmptyKey();
602 static inline ConstantClass *getTombstoneKey() {
603 return ConstantClassInfo::getTombstoneKey();
606 static unsigned getHashValue(const ConstantClass *CP) {
607 SmallVector<Constant *, 32> Storage;
608 return getHashValue(LookupKey(CP->getType(), ValType(CP, Storage)));
611 static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) {
615 static unsigned getHashValue(const LookupKey &Val) {
616 return hash_combine(Val.first, Val.second.getHash());
619 static unsigned getHashValue(const LookupKeyHashed &Val) {
623 static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) {
624 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
626 if (LHS.first != RHS->getType())
628 return LHS.second == RHS;
631 static bool isEqual(const LookupKeyHashed &LHS, const ConstantClass *RHS) {
632 return isEqual(LHS.second, RHS);
637 using MapTy = DenseSet<ConstantClass *, MapInfo>;
643 typename MapTy::iterator begin() { return Map.begin(); }
644 typename MapTy::iterator end() { return Map.end(); }
646 void freeConstants() {
648 delete I; // Asserts that use_empty().
652 ConstantClass *create(TypeClass *Ty, ValType V, LookupKeyHashed &HashKey) {
653 ConstantClass *Result = V.create(Ty);
655 assert(Result->getType() == Ty && "Type specified is not correct!");
656 Map.insert_as(Result, HashKey);
662 /// Return the specified constant from the map, creating it if necessary.
663 ConstantClass *getOrCreate(TypeClass *Ty, ValType V) {
664 LookupKey Key(Ty, V);
665 /// Hash once, and reuse it for the lookup and the insertion if needed.
666 LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
668 ConstantClass *Result = nullptr;
670 auto I = Map.find_as(Lookup);
672 Result = create(Ty, V, Lookup);
675 assert(Result && "Unexpected nullptr");
680 /// Remove this constant from the map
681 void remove(ConstantClass *CP) {
682 typename MapTy::iterator I = Map.find(CP);
683 assert(I != Map.end() && "Constant not found in constant table!");
684 assert(*I == CP && "Didn't find correct element?");
688 ConstantClass *replaceOperandsInPlace(ArrayRef<Constant *> Operands,
689 ConstantClass *CP, Value *From,
690 Constant *To, unsigned NumUpdated = 0,
691 unsigned OperandNo = ~0u) {
692 LookupKey Key(CP->getType(), ValType(Operands, CP));
693 /// Hash once, and reuse it for the lookup and the insertion if needed.
694 LookupKeyHashed Lookup(MapInfo::getHashValue(Key), Key);
696 auto I = Map.find_as(Lookup);
700 // Update to the new value. Optimize for the case when we have a single
701 // operand that we're changing, but handle bulk updates efficiently.
703 if (NumUpdated == 1) {
704 assert(OperandNo < CP->getNumOperands() && "Invalid index");
705 assert(CP->getOperand(OperandNo) != To && "I didn't contain From!");
706 CP->setOperand(OperandNo, To);
708 for (unsigned I = 0, E = CP->getNumOperands(); I != E; ++I)
709 if (CP->getOperand(I) == From)
710 CP->setOperand(I, To);
712 Map.insert_as(CP, Lookup);
716 void dump() const { DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); }
719 } // end namespace llvm
721 #endif // LLVM_LIB_IR_CONSTANTSCONTEXT_H