-template<>
-struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> {
- static ConstantExpr *create(Type *Ty, const ExprMapKeyType &V,
- unsigned short pred = 0) {
- if (Instruction::isCast(V.opcode))
- return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
- if ((V.opcode >= Instruction::BinaryOpsBegin &&
- V.opcode < Instruction::BinaryOpsEnd))
- return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
- V.subclassoptionaldata);
- if (V.opcode == Instruction::Select)
- return new SelectConstantExpr(V.operands[0], V.operands[1],
- V.operands[2]);
- if (V.opcode == Instruction::ExtractElement)
- return new ExtractElementConstantExpr(V.operands[0], V.operands[1]);
- if (V.opcode == Instruction::InsertElement)
- return new InsertElementConstantExpr(V.operands[0], V.operands[1],
- V.operands[2]);
- if (V.opcode == Instruction::ShuffleVector)
- return new ShuffleVectorConstantExpr(V.operands[0], V.operands[1],
- V.operands[2]);
- if (V.opcode == Instruction::InsertValue)
- return new InsertValueConstantExpr(V.operands[0], V.operands[1],
- V.indices, Ty);
- if (V.opcode == Instruction::ExtractValue)
- return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
- if (V.opcode == Instruction::GetElementPtr) {
- std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end());
- return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
- V.subclassoptionaldata);
+struct InlineAsmKeyType {
+ StringRef AsmString;
+ StringRef Constraints;
+ FunctionType *FTy;
+ bool HasSideEffects;
+ bool IsAlignStack;
+ InlineAsm::AsmDialect AsmDialect;
+
+ InlineAsmKeyType(StringRef AsmString, StringRef Constraints,
+ FunctionType *FTy, bool HasSideEffects, bool IsAlignStack,
+ InlineAsm::AsmDialect AsmDialect)
+ : AsmString(AsmString), Constraints(Constraints), FTy(FTy),
+ HasSideEffects(HasSideEffects), IsAlignStack(IsAlignStack),
+ AsmDialect(AsmDialect) {}
+ InlineAsmKeyType(const InlineAsm *Asm, SmallVectorImpl<Constant *> &)
+ : AsmString(Asm->getAsmString()), Constraints(Asm->getConstraintString()),
+ FTy(Asm->getFunctionType()), HasSideEffects(Asm->hasSideEffects()),
+ IsAlignStack(Asm->isAlignStack()), AsmDialect(Asm->getDialect()) {}
+
+ bool operator==(const InlineAsmKeyType &X) const {
+ return HasSideEffects == X.HasSideEffects &&
+ IsAlignStack == X.IsAlignStack && AsmDialect == X.AsmDialect &&
+ AsmString == X.AsmString && Constraints == X.Constraints &&
+ FTy == X.FTy;
+ }
+ bool operator==(const InlineAsm *Asm) const {
+ return HasSideEffects == Asm->hasSideEffects() &&
+ IsAlignStack == Asm->isAlignStack() &&
+ AsmDialect == Asm->getDialect() &&
+ AsmString == Asm->getAsmString() &&
+ Constraints == Asm->getConstraintString() &&
+ FTy == Asm->getFunctionType();
+ }
+ unsigned getHash() const {
+ return hash_combine(AsmString, Constraints, HasSideEffects, IsAlignStack,
+ AsmDialect, FTy);
+ }
+
+ typedef ConstantInfo<InlineAsm>::TypeClass TypeClass;
+ InlineAsm *create(TypeClass *Ty) const {
+ assert(PointerType::getUnqual(FTy) == Ty);
+ return new InlineAsm(FTy, AsmString, Constraints, HasSideEffects,
+ IsAlignStack, AsmDialect);
+ }
+};
+
+struct ConstantExprKeyType {
+ uint8_t Opcode;
+ uint8_t SubclassOptionalData;
+ uint16_t SubclassData;
+ ArrayRef<Constant *> Ops;
+ ArrayRef<unsigned> Indexes;
+ Type *ExplicitTy;
+
+ ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops,
+ unsigned short SubclassData = 0,
+ unsigned short SubclassOptionalData = 0,
+ ArrayRef<unsigned> Indexes = None,
+ Type *ExplicitTy = nullptr)
+ : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData),
+ SubclassData(SubclassData), Ops(Ops), Indexes(Indexes),
+ ExplicitTy(ExplicitTy) {}
+ ConstantExprKeyType(ArrayRef<Constant *> Operands, const ConstantExpr *CE)
+ : Opcode(CE->getOpcode()),
+ SubclassOptionalData(CE->getRawSubclassOptionalData()),
+ SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands),
+ Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {}
+ ConstantExprKeyType(const ConstantExpr *CE,
+ SmallVectorImpl<Constant *> &Storage)
+ : Opcode(CE->getOpcode()),
+ SubclassOptionalData(CE->getRawSubclassOptionalData()),
+ SubclassData(CE->isCompare() ? CE->getPredicate() : 0),
+ Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()) {
+ assert(Storage.empty() && "Expected empty storage");
+ for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I)
+ Storage.push_back(CE->getOperand(I));
+ Ops = Storage;
+ }
+
+ bool operator==(const ConstantExprKeyType &X) const {
+ return Opcode == X.Opcode && SubclassData == X.SubclassData &&
+ SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops &&
+ Indexes == X.Indexes;
+ }
+
+ bool operator==(const ConstantExpr *CE) const {
+ if (Opcode != CE->getOpcode())
+ return false;
+ if (SubclassOptionalData != CE->getRawSubclassOptionalData())
+ return false;
+ if (Ops.size() != CE->getNumOperands())
+ return false;
+ if (SubclassData != (CE->isCompare() ? CE->getPredicate() : 0))
+ return false;
+ for (unsigned I = 0, E = Ops.size(); I != E; ++I)
+ if (Ops[I] != CE->getOperand(I))
+ return false;
+ if (Indexes != (CE->hasIndices() ? CE->getIndices() : ArrayRef<unsigned>()))
+ return false;
+ return true;
+ }
+
+ unsigned getHash() const {
+ return hash_combine(Opcode, SubclassOptionalData, SubclassData,
+ hash_combine_range(Ops.begin(), Ops.end()),
+ hash_combine_range(Indexes.begin(), Indexes.end()));
+ }
+
+ typedef ConstantInfo<ConstantExpr>::TypeClass TypeClass;
+ ConstantExpr *create(TypeClass *Ty) const {
+ switch (Opcode) {
+ default:
+ if (Instruction::isCast(Opcode))
+ return new UnaryConstantExpr(Opcode, Ops[0], Ty);
+ if ((Opcode >= Instruction::BinaryOpsBegin &&
+ Opcode < Instruction::BinaryOpsEnd))
+ return new BinaryConstantExpr(Opcode, Ops[0], Ops[1],
+ SubclassOptionalData);
+ llvm_unreachable("Invalid ConstantExpr!");
+ case Instruction::Select:
+ return new SelectConstantExpr(Ops[0], Ops[1], Ops[2]);
+ case Instruction::ExtractElement:
+ return new ExtractElementConstantExpr(Ops[0], Ops[1]);
+ case Instruction::InsertElement:
+ return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]);
+ case Instruction::ShuffleVector:
+ return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]);
+ case Instruction::InsertValue:
+ return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty);
+ case Instruction::ExtractValue:
+ return new ExtractValueConstantExpr(Ops[0], Indexes, Ty);
+ case Instruction::GetElementPtr:
+ return GetElementPtrConstantExpr::Create(
+ ExplicitTy ? ExplicitTy
+ : cast<PointerType>(Ops[0]->getType()->getScalarType())
+ ->getElementType(),
+ Ops[0], Ops.slice(1), Ty, SubclassOptionalData);
+ case Instruction::ICmp:
+ return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData,
+ Ops[0], Ops[1]);
+ case Instruction::FCmp:
+ return new CompareConstantExpr(Ty, Instruction::FCmp, SubclassData,
+ Ops[0], Ops[1]);