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