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 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
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
{
65 BinaryConstantExpr(unsigned Opcode
, Constant
*C1
, Constant
*C2
,
67 : ConstantExpr(C1
->getType(), Opcode
, &Op
<0>(), 2) {
70 SubclassOptionalData
= Flags
;
73 // allocate space for exactly two operands
74 void *operator new(size_t s
) {
75 return User::operator new(s
, 2);
78 /// Transparently provide more efficient getOperand methods.
79 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
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
{
86 SelectConstantExpr(Constant
*C1
, Constant
*C2
, Constant
*C3
)
87 : ConstantExpr(C2
->getType(), Instruction::Select
, &Op
<0>(), 3) {
93 // allocate space for exactly three operands
94 void *operator new(size_t s
) {
95 return User::operator new(s
, 3);
98 /// Transparently provide more efficient getOperand methods.
99 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
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
{
107 ExtractElementConstantExpr(Constant
*C1
, Constant
*C2
)
108 : ConstantExpr(cast
<VectorType
>(C1
->getType())->getElementType(),
109 Instruction::ExtractElement
, &Op
<0>(), 2) {
114 // allocate space for exactly two operands
115 void *operator new(size_t s
) {
116 return User::operator new(s
, 2);
119 /// Transparently provide more efficient getOperand methods.
120 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
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
{
128 InsertElementConstantExpr(Constant
*C1
, Constant
*C2
, Constant
*C3
)
129 : ConstantExpr(C1
->getType(), Instruction::InsertElement
,
136 // allocate space for exactly three operands
137 void *operator new(size_t s
) {
138 return User::operator new(s
, 3);
141 /// Transparently provide more efficient getOperand methods.
142 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
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
{
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
,
161 // allocate space for exactly three operands
162 void *operator new(size_t s
) {
163 return User::operator new(s
, 3);
166 /// Transparently provide more efficient getOperand methods.
167 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
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
{
175 ExtractValueConstantExpr(Constant
*Agg
, ArrayRef
<unsigned> IdxList
,
177 : ConstantExpr(DestTy
, Instruction::ExtractValue
, &Op
<0>(), 1),
178 Indices(IdxList
.begin(), IdxList
.end()) {
182 // allocate space for exactly one operand
183 void *operator new(size_t s
) {
184 return User::operator new(s
, 1);
187 /// Indices - These identify which value to extract.
188 const SmallVector
<unsigned, 4> Indices
;
190 /// Transparently provide more efficient getOperand methods.
191 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
193 static bool classof(const ConstantExpr
*CE
) {
194 return CE
->getOpcode() == Instruction::ExtractValue
;
196 static bool classof(const Value
*V
) {
197 return isa
<ConstantExpr
>(V
) && classof(cast
<ConstantExpr
>(V
));
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
{
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()) {
214 // allocate space for exactly one operand
215 void *operator new(size_t s
) {
216 return User::operator new(s
, 2);
219 /// Indices - These identify the position for the insertion.
220 const SmallVector
<unsigned, 4> Indices
;
222 /// Transparently provide more efficient getOperand methods.
223 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
225 static bool classof(const ConstantExpr
*CE
) {
226 return CE
->getOpcode() == Instruction::InsertValue
;
228 static bool classof(const Value
*V
) {
229 return isa
<ConstantExpr
>(V
) && classof(cast
<ConstantExpr
>(V
));
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
{
239 GetElementPtrConstantExpr(Type
*SrcElementTy
, Constant
*C
,
240 ArrayRef
<Constant
*> IdxList
, Type
*DestTy
);
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
;
252 Type
*getSourceElementType() const;
253 Type
*getResultElementType() const;
255 /// Transparently provide more efficient getOperand methods.
256 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
258 static bool classof(const ConstantExpr
*CE
) {
259 return CE
->getOpcode() == Instruction::GetElementPtr
;
261 static bool classof(const Value
*V
) {
262 return isa
<ConstantExpr
>(V
) && classof(cast
<ConstantExpr
>(V
));
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
{
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
) {
279 // allocate space for exactly two operands
280 void *operator new(size_t s
) {
281 return User::operator new(s
, 2);
284 /// Transparently provide more efficient getOperand methods.
285 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
287 static bool classof(const ConstantExpr
*CE
) {
288 return CE
->getOpcode() == Instruction::ICmp
||
289 CE
->getOpcode() == Instruction::FCmp
;
291 static bool classof(const Value
*V
) {
292 return isa
<ConstantExpr
>(V
) && classof(cast
<ConstantExpr
>(V
));
297 struct OperandTraits
<UnaryConstantExpr
>
298 : public FixedNumOperandTraits
<UnaryConstantExpr
, 1> {};
299 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr
, Value
)
302 struct OperandTraits
<BinaryConstantExpr
>
303 : public FixedNumOperandTraits
<BinaryConstantExpr
, 2> {};
304 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr
, Value
)
307 struct OperandTraits
<SelectConstantExpr
>
308 : public FixedNumOperandTraits
<SelectConstantExpr
, 3> {};
309 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr
, Value
)
312 struct OperandTraits
<ExtractElementConstantExpr
>
313 : public FixedNumOperandTraits
<ExtractElementConstantExpr
, 2> {};
314 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr
, Value
)
317 struct OperandTraits
<InsertElementConstantExpr
>
318 : public FixedNumOperandTraits
<InsertElementConstantExpr
, 3> {};
319 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr
, Value
)
322 struct OperandTraits
<ShuffleVectorConstantExpr
>
323 : public FixedNumOperandTraits
<ShuffleVectorConstantExpr
, 3> {};
324 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr
, Value
)
327 struct OperandTraits
<ExtractValueConstantExpr
>
328 : public FixedNumOperandTraits
<ExtractValueConstantExpr
, 1> {};
329 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr
, Value
)
332 struct OperandTraits
<InsertValueConstantExpr
>
333 : public FixedNumOperandTraits
<InsertValueConstantExpr
, 2> {};
334 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr
, Value
)
337 struct OperandTraits
<GetElementPtrConstantExpr
>
338 : public VariadicOperandTraits
<GetElementPtrConstantExpr
, 1> {};
340 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr
, Value
)
343 struct OperandTraits
<CompareConstantExpr
>
344 : public FixedNumOperandTraits
<CompareConstantExpr
, 2> {};
345 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr
, Value
)
347 template <class ConstantClass
> struct ConstantAggrKeyType
;
348 struct InlineAsmKeyType
;
349 struct ConstantExprKeyType
;
351 template <class ConstantClass
> struct ConstantInfo
;
352 template <> struct ConstantInfo
<ConstantExpr
> {
353 using ValType
= ConstantExprKeyType
;
354 using TypeClass
= Type
;
356 template <> struct ConstantInfo
<InlineAsm
> {
357 using ValType
= InlineAsmKeyType
;
358 using TypeClass
= PointerType
;
360 template <> struct ConstantInfo
<ConstantArray
> {
361 using ValType
= ConstantAggrKeyType
<ConstantArray
>;
362 using TypeClass
= ArrayType
;
364 template <> struct ConstantInfo
<ConstantStruct
> {
365 using ValType
= ConstantAggrKeyType
<ConstantStruct
>;
366 using TypeClass
= StructType
;
368 template <> struct ConstantInfo
<ConstantVector
> {
369 using ValType
= ConstantAggrKeyType
<ConstantVector
>;
370 using TypeClass
= VectorType
;
373 template <class ConstantClass
> struct ConstantAggrKeyType
{
374 ArrayRef
<Constant
*> Operands
;
376 ConstantAggrKeyType(ArrayRef
<Constant
*> Operands
) : Operands(Operands
) {}
378 ConstantAggrKeyType(ArrayRef
<Constant
*> Operands
, const ConstantClass
*)
379 : Operands(Operands
) {}
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
));
389 bool operator==(const ConstantAggrKeyType
&X
) const {
390 return Operands
== X
.Operands
;
393 bool operator==(const ConstantClass
*C
) const {
394 if (Operands
.size() != C
->getNumOperands())
396 for (unsigned I
= 0, E
= Operands
.size(); I
!= E
; ++I
)
397 if (Operands
[I
] != C
->getOperand(I
))
402 unsigned getHash() const {
403 return hash_combine_range(Operands
.begin(), Operands
.end());
406 using TypeClass
= typename ConstantInfo
<ConstantClass
>::TypeClass
;
408 ConstantClass
*create(TypeClass
*Ty
) const {
409 return new (Operands
.size()) ConstantClass(Ty
, Operands
);
413 struct InlineAsmKeyType
{
415 StringRef Constraints
;
419 InlineAsm::AsmDialect AsmDialect
;
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
) {}
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()) {}
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
&&
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();
449 unsigned getHash() const {
450 return hash_combine(AsmString
, Constraints
, HasSideEffects
, IsAlignStack
,
454 using TypeClass
= ConstantInfo
<InlineAsm
>::TypeClass
;
456 InlineAsm
*create(TypeClass
*Ty
) const {
457 assert(PointerType::getUnqual(FTy
) == Ty
);
458 return new InlineAsm(FTy
, AsmString
, Constraints
, HasSideEffects
,
459 IsAlignStack
, AsmDialect
);
463 struct ConstantExprKeyType
{
465 uint8_t SubclassOptionalData
;
466 uint16_t SubclassData
;
467 ArrayRef
<Constant
*> Ops
;
468 ArrayRef
<unsigned> Indexes
;
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
) {}
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>()) {}
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
));
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
;
504 bool operator==(const ConstantExpr
*CE
) const {
505 if (Opcode
!= CE
->getOpcode())
507 if (SubclassOptionalData
!= CE
->getRawSubclassOptionalData())
509 if (Ops
.size() != CE
->getNumOperands())
511 if (SubclassData
!= (CE
->isCompare() ? CE
->getPredicate() : 0))
513 for (unsigned I
= 0, E
= Ops
.size(); I
!= E
; ++I
)
514 if (Ops
[I
] != CE
->getOperand(I
))
516 if (Indexes
!= (CE
->hasIndices() ? CE
->getIndices() : ArrayRef
<unsigned>()))
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()));
527 using TypeClass
= ConstantInfo
<ConstantExpr
>::TypeClass
;
529 ConstantExpr
*create(TypeClass
*Ty
) const {
532 if (Instruction::isCast(Opcode
))
533 return new UnaryConstantExpr(Opcode
, Ops
[0], Ty
);
534 if ((Opcode
>= Instruction::BinaryOpsBegin
&&
535 Opcode
< Instruction::BinaryOpsEnd
))
536 return new BinaryConstantExpr(Opcode
, Ops
[0], Ops
[1],
537 SubclassOptionalData
);
538 llvm_unreachable("Invalid ConstantExpr!");
539 case Instruction::Select
:
540 return new SelectConstantExpr(Ops
[0], Ops
[1], Ops
[2]);
541 case Instruction::ExtractElement
:
542 return new ExtractElementConstantExpr(Ops
[0], Ops
[1]);
543 case Instruction::InsertElement
:
544 return new InsertElementConstantExpr(Ops
[0], Ops
[1], Ops
[2]);
545 case Instruction::ShuffleVector
:
546 return new ShuffleVectorConstantExpr(Ops
[0], Ops
[1], Ops
[2]);
547 case Instruction::InsertValue
:
548 return new InsertValueConstantExpr(Ops
[0], Ops
[1], Indexes
, Ty
);
549 case Instruction::ExtractValue
:
550 return new ExtractValueConstantExpr(Ops
[0], Indexes
, Ty
);
551 case Instruction::GetElementPtr
:
552 return GetElementPtrConstantExpr::Create(
553 ExplicitTy
? ExplicitTy
554 : cast
<PointerType
>(Ops
[0]->getType()->getScalarType())
556 Ops
[0], Ops
.slice(1), Ty
, SubclassOptionalData
);
557 case Instruction::ICmp
:
558 return new CompareConstantExpr(Ty
, Instruction::ICmp
, SubclassData
,
560 case Instruction::FCmp
:
561 return new CompareConstantExpr(Ty
, Instruction::FCmp
, SubclassData
,
567 template <class ConstantClass
> class ConstantUniqueMap
{
569 using ValType
= typename ConstantInfo
<ConstantClass
>::ValType
;
570 using TypeClass
= typename ConstantInfo
<ConstantClass
>::TypeClass
;
571 using LookupKey
= std::pair
<TypeClass
*, ValType
>;
573 /// Key and hash together, so that we compute the hash only once and reuse it.
574 using LookupKeyHashed
= std::pair
<unsigned, LookupKey
>;
578 using ConstantClassInfo
= DenseMapInfo
<ConstantClass
*>;
580 static inline ConstantClass
*getEmptyKey() {
581 return ConstantClassInfo::getEmptyKey();
584 static inline ConstantClass
*getTombstoneKey() {
585 return ConstantClassInfo::getTombstoneKey();
588 static unsigned getHashValue(const ConstantClass
*CP
) {
589 SmallVector
<Constant
*, 32> Storage
;
590 return getHashValue(LookupKey(CP
->getType(), ValType(CP
, Storage
)));
593 static bool isEqual(const ConstantClass
*LHS
, const ConstantClass
*RHS
) {
597 static unsigned getHashValue(const LookupKey
&Val
) {
598 return hash_combine(Val
.first
, Val
.second
.getHash());
601 static unsigned getHashValue(const LookupKeyHashed
&Val
) {
605 static bool isEqual(const LookupKey
&LHS
, const ConstantClass
*RHS
) {
606 if (RHS
== getEmptyKey() || RHS
== getTombstoneKey())
608 if (LHS
.first
!= RHS
->getType())
610 return LHS
.second
== RHS
;
613 static bool isEqual(const LookupKeyHashed
&LHS
, const ConstantClass
*RHS
) {
614 return isEqual(LHS
.second
, RHS
);
619 using MapTy
= DenseSet
<ConstantClass
*, MapInfo
>;
625 typename
MapTy::iterator
begin() { return Map
.begin(); }
626 typename
MapTy::iterator
end() { return Map
.end(); }
628 void freeConstants() {
630 delete I
; // Asserts that use_empty().
634 ConstantClass
*create(TypeClass
*Ty
, ValType V
, LookupKeyHashed
&HashKey
) {
635 ConstantClass
*Result
= V
.create(Ty
);
637 assert(Result
->getType() == Ty
&& "Type specified is not correct!");
638 Map
.insert_as(Result
, HashKey
);
644 /// Return the specified constant from the map, creating it if necessary.
645 ConstantClass
*getOrCreate(TypeClass
*Ty
, ValType V
) {
646 LookupKey
Key(Ty
, V
);
647 /// Hash once, and reuse it for the lookup and the insertion if needed.
648 LookupKeyHashed
Lookup(MapInfo::getHashValue(Key
), Key
);
650 ConstantClass
*Result
= nullptr;
652 auto I
= Map
.find_as(Lookup
);
654 Result
= create(Ty
, V
, Lookup
);
657 assert(Result
&& "Unexpected nullptr");
662 /// Remove this constant from the map
663 void remove(ConstantClass
*CP
) {
664 typename
MapTy::iterator I
= Map
.find(CP
);
665 assert(I
!= Map
.end() && "Constant not found in constant table!");
666 assert(*I
== CP
&& "Didn't find correct element?");
670 ConstantClass
*replaceOperandsInPlace(ArrayRef
<Constant
*> Operands
,
671 ConstantClass
*CP
, Value
*From
,
672 Constant
*To
, unsigned NumUpdated
= 0,
673 unsigned OperandNo
= ~0u) {
674 LookupKey
Key(CP
->getType(), ValType(Operands
, CP
));
675 /// Hash once, and reuse it for the lookup and the insertion if needed.
676 LookupKeyHashed
Lookup(MapInfo::getHashValue(Key
), Key
);
678 auto I
= Map
.find_as(Lookup
);
682 // Update to the new value. Optimize for the case when we have a single
683 // operand that we're changing, but handle bulk updates efficiently.
685 if (NumUpdated
== 1) {
686 assert(OperandNo
< CP
->getNumOperands() && "Invalid index");
687 assert(CP
->getOperand(OperandNo
) != To
&& "I didn't contain From!");
688 CP
->setOperand(OperandNo
, To
);
690 for (unsigned I
= 0, E
= CP
->getNumOperands(); I
!= E
; ++I
)
691 if (CP
->getOperand(I
) == From
)
692 CP
->setOperand(I
, To
);
694 Map
.insert_as(CP
, Lookup
);
699 LLVM_DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n");
703 } // end namespace llvm
705 #endif // LLVM_LIB_IR_CONSTANTSCONTEXT_H