diff options
Diffstat (limited to 'llvm/lib/IR/ConstantsContext.h')
-rw-r--r-- | llvm/lib/IR/ConstantsContext.h | 164 |
1 files changed, 123 insertions, 41 deletions
diff --git a/llvm/lib/IR/ConstantsContext.h b/llvm/lib/IR/ConstantsContext.h index f5e2481f3903c..95c5ab6d0ee4d 100644 --- a/llvm/lib/IR/ConstantsContext.h +++ b/llvm/lib/IR/ConstantsContext.h @@ -26,6 +26,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/OperandTraits.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" @@ -42,7 +43,7 @@ namespace llvm { /// UnaryConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement unary constant exprs. -class UnaryConstantExpr : public ConstantExpr { +class UnaryConstantExpr final : public ConstantExpr { public: UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty) : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { @@ -55,11 +56,19 @@ public: } DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + static bool classof(const ConstantExpr *CE) { + return Instruction::isCast(CE->getOpcode()) || + Instruction::isUnaryOp(CE->getOpcode()); + } + static bool classof(const Value *V) { + return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)); + } }; /// BinaryConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement binary constant exprs. -class BinaryConstantExpr : public ConstantExpr { +class BinaryConstantExpr final : public ConstantExpr { public: BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags) @@ -76,11 +85,18 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + static bool classof(const ConstantExpr *CE) { + return Instruction::isBinaryOp(CE->getOpcode()); + } + static bool classof(const Value *V) { + return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)); + } }; /// SelectConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement select constant exprs. -class SelectConstantExpr : public ConstantExpr { +class SelectConstantExpr final : public ConstantExpr { public: SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { @@ -96,12 +112,19 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + static bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::Select; + } + static bool classof(const Value *V) { + return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)); + } }; /// ExtractElementConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// extractelement constant exprs. -class ExtractElementConstantExpr : public ConstantExpr { +class ExtractElementConstantExpr final : public ConstantExpr { public: ExtractElementConstantExpr(Constant *C1, Constant *C2) : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), @@ -117,12 +140,19 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + static bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::ExtractElement; + } + static bool classof(const Value *V) { + return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)); + } }; /// InsertElementConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// insertelement constant exprs. -class InsertElementConstantExpr : public ConstantExpr { +class InsertElementConstantExpr final : public ConstantExpr { public: InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) : ConstantExpr(C1->getType(), Instruction::InsertElement, @@ -139,37 +169,54 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + static bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::InsertElement; + } + static bool classof(const Value *V) { + return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)); + } }; /// ShuffleVectorConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// shufflevector constant exprs. -class ShuffleVectorConstantExpr : public ConstantExpr { +class ShuffleVectorConstantExpr final : public ConstantExpr { public: - ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(VectorType::get( - cast<VectorType>(C1->getType())->getElementType(), - cast<VectorType>(C3->getType())->getElementCount()), - Instruction::ShuffleVector, - &Op<0>(), 3) { + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, ArrayRef<int> Mask) + : ConstantExpr(VectorType::get( + cast<VectorType>(C1->getType())->getElementType(), + Mask.size(), isa<ScalableVectorType>(C1->getType())), + Instruction::ShuffleVector, &Op<0>(), 2) { + assert(ShuffleVectorInst::isValidOperands(C1, C2, Mask) && + "Invalid shuffle vector instruction operands!"); Op<0>() = C1; Op<1>() = C2; - Op<2>() = C3; + ShuffleMask.assign(Mask.begin(), Mask.end()); + ShuffleMaskForBitcode = + ShuffleVectorInst::convertShuffleMaskForBitcode(Mask, getType()); } - // allocate space for exactly three operands - void *operator new(size_t s) { - return User::operator new(s, 3); - } + SmallVector<int, 4> ShuffleMask; + Constant *ShuffleMaskForBitcode; + + void *operator new(size_t s) { return User::operator new(s, 2); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + static bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::ShuffleVector; + } + static bool classof(const Value *V) { + return isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)); + } }; /// ExtractValueConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// extractvalue constant exprs. -class ExtractValueConstantExpr : public ConstantExpr { +class ExtractValueConstantExpr final : public ConstantExpr { public: ExtractValueConstantExpr(Constant *Agg, ArrayRef<unsigned> IdxList, Type *DestTy) @@ -200,7 +247,7 @@ public: /// InsertValueConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// insertvalue constant exprs. -class InsertValueConstantExpr : public ConstantExpr { +class InsertValueConstantExpr final : public ConstantExpr { public: InsertValueConstantExpr(Constant *Agg, Constant *Val, ArrayRef<unsigned> IdxList, Type *DestTy) @@ -231,7 +278,7 @@ public: /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementpr constant exprs. -class GetElementPtrConstantExpr : public ConstantExpr { +class GetElementPtrConstantExpr final : public ConstantExpr { Type *SrcElementTy; Type *ResElementTy; @@ -265,7 +312,7 @@ public: // CompareConstantExpr - This class is private to Constants.cpp, and is used // behind the scenes to implement ICmp and FCmp constant expressions. This is // needed in order to store the predicate value for these instructions. -class CompareConstantExpr : public ConstantExpr { +class CompareConstantExpr final : public ConstantExpr { public: unsigned short predicate; CompareConstantExpr(Type *ty, Instruction::OtherOps opc, @@ -319,7 +366,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) template <> struct OperandTraits<ShuffleVectorConstantExpr> - : public FixedNumOperandTraits<ShuffleVectorConstantExpr, 3> {}; + : public FixedNumOperandTraits<ShuffleVectorConstantExpr, 2> {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) template <> @@ -454,42 +501,64 @@ struct InlineAsmKeyType { InlineAsm *create(TypeClass *Ty) const { assert(PointerType::getUnqual(FTy) == Ty); - return new InlineAsm(FTy, AsmString, Constraints, HasSideEffects, - IsAlignStack, AsmDialect); + return new InlineAsm(FTy, std::string(AsmString), std::string(Constraints), + HasSideEffects, IsAlignStack, AsmDialect); } }; struct ConstantExprKeyType { +private: uint8_t Opcode; uint8_t SubclassOptionalData; uint16_t SubclassData; ArrayRef<Constant *> Ops; ArrayRef<unsigned> Indexes; + ArrayRef<int> ShuffleMask; Type *ExplicitTy; + static ArrayRef<int> getShuffleMaskIfValid(const ConstantExpr *CE) { + if (CE->getOpcode() == Instruction::ShuffleVector) + return CE->getShuffleMask(); + return None; + } + + static ArrayRef<unsigned> getIndicesIfValid(const ConstantExpr *CE) { + if (CE->hasIndices()) + return CE->getIndices(); + return None; + } + + static Type *getSourceElementTypeIfValid(const ConstantExpr *CE) { + if (auto *GEPCE = dyn_cast<GetElementPtrConstantExpr>(CE)) + return GEPCE->getSourceElementType(); + return nullptr; + } + +public: ConstantExprKeyType(unsigned Opcode, ArrayRef<Constant *> Ops, unsigned short SubclassData = 0, unsigned short SubclassOptionalData = 0, ArrayRef<unsigned> Indexes = None, + ArrayRef<int> ShuffleMask = None, Type *ExplicitTy = nullptr) : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData), SubclassData(SubclassData), Ops(Ops), Indexes(Indexes), - ExplicitTy(ExplicitTy) {} + ShuffleMask(ShuffleMask), 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>()), - ExplicitTy(nullptr) {} + Indexes(getIndicesIfValid(CE)), ShuffleMask(getShuffleMaskIfValid(CE)), + ExplicitTy(getSourceElementTypeIfValid(CE)) {} 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>()), - ExplicitTy(nullptr) { + Indexes(getIndicesIfValid(CE)), ShuffleMask(getShuffleMaskIfValid(CE)), + ExplicitTy(getSourceElementTypeIfValid(CE)) { assert(Storage.empty() && "Expected empty storage"); for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I) Storage.push_back(CE->getOperand(I)); @@ -499,7 +568,8 @@ struct ConstantExprKeyType { bool operator==(const ConstantExprKeyType &X) const { return Opcode == X.Opcode && SubclassData == X.SubclassData && SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops && - Indexes == X.Indexes; + Indexes == X.Indexes && ShuffleMask == X.ShuffleMask && + ExplicitTy == X.ExplicitTy; } bool operator==(const ConstantExpr *CE) const { @@ -514,15 +584,21 @@ struct ConstantExprKeyType { 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>())) + if (Indexes != getIndicesIfValid(CE)) + return false; + if (ShuffleMask != getShuffleMaskIfValid(CE)) + return false; + if (ExplicitTy != getSourceElementTypeIfValid(CE)) 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())); + return hash_combine( + Opcode, SubclassOptionalData, SubclassData, + hash_combine_range(Ops.begin(), Ops.end()), + hash_combine_range(Indexes.begin(), Indexes.end()), + hash_combine_range(ShuffleMask.begin(), ShuffleMask.end()), ExplicitTy); } using TypeClass = ConstantInfo<ConstantExpr>::TypeClass; @@ -546,17 +622,14 @@ struct ConstantExprKeyType { case Instruction::InsertElement: return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]); case Instruction::ShuffleVector: - return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]); + return new ShuffleVectorConstantExpr(Ops[0], Ops[1], ShuffleMask); 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); + return GetElementPtrConstantExpr::Create(ExplicitTy, Ops[0], Ops.slice(1), + Ty, SubclassOptionalData); case Instruction::ICmp: return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData, Ops[0], Ops[1]); @@ -567,6 +640,10 @@ struct ConstantExprKeyType { } }; +// Free memory for a given constant. Assumes the constant has already been +// removed from all relevant maps. +void deleteConstant(Constant *C); + template <class ConstantClass> class ConstantUniqueMap { public: using ValType = typename ConstantInfo<ConstantClass>::ValType; @@ -630,7 +707,7 @@ public: void freeConstants() { for (auto &I : Map) - delete I; // Asserts that use_empty(). + deleteConstant(I); } private: @@ -703,6 +780,11 @@ public: } }; +template <> inline void ConstantUniqueMap<InlineAsm>::freeConstants() { + for (auto &I : Map) + delete I; +} + } // end namespace llvm #endif // LLVM_LIB_IR_CONSTANTSCONTEXT_H |