LLVM API Documentation
00001 //===-- ConstantsContext.h - Constants-related Context Interals -----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines various helper methods and classes used by 00011 // LLVMContextImpl for creating and managing constants. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_LIB_IR_CONSTANTSCONTEXT_H 00016 #define LLVM_LIB_IR_CONSTANTSCONTEXT_H 00017 00018 #include "llvm/ADT/DenseMap.h" 00019 #include "llvm/ADT/Hashing.h" 00020 #include "llvm/IR/InlineAsm.h" 00021 #include "llvm/IR/Instructions.h" 00022 #include "llvm/IR/Operator.h" 00023 #include "llvm/Support/Debug.h" 00024 #include "llvm/Support/ErrorHandling.h" 00025 #include "llvm/Support/raw_ostream.h" 00026 #include <map> 00027 #include <tuple> 00028 00029 #define DEBUG_TYPE "ir" 00030 00031 namespace llvm { 00032 00033 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used 00034 /// behind the scenes to implement unary constant exprs. 00035 class UnaryConstantExpr : public ConstantExpr { 00036 void anchor() override; 00037 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00038 public: 00039 // allocate space for exactly one operand 00040 void *operator new(size_t s) { 00041 return User::operator new(s, 1); 00042 } 00043 UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty) 00044 : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { 00045 Op<0>() = C; 00046 } 00047 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00048 }; 00049 00050 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used 00051 /// behind the scenes to implement binary constant exprs. 00052 class BinaryConstantExpr : public ConstantExpr { 00053 void anchor() override; 00054 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00055 public: 00056 // allocate space for exactly two operands 00057 void *operator new(size_t s) { 00058 return User::operator new(s, 2); 00059 } 00060 BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2, 00061 unsigned Flags) 00062 : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) { 00063 Op<0>() = C1; 00064 Op<1>() = C2; 00065 SubclassOptionalData = Flags; 00066 } 00067 /// Transparently provide more efficient getOperand methods. 00068 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00069 }; 00070 00071 /// SelectConstantExpr - This class is private to Constants.cpp, and is used 00072 /// behind the scenes to implement select constant exprs. 00073 class SelectConstantExpr : public ConstantExpr { 00074 void anchor() override; 00075 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00076 public: 00077 // allocate space for exactly three operands 00078 void *operator new(size_t s) { 00079 return User::operator new(s, 3); 00080 } 00081 SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) 00082 : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { 00083 Op<0>() = C1; 00084 Op<1>() = C2; 00085 Op<2>() = C3; 00086 } 00087 /// Transparently provide more efficient getOperand methods. 00088 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00089 }; 00090 00091 /// ExtractElementConstantExpr - This class is private to 00092 /// Constants.cpp, and is used behind the scenes to implement 00093 /// extractelement constant exprs. 00094 class ExtractElementConstantExpr : public ConstantExpr { 00095 void anchor() override; 00096 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00097 public: 00098 // allocate space for exactly two operands 00099 void *operator new(size_t s) { 00100 return User::operator new(s, 2); 00101 } 00102 ExtractElementConstantExpr(Constant *C1, Constant *C2) 00103 : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), 00104 Instruction::ExtractElement, &Op<0>(), 2) { 00105 Op<0>() = C1; 00106 Op<1>() = C2; 00107 } 00108 /// Transparently provide more efficient getOperand methods. 00109 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00110 }; 00111 00112 /// InsertElementConstantExpr - This class is private to 00113 /// Constants.cpp, and is used behind the scenes to implement 00114 /// insertelement constant exprs. 00115 class InsertElementConstantExpr : public ConstantExpr { 00116 void anchor() override; 00117 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00118 public: 00119 // allocate space for exactly three operands 00120 void *operator new(size_t s) { 00121 return User::operator new(s, 3); 00122 } 00123 InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) 00124 : ConstantExpr(C1->getType(), Instruction::InsertElement, 00125 &Op<0>(), 3) { 00126 Op<0>() = C1; 00127 Op<1>() = C2; 00128 Op<2>() = C3; 00129 } 00130 /// Transparently provide more efficient getOperand methods. 00131 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00132 }; 00133 00134 /// ShuffleVectorConstantExpr - This class is private to 00135 /// Constants.cpp, and is used behind the scenes to implement 00136 /// shufflevector constant exprs. 00137 class ShuffleVectorConstantExpr : public ConstantExpr { 00138 void anchor() override; 00139 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00140 public: 00141 // allocate space for exactly three operands 00142 void *operator new(size_t s) { 00143 return User::operator new(s, 3); 00144 } 00145 ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) 00146 : ConstantExpr(VectorType::get( 00147 cast<VectorType>(C1->getType())->getElementType(), 00148 cast<VectorType>(C3->getType())->getNumElements()), 00149 Instruction::ShuffleVector, 00150 &Op<0>(), 3) { 00151 Op<0>() = C1; 00152 Op<1>() = C2; 00153 Op<2>() = C3; 00154 } 00155 /// Transparently provide more efficient getOperand methods. 00156 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00157 }; 00158 00159 /// ExtractValueConstantExpr - This class is private to 00160 /// Constants.cpp, and is used behind the scenes to implement 00161 /// extractvalue constant exprs. 00162 class ExtractValueConstantExpr : public ConstantExpr { 00163 void anchor() override; 00164 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00165 public: 00166 // allocate space for exactly one operand 00167 void *operator new(size_t s) { 00168 return User::operator new(s, 1); 00169 } 00170 ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList, 00171 Type *DestTy) 00172 : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), 00173 Indices(IdxList.begin(), IdxList.end()) { 00174 Op<0>() = Agg; 00175 } 00176 00177 /// Indices - These identify which value to extract. 00178 const SmallVector<unsigned, 4> Indices; 00179 00180 /// Transparently provide more efficient getOperand methods. 00181 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00182 }; 00183 00184 /// InsertValueConstantExpr - This class is private to 00185 /// Constants.cpp, and is used behind the scenes to implement 00186 /// insertvalue constant exprs. 00187 class InsertValueConstantExpr : public ConstantExpr { 00188 void anchor() override; 00189 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00190 public: 00191 // allocate space for exactly one operand 00192 void *operator new(size_t s) { 00193 return User::operator new(s, 2); 00194 } 00195 InsertValueConstantExpr(Constant *Agg, Constant *Val, 00196 ArrayRef<unsigned> IdxList, Type *DestTy) 00197 : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2), 00198 Indices(IdxList.begin(), IdxList.end()) { 00199 Op<0>() = Agg; 00200 Op<1>() = Val; 00201 } 00202 00203 /// Indices - These identify the position for the insertion. 00204 const SmallVector<unsigned, 4> Indices; 00205 00206 /// Transparently provide more efficient getOperand methods. 00207 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00208 }; 00209 00210 00211 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is 00212 /// used behind the scenes to implement getelementpr constant exprs. 00213 class GetElementPtrConstantExpr : public ConstantExpr { 00214 void anchor() override; 00215 GetElementPtrConstantExpr(Constant *C, ArrayRef<Constant*> IdxList, 00216 Type *DestTy); 00217 public: 00218 static GetElementPtrConstantExpr *Create(Constant *C, 00219 ArrayRef<Constant*> IdxList, 00220 Type *DestTy, 00221 unsigned Flags) { 00222 GetElementPtrConstantExpr *Result = 00223 new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); 00224 Result->SubclassOptionalData = Flags; 00225 return Result; 00226 } 00227 /// Transparently provide more efficient getOperand methods. 00228 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00229 }; 00230 00231 // CompareConstantExpr - This class is private to Constants.cpp, and is used 00232 // behind the scenes to implement ICmp and FCmp constant expressions. This is 00233 // needed in order to store the predicate value for these instructions. 00234 class CompareConstantExpr : public ConstantExpr { 00235 void anchor() override; 00236 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00237 public: 00238 // allocate space for exactly two operands 00239 void *operator new(size_t s) { 00240 return User::operator new(s, 2); 00241 } 00242 unsigned short predicate; 00243 CompareConstantExpr(Type *ty, Instruction::OtherOps opc, 00244 unsigned short pred, Constant* LHS, Constant* RHS) 00245 : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { 00246 Op<0>() = LHS; 00247 Op<1>() = RHS; 00248 } 00249 /// Transparently provide more efficient getOperand methods. 00250 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00251 }; 00252 00253 template <> 00254 struct OperandTraits<UnaryConstantExpr> : 00255 public FixedNumOperandTraits<UnaryConstantExpr, 1> { 00256 }; 00257 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) 00258 00259 template <> 00260 struct OperandTraits<BinaryConstantExpr> : 00261 public FixedNumOperandTraits<BinaryConstantExpr, 2> { 00262 }; 00263 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) 00264 00265 template <> 00266 struct OperandTraits<SelectConstantExpr> : 00267 public FixedNumOperandTraits<SelectConstantExpr, 3> { 00268 }; 00269 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) 00270 00271 template <> 00272 struct OperandTraits<ExtractElementConstantExpr> : 00273 public FixedNumOperandTraits<ExtractElementConstantExpr, 2> { 00274 }; 00275 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) 00276 00277 template <> 00278 struct OperandTraits<InsertElementConstantExpr> : 00279 public FixedNumOperandTraits<InsertElementConstantExpr, 3> { 00280 }; 00281 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) 00282 00283 template <> 00284 struct OperandTraits<ShuffleVectorConstantExpr> : 00285 public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> { 00286 }; 00287 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) 00288 00289 template <> 00290 struct OperandTraits<ExtractValueConstantExpr> : 00291 public FixedNumOperandTraits<ExtractValueConstantExpr, 1> { 00292 }; 00293 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) 00294 00295 template <> 00296 struct OperandTraits<InsertValueConstantExpr> : 00297 public FixedNumOperandTraits<InsertValueConstantExpr, 2> { 00298 }; 00299 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) 00300 00301 template <> 00302 struct OperandTraits<GetElementPtrConstantExpr> : 00303 public VariadicOperandTraits<GetElementPtrConstantExpr, 1> { 00304 }; 00305 00306 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) 00307 00308 00309 template <> 00310 struct OperandTraits<CompareConstantExpr> : 00311 public FixedNumOperandTraits<CompareConstantExpr, 2> { 00312 }; 00313 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) 00314 00315 template <class ConstantClass> struct ConstantAggrKeyType; 00316 struct InlineAsmKeyType; 00317 struct ConstantExprKeyType; 00318 00319 template <class ConstantClass> struct ConstantInfo; 00320 template <> struct ConstantInfo<ConstantExpr> { 00321 typedef ConstantExprKeyType ValType; 00322 typedef Type TypeClass; 00323 }; 00324 template <> struct ConstantInfo<InlineAsm> { 00325 typedef InlineAsmKeyType ValType; 00326 typedef PointerType TypeClass; 00327 }; 00328 template <> struct ConstantInfo<ConstantArray> { 00329 typedef ConstantAggrKeyType<ConstantArray> ValType; 00330 typedef ArrayType TypeClass; 00331 }; 00332 template <> struct ConstantInfo<ConstantStruct> { 00333 typedef ConstantAggrKeyType<ConstantStruct> ValType; 00334 typedef StructType TypeClass; 00335 }; 00336 template <> struct ConstantInfo<ConstantVector> { 00337 typedef ConstantAggrKeyType<ConstantVector> ValType; 00338 typedef VectorType TypeClass; 00339 }; 00340 00341 template <class ConstantClass> struct ConstantAggrKeyType { 00342 ArrayRef<Constant *> Operands; 00343 ConstantAggrKeyType(ArrayRef<Constant *> Operands) : Operands(Operands) {} 00344 ConstantAggrKeyType(ArrayRef<Constant *> Operands, const ConstantClass *) 00345 : Operands(Operands) {} 00346 ConstantAggrKeyType(const ConstantClass *C, 00347 SmallVectorImpl<Constant *> &Storage) { 00348 assert(Storage.empty() && "Expected empty storage"); 00349 for (unsigned I = 0, E = C->getNumOperands(); I != E; ++I) 00350 Storage.push_back(C->getOperand(I)); 00351 Operands = Storage; 00352 } 00353 00354 bool operator==(const ConstantAggrKeyType &X) const { 00355 return Operands == X.Operands; 00356 } 00357 bool operator==(const ConstantClass *C) const { 00358 if (Operands.size() != C->getNumOperands()) 00359 return false; 00360 for (unsigned I = 0, E = Operands.size(); I != E; ++I) 00361 if (Operands[I] != C->getOperand(I)) 00362 return false; 00363 return true; 00364 } 00365 unsigned getHash() const { 00366 return hash_combine_range(Operands.begin(), Operands.end()); 00367 } 00368 00369 typedef typename ConstantInfo<ConstantClass>::TypeClass TypeClass; 00370 ConstantClass *create(TypeClass *Ty) const { 00371 return new (Operands.size()) ConstantClass(Ty, Operands); 00372 } 00373 }; 00374 00375 struct InlineAsmKeyType { 00376 StringRef AsmString; 00377 StringRef Constraints; 00378 bool HasSideEffects; 00379 bool IsAlignStack; 00380 InlineAsm::AsmDialect AsmDialect; 00381 00382 InlineAsmKeyType(StringRef AsmString, StringRef Constraints, 00383 bool HasSideEffects, bool IsAlignStack, 00384 InlineAsm::AsmDialect AsmDialect) 00385 : AsmString(AsmString), Constraints(Constraints), 00386 HasSideEffects(HasSideEffects), IsAlignStack(IsAlignStack), 00387 AsmDialect(AsmDialect) {} 00388 InlineAsmKeyType(const InlineAsm *Asm, SmallVectorImpl<Constant *> &) 00389 : AsmString(Asm->getAsmString()), Constraints(Asm->getConstraintString()), 00390 HasSideEffects(Asm->hasSideEffects()), 00391 IsAlignStack(Asm->isAlignStack()), AsmDialect(Asm->getDialect()) {} 00392 00393 bool operator==(const InlineAsmKeyType &X) const { 00394 return HasSideEffects == X.HasSideEffects && 00395 IsAlignStack == X.IsAlignStack && AsmDialect == X.AsmDialect && 00396 AsmString == X.AsmString && Constraints == X.Constraints; 00397 } 00398 bool operator==(const InlineAsm *Asm) const { 00399 return HasSideEffects == Asm->hasSideEffects() && 00400 IsAlignStack == Asm->isAlignStack() && 00401 AsmDialect == Asm->getDialect() && 00402 AsmString == Asm->getAsmString() && 00403 Constraints == Asm->getConstraintString(); 00404 } 00405 unsigned getHash() const { 00406 return hash_combine(AsmString, Constraints, HasSideEffects, IsAlignStack, 00407 AsmDialect); 00408 } 00409 00410 typedef ConstantInfo<InlineAsm>::TypeClass TypeClass; 00411 InlineAsm *create(TypeClass *Ty) const { 00412 return new InlineAsm(Ty, AsmString, Constraints, HasSideEffects, 00413 IsAlignStack, AsmDialect); 00414 } 00415 }; 00416 00417 struct ConstantExprKeyType { 00418 uint8_t Opcode; 00419 uint8_t SubclassOptionalData; 00420 uint16_t SubclassData; 00421 ArrayRef<Constant *> Ops; 00422 ArrayRef<unsigned> Indexes; 00423 00424 ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops, 00425 unsigned short SubclassData = 0, 00426 unsigned short SubclassOptionalData = 0, 00427 ArrayRef<unsigned> Indexes = None) 00428 : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData), 00429 SubclassData(SubclassData), Ops(Ops), Indexes(Indexes) {} 00430 ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE) 00431 : Opcode(CE->getOpcode()), 00432 SubclassOptionalData(CE->getRawSubclassOptionalData()), 00433 SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands), 00434 Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {} 00435 ConstantExprKeyType(const ConstantExpr *CE, 00436 SmallVectorImpl<Constant *> &Storage) 00437 : Opcode(CE->getOpcode()), 00438 SubclassOptionalData(CE->getRawSubclassOptionalData()), 00439 SubclassData(CE->isCompare() ? CE->getPredicate() : 0), 00440 Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) { 00441 assert(Storage.empty() && "Expected empty storage"); 00442 for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I) 00443 Storage.push_back(CE->getOperand(I)); 00444 Ops = Storage; 00445 } 00446 00447 bool operator==(const ConstantExprKeyType &X) const { 00448 return Opcode == X.Opcode && SubclassData == X.SubclassData && 00449 SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops && 00450 Indexes == X.Indexes; 00451 } 00452 00453 bool operator==(const ConstantExpr *CE) const { 00454 if (Opcode != CE->getOpcode()) 00455 return false; 00456 if (SubclassOptionalData != CE->getRawSubclassOptionalData()) 00457 return false; 00458 if (Ops.size() != CE->getNumOperands()) 00459 return false; 00460 if (SubclassData != (CE->isCompare() ? CE->getPredicate() : 0)) 00461 return false; 00462 for (unsigned I = 0, E = Ops.size(); I != E; ++I) 00463 if (Ops[I] != CE->getOperand(I)) 00464 return false; 00465 if (Indexes != (CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>())) 00466 return false; 00467 return true; 00468 } 00469 00470 unsigned getHash() const { 00471 return hash_combine(Opcode, SubclassOptionalData, SubclassData, 00472 hash_combine_range(Ops.begin(), Ops.end()), 00473 hash_combine_range(Indexes.begin(), Indexes.end())); 00474 } 00475 00476 typedef ConstantInfo<ConstantExpr>::TypeClass TypeClass; 00477 ConstantExpr *create(TypeClass *Ty) const { 00478 switch (Opcode) { 00479 default: 00480 if (Instruction::isCast(Opcode)) 00481 return new UnaryConstantExpr(Opcode, Ops[0], Ty); 00482 if ((Opcode >= Instruction::BinaryOpsBegin && 00483 Opcode < Instruction::BinaryOpsEnd)) 00484 return new BinaryConstantExpr(Opcode, Ops[0], Ops[1], 00485 SubclassOptionalData); 00486 llvm_unreachable("Invalid ConstantExpr!"); 00487 case Instruction::Select: 00488 return new SelectConstantExpr(Ops[0], Ops[1], Ops[2]); 00489 case Instruction::ExtractElement: 00490 return new ExtractElementConstantExpr(Ops[0], Ops[1]); 00491 case Instruction::InsertElement: 00492 return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]); 00493 case Instruction::ShuffleVector: 00494 return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]); 00495 case Instruction::InsertValue: 00496 return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty); 00497 case Instruction::ExtractValue: 00498 return new ExtractValueConstantExpr(Ops[0], Indexes, Ty); 00499 case Instruction::GetElementPtr: 00500 return GetElementPtrConstantExpr::Create(Ops[0], Ops.slice(1), Ty, 00501 SubclassOptionalData); 00502 case Instruction::ICmp: 00503 return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData, 00504 Ops[0], Ops[1]); 00505 case Instruction::FCmp: 00506 return new CompareConstantExpr(Ty, Instruction::FCmp, SubclassData, 00507 Ops[0], Ops[1]); 00508 } 00509 } 00510 }; 00511 00512 template <class ConstantClass> class ConstantUniqueMap { 00513 public: 00514 typedef typename ConstantInfo<ConstantClass>::ValType ValType; 00515 typedef typename ConstantInfo<ConstantClass>::TypeClass TypeClass; 00516 typedef std::pair<TypeClass *, ValType> LookupKey; 00517 00518 private: 00519 struct MapInfo { 00520 typedef DenseMapInfo<ConstantClass *> ConstantClassInfo; 00521 static inline ConstantClass *getEmptyKey() { 00522 return ConstantClassInfo::getEmptyKey(); 00523 } 00524 static inline ConstantClass *getTombstoneKey() { 00525 return ConstantClassInfo::getTombstoneKey(); 00526 } 00527 static unsigned getHashValue(const ConstantClass *CP) { 00528 SmallVector<Constant *, 8> Storage; 00529 return getHashValue(LookupKey(CP->getType(), ValType(CP, Storage))); 00530 } 00531 static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) { 00532 return LHS == RHS; 00533 } 00534 static unsigned getHashValue(const LookupKey &Val) { 00535 return hash_combine(Val.first, Val.second.getHash()); 00536 } 00537 static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) { 00538 if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 00539 return false; 00540 if (LHS.first != RHS->getType()) 00541 return false; 00542 return LHS.second == RHS; 00543 } 00544 }; 00545 00546 public: 00547 typedef DenseMap<ConstantClass *, char, MapInfo> MapTy; 00548 00549 private: 00550 MapTy Map; 00551 00552 public: 00553 typename MapTy::iterator map_begin() { return Map.begin(); } 00554 typename MapTy::iterator map_end() { return Map.end(); } 00555 00556 void freeConstants() { 00557 for (auto &I : Map) 00558 // Asserts that use_empty(). 00559 delete I.first; 00560 } 00561 00562 private: 00563 ConstantClass *create(TypeClass *Ty, ValType V) { 00564 ConstantClass *Result = V.create(Ty); 00565 00566 assert(Result->getType() == Ty && "Type specified is not correct!"); 00567 insert(Result); 00568 00569 return Result; 00570 } 00571 00572 public: 00573 /// Return the specified constant from the map, creating it if necessary. 00574 ConstantClass *getOrCreate(TypeClass *Ty, ValType V) { 00575 LookupKey Lookup(Ty, V); 00576 ConstantClass *Result = nullptr; 00577 00578 auto I = find(Lookup); 00579 if (I == Map.end()) 00580 Result = create(Ty, V); 00581 else 00582 Result = I->first; 00583 assert(Result && "Unexpected nullptr"); 00584 00585 return Result; 00586 } 00587 00588 /// Find the constant by lookup key. 00589 typename MapTy::iterator find(LookupKey Lookup) { 00590 return Map.find_as(Lookup); 00591 } 00592 00593 /// Insert the constant into its proper slot. 00594 void insert(ConstantClass *CP) { Map[CP] = '\0'; } 00595 00596 /// Remove this constant from the map 00597 void remove(ConstantClass *CP) { 00598 typename MapTy::iterator I = Map.find(CP); 00599 assert(I != Map.end() && "Constant not found in constant table!"); 00600 assert(I->first == CP && "Didn't find correct element?"); 00601 Map.erase(I); 00602 } 00603 00604 ConstantClass *replaceOperandsInPlace(ArrayRef<Constant *> Operands, 00605 ConstantClass *CP, Value *From, 00606 Constant *To, unsigned NumUpdated = 0, 00607 unsigned OperandNo = ~0u) { 00608 LookupKey Lookup(CP->getType(), ValType(Operands, CP)); 00609 auto I = find(Lookup); 00610 if (I != Map.end()) 00611 return I->first; 00612 00613 // Update to the new value. Optimize for the case when we have a single 00614 // operand that we're changing, but handle bulk updates efficiently. 00615 remove(CP); 00616 if (NumUpdated == 1) { 00617 assert(OperandNo < CP->getNumOperands() && "Invalid index"); 00618 assert(CP->getOperand(OperandNo) != To && "I didn't contain From!"); 00619 CP->setOperand(OperandNo, To); 00620 } else { 00621 for (unsigned I = 0, E = CP->getNumOperands(); I != E; ++I) 00622 if (CP->getOperand(I) == From) 00623 CP->setOperand(I, To); 00624 } 00625 insert(CP); 00626 return nullptr; 00627 } 00628 00629 void dump() const { DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); } 00630 }; 00631 00632 } // end namespace llvm 00633 00634 #endif