1249259Sdim//===-- ConstantsContext.h - Constants-related Context Interals -----------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file defines various helper methods and classes used by 11249259Sdim// LLVMContextImpl for creating and managing constants. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15249259Sdim#ifndef LLVM_CONSTANTSCONTEXT_H 16249259Sdim#define LLVM_CONSTANTSCONTEXT_H 17249259Sdim 18249259Sdim#include "llvm/ADT/DenseMap.h" 19249259Sdim#include "llvm/ADT/Hashing.h" 20249259Sdim#include "llvm/IR/InlineAsm.h" 21249259Sdim#include "llvm/IR/Instructions.h" 22249259Sdim#include "llvm/IR/Operator.h" 23249259Sdim#include "llvm/Support/Debug.h" 24249259Sdim#include "llvm/Support/ErrorHandling.h" 25249259Sdim#include "llvm/Support/raw_ostream.h" 26249259Sdim#include <map> 27249259Sdim 28249259Sdimnamespace llvm { 29249259Sdimtemplate<class ValType> 30249259Sdimstruct ConstantTraits; 31249259Sdim 32249259Sdim/// UnaryConstantExpr - This class is private to Constants.cpp, and is used 33249259Sdim/// behind the scenes to implement unary constant exprs. 34249259Sdimclass UnaryConstantExpr : public ConstantExpr { 35249259Sdim virtual void anchor(); 36249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 37249259Sdimpublic: 38249259Sdim // allocate space for exactly one operand 39249259Sdim void *operator new(size_t s) { 40249259Sdim return User::operator new(s, 1); 41249259Sdim } 42249259Sdim UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty) 43249259Sdim : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { 44249259Sdim Op<0>() = C; 45249259Sdim } 46249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 47249259Sdim}; 48249259Sdim 49249259Sdim/// BinaryConstantExpr - This class is private to Constants.cpp, and is used 50249259Sdim/// behind the scenes to implement binary constant exprs. 51249259Sdimclass BinaryConstantExpr : public ConstantExpr { 52249259Sdim virtual void anchor(); 53249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 54249259Sdimpublic: 55249259Sdim // allocate space for exactly two operands 56249259Sdim void *operator new(size_t s) { 57249259Sdim return User::operator new(s, 2); 58249259Sdim } 59249259Sdim BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2, 60249259Sdim unsigned Flags) 61249259Sdim : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) { 62249259Sdim Op<0>() = C1; 63249259Sdim Op<1>() = C2; 64249259Sdim SubclassOptionalData = Flags; 65249259Sdim } 66249259Sdim /// Transparently provide more efficient getOperand methods. 67249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 68249259Sdim}; 69249259Sdim 70249259Sdim/// SelectConstantExpr - This class is private to Constants.cpp, and is used 71249259Sdim/// behind the scenes to implement select constant exprs. 72249259Sdimclass SelectConstantExpr : public ConstantExpr { 73249259Sdim virtual void anchor(); 74249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 75249259Sdimpublic: 76249259Sdim // allocate space for exactly three operands 77249259Sdim void *operator new(size_t s) { 78249259Sdim return User::operator new(s, 3); 79249259Sdim } 80249259Sdim SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) 81249259Sdim : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { 82249259Sdim Op<0>() = C1; 83249259Sdim Op<1>() = C2; 84249259Sdim Op<2>() = C3; 85249259Sdim } 86249259Sdim /// Transparently provide more efficient getOperand methods. 87249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 88249259Sdim}; 89249259Sdim 90249259Sdim/// ExtractElementConstantExpr - This class is private to 91249259Sdim/// Constants.cpp, and is used behind the scenes to implement 92249259Sdim/// extractelement constant exprs. 93249259Sdimclass ExtractElementConstantExpr : public ConstantExpr { 94249259Sdim virtual void anchor(); 95249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 96249259Sdimpublic: 97249259Sdim // allocate space for exactly two operands 98249259Sdim void *operator new(size_t s) { 99249259Sdim return User::operator new(s, 2); 100249259Sdim } 101249259Sdim ExtractElementConstantExpr(Constant *C1, Constant *C2) 102249259Sdim : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), 103249259Sdim Instruction::ExtractElement, &Op<0>(), 2) { 104249259Sdim Op<0>() = C1; 105249259Sdim Op<1>() = C2; 106249259Sdim } 107249259Sdim /// Transparently provide more efficient getOperand methods. 108249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 109249259Sdim}; 110249259Sdim 111249259Sdim/// InsertElementConstantExpr - This class is private to 112249259Sdim/// Constants.cpp, and is used behind the scenes to implement 113249259Sdim/// insertelement constant exprs. 114249259Sdimclass InsertElementConstantExpr : public ConstantExpr { 115249259Sdim virtual void anchor(); 116249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 117249259Sdimpublic: 118249259Sdim // allocate space for exactly three operands 119249259Sdim void *operator new(size_t s) { 120249259Sdim return User::operator new(s, 3); 121249259Sdim } 122249259Sdim InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) 123249259Sdim : ConstantExpr(C1->getType(), Instruction::InsertElement, 124249259Sdim &Op<0>(), 3) { 125249259Sdim Op<0>() = C1; 126249259Sdim Op<1>() = C2; 127249259Sdim Op<2>() = C3; 128249259Sdim } 129249259Sdim /// Transparently provide more efficient getOperand methods. 130249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 131249259Sdim}; 132249259Sdim 133249259Sdim/// ShuffleVectorConstantExpr - This class is private to 134249259Sdim/// Constants.cpp, and is used behind the scenes to implement 135249259Sdim/// shufflevector constant exprs. 136249259Sdimclass ShuffleVectorConstantExpr : public ConstantExpr { 137249259Sdim virtual void anchor(); 138249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 139249259Sdimpublic: 140249259Sdim // allocate space for exactly three operands 141249259Sdim void *operator new(size_t s) { 142249259Sdim return User::operator new(s, 3); 143249259Sdim } 144249259Sdim ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) 145249259Sdim : ConstantExpr(VectorType::get( 146249259Sdim cast<VectorType>(C1->getType())->getElementType(), 147249259Sdim cast<VectorType>(C3->getType())->getNumElements()), 148249259Sdim Instruction::ShuffleVector, 149249259Sdim &Op<0>(), 3) { 150249259Sdim Op<0>() = C1; 151249259Sdim Op<1>() = C2; 152249259Sdim Op<2>() = C3; 153249259Sdim } 154249259Sdim /// Transparently provide more efficient getOperand methods. 155249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 156249259Sdim}; 157249259Sdim 158249259Sdim/// ExtractValueConstantExpr - This class is private to 159249259Sdim/// Constants.cpp, and is used behind the scenes to implement 160249259Sdim/// extractvalue constant exprs. 161249259Sdimclass ExtractValueConstantExpr : public ConstantExpr { 162249259Sdim virtual void anchor(); 163249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 164249259Sdimpublic: 165249259Sdim // allocate space for exactly one operand 166249259Sdim void *operator new(size_t s) { 167249259Sdim return User::operator new(s, 1); 168249259Sdim } 169249259Sdim ExtractValueConstantExpr(Constant *Agg, 170249259Sdim const SmallVector<unsigned, 4> &IdxList, 171249259Sdim Type *DestTy) 172249259Sdim : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), 173249259Sdim Indices(IdxList) { 174249259Sdim Op<0>() = Agg; 175249259Sdim } 176249259Sdim 177249259Sdim /// Indices - These identify which value to extract. 178249259Sdim const SmallVector<unsigned, 4> Indices; 179249259Sdim 180249259Sdim /// Transparently provide more efficient getOperand methods. 181249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 182249259Sdim}; 183249259Sdim 184249259Sdim/// InsertValueConstantExpr - This class is private to 185249259Sdim/// Constants.cpp, and is used behind the scenes to implement 186249259Sdim/// insertvalue constant exprs. 187249259Sdimclass InsertValueConstantExpr : public ConstantExpr { 188249259Sdim virtual void anchor(); 189249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 190249259Sdimpublic: 191249259Sdim // allocate space for exactly one operand 192249259Sdim void *operator new(size_t s) { 193249259Sdim return User::operator new(s, 2); 194249259Sdim } 195249259Sdim InsertValueConstantExpr(Constant *Agg, Constant *Val, 196249259Sdim const SmallVector<unsigned, 4> &IdxList, 197249259Sdim Type *DestTy) 198249259Sdim : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2), 199249259Sdim Indices(IdxList) { 200249259Sdim Op<0>() = Agg; 201249259Sdim Op<1>() = Val; 202249259Sdim } 203249259Sdim 204249259Sdim /// Indices - These identify the position for the insertion. 205249259Sdim const SmallVector<unsigned, 4> Indices; 206249259Sdim 207249259Sdim /// Transparently provide more efficient getOperand methods. 208249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 209249259Sdim}; 210249259Sdim 211249259Sdim 212249259Sdim/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is 213249259Sdim/// used behind the scenes to implement getelementpr constant exprs. 214249259Sdimclass GetElementPtrConstantExpr : public ConstantExpr { 215249259Sdim virtual void anchor(); 216249259Sdim GetElementPtrConstantExpr(Constant *C, ArrayRef<Constant*> IdxList, 217249259Sdim Type *DestTy); 218249259Sdimpublic: 219249259Sdim static GetElementPtrConstantExpr *Create(Constant *C, 220249259Sdim ArrayRef<Constant*> IdxList, 221249259Sdim Type *DestTy, 222249259Sdim unsigned Flags) { 223249259Sdim GetElementPtrConstantExpr *Result = 224249259Sdim new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); 225249259Sdim Result->SubclassOptionalData = Flags; 226249259Sdim return Result; 227249259Sdim } 228249259Sdim /// Transparently provide more efficient getOperand methods. 229249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 230249259Sdim}; 231249259Sdim 232249259Sdim// CompareConstantExpr - This class is private to Constants.cpp, and is used 233249259Sdim// behind the scenes to implement ICmp and FCmp constant expressions. This is 234249259Sdim// needed in order to store the predicate value for these instructions. 235249259Sdimclass CompareConstantExpr : public ConstantExpr { 236249259Sdim virtual void anchor(); 237249259Sdim void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; 238249259Sdimpublic: 239249259Sdim // allocate space for exactly two operands 240249259Sdim void *operator new(size_t s) { 241249259Sdim return User::operator new(s, 2); 242249259Sdim } 243249259Sdim unsigned short predicate; 244249259Sdim CompareConstantExpr(Type *ty, Instruction::OtherOps opc, 245249259Sdim unsigned short pred, Constant* LHS, Constant* RHS) 246249259Sdim : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { 247249259Sdim Op<0>() = LHS; 248249259Sdim Op<1>() = RHS; 249249259Sdim } 250249259Sdim /// Transparently provide more efficient getOperand methods. 251249259Sdim DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); 252249259Sdim}; 253249259Sdim 254249259Sdimtemplate <> 255249259Sdimstruct OperandTraits<UnaryConstantExpr> : 256249259Sdim public FixedNumOperandTraits<UnaryConstantExpr, 1> { 257249259Sdim}; 258249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) 259249259Sdim 260249259Sdimtemplate <> 261249259Sdimstruct OperandTraits<BinaryConstantExpr> : 262249259Sdim public FixedNumOperandTraits<BinaryConstantExpr, 2> { 263249259Sdim}; 264249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) 265249259Sdim 266249259Sdimtemplate <> 267249259Sdimstruct OperandTraits<SelectConstantExpr> : 268249259Sdim public FixedNumOperandTraits<SelectConstantExpr, 3> { 269249259Sdim}; 270249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) 271249259Sdim 272249259Sdimtemplate <> 273249259Sdimstruct OperandTraits<ExtractElementConstantExpr> : 274249259Sdim public FixedNumOperandTraits<ExtractElementConstantExpr, 2> { 275249259Sdim}; 276249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) 277249259Sdim 278249259Sdimtemplate <> 279249259Sdimstruct OperandTraits<InsertElementConstantExpr> : 280249259Sdim public FixedNumOperandTraits<InsertElementConstantExpr, 3> { 281249259Sdim}; 282249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) 283249259Sdim 284249259Sdimtemplate <> 285249259Sdimstruct OperandTraits<ShuffleVectorConstantExpr> : 286249259Sdim public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> { 287249259Sdim}; 288249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) 289249259Sdim 290249259Sdimtemplate <> 291249259Sdimstruct OperandTraits<ExtractValueConstantExpr> : 292249259Sdim public FixedNumOperandTraits<ExtractValueConstantExpr, 1> { 293249259Sdim}; 294249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) 295249259Sdim 296249259Sdimtemplate <> 297249259Sdimstruct OperandTraits<InsertValueConstantExpr> : 298249259Sdim public FixedNumOperandTraits<InsertValueConstantExpr, 2> { 299249259Sdim}; 300249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) 301249259Sdim 302249259Sdimtemplate <> 303249259Sdimstruct OperandTraits<GetElementPtrConstantExpr> : 304249259Sdim public VariadicOperandTraits<GetElementPtrConstantExpr, 1> { 305249259Sdim}; 306249259Sdim 307249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) 308249259Sdim 309249259Sdim 310249259Sdimtemplate <> 311249259Sdimstruct OperandTraits<CompareConstantExpr> : 312249259Sdim public FixedNumOperandTraits<CompareConstantExpr, 2> { 313249259Sdim}; 314249259SdimDEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) 315249259Sdim 316249259Sdimstruct ExprMapKeyType { 317249259Sdim ExprMapKeyType(unsigned opc, 318249259Sdim ArrayRef<Constant*> ops, 319249259Sdim unsigned short flags = 0, 320249259Sdim unsigned short optionalflags = 0, 321251662Sdim ArrayRef<unsigned> inds = None) 322249259Sdim : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags), 323249259Sdim operands(ops.begin(), ops.end()), indices(inds.begin(), inds.end()) {} 324249259Sdim uint8_t opcode; 325249259Sdim uint8_t subclassoptionaldata; 326249259Sdim uint16_t subclassdata; 327249259Sdim std::vector<Constant*> operands; 328249259Sdim SmallVector<unsigned, 4> indices; 329249259Sdim bool operator==(const ExprMapKeyType& that) const { 330249259Sdim return this->opcode == that.opcode && 331249259Sdim this->subclassdata == that.subclassdata && 332249259Sdim this->subclassoptionaldata == that.subclassoptionaldata && 333249259Sdim this->operands == that.operands && 334249259Sdim this->indices == that.indices; 335249259Sdim } 336249259Sdim bool operator<(const ExprMapKeyType & that) const { 337249259Sdim if (this->opcode != that.opcode) return this->opcode < that.opcode; 338249259Sdim if (this->operands != that.operands) return this->operands < that.operands; 339249259Sdim if (this->subclassdata != that.subclassdata) 340249259Sdim return this->subclassdata < that.subclassdata; 341249259Sdim if (this->subclassoptionaldata != that.subclassoptionaldata) 342249259Sdim return this->subclassoptionaldata < that.subclassoptionaldata; 343249259Sdim if (this->indices != that.indices) return this->indices < that.indices; 344249259Sdim return false; 345249259Sdim } 346249259Sdim 347249259Sdim bool operator!=(const ExprMapKeyType& that) const { 348249259Sdim return !(*this == that); 349249259Sdim } 350249259Sdim}; 351249259Sdim 352249259Sdimstruct InlineAsmKeyType { 353249259Sdim InlineAsmKeyType(StringRef AsmString, 354249259Sdim StringRef Constraints, bool hasSideEffects, 355249259Sdim bool isAlignStack, InlineAsm::AsmDialect asmDialect) 356249259Sdim : asm_string(AsmString), constraints(Constraints), 357249259Sdim has_side_effects(hasSideEffects), is_align_stack(isAlignStack), 358249259Sdim asm_dialect(asmDialect) {} 359249259Sdim std::string asm_string; 360249259Sdim std::string constraints; 361249259Sdim bool has_side_effects; 362249259Sdim bool is_align_stack; 363249259Sdim InlineAsm::AsmDialect asm_dialect; 364249259Sdim bool operator==(const InlineAsmKeyType& that) const { 365249259Sdim return this->asm_string == that.asm_string && 366249259Sdim this->constraints == that.constraints && 367249259Sdim this->has_side_effects == that.has_side_effects && 368249259Sdim this->is_align_stack == that.is_align_stack && 369249259Sdim this->asm_dialect == that.asm_dialect; 370249259Sdim } 371249259Sdim bool operator<(const InlineAsmKeyType& that) const { 372249259Sdim if (this->asm_string != that.asm_string) 373249259Sdim return this->asm_string < that.asm_string; 374249259Sdim if (this->constraints != that.constraints) 375249259Sdim return this->constraints < that.constraints; 376249259Sdim if (this->has_side_effects != that.has_side_effects) 377249259Sdim return this->has_side_effects < that.has_side_effects; 378249259Sdim if (this->is_align_stack != that.is_align_stack) 379249259Sdim return this->is_align_stack < that.is_align_stack; 380249259Sdim if (this->asm_dialect != that.asm_dialect) 381249259Sdim return this->asm_dialect < that.asm_dialect; 382249259Sdim return false; 383249259Sdim } 384249259Sdim 385249259Sdim bool operator!=(const InlineAsmKeyType& that) const { 386249259Sdim return !(*this == that); 387249259Sdim } 388249259Sdim}; 389249259Sdim 390249259Sdim// The number of operands for each ConstantCreator::create method is 391249259Sdim// determined by the ConstantTraits template. 392249259Sdim// ConstantCreator - A class that is used to create constants by 393249259Sdim// ConstantUniqueMap*. This class should be partially specialized if there is 394249259Sdim// something strange that needs to be done to interface to the ctor for the 395249259Sdim// constant. 396249259Sdim// 397249259Sdimtemplate<typename T, typename Alloc> 398249259Sdimstruct ConstantTraits< std::vector<T, Alloc> > { 399249259Sdim static unsigned uses(const std::vector<T, Alloc>& v) { 400249259Sdim return v.size(); 401249259Sdim } 402249259Sdim}; 403249259Sdim 404249259Sdimtemplate<> 405249259Sdimstruct ConstantTraits<Constant *> { 406249259Sdim static unsigned uses(Constant * const & v) { 407249259Sdim return 1; 408249259Sdim } 409249259Sdim}; 410249259Sdim 411249259Sdimtemplate<class ConstantClass, class TypeClass, class ValType> 412249259Sdimstruct ConstantCreator { 413249259Sdim static ConstantClass *create(TypeClass *Ty, const ValType &V) { 414249259Sdim return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V); 415249259Sdim } 416249259Sdim}; 417249259Sdim 418249259Sdimtemplate<class ConstantClass, class TypeClass> 419249259Sdimstruct ConstantArrayCreator { 420249259Sdim static ConstantClass *create(TypeClass *Ty, ArrayRef<Constant*> V) { 421249259Sdim return new(V.size()) ConstantClass(Ty, V); 422249259Sdim } 423249259Sdim}; 424249259Sdim 425249259Sdimtemplate<class ConstantClass> 426249259Sdimstruct ConstantKeyData { 427249259Sdim typedef void ValType; 428249259Sdim static ValType getValType(ConstantClass *C) { 429249259Sdim llvm_unreachable("Unknown Constant type!"); 430249259Sdim } 431249259Sdim}; 432249259Sdim 433249259Sdimtemplate<> 434249259Sdimstruct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> { 435249259Sdim static ConstantExpr *create(Type *Ty, const ExprMapKeyType &V, 436249259Sdim unsigned short pred = 0) { 437249259Sdim if (Instruction::isCast(V.opcode)) 438249259Sdim return new UnaryConstantExpr(V.opcode, V.operands[0], Ty); 439249259Sdim if ((V.opcode >= Instruction::BinaryOpsBegin && 440249259Sdim V.opcode < Instruction::BinaryOpsEnd)) 441249259Sdim return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1], 442249259Sdim V.subclassoptionaldata); 443249259Sdim if (V.opcode == Instruction::Select) 444249259Sdim return new SelectConstantExpr(V.operands[0], V.operands[1], 445249259Sdim V.operands[2]); 446249259Sdim if (V.opcode == Instruction::ExtractElement) 447249259Sdim return new ExtractElementConstantExpr(V.operands[0], V.operands[1]); 448249259Sdim if (V.opcode == Instruction::InsertElement) 449249259Sdim return new InsertElementConstantExpr(V.operands[0], V.operands[1], 450249259Sdim V.operands[2]); 451249259Sdim if (V.opcode == Instruction::ShuffleVector) 452249259Sdim return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1], 453249259Sdim V.operands[2]); 454249259Sdim if (V.opcode == Instruction::InsertValue) 455249259Sdim return new InsertValueConstantExpr(V.operands[0], V.operands[1], 456249259Sdim V.indices, Ty); 457249259Sdim if (V.opcode == Instruction::ExtractValue) 458249259Sdim return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty); 459249259Sdim if (V.opcode == Instruction::GetElementPtr) { 460249259Sdim std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end()); 461249259Sdim return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty, 462249259Sdim V.subclassoptionaldata); 463249259Sdim } 464249259Sdim 465249259Sdim // The compare instructions are weird. We have to encode the predicate 466249259Sdim // value and it is combined with the instruction opcode by multiplying 467249259Sdim // the opcode by one hundred. We must decode this to get the predicate. 468249259Sdim if (V.opcode == Instruction::ICmp) 469249259Sdim return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata, 470249259Sdim V.operands[0], V.operands[1]); 471249259Sdim if (V.opcode == Instruction::FCmp) 472249259Sdim return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata, 473249259Sdim V.operands[0], V.operands[1]); 474249259Sdim llvm_unreachable("Invalid ConstantExpr!"); 475249259Sdim } 476249259Sdim}; 477249259Sdim 478249259Sdimtemplate<> 479249259Sdimstruct ConstantKeyData<ConstantExpr> { 480249259Sdim typedef ExprMapKeyType ValType; 481249259Sdim static ValType getValType(ConstantExpr *CE) { 482249259Sdim std::vector<Constant*> Operands; 483249259Sdim Operands.reserve(CE->getNumOperands()); 484249259Sdim for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) 485249259Sdim Operands.push_back(cast<Constant>(CE->getOperand(i))); 486249259Sdim return ExprMapKeyType(CE->getOpcode(), Operands, 487249259Sdim CE->isCompare() ? CE->getPredicate() : 0, 488249259Sdim CE->getRawSubclassOptionalData(), 489249259Sdim CE->hasIndices() ? 490249259Sdim CE->getIndices() : ArrayRef<unsigned>()); 491249259Sdim } 492249259Sdim}; 493249259Sdim 494249259Sdimtemplate<> 495249259Sdimstruct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> { 496249259Sdim static InlineAsm *create(PointerType *Ty, const InlineAsmKeyType &Key) { 497249259Sdim return new InlineAsm(Ty, Key.asm_string, Key.constraints, 498249259Sdim Key.has_side_effects, Key.is_align_stack, 499249259Sdim Key.asm_dialect); 500249259Sdim } 501249259Sdim}; 502249259Sdim 503249259Sdimtemplate<> 504249259Sdimstruct ConstantKeyData<InlineAsm> { 505249259Sdim typedef InlineAsmKeyType ValType; 506249259Sdim static ValType getValType(InlineAsm *Asm) { 507249259Sdim return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(), 508249259Sdim Asm->hasSideEffects(), Asm->isAlignStack(), 509249259Sdim Asm->getDialect()); 510249259Sdim } 511249259Sdim}; 512249259Sdim 513249259Sdimtemplate<class ValType, class ValRefType, class TypeClass, class ConstantClass, 514249259Sdim bool HasLargeKey = false /*true for arrays and structs*/ > 515249259Sdimclass ConstantUniqueMap { 516249259Sdimpublic: 517249259Sdim typedef std::pair<TypeClass*, ValType> MapKey; 518249259Sdim typedef std::map<MapKey, ConstantClass *> MapTy; 519249259Sdim typedef std::map<ConstantClass *, typename MapTy::iterator> InverseMapTy; 520249259Sdimprivate: 521249259Sdim /// Map - This is the main map from the element descriptor to the Constants. 522249259Sdim /// This is the primary way we avoid creating two of the same shape 523249259Sdim /// constant. 524249259Sdim MapTy Map; 525249259Sdim 526249259Sdim /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping 527249259Sdim /// from the constants to their element in Map. This is important for 528249259Sdim /// removal of constants from the array, which would otherwise have to scan 529249259Sdim /// through the map with very large keys. 530249259Sdim InverseMapTy InverseMap; 531249259Sdim 532249259Sdimpublic: 533249259Sdim typename MapTy::iterator map_begin() { return Map.begin(); } 534249259Sdim typename MapTy::iterator map_end() { return Map.end(); } 535249259Sdim 536249259Sdim void freeConstants() { 537249259Sdim for (typename MapTy::iterator I=Map.begin(), E=Map.end(); 538249259Sdim I != E; ++I) { 539249259Sdim // Asserts that use_empty(). 540249259Sdim delete I->second; 541249259Sdim } 542249259Sdim } 543249259Sdim 544249259Sdim /// InsertOrGetItem - Return an iterator for the specified element. 545249259Sdim /// If the element exists in the map, the returned iterator points to the 546249259Sdim /// entry and Exists=true. If not, the iterator points to the newly 547249259Sdim /// inserted entry and returns Exists=false. Newly inserted entries have 548249259Sdim /// I->second == 0, and should be filled in. 549249259Sdim typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, ConstantClass *> 550249259Sdim &InsertVal, 551249259Sdim bool &Exists) { 552249259Sdim std::pair<typename MapTy::iterator, bool> IP = Map.insert(InsertVal); 553249259Sdim Exists = !IP.second; 554249259Sdim return IP.first; 555249259Sdim } 556249259Sdim 557249259Sdimprivate: 558249259Sdim typename MapTy::iterator FindExistingElement(ConstantClass *CP) { 559249259Sdim if (HasLargeKey) { 560249259Sdim typename InverseMapTy::iterator IMI = InverseMap.find(CP); 561249259Sdim assert(IMI != InverseMap.end() && IMI->second != Map.end() && 562249259Sdim IMI->second->second == CP && 563249259Sdim "InverseMap corrupt!"); 564249259Sdim return IMI->second; 565249259Sdim } 566249259Sdim 567249259Sdim typename MapTy::iterator I = 568249259Sdim Map.find(MapKey(static_cast<TypeClass*>(CP->getType()), 569249259Sdim ConstantKeyData<ConstantClass>::getValType(CP))); 570249259Sdim if (I == Map.end() || I->second != CP) { 571249259Sdim // FIXME: This should not use a linear scan. If this gets to be a 572249259Sdim // performance problem, someone should look at this. 573249259Sdim for (I = Map.begin(); I != Map.end() && I->second != CP; ++I) 574249259Sdim /* empty */; 575249259Sdim } 576249259Sdim return I; 577249259Sdim } 578249259Sdim 579249259Sdim ConstantClass *Create(TypeClass *Ty, ValRefType V, 580249259Sdim typename MapTy::iterator I) { 581249259Sdim ConstantClass* Result = 582249259Sdim ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V); 583249259Sdim 584249259Sdim assert(Result->getType() == Ty && "Type specified is not correct!"); 585249259Sdim I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result)); 586249259Sdim 587249259Sdim if (HasLargeKey) // Remember the reverse mapping if needed. 588249259Sdim InverseMap.insert(std::make_pair(Result, I)); 589249259Sdim 590249259Sdim return Result; 591249259Sdim } 592249259Sdimpublic: 593249259Sdim 594249259Sdim /// getOrCreate - Return the specified constant from the map, creating it if 595249259Sdim /// necessary. 596249259Sdim ConstantClass *getOrCreate(TypeClass *Ty, ValRefType V) { 597249259Sdim MapKey Lookup(Ty, V); 598249259Sdim ConstantClass* Result = 0; 599249259Sdim 600249259Sdim typename MapTy::iterator I = Map.find(Lookup); 601249259Sdim // Is it in the map? 602249259Sdim if (I != Map.end()) 603249259Sdim Result = I->second; 604249259Sdim 605249259Sdim if (!Result) { 606249259Sdim // If no preexisting value, create one now... 607249259Sdim Result = Create(Ty, V, I); 608249259Sdim } 609249259Sdim 610249259Sdim return Result; 611249259Sdim } 612249259Sdim 613249259Sdim void remove(ConstantClass *CP) { 614249259Sdim typename MapTy::iterator I = FindExistingElement(CP); 615249259Sdim assert(I != Map.end() && "Constant not found in constant table!"); 616249259Sdim assert(I->second == CP && "Didn't find correct element?"); 617249259Sdim 618249259Sdim if (HasLargeKey) // Remember the reverse mapping if needed. 619249259Sdim InverseMap.erase(CP); 620249259Sdim 621249259Sdim Map.erase(I); 622249259Sdim } 623249259Sdim 624249259Sdim /// MoveConstantToNewSlot - If we are about to change C to be the element 625249259Sdim /// specified by I, update our internal data structures to reflect this 626249259Sdim /// fact. 627249259Sdim void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) { 628249259Sdim // First, remove the old location of the specified constant in the map. 629249259Sdim typename MapTy::iterator OldI = FindExistingElement(C); 630249259Sdim assert(OldI != Map.end() && "Constant not found in constant table!"); 631249259Sdim assert(OldI->second == C && "Didn't find correct element?"); 632249259Sdim 633249259Sdim // Remove the old entry from the map. 634249259Sdim Map.erase(OldI); 635249259Sdim 636249259Sdim // Update the inverse map so that we know that this constant is now 637249259Sdim // located at descriptor I. 638249259Sdim if (HasLargeKey) { 639249259Sdim assert(I->second == C && "Bad inversemap entry!"); 640249259Sdim InverseMap[C] = I; 641249259Sdim } 642249259Sdim } 643249259Sdim 644249259Sdim void dump() const { 645249259Sdim DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); 646249259Sdim } 647249259Sdim}; 648249259Sdim 649249259Sdim// Unique map for aggregate constants 650249259Sdimtemplate<class TypeClass, class ConstantClass> 651249259Sdimclass ConstantAggrUniqueMap { 652249259Sdimpublic: 653249259Sdim typedef ArrayRef<Constant*> Operands; 654249259Sdim typedef std::pair<TypeClass*, Operands> LookupKey; 655249259Sdimprivate: 656249259Sdim struct MapInfo { 657249259Sdim typedef DenseMapInfo<ConstantClass*> ConstantClassInfo; 658249259Sdim typedef DenseMapInfo<Constant*> ConstantInfo; 659249259Sdim typedef DenseMapInfo<TypeClass*> TypeClassInfo; 660249259Sdim static inline ConstantClass* getEmptyKey() { 661249259Sdim return ConstantClassInfo::getEmptyKey(); 662249259Sdim } 663249259Sdim static inline ConstantClass* getTombstoneKey() { 664249259Sdim return ConstantClassInfo::getTombstoneKey(); 665249259Sdim } 666249259Sdim static unsigned getHashValue(const ConstantClass *CP) { 667249259Sdim SmallVector<Constant*, 8> CPOperands; 668249259Sdim CPOperands.reserve(CP->getNumOperands()); 669249259Sdim for (unsigned I = 0, E = CP->getNumOperands(); I < E; ++I) 670249259Sdim CPOperands.push_back(CP->getOperand(I)); 671249259Sdim return getHashValue(LookupKey(CP->getType(), CPOperands)); 672249259Sdim } 673249259Sdim static bool isEqual(const ConstantClass *LHS, const ConstantClass *RHS) { 674249259Sdim return LHS == RHS; 675249259Sdim } 676249259Sdim static unsigned getHashValue(const LookupKey &Val) { 677249259Sdim return hash_combine(Val.first, hash_combine_range(Val.second.begin(), 678249259Sdim Val.second.end())); 679249259Sdim } 680249259Sdim static bool isEqual(const LookupKey &LHS, const ConstantClass *RHS) { 681249259Sdim if (RHS == getEmptyKey() || RHS == getTombstoneKey()) 682249259Sdim return false; 683249259Sdim if (LHS.first != RHS->getType() 684249259Sdim || LHS.second.size() != RHS->getNumOperands()) 685249259Sdim return false; 686249259Sdim for (unsigned I = 0, E = RHS->getNumOperands(); I < E; ++I) { 687249259Sdim if (LHS.second[I] != RHS->getOperand(I)) 688249259Sdim return false; 689249259Sdim } 690249259Sdim return true; 691249259Sdim } 692249259Sdim }; 693249259Sdimpublic: 694249259Sdim typedef DenseMap<ConstantClass *, char, MapInfo> MapTy; 695249259Sdim 696249259Sdimprivate: 697249259Sdim /// Map - This is the main map from the element descriptor to the Constants. 698249259Sdim /// This is the primary way we avoid creating two of the same shape 699249259Sdim /// constant. 700249259Sdim MapTy Map; 701249259Sdim 702249259Sdimpublic: 703249259Sdim typename MapTy::iterator map_begin() { return Map.begin(); } 704249259Sdim typename MapTy::iterator map_end() { return Map.end(); } 705249259Sdim 706249259Sdim void freeConstants() { 707249259Sdim for (typename MapTy::iterator I=Map.begin(), E=Map.end(); 708249259Sdim I != E; ++I) { 709249259Sdim // Asserts that use_empty(). 710249259Sdim delete I->first; 711249259Sdim } 712249259Sdim } 713249259Sdim 714249259Sdimprivate: 715249259Sdim typename MapTy::iterator findExistingElement(ConstantClass *CP) { 716249259Sdim return Map.find(CP); 717249259Sdim } 718249259Sdim 719249259Sdim ConstantClass *Create(TypeClass *Ty, Operands V, typename MapTy::iterator I) { 720249259Sdim ConstantClass* Result = 721249259Sdim ConstantArrayCreator<ConstantClass,TypeClass>::create(Ty, V); 722249259Sdim 723249259Sdim assert(Result->getType() == Ty && "Type specified is not correct!"); 724249259Sdim Map[Result] = '\0'; 725249259Sdim 726249259Sdim return Result; 727249259Sdim } 728249259Sdimpublic: 729249259Sdim 730249259Sdim /// getOrCreate - Return the specified constant from the map, creating it if 731249259Sdim /// necessary. 732249259Sdim ConstantClass *getOrCreate(TypeClass *Ty, Operands V) { 733249259Sdim LookupKey Lookup(Ty, V); 734249259Sdim ConstantClass* Result = 0; 735249259Sdim 736249259Sdim typename MapTy::iterator I = Map.find_as(Lookup); 737249259Sdim // Is it in the map? 738249259Sdim if (I != Map.end()) 739249259Sdim Result = I->first; 740249259Sdim 741249259Sdim if (!Result) { 742249259Sdim // If no preexisting value, create one now... 743249259Sdim Result = Create(Ty, V, I); 744249259Sdim } 745249259Sdim 746249259Sdim return Result; 747249259Sdim } 748249259Sdim 749249259Sdim /// Find the constant by lookup key. 750249259Sdim typename MapTy::iterator find(LookupKey Lookup) { 751249259Sdim return Map.find_as(Lookup); 752249259Sdim } 753249259Sdim 754249259Sdim /// Insert the constant into its proper slot. 755249259Sdim void insert(ConstantClass *CP) { 756249259Sdim Map[CP] = '\0'; 757249259Sdim } 758249259Sdim 759249259Sdim /// Remove this constant from the map 760249259Sdim void remove(ConstantClass *CP) { 761249259Sdim typename MapTy::iterator I = findExistingElement(CP); 762249259Sdim assert(I != Map.end() && "Constant not found in constant table!"); 763249259Sdim assert(I->first == CP && "Didn't find correct element?"); 764249259Sdim Map.erase(I); 765249259Sdim } 766249259Sdim 767249259Sdim void dump() const { 768249259Sdim DEBUG(dbgs() << "Constant.cpp: ConstantUniqueMap\n"); 769249259Sdim } 770249259Sdim}; 771249259Sdim 772249259Sdim} 773249259Sdim 774249259Sdim#endif 775