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_CONSTANTSCONTEXT_H 00016 #define LLVM_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 00028 namespace llvm { 00029 template<class ValType> 00030 struct ConstantTraits; 00031 00032 /// UnaryConstantExpr - This class is private to Constants.cpp, and is used 00033 /// behind the scenes to implement unary constant exprs. 00034 class UnaryConstantExpr : public ConstantExpr { 00035 virtual void anchor(); 00036 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00037 public: 00038 // allocate space for exactly one operand 00039 void *operator new(size_t s) { 00040 return User::operator new(s, 1); 00041 } 00042 UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty) 00043 : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { 00044 Op<0>() = C; 00045 } 00046 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00047 }; 00048 00049 /// BinaryConstantExpr - This class is private to Constants.cpp, and is used 00050 /// behind the scenes to implement binary constant exprs. 00051 class BinaryConstantExpr : public ConstantExpr { 00052 virtual void anchor(); 00053 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00054 public: 00055 // allocate space for exactly two operands 00056 void *operator new(size_t s) { 00057 return User::operator new(s, 2); 00058 } 00059 BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2, 00060 unsigned Flags) 00061 : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) { 00062 Op<0>() = C1; 00063 Op<1>() = C2; 00064 SubclassOptionalData = Flags; 00065 } 00066 /// Transparently provide more efficient getOperand methods. 00067 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00068 }; 00069 00070 /// SelectConstantExpr - This class is private to Constants.cpp, and is used 00071 /// behind the scenes to implement select constant exprs. 00072 class SelectConstantExpr : public ConstantExpr { 00073 virtual void anchor(); 00074 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00075 public: 00076 // allocate space for exactly three operands 00077 void *operator new(size_t s) { 00078 return User::operator new(s, 3); 00079 } 00080 SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) 00081 : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { 00082 Op<0>() = C1; 00083 Op<1>() = C2; 00084 Op<2>() = C3; 00085 } 00086 /// Transparently provide more efficient getOperand methods. 00087 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00088 }; 00089 00090 /// ExtractElementConstantExpr - This class is private to 00091 /// Constants.cpp, and is used behind the scenes to implement 00092 /// extractelement constant exprs. 00093 class ExtractElementConstantExpr : public ConstantExpr { 00094 virtual void anchor(); 00095 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00096 public: 00097 // allocate space for exactly two operands 00098 void *operator new(size_t s) { 00099 return User::operator new(s, 2); 00100 } 00101 ExtractElementConstantExpr(Constant *C1, Constant *C2) 00102 : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), 00103 Instruction::ExtractElement, &Op<0>(), 2) { 00104 Op<0>() = C1; 00105 Op<1>() = C2; 00106 } 00107 /// Transparently provide more efficient getOperand methods. 00108 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00109 }; 00110 00111 /// InsertElementConstantExpr - This class is private to 00112 /// Constants.cpp, and is used behind the scenes to implement 00113 /// insertelement constant exprs. 00114 class InsertElementConstantExpr : public ConstantExpr { 00115 virtual void anchor(); 00116 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00117 public: 00118 // allocate space for exactly three operands 00119 void *operator new(size_t s) { 00120 return User::operator new(s, 3); 00121 } 00122 InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) 00123 : ConstantExpr(C1->getType(), Instruction::InsertElement, 00124 &Op<0>(), 3) { 00125 Op<0>() = C1; 00126 Op<1>() = C2; 00127 Op<2>() = C3; 00128 } 00129 /// Transparently provide more efficient getOperand methods. 00130 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00131 }; 00132 00133 /// ShuffleVectorConstantExpr - This class is private to 00134 /// Constants.cpp, and is used behind the scenes to implement 00135 /// shufflevector constant exprs. 00136 class ShuffleVectorConstantExpr : public ConstantExpr { 00137 virtual void anchor(); 00138 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00139 public: 00140 // allocate space for exactly three operands 00141 void *operator new(size_t s) { 00142 return User::operator new(s, 3); 00143 } 00144 ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) 00145 : ConstantExpr(VectorType::get( 00146 cast<VectorType>(C1->getType())->getElementType(), 00147 cast<VectorType>(C3->getType())->getNumElements()), 00148 Instruction::ShuffleVector, 00149 &Op<0>(), 3) { 00150 Op<0>() = C1; 00151 Op<1>() = C2; 00152 Op<2>() = C3; 00153 } 00154 /// Transparently provide more efficient getOperand methods. 00155 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00156 }; 00157 00158 /// ExtractValueConstantExpr - This class is private to 00159 /// Constants.cpp, and is used behind the scenes to implement 00160 /// extractvalue constant exprs. 00161 class ExtractValueConstantExpr : public ConstantExpr { 00162 virtual void anchor(); 00163 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00164 public: 00165 // allocate space for exactly one operand 00166 void *operator new(size_t s) { 00167 return User::operator new(s, 1); 00168 } 00169 ExtractValueConstantExpr(Constant *Agg, 00170 const SmallVector<unsigned, 4> &IdxList, 00171 Type *DestTy) 00172 : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), 00173 Indices(IdxList) { 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 virtual void anchor(); 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 const SmallVector<unsigned, 4> &IdxList, 00197 Type *DestTy) 00198 : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2), 00199 Indices(IdxList) { 00200 Op<0>() = Agg; 00201 Op<1>() = Val; 00202 } 00203 00204 /// Indices - These identify the position for the insertion. 00205 const SmallVector<unsigned, 4> Indices; 00206 00207 /// Transparently provide more efficient getOperand methods. 00208 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00209 }; 00210 00211 00212 /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is 00213 /// used behind the scenes to implement getelementpr constant exprs. 00214 class GetElementPtrConstantExpr : public ConstantExpr { 00215 virtual void anchor(); 00216 GetElementPtrConstantExpr(Constant *C, ArrayRef<Constant*> IdxList, 00217 Type *DestTy); 00218 public: 00219 static GetElementPtrConstantExpr *Create(Constant *C, 00220 ArrayRef<Constant*> IdxList, 00221 Type *DestTy, 00222 unsigned Flags) { 00223 GetElementPtrConstantExpr *Result = 00224 new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); 00225 Result->SubclassOptionalData = Flags; 00226 return Result; 00227 } 00228 /// Transparently provide more efficient getOperand methods. 00229 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00230 }; 00231 00232 // CompareConstantExpr - This class is private to Constants.cpp, and is used 00233 // behind the scenes to implement ICmp and FCmp constant expressions. This is 00234 // needed in order to store the predicate value for these instructions. 00235 class CompareConstantExpr : public ConstantExpr { 00236 virtual void anchor(); 00237 void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 00238 public: 00239 // allocate space for exactly two operands 00240 void *operator new(size_t s) { 00241 return User::operator new(s, 2); 00242 } 00243 unsigned short predicate; 00244 CompareConstantExpr(Type *ty, Instruction::OtherOps opc, 00245 unsigned short pred, Constant* LHS, Constant* RHS) 00246 : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { 00247 Op<0>() = LHS; 00248 Op<1>() = RHS; 00249 } 00250 /// Transparently provide more efficient getOperand methods. 00251 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 00252 }; 00253 00254 template <> 00255 struct OperandTraits<UnaryConstantExpr> : 00256 public FixedNumOperandTraits<UnaryConstantExpr, 1> { 00257 }; 00258 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) 00259 00260 template <> 00261 struct OperandTraits<BinaryConstantExpr> : 00262 public FixedNumOperandTraits<BinaryConstantExpr, 2> { 00263 }; 00264 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) 00265 00266 template <> 00267 struct OperandTraits<SelectConstantExpr> : 00268 public FixedNumOperandTraits<SelectConstantExpr, 3> { 00269 }; 00270 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) 00271 00272 template <> 00273 struct OperandTraits<ExtractElementConstantExpr> : 00274 public FixedNumOperandTraits<ExtractElementConstantExpr, 2> { 00275 }; 00276 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) 00277 00278 template <> 00279 struct OperandTraits<InsertElementConstantExpr> : 00280 public FixedNumOperandTraits<InsertElementConstantExpr, 3> { 00281 }; 00282 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) 00283 00284 template <> 00285 struct OperandTraits<ShuffleVectorConstantExpr> : 00286 public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> { 00287 }; 00288 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) 00289 00290 template <> 00291 struct OperandTraits<ExtractValueConstantExpr> : 00292 public FixedNumOperandTraits<ExtractValueConstantExpr, 1> { 00293 }; 00294 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) 00295 00296 template <> 00297 struct OperandTraits<InsertValueConstantExpr> : 00298 public FixedNumOperandTraits<InsertValueConstantExpr, 2> { 00299 }; 00300 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) 00301 00302 template <> 00303 struct OperandTraits<GetElementPtrConstantExpr> : 00304 public VariadicOperandTraits<GetElementPtrConstantExpr, 1> { 00305 }; 00306 00307 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) 00308 00309 00310 template <> 00311 struct OperandTraits<CompareConstantExpr> : 00312 public FixedNumOperandTraits<CompareConstantExpr, 2> { 00313 }; 00314 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) 00315 00316 struct ExprMapKeyType { 00317 ExprMapKeyType(unsigned opc, 00318 ArrayRef<Constant*> ops, 00319 unsigned short flags = 0, 00320 unsigned short optionalflags = 0, 00321 ArrayRef<unsigned> inds = None) 00322 : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags), 00323 operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {} 00324 uint8_t opcode; 00325 uint8_t subclassoptionaldata; 00326 uint16_t subclassdata; 00327 std::vector<Constant*> operands; 00328 SmallVector<unsigned, 4> indices; 00329 bool operator==(const ExprMapKeyType& that) const { 00330 return this->opcode == that.opcode && 00331 this->subclassdata == that.subclassdata && 00332 this->subclassoptionaldata == that.subclassoptionaldata && 00333 this->operands == that.operands && 00334 this->indices == that.indices; 00335 } 00336 bool operator<(const ExprMapKeyType & that) const { 00337 if (this->opcode != that.opcode) return this->opcode < that.opcode; 00338 if (this->operands != that.operands) return this->operands < that.operands; 00339 if (this->subclassdata != that.subclassdata) 00340 return this->subclassdata < that.subclassdata; 00341 if (this->subclassoptionaldata != that.subclassoptionaldata) 00342 return this->subclassoptionaldata < that.subclassoptionaldata; 00343 if (this->indices != that.indices) return this->indices < that.indices; 00344 return false; 00345 } 00346 00347 bool operator!=(const ExprMapKeyType& that) const { 00348 return !(*this == that); 00349 } 00350 }; 00351 00352 struct InlineAsmKeyType { 00353 InlineAsmKeyType(StringRef AsmString, 00354 StringRef Constraints, bool hasSideEffects, 00355 bool isAlignStack, InlineAsm::AsmDialect asmDialect) 00356 : asm_string(AsmString), constraints(Constraints), 00357 has_side_effects(hasSideEffects), is_align_stack(isAlignStack), 00358 asm_dialect(asmDialect) {} 00359 std::string asm_string; 00360 std::string constraints; 00361 bool has_side_effects; 00362 bool is_align_stack; 00363 InlineAsm::AsmDialect asm_dialect; 00364 bool operator==(const InlineAsmKeyType& that) const { 00365 return this->asm_string == that.asm_string && 00366 this->constraints == that.constraints && 00367 this->has_side_effects == that.has_side_effects && 00368 this->is_align_stack == that.is_align_stack && 00369 this->asm_dialect == that.asm_dialect; 00370 } 00371 bool operator<(const InlineAsmKeyType& that) const { 00372 if (this->asm_string != that.asm_string) 00373 return this->asm_string < that.asm_string; 00374 if (this->constraints != that.constraints) 00375 return this->constraints < that.constraints; 00376 if (this->has_side_effects != that.has_side_effects) 00377 return this->has_side_effects < that.has_side_effects; 00378 if (this->is_align_stack != that.is_align_stack) 00379 return this->is_align_stack < that.is_align_stack; 00380 if (this->asm_dialect != that.asm_dialect) 00381 return this->asm_dialect < that.asm_dialect; 00382 return false; 00383 } 00384 00385 bool operator!=(const InlineAsmKeyType& that) const { 00386 return !(*this == that); 00387 } 00388 }; 00389 00390 // The number of operands for each ConstantCreator::create method is 00391 // determined by the ConstantTraits template. 00392 // ConstantCreator - A class that is used to create constants by 00393 // ConstantUniqueMap*. This class should be partially specialized if there is 00394 // something strange that needs to be done to interface to the ctor for the 00395 // constant. 00396 // 00397 template<typename T, typename Alloc> 00398 struct ConstantTraits< std::vector<T, Alloc> > { 00399 static unsigned uses(const std::vector<T, Alloc>& v) { 00400 return v.size(); 00401 } 00402 }; 00403 00404 template<> 00405 struct ConstantTraits<Constant *> { 00406 static unsigned uses(Constant * const & v) { 00407 return 1; 00408 } 00409 }; 00410 00411 template<class ConstantClass, class TypeClass, class ValType> 00412 struct ConstantCreator { 00413 static ConstantClass *create(TypeClass *Ty, const ValType &V) { 00414 return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V); 00415 } 00416 }; 00417 00418 template<class ConstantClass, class TypeClass> 00419 struct ConstantArrayCreator { 00420 static ConstantClass *create(TypeClass *Ty, ArrayRef<Constant*> V) { 00421 return new(V.size()) ConstantClass(Ty, V); 00422 } 00423 }; 00424 00425 template<class ConstantClass> 00426 struct ConstantKeyData { 00427 typedef void ValType; 00428 static ValType getValType(ConstantClass *C) { 00429 llvm_unreachable("Unknown Constant type!"); 00430 } 00431 }; 00432 00433 template<> 00434 struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> { 00435 static ConstantExpr *create(Type *Ty, const ExprMapKeyType &V, 00436 unsigned short pred = 0) { 00437 if (Instruction::isCast(V.opcode)) 00438 return new UnaryConstantExpr(V.opcode, V.operands[0], Ty); 00439 if ((V.opcode >= Instruction::BinaryOpsBegin && 00440 V.opcode < Instruction::BinaryOpsEnd)) 00441 return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1], 00442 V.subclassoptionaldata); 00443 if (V.opcode == Instruction::Select) 00444 return new SelectConstantExpr(V.operands[0], V.operands[1], 00445 V.operands[2]); 00446 if (V.opcode == Instruction::ExtractElement) 00447 return new ExtractElementConstantExpr(V.operands[0], V.operands[1]); 00448 if (V.opcode == Instruction::InsertElement) 00449 return new InsertElementConstantExpr(V.operands[0], V.operands[1], 00450 V.operands[2]); 00451 if (V.opcode == Instruction::ShuffleVector) 00452 return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1], 00453 V.operands[2]); 00454 if (V.opcode == Instruction::InsertValue) 00455 return new InsertValueConstantExpr(V.operands[0], V.operands[1], 00456 V.indices, Ty); 00457 if (V.opcode == Instruction::ExtractValue) 00458 return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty); 00459 if (V.opcode == Instruction::GetElementPtr) { 00460 std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end()); 00461 return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty, 00462 V.subclassoptionaldata); 00463 } 00464 00465 // The compare instructions are weird. We have to encode the predicate 00466 // value and it is combined with the instruction opcode by multiplying 00467 // the opcode by one hundred. We must decode this to get the predicate. 00468 if (V.opcode == Instruction::ICmp) 00469 return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata, 00470 V.operands[0], V.operands[1]); 00471 if (V.opcode == Instruction::FCmp) 00472 return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata, 00473 V.operands[0], V.operands[1]); 00474 llvm_unreachable("Invalid ConstantExpr!"); 00475 } 00476 }; 00477 00478 template<> 00479 struct ConstantKeyData<ConstantExpr> { 00480 typedef ExprMapKeyType ValType; 00481 static ValType getValType(ConstantExpr *CE) { 00482 std::vector<Constant*> Operands; 00483 Operands.reserve(CE->getNumOperands()); 00484 for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) 00485 Operands.push_back(cast<Constant>(CE->getOperand(i))); 00486 return ExprMapKeyType(CE->getOpcode(), Operands, 00487 CE->isCompare() ? CE->getPredicate() : 0, 00488 CE->getRawSubclassOptionalData(), 00489 CE->hasIndices() ? 00490 CE->getIndices() : ArrayRef<unsigned>()); 00491 } 00492 }; 00493 00494 template<> 00495 struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> { 00496 static InlineAsm *create(PointerType *Ty, const InlineAsmKeyType &Key) { 00497 return new InlineAsm(Ty, Key.asm_string, Key.constraints, 00498 Key.has_side_effects, Key.is_align_stack, 00499 Key.asm_dialect); 00500 } 00501 }; 00502 00503 template<> 00504 struct ConstantKeyData<InlineAsm> { 00505 typedef InlineAsmKeyType ValType; 00506 static ValType getValType(InlineAsm *Asm) { 00507 return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(), 00508 Asm->hasSideEffects(), Asm->isAlignStack(), 00509 Asm->getDialect()); 00510 } 00511 }; 00512 00513 template<class ValType, class ValRefType, class TypeClass, class ConstantClass, 00514 bool HasLargeKey = false /*true for arrays and structs*/ > 00515 class ConstantUniqueMap { 00516 public: 00517 typedef std::pair<TypeClass*, ValType> MapKey; 00518 typedef std::map<MapKey, ConstantClass *> MapTy; 00519 typedef std::map<ConstantClass *, typename MapTy::iterator> InverseMapTy; 00520 private: 00521 /// Map - This is the main map from the element descriptor to the Constants. 00522 /// This is the primary way we avoid creating two of the same shape 00523 /// constant. 00524 MapTy Map; 00525 00526 /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping 00527 /// from the constants to their element in Map. This is important for 00528 /// removal of constants from the array, which would otherwise have to scan 00529 /// through the map with very large keys. 00530 InverseMapTy InverseMap; 00531 00532 public: 00533 typename MapTy::iterator map_begin() { return Map.begin(); } 00534 typename MapTy::iterator map_end() { return Map.end(); } 00535 00536 void freeConstants() { 00537 for (typename MapTy::iterator I=Map.begin(), E=Map.end(); 00538 I != E; ++I) { 00539 // Asserts that use_empty(). 00540 delete I->second; 00541 } 00542 } 00543 00544 /// InsertOrGetItem - Return an iterator for the specified element. 00545 /// If the element exists in the map, the returned iterator points to the 00546 /// entry and Exists=true. If not, the iterator points to the newly 00547 /// inserted entry and returns Exists=false. Newly inserted entries have 00548 /// I->second == 0, and should be filled in. 00549 typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, ConstantClass *> 00550 &InsertVal, 00551 bool &Exists) { 00552 std::pair<typename MapTy::iterator, bool> IP = Map.insert(InsertVal); 00553 Exists = !IP.second; 00554 return IP.first; 00555 } 00556 00557 private: 00558 typename MapTy::iterator FindExistingElement(ConstantClass *CP) { 00559 if (HasLargeKey) { 00560 typename InverseMapTy::iterator IMI = InverseMap.find(CP); 00561 assert(IMI != InverseMap.end() && IMI->second != Map.end() && 00562 IMI->second->second == CP && 00563 "InverseMap corrupt!"); 00564 return IMI->second; 00565 } 00566 00567 typename MapTy::iterator I = 00568 Map.find(MapKey(static_cast<TypeClass*>(CP->getType()), 00569 ConstantKeyData<ConstantClass>::getValType(CP))); 00570 if (I == Map.end() || I->second != CP) { 00571 // FIXME: This should not use a linear scan. If this gets to be a 00572 // performance problem, someone should look at this. 00573 for (I = Map.begin(); I != Map.end() && I->second != CP; ++I) 00574 /* empty */; 00575 } 00576 return I; 00577 } 00578 00579 ConstantClass *Create(TypeClass *Ty, ValRefType V, 00580 typename MapTy::iterator I) { 00581 ConstantClass* Result = 00582 ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V); 00583 00584 assert(Result->getType() == Ty && "Type specified is not correct!"); 00585 I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result)); 00586 00587 if (HasLargeKey) // Remember the reverse mapping if needed. 00588 InverseMap.insert(std::make_pair(Result, I)); 00589 00590 return Result; 00591 } 00592 public: 00593 00594 /// getOrCreate - Return the specified constant from the map, creating it if 00595 /// necessary. 00596 ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) { 00597 MapKey Lookup(Ty, V); 00598 ConstantClass* Result = 0; 00599 00600 typename MapTy::iterator I = Map.find(Lookup); 00601 // Is it in the map? 00602 if (I != Map.end()) 00603 Result = I->second; 00604 00605 if (!Result) { 00606 // If no preexisting value, create one now... 00607 Result = Create(Ty, V, I); 00608 } 00609 00610 return Result; 00611 } 00612 00613 void remove(ConstantClass *CP) { 00614 typename MapTy::iterator I = FindExistingElement(CP); 00615 assert(I != Map.end() && "Constant not found in constant table!"); 00616 assert(I->second == CP && "Didn't find correct element?"); 00617 00618 if (HasLargeKey) // Remember the reverse mapping if needed. 00619 InverseMap.erase(CP); 00620 00621 Map.erase(I); 00622 } 00623 00624 /// MoveConstantToNewSlot - If we are about to change C to be the element 00625 /// specified by I, update our internal data structures to reflect this 00626 /// fact. 00627 void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) { 00628 // First, remove the old location of the specified constant in the map. 00629 typename MapTy::iterator OldI = FindExistingElement(C); 00630 assert(OldI != Map.end() && "Constant not found in constant table!"); 00631 assert(OldI->second == C && "Didn't find correct element?"); 00632 00633 // Remove the old entry from the map. 00634 Map.erase(OldI); 00635 00636 // Update the inverse map so that we know that this constant is now 00637 // located at descriptor I. 00638 if (HasLargeKey) { 00639 assert(I->second == C && "Bad inversemap entry!"); 00640 InverseMap[C] = I; 00641 } 00642 } 00643 00644 void dump() const { 00645 DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); 00646 } 00647 }; 00648 00649 // Unique map for aggregate constants 00650 template<class TypeClass, class ConstantClass> 00651 class ConstantAggrUniqueMap { 00652 public: 00653 typedef ArrayRef<Constant*> Operands; 00654 typedef std::pair<TypeClass*, Operands> LookupKey; 00655 private: 00656 struct MapInfo { 00657 typedef DenseMapInfo<ConstantClass*> ConstantClassInfo; 00658 typedef DenseMapInfo<Constant*> ConstantInfo; 00659 typedef DenseMapInfo<TypeClass*> TypeClassInfo; 00660 static inline ConstantClass* getEmptyKey() { 00661 return ConstantClassInfo::getEmptyKey(); 00662 } 00663 static inline ConstantClass* getTombstoneKey() { 00664 return ConstantClassInfo::getTombstoneKey(); 00665 } 00666 static unsigned getHashValue(const ConstantClass *CP) { 00667 SmallVector<Constant*, 8> CPOperands; 00668 CPOperands.reserve(CP->getNumOperands()); 00669 for (unsigned I = 0, E = CP->getNumOperands(); I < E; ++I) 00670 CPOperands.push_back(CP->getOperand(I)); 00671 return getHashValue(LookupKey(CP->getType(), CPOperands)); 00672 } 00673 static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) { 00674 return LHS == RHS; 00675 } 00676 static unsigned getHashValue(const LookupKey &Val) { 00677 return hash_combine(Val.first, hash_combine_range(Val.second.begin(), 00678 Val.second.end())); 00679 } 00680 static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) { 00681 if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 00682 return false; 00683 if (LHS.first != RHS->getType() 00684 || LHS.second.size() != RHS->getNumOperands()) 00685 return false; 00686 for (unsigned I = 0, E = RHS->getNumOperands(); I < E; ++I) { 00687 if (LHS.second[I] != RHS->getOperand(I)) 00688 return false; 00689 } 00690 return true; 00691 } 00692 }; 00693 public: 00694 typedef DenseMap<ConstantClass *, char, MapInfo> MapTy; 00695 00696 private: 00697 /// Map - This is the main map from the element descriptor to the Constants. 00698 /// This is the primary way we avoid creating two of the same shape 00699 /// constant. 00700 MapTy Map; 00701 00702 public: 00703 typename MapTy::iterator map_begin() { return Map.begin(); } 00704 typename MapTy::iterator map_end() { return Map.end(); } 00705 00706 void freeConstants() { 00707 for (typename MapTy::iterator I=Map.begin(), E=Map.end(); 00708 I != E; ++I) { 00709 // Asserts that use_empty(). 00710 delete I->first; 00711 } 00712 } 00713 00714 private: 00715 typename MapTy::iterator findExistingElement(ConstantClass *CP) { 00716 return Map.find(CP); 00717 } 00718 00719 ConstantClass *Create(TypeClass *Ty, Operands V, typename MapTy::iterator I) { 00720 ConstantClass* Result = 00721 ConstantArrayCreator<ConstantClass,TypeClass>::create(Ty, V); 00722 00723 assert(Result->getType() == Ty && "Type specified is not correct!"); 00724 Map[Result] = '\0'; 00725 00726 return Result; 00727 } 00728 public: 00729 00730 /// getOrCreate - Return the specified constant from the map, creating it if 00731 /// necessary. 00732 ConstantClass *getOrCreate(TypeClass *Ty, Operands V) { 00733 LookupKey Lookup(Ty, V); 00734 ConstantClass* Result = 0; 00735 00736 typename MapTy::iterator I = Map.find_as(Lookup); 00737 // Is it in the map? 00738 if (I != Map.end()) 00739 Result = I->first; 00740 00741 if (!Result) { 00742 // If no preexisting value, create one now... 00743 Result = Create(Ty, V, I); 00744 } 00745 00746 return Result; 00747 } 00748 00749 /// Find the constant by lookup key. 00750 typename MapTy::iterator find(LookupKey Lookup) { 00751 return Map.find_as(Lookup); 00752 } 00753 00754 /// Insert the constant into its proper slot. 00755 void insert(ConstantClass *CP) { 00756 Map[CP] = '\0'; 00757 } 00758 00759 /// Remove this constant from the map 00760 void remove(ConstantClass *CP) { 00761 typename MapTy::iterator I = findExistingElement(CP); 00762 assert(I != Map.end() && "Constant not found in constant table!"); 00763 assert(I->first == CP && "Didn't find correct element?"); 00764 Map.erase(I); 00765 } 00766 00767 void dump() const { 00768 DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); 00769 } 00770 }; 00771 00772 } 00773 00774 #endif