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