1 //===---------------- ConstantsContext.h - Implementation ------*- 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_CONSTANTSCONTEXT_H
16 #define LLVM_CONSTANTSCONTEXT_H
18 #include "llvm/Instructions.h"
19 #include "llvm/Metadata.h"
20 #include "llvm/Operator.h"
21 #include "llvm/Support/Debug.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/System/Mutex.h"
24 #include "llvm/System/RWMutex.h"
28 template<class ValType
>
29 struct ConstantTraits
;
31 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used
32 /// behind the scenes to implement unary constant exprs.
33 class UnaryConstantExpr
: public ConstantExpr
{
34 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
36 // allocate space for exactly one operand
37 void *operator new(size_t s
) {
38 return User::operator new(s
, 1);
40 UnaryConstantExpr(unsigned Opcode
, Constant
*C
, const Type
*Ty
)
41 : ConstantExpr(Ty
, Opcode
, &Op
<0>(), 1) {
44 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
47 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used
48 /// behind the scenes to implement binary constant exprs.
49 class BinaryConstantExpr
: public ConstantExpr
{
50 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
52 // allocate space for exactly two operands
53 void *operator new(size_t s
) {
54 return User::operator new(s
, 2);
56 BinaryConstantExpr(unsigned Opcode
, Constant
*C1
, Constant
*C2
)
57 : ConstantExpr(C1
->getType(), Opcode
, &Op
<0>(), 2) {
61 /// Transparently provide more efficient getOperand methods.
62 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
65 /// SelectConstantExpr - This class is private to Constants.cpp, and is used
66 /// behind the scenes to implement select constant exprs.
67 class SelectConstantExpr
: public ConstantExpr
{
68 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
70 // allocate space for exactly three operands
71 void *operator new(size_t s
) {
72 return User::operator new(s
, 3);
74 SelectConstantExpr(Constant
*C1
, Constant
*C2
, Constant
*C3
)
75 : ConstantExpr(C2
->getType(), Instruction::Select
, &Op
<0>(), 3) {
80 /// Transparently provide more efficient getOperand methods.
81 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
84 /// ExtractElementConstantExpr - This class is private to
85 /// Constants.cpp, and is used behind the scenes to implement
86 /// extractelement constant exprs.
87 class ExtractElementConstantExpr
: public ConstantExpr
{
88 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
90 // allocate space for exactly two operands
91 void *operator new(size_t s
) {
92 return User::operator new(s
, 2);
94 ExtractElementConstantExpr(Constant
*C1
, Constant
*C2
)
95 : ConstantExpr(cast
<VectorType
>(C1
->getType())->getElementType(),
96 Instruction::ExtractElement
, &Op
<0>(), 2) {
100 /// Transparently provide more efficient getOperand methods.
101 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
104 /// InsertElementConstantExpr - This class is private to
105 /// Constants.cpp, and is used behind the scenes to implement
106 /// insertelement constant exprs.
107 class InsertElementConstantExpr
: public ConstantExpr
{
108 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
110 // allocate space for exactly three operands
111 void *operator new(size_t s
) {
112 return User::operator new(s
, 3);
114 InsertElementConstantExpr(Constant
*C1
, Constant
*C2
, Constant
*C3
)
115 : ConstantExpr(C1
->getType(), Instruction::InsertElement
,
121 /// Transparently provide more efficient getOperand methods.
122 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
125 /// ShuffleVectorConstantExpr - This class is private to
126 /// Constants.cpp, and is used behind the scenes to implement
127 /// shufflevector constant exprs.
128 class ShuffleVectorConstantExpr
: public ConstantExpr
{
129 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
131 // allocate space for exactly three operands
132 void *operator new(size_t s
) {
133 return User::operator new(s
, 3);
135 ShuffleVectorConstantExpr(Constant
*C1
, Constant
*C2
, Constant
*C3
)
136 : ConstantExpr(VectorType::get(
137 cast
<VectorType
>(C1
->getType())->getElementType(),
138 cast
<VectorType
>(C3
->getType())->getNumElements()),
139 Instruction::ShuffleVector
,
145 /// Transparently provide more efficient getOperand methods.
146 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
149 /// ExtractValueConstantExpr - This class is private to
150 /// Constants.cpp, and is used behind the scenes to implement
151 /// extractvalue constant exprs.
152 class ExtractValueConstantExpr
: public ConstantExpr
{
153 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
155 // allocate space for exactly one operand
156 void *operator new(size_t s
) {
157 return User::operator new(s
, 1);
159 ExtractValueConstantExpr(Constant
*Agg
,
160 const SmallVector
<unsigned, 4> &IdxList
,
162 : ConstantExpr(DestTy
, Instruction::ExtractValue
, &Op
<0>(), 1),
167 /// Indices - These identify which value to extract.
168 const SmallVector
<unsigned, 4> Indices
;
170 /// Transparently provide more efficient getOperand methods.
171 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
174 /// InsertValueConstantExpr - This class is private to
175 /// Constants.cpp, and is used behind the scenes to implement
176 /// insertvalue constant exprs.
177 class InsertValueConstantExpr
: public ConstantExpr
{
178 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
180 // allocate space for exactly one operand
181 void *operator new(size_t s
) {
182 return User::operator new(s
, 2);
184 InsertValueConstantExpr(Constant
*Agg
, Constant
*Val
,
185 const SmallVector
<unsigned, 4> &IdxList
,
187 : ConstantExpr(DestTy
, Instruction::InsertValue
, &Op
<0>(), 2),
193 /// Indices - These identify the position for the insertion.
194 const SmallVector
<unsigned, 4> Indices
;
196 /// Transparently provide more efficient getOperand methods.
197 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
201 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is
202 /// used behind the scenes to implement getelementpr constant exprs.
203 class GetElementPtrConstantExpr
: public ConstantExpr
{
204 GetElementPtrConstantExpr(Constant
*C
, const std::vector
<Constant
*> &IdxList
,
207 static GetElementPtrConstantExpr
*Create(Constant
*C
,
208 const std::vector
<Constant
*>&IdxList
,
209 const Type
*DestTy
) {
211 new(IdxList
.size() + 1) GetElementPtrConstantExpr(C
, IdxList
, DestTy
);
213 /// Transparently provide more efficient getOperand methods.
214 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
217 // CompareConstantExpr - This class is private to Constants.cpp, and is used
218 // behind the scenes to implement ICmp and FCmp constant expressions. This is
219 // needed in order to store the predicate value for these instructions.
220 struct CompareConstantExpr
: public ConstantExpr
{
221 void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
222 // allocate space for exactly two operands
223 void *operator new(size_t s
) {
224 return User::operator new(s
, 2);
226 unsigned short predicate
;
227 CompareConstantExpr(const Type
*ty
, Instruction::OtherOps opc
,
228 unsigned short pred
, Constant
* LHS
, Constant
* RHS
)
229 : ConstantExpr(ty
, opc
, &Op
<0>(), 2), predicate(pred
) {
233 /// Transparently provide more efficient getOperand methods.
234 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
238 struct OperandTraits
<UnaryConstantExpr
> : FixedNumOperandTraits
<1> {
240 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr
, Value
)
243 struct OperandTraits
<BinaryConstantExpr
> : FixedNumOperandTraits
<2> {
245 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr
, Value
)
248 struct OperandTraits
<SelectConstantExpr
> : FixedNumOperandTraits
<3> {
250 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr
, Value
)
253 struct OperandTraits
<ExtractElementConstantExpr
> : FixedNumOperandTraits
<2> {
255 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr
, Value
)
258 struct OperandTraits
<InsertElementConstantExpr
> : FixedNumOperandTraits
<3> {
260 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr
, Value
)
263 struct OperandTraits
<ShuffleVectorConstantExpr
> : FixedNumOperandTraits
<3> {
265 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr
, Value
)
268 struct OperandTraits
<ExtractValueConstantExpr
> : FixedNumOperandTraits
<1> {
270 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr
, Value
)
273 struct OperandTraits
<InsertValueConstantExpr
> : FixedNumOperandTraits
<2> {
275 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr
, Value
)
278 struct OperandTraits
<GetElementPtrConstantExpr
> : VariadicOperandTraits
<1> {
281 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr
, Value
)
285 struct OperandTraits
<CompareConstantExpr
> : FixedNumOperandTraits
<2> {
287 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr
, Value
)
289 struct ExprMapKeyType
{
290 typedef SmallVector
<unsigned, 4> IndexList
;
292 ExprMapKeyType(unsigned opc
,
293 const std::vector
<Constant
*> &ops
,
294 unsigned short pred
= 0,
295 const IndexList
&inds
= IndexList())
296 : opcode(opc
), predicate(pred
), operands(ops
), indices(inds
) {}
299 std::vector
<Constant
*> operands
;
301 bool operator==(const ExprMapKeyType
& that
) const {
302 return this->opcode
== that
.opcode
&&
303 this->predicate
== that
.predicate
&&
304 this->operands
== that
.operands
&&
305 this->indices
== that
.indices
;
307 bool operator<(const ExprMapKeyType
& that
) const {
308 return this->opcode
< that
.opcode
||
309 (this->opcode
== that
.opcode
&& this->predicate
< that
.predicate
) ||
310 (this->opcode
== that
.opcode
&& this->predicate
== that
.predicate
&&
311 this->operands
< that
.operands
) ||
312 (this->opcode
== that
.opcode
&& this->predicate
== that
.predicate
&&
313 this->operands
== that
.operands
&& this->indices
< that
.indices
);
316 bool operator!=(const ExprMapKeyType
& that
) const {
317 return !(*this == that
);
321 // The number of operands for each ConstantCreator::create method is
322 // determined by the ConstantTraits template.
323 // ConstantCreator - A class that is used to create constants by
324 // ValueMap*. This class should be partially specialized if there is
325 // something strange that needs to be done to interface to the ctor for the
328 template<typename T
, typename Alloc
>
329 struct ConstantTraits
< std::vector
<T
, Alloc
> > {
330 static unsigned uses(const std::vector
<T
, Alloc
>& v
) {
335 template<class ConstantClass
, class TypeClass
, class ValType
>
336 struct ConstantCreator
{
337 static ConstantClass
*create(const TypeClass
*Ty
, const ValType
&V
) {
338 return new(ConstantTraits
<ValType
>::uses(V
)) ConstantClass(Ty
, V
);
342 template<class ConstantClass
, class TypeClass
>
343 struct ConvertConstant
{
344 static void convert(ConstantClass
*OldC
, const TypeClass
*NewTy
) {
345 llvm_unreachable("This type cannot be converted!");
350 struct ConstantCreator
<ConstantExpr
, Type
, ExprMapKeyType
> {
351 static ConstantExpr
*create(const Type
*Ty
, const ExprMapKeyType
&V
,
352 unsigned short pred
= 0) {
353 if (Instruction::isCast(V
.opcode
))
354 return new UnaryConstantExpr(V
.opcode
, V
.operands
[0], Ty
);
355 if ((V
.opcode
>= Instruction::BinaryOpsBegin
&&
356 V
.opcode
< Instruction::BinaryOpsEnd
))
357 return new BinaryConstantExpr(V
.opcode
, V
.operands
[0], V
.operands
[1]);
358 if (V
.opcode
== Instruction::Select
)
359 return new SelectConstantExpr(V
.operands
[0], V
.operands
[1],
361 if (V
.opcode
== Instruction::ExtractElement
)
362 return new ExtractElementConstantExpr(V
.operands
[0], V
.operands
[1]);
363 if (V
.opcode
== Instruction::InsertElement
)
364 return new InsertElementConstantExpr(V
.operands
[0], V
.operands
[1],
366 if (V
.opcode
== Instruction::ShuffleVector
)
367 return new ShuffleVectorConstantExpr(V
.operands
[0], V
.operands
[1],
369 if (V
.opcode
== Instruction::InsertValue
)
370 return new InsertValueConstantExpr(V
.operands
[0], V
.operands
[1],
372 if (V
.opcode
== Instruction::ExtractValue
)
373 return new ExtractValueConstantExpr(V
.operands
[0], V
.indices
, Ty
);
374 if (V
.opcode
== Instruction::GetElementPtr
) {
375 std::vector
<Constant
*> IdxList(V
.operands
.begin()+1, V
.operands
.end());
376 return GetElementPtrConstantExpr::Create(V
.operands
[0], IdxList
, Ty
);
379 // The compare instructions are weird. We have to encode the predicate
380 // value and it is combined with the instruction opcode by multiplying
381 // the opcode by one hundred. We must decode this to get the predicate.
382 if (V
.opcode
== Instruction::ICmp
)
383 return new CompareConstantExpr(Ty
, Instruction::ICmp
, V
.predicate
,
384 V
.operands
[0], V
.operands
[1]);
385 if (V
.opcode
== Instruction::FCmp
)
386 return new CompareConstantExpr(Ty
, Instruction::FCmp
, V
.predicate
,
387 V
.operands
[0], V
.operands
[1]);
388 llvm_unreachable("Invalid ConstantExpr!");
394 struct ConvertConstant
<ConstantExpr
, Type
> {
395 static void convert(ConstantExpr
*OldC
, const Type
*NewTy
) {
397 switch (OldC
->getOpcode()) {
398 case Instruction::Trunc
:
399 case Instruction::ZExt
:
400 case Instruction::SExt
:
401 case Instruction::FPTrunc
:
402 case Instruction::FPExt
:
403 case Instruction::UIToFP
:
404 case Instruction::SIToFP
:
405 case Instruction::FPToUI
:
406 case Instruction::FPToSI
:
407 case Instruction::PtrToInt
:
408 case Instruction::IntToPtr
:
409 case Instruction::BitCast
:
410 New
= ConstantExpr::getCast(OldC
->getOpcode(), OldC
->getOperand(0),
413 case Instruction::Select
:
414 New
= ConstantExpr::getSelectTy(NewTy
, OldC
->getOperand(0),
416 OldC
->getOperand(2));
419 assert(OldC
->getOpcode() >= Instruction::BinaryOpsBegin
&&
420 OldC
->getOpcode() < Instruction::BinaryOpsEnd
);
421 New
= ConstantExpr::getTy(NewTy
, OldC
->getOpcode(), OldC
->getOperand(0),
422 OldC
->getOperand(1));
424 case Instruction::GetElementPtr
:
425 // Make everyone now use a constant of the new type...
426 std::vector
<Value
*> Idx(OldC
->op_begin()+1, OldC
->op_end());
427 New
= ConstantExpr::getGetElementPtrTy(NewTy
, OldC
->getOperand(0),
428 &Idx
[0], Idx
.size());
432 assert(New
!= OldC
&& "Didn't replace constant??");
433 OldC
->uncheckedReplaceAllUsesWith(New
);
434 OldC
->destroyConstant(); // This constant is now dead, destroy it.
438 // ConstantAggregateZero does not take extra "value" argument...
439 template<class ValType
>
440 struct ConstantCreator
<ConstantAggregateZero
, Type
, ValType
> {
441 static ConstantAggregateZero
*create(const Type
*Ty
, const ValType
&V
){
442 return new ConstantAggregateZero(Ty
);
447 struct ConstantCreator
<MDNode
, Type
, std::vector
<Value
*> > {
448 static MDNode
*create(const Type
* Ty
, const std::vector
<Value
*> &V
) {
449 return new MDNode(Ty
->getContext(), &V
[0], V
.size());
454 struct ConvertConstant
<ConstantVector
, VectorType
> {
455 static void convert(ConstantVector
*OldC
, const VectorType
*NewTy
) {
456 // Make everyone now use a constant of the new type...
457 std::vector
<Constant
*> C
;
458 for (unsigned i
= 0, e
= OldC
->getNumOperands(); i
!= e
; ++i
)
459 C
.push_back(cast
<Constant
>(OldC
->getOperand(i
)));
460 Constant
*New
= ConstantVector::get(NewTy
, C
);
461 assert(New
!= OldC
&& "Didn't replace constant??");
462 OldC
->uncheckedReplaceAllUsesWith(New
);
463 OldC
->destroyConstant(); // This constant is now dead, destroy it.
468 struct ConvertConstant
<ConstantAggregateZero
, Type
> {
469 static void convert(ConstantAggregateZero
*OldC
, const Type
*NewTy
) {
470 // Make everyone now use a constant of the new type...
471 Constant
*New
= ConstantAggregateZero::get(NewTy
);
472 assert(New
!= OldC
&& "Didn't replace constant??");
473 OldC
->uncheckedReplaceAllUsesWith(New
);
474 OldC
->destroyConstant(); // This constant is now dead, destroy it.
479 struct ConvertConstant
<ConstantArray
, ArrayType
> {
480 static void convert(ConstantArray
*OldC
, const ArrayType
*NewTy
) {
481 // Make everyone now use a constant of the new type...
482 std::vector
<Constant
*> C
;
483 for (unsigned i
= 0, e
= OldC
->getNumOperands(); i
!= e
; ++i
)
484 C
.push_back(cast
<Constant
>(OldC
->getOperand(i
)));
485 Constant
*New
= ConstantArray::get(NewTy
, C
);
486 assert(New
!= OldC
&& "Didn't replace constant??");
487 OldC
->uncheckedReplaceAllUsesWith(New
);
488 OldC
->destroyConstant(); // This constant is now dead, destroy it.
493 struct ConvertConstant
<ConstantStruct
, StructType
> {
494 static void convert(ConstantStruct
*OldC
, const StructType
*NewTy
) {
495 // Make everyone now use a constant of the new type...
496 std::vector
<Constant
*> C
;
497 for (unsigned i
= 0, e
= OldC
->getNumOperands(); i
!= e
; ++i
)
498 C
.push_back(cast
<Constant
>(OldC
->getOperand(i
)));
499 Constant
*New
= ConstantStruct::get(NewTy
, C
);
500 assert(New
!= OldC
&& "Didn't replace constant??");
502 OldC
->uncheckedReplaceAllUsesWith(New
);
503 OldC
->destroyConstant(); // This constant is now dead, destroy it.
507 // ConstantPointerNull does not take extra "value" argument...
508 template<class ValType
>
509 struct ConstantCreator
<ConstantPointerNull
, PointerType
, ValType
> {
510 static ConstantPointerNull
*create(const PointerType
*Ty
, const ValType
&V
){
511 return new ConstantPointerNull(Ty
);
516 struct ConvertConstant
<ConstantPointerNull
, PointerType
> {
517 static void convert(ConstantPointerNull
*OldC
, const PointerType
*NewTy
) {
518 // Make everyone now use a constant of the new type...
519 Constant
*New
= ConstantPointerNull::get(NewTy
);
520 assert(New
!= OldC
&& "Didn't replace constant??");
521 OldC
->uncheckedReplaceAllUsesWith(New
);
522 OldC
->destroyConstant(); // This constant is now dead, destroy it.
526 // UndefValue does not take extra "value" argument...
527 template<class ValType
>
528 struct ConstantCreator
<UndefValue
, Type
, ValType
> {
529 static UndefValue
*create(const Type
*Ty
, const ValType
&V
) {
530 return new UndefValue(Ty
);
535 struct ConvertConstant
<UndefValue
, Type
> {
536 static void convert(UndefValue
*OldC
, const Type
*NewTy
) {
537 // Make everyone now use a constant of the new type.
538 Constant
*New
= UndefValue::get(NewTy
);
539 assert(New
!= OldC
&& "Didn't replace constant??");
540 OldC
->uncheckedReplaceAllUsesWith(New
);
541 OldC
->destroyConstant(); // This constant is now dead, destroy it.
545 template<class ValType
, class TypeClass
, class ConstantClass
,
546 bool HasLargeKey
= false /*true for arrays and structs*/ >
547 class ValueMap
: public AbstractTypeUser
{
549 typedef std::pair
<const Type
*, ValType
> MapKey
;
550 typedef std::map
<MapKey
, Value
*> MapTy
;
551 typedef std::map
<Value
*, typename
MapTy::iterator
> InverseMapTy
;
552 typedef std::map
<const Type
*, typename
MapTy::iterator
> AbstractTypeMapTy
;
554 /// Map - This is the main map from the element descriptor to the Constants.
555 /// This is the primary way we avoid creating two of the same shape
559 /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping
560 /// from the constants to their element in Map. This is important for
561 /// removal of constants from the array, which would otherwise have to scan
562 /// through the map with very large keys.
563 InverseMapTy InverseMap
;
565 /// AbstractTypeMap - Map for abstract type constants.
567 AbstractTypeMapTy AbstractTypeMap
;
569 /// ValueMapLock - Mutex for this map.
570 sys::SmartMutex
<true> ValueMapLock
;
573 // NOTE: This function is not locked. It is the caller's responsibility
574 // to enforce proper synchronization.
575 typename
MapTy::iterator
map_begin() { return Map
.begin(); }
576 typename
MapTy::iterator
map_end() { return Map
.end(); }
578 /// InsertOrGetItem - Return an iterator for the specified element.
579 /// If the element exists in the map, the returned iterator points to the
580 /// entry and Exists=true. If not, the iterator points to the newly
581 /// inserted entry and returns Exists=false. Newly inserted entries have
582 /// I->second == 0, and should be filled in.
583 /// NOTE: This function is not locked. It is the caller's responsibility
584 // to enforce proper synchronization.
585 typename
MapTy::iterator
InsertOrGetItem(std::pair
<MapKey
, Constant
*>
588 std::pair
<typename
MapTy::iterator
, bool> IP
= Map
.insert(InsertVal
);
594 typename
MapTy::iterator
FindExistingElement(ConstantClass
*CP
) {
596 typename
InverseMapTy::iterator IMI
= InverseMap
.find(CP
);
597 assert(IMI
!= InverseMap
.end() && IMI
->second
!= Map
.end() &&
598 IMI
->second
->second
== CP
&&
599 "InverseMap corrupt!");
603 typename
MapTy::iterator I
=
604 Map
.find(MapKey(static_cast<const TypeClass
*>(CP
->getRawType()),
606 if (I
== Map
.end() || I
->second
!= CP
) {
607 // FIXME: This should not use a linear scan. If this gets to be a
608 // performance problem, someone should look at this.
609 for (I
= Map
.begin(); I
!= Map
.end() && I
->second
!= CP
; ++I
)
615 ConstantClass
* Create(const TypeClass
*Ty
, const ValType
&V
,
616 typename
MapTy::iterator I
) {
617 ConstantClass
* Result
=
618 ConstantCreator
<ConstantClass
,TypeClass
,ValType
>::create(Ty
, V
);
620 assert(Result
->getType() == Ty
&& "Type specified is not correct!");
621 I
= Map
.insert(I
, std::make_pair(MapKey(Ty
, V
), Result
));
623 if (HasLargeKey
) // Remember the reverse mapping if needed.
624 InverseMap
.insert(std::make_pair(Result
, I
));
626 // If the type of the constant is abstract, make sure that an entry
627 // exists for it in the AbstractTypeMap.
628 if (Ty
->isAbstract()) {
629 typename
AbstractTypeMapTy::iterator TI
=
630 AbstractTypeMap
.find(Ty
);
632 if (TI
== AbstractTypeMap
.end()) {
633 // Add ourselves to the ATU list of the type.
634 cast
<DerivedType
>(Ty
)->addAbstractTypeUser(this);
636 AbstractTypeMap
.insert(TI
, std::make_pair(Ty
, I
));
644 /// getOrCreate - Return the specified constant from the map, creating it if
646 ConstantClass
*getOrCreate(const TypeClass
*Ty
, const ValType
&V
) {
647 sys::SmartScopedLock
<true> Lock(ValueMapLock
);
648 MapKey
Lookup(Ty
, V
);
649 ConstantClass
* Result
= 0;
651 typename
MapTy::iterator I
= Map
.find(Lookup
);
654 Result
= static_cast<ConstantClass
*>(I
->second
);
657 // If no preexisting value, create one now...
658 Result
= Create(Ty
, V
, I
);
664 void remove(ConstantClass
*CP
) {
665 sys::SmartScopedLock
<true> Lock(ValueMapLock
);
666 typename
MapTy::iterator I
= FindExistingElement(CP
);
667 assert(I
!= Map
.end() && "Constant not found in constant table!");
668 assert(I
->second
== CP
&& "Didn't find correct element?");
670 if (HasLargeKey
) // Remember the reverse mapping if needed.
671 InverseMap
.erase(CP
);
673 // Now that we found the entry, make sure this isn't the entry that
674 // the AbstractTypeMap points to.
675 const TypeClass
*Ty
= static_cast<const TypeClass
*>(I
->first
.first
);
676 if (Ty
->isAbstract()) {
677 assert(AbstractTypeMap
.count(Ty
) &&
678 "Abstract type not in AbstractTypeMap?");
679 typename
MapTy::iterator
&ATMEntryIt
= AbstractTypeMap
[Ty
];
680 if (ATMEntryIt
== I
) {
681 // Yes, we are removing the representative entry for this type.
682 // See if there are any other entries of the same type.
683 typename
MapTy::iterator TmpIt
= ATMEntryIt
;
685 // First check the entry before this one...
686 if (TmpIt
!= Map
.begin()) {
688 if (TmpIt
->first
.first
!= Ty
) // Not the same type, move back...
692 // If we didn't find the same type, try to move forward...
693 if (TmpIt
== ATMEntryIt
) {
695 if (TmpIt
== Map
.end() || TmpIt
->first
.first
!= Ty
)
696 --TmpIt
; // No entry afterwards with the same type
699 // If there is another entry in the map of the same abstract type,
700 // update the AbstractTypeMap entry now.
701 if (TmpIt
!= ATMEntryIt
) {
704 // Otherwise, we are removing the last instance of this type
705 // from the table. Remove from the ATM, and from user list.
706 cast
<DerivedType
>(Ty
)->removeAbstractTypeUser(this);
707 AbstractTypeMap
.erase(Ty
);
716 /// MoveConstantToNewSlot - If we are about to change C to be the element
717 /// specified by I, update our internal data structures to reflect this
719 /// NOTE: This function is not locked. It is the responsibility of the
720 /// caller to enforce proper synchronization if using this method.
721 void MoveConstantToNewSlot(ConstantClass
*C
, typename
MapTy::iterator I
) {
722 // First, remove the old location of the specified constant in the map.
723 typename
MapTy::iterator OldI
= FindExistingElement(C
);
724 assert(OldI
!= Map
.end() && "Constant not found in constant table!");
725 assert(OldI
->second
== C
&& "Didn't find correct element?");
727 // If this constant is the representative element for its abstract type,
728 // update the AbstractTypeMap so that the representative element is I.
729 if (C
->getType()->isAbstract()) {
730 typename
AbstractTypeMapTy::iterator ATI
=
731 AbstractTypeMap
.find(C
->getType());
732 assert(ATI
!= AbstractTypeMap
.end() &&
733 "Abstract type not in AbstractTypeMap?");
734 if (ATI
->second
== OldI
)
738 // Remove the old entry from the map.
741 // Update the inverse map so that we know that this constant is now
742 // located at descriptor I.
744 assert(I
->second
== C
&& "Bad inversemap entry!");
749 void refineAbstractType(const DerivedType
*OldTy
, const Type
*NewTy
) {
750 sys::SmartScopedLock
<true> Lock(ValueMapLock
);
751 typename
AbstractTypeMapTy::iterator I
=
752 AbstractTypeMap
.find(cast
<Type
>(OldTy
));
754 assert(I
!= AbstractTypeMap
.end() &&
755 "Abstract type not in AbstractTypeMap?");
757 // Convert a constant at a time until the last one is gone. The last one
758 // leaving will remove() itself, causing the AbstractTypeMapEntry to be
759 // eliminated eventually.
761 ConvertConstant
<ConstantClass
, TypeClass
>::convert(
762 static_cast<ConstantClass
*>(I
->second
->second
),
763 cast
<TypeClass
>(NewTy
));
765 I
= AbstractTypeMap
.find(cast
<Type
>(OldTy
));
766 } while (I
!= AbstractTypeMap
.end());
769 // If the type became concrete without being refined to any other existing
770 // type, we just remove ourselves from the ATU list.
771 void typeBecameConcrete(const DerivedType
*AbsTy
) {
772 AbsTy
->removeAbstractTypeUser(this);
776 DOUT
<< "Constant.cpp: ValueMap\n";