diff options
author | Owen Anderson <resistor@mac.com> | 2009-08-04 20:25:11 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2009-08-04 20:25:11 +0000 |
commit | 556a7eb93873477106bfacb1b61a03a272407fcb (patch) | |
tree | 0fcc71e3d8dd3c289f4529427dcfc91331f03dfa /lib/VMCore/LLVMContextImpl.h | |
parent | 9dcecb924df97dee0a45b639a8bd1a364eba23e5 (diff) | |
download | external_llvm-556a7eb93873477106bfacb1b61a03a272407fcb.zip external_llvm-556a7eb93873477106bfacb1b61a03a272407fcb.tar.gz external_llvm-556a7eb93873477106bfacb1b61a03a272407fcb.tar.bz2 |
Privatize the last bit of Constant-creation state.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78097 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/LLVMContextImpl.h')
-rw-r--r-- | lib/VMCore/LLVMContextImpl.h | 407 |
1 files changed, 390 insertions, 17 deletions
diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 6d18933..d7ad74f 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -18,6 +18,8 @@ #include "llvm/LLVMContext.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/Operator.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/System/Mutex.h" @@ -34,6 +36,297 @@ namespace llvm { template<class ValType> struct ConstantTraits; + +/// UnaryConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement unary constant exprs. +class UnaryConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly one operand + void *operator new(size_t s) { + return User::operator new(s, 1); + } + UnaryConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) + : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { + Op<0>() = C; + } + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// BinaryConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement binary constant exprs. +class BinaryConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); + } + BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) + : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) { + Op<0>() = C1; + Op<1>() = C2; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// SelectConstantExpr - This class is private to Constants.cpp, and is used +/// behind the scenes to implement select constant exprs. +class SelectConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly three operands + void *operator new(size_t s) { + return User::operator new(s, 3); + } + SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ExtractElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// extractelement constant exprs. +class ExtractElementConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); + } + ExtractElementConstantExpr(Constant *C1, Constant *C2) + : ConstantExpr(cast<VectorType>(C1->getType())->getElementType(), + Instruction::ExtractElement, &Op<0>(), 2) { + Op<0>() = C1; + Op<1>() = C2; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// InsertElementConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertelement constant exprs. +class InsertElementConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly three operands + void *operator new(size_t s) { + return User::operator new(s, 3); + } + InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(C1->getType(), Instruction::InsertElement, + &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ShuffleVectorConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// shufflevector constant exprs. +class ShuffleVectorConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly three operands + void *operator new(size_t s) { + return User::operator new(s, 3); + } + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) + : ConstantExpr(VectorType::get( + cast<VectorType>(C1->getType())->getElementType(), + cast<VectorType>(C3->getType())->getNumElements()), + Instruction::ShuffleVector, + &Op<0>(), 3) { + Op<0>() = C1; + Op<1>() = C2; + Op<2>() = C3; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// ExtractValueConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// extractvalue constant exprs. +class ExtractValueConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly one operand + void *operator new(size_t s) { + return User::operator new(s, 1); + } + ExtractValueConstantExpr(Constant *Agg, + const SmallVector<unsigned, 4> &IdxList, + const Type *DestTy) + : ConstantExpr(DestTy, Instruction::ExtractValue, &Op<0>(), 1), + Indices(IdxList) { + Op<0>() = Agg; + } + + /// Indices - These identify which value to extract. + const SmallVector<unsigned, 4> Indices; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +/// InsertValueConstantExpr - This class is private to +/// Constants.cpp, and is used behind the scenes to implement +/// insertvalue constant exprs. +class InsertValueConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +public: + // allocate space for exactly one operand + void *operator new(size_t s) { + return User::operator new(s, 2); + } + InsertValueConstantExpr(Constant *Agg, Constant *Val, + const SmallVector<unsigned, 4> &IdxList, + const Type *DestTy) + : ConstantExpr(DestTy, Instruction::InsertValue, &Op<0>(), 2), + Indices(IdxList) { + Op<0>() = Agg; + Op<1>() = Val; + } + + /// Indices - These identify the position for the insertion. + const SmallVector<unsigned, 4> Indices; + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + + +/// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is +/// used behind the scenes to implement getelementpr constant exprs. +class GetElementPtrConstantExpr : public ConstantExpr { + GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList, + const Type *DestTy); +public: + static GetElementPtrConstantExpr *Create(Constant *C, + const std::vector<Constant*>&IdxList, + const Type *DestTy) { + return + new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +// 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. +struct CompareConstantExpr : public ConstantExpr { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + // allocate space for exactly two operands + void *operator new(size_t s) { + return User::operator new(s, 2); + } + unsigned short predicate; + CompareConstantExpr(const Type *ty, Instruction::OtherOps opc, + unsigned short pred, Constant* LHS, Constant* RHS) + : ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) { + Op<0>() = LHS; + Op<1>() = RHS; + } + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; + +template <> +struct OperandTraits<UnaryConstantExpr> : FixedNumOperandTraits<1> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryConstantExpr, Value) + +template <> +struct OperandTraits<BinaryConstantExpr> : FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryConstantExpr, Value) + +template <> +struct OperandTraits<SelectConstantExpr> : FixedNumOperandTraits<3> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectConstantExpr, Value) + +template <> +struct OperandTraits<ExtractElementConstantExpr> : FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementConstantExpr, Value) + +template <> +struct OperandTraits<InsertElementConstantExpr> : FixedNumOperandTraits<3> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) + +template <> +struct OperandTraits<ShuffleVectorConstantExpr> : FixedNumOperandTraits<3> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) + +template <> +struct OperandTraits<ExtractValueConstantExpr> : FixedNumOperandTraits<1> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractValueConstantExpr, Value) + +template <> +struct OperandTraits<InsertValueConstantExpr> : FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueConstantExpr, Value) + +template <> +struct OperandTraits<GetElementPtrConstantExpr> : VariadicOperandTraits<1> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrConstantExpr, Value) + + +template <> +struct OperandTraits<CompareConstantExpr> : FixedNumOperandTraits<2> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CompareConstantExpr, Value) + +struct ExprMapKeyType { + typedef SmallVector<unsigned, 4> IndexList; + + ExprMapKeyType(unsigned opc, + const std::vector<Constant*> &ops, + unsigned short pred = 0, + const IndexList &inds = IndexList()) + : opcode(opc), predicate(pred), operands(ops), indices(inds) {} + uint16_t opcode; + uint16_t predicate; + std::vector<Constant*> operands; + IndexList indices; + bool operator==(const ExprMapKeyType& that) const { + return this->opcode == that.opcode && + this->predicate == that.predicate && + this->operands == that.operands && + this->indices == that.indices; + } + bool operator<(const ExprMapKeyType & that) const { + return this->opcode < that.opcode || + (this->opcode == that.opcode && this->predicate < that.predicate) || + (this->opcode == that.opcode && this->predicate == that.predicate && + this->operands < that.operands) || + (this->opcode == that.opcode && this->predicate == that.predicate && + this->operands == that.operands && this->indices < that.indices); + } + + bool operator!=(const ExprMapKeyType& that) const { + return !(*this == that); + } +}; + // The number of operands for each ConstantCreator::create method is // determined by the ConstantTraits template. // ConstantCreator - A class that is used to create constants by @@ -42,26 +335,115 @@ struct ConstantTraits; // constant. // template<typename T, typename Alloc> -struct VISIBILITY_HIDDEN ConstantTraits< std::vector<T, Alloc> > { +struct ConstantTraits< std::vector<T, Alloc> > { static unsigned uses(const std::vector<T, Alloc>& v) { return v.size(); } }; template<class ConstantClass, class TypeClass, class ValType> -struct VISIBILITY_HIDDEN ConstantCreator { +struct ConstantCreator { static ConstantClass *create(const TypeClass *Ty, const ValType &V) { return new(ConstantTraits<ValType>::uses(V)) ConstantClass(Ty, V); } }; template<class ConstantClass, class TypeClass> -struct VISIBILITY_HIDDEN ConvertConstantType { +struct ConvertConstantType { static void convert(ConstantClass *OldC, const TypeClass *NewTy) { llvm_unreachable("This type cannot be converted!"); } }; +template<> +struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> { + static ConstantExpr *create(const 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]); + 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); + } + + // The compare instructions are weird. We have to encode the predicate + // value and it is combined with the instruction opcode by multiplying + // the opcode by one hundred. We must decode this to get the predicate. + if (V.opcode == Instruction::ICmp) + return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate, + V.operands[0], V.operands[1]); + if (V.opcode == Instruction::FCmp) + return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate, + V.operands[0], V.operands[1]); + llvm_unreachable("Invalid ConstantExpr!"); + return 0; + } +}; + +template<> +struct ConvertConstantType<ConstantExpr, Type> { + static void convert(ConstantExpr *OldC, const Type *NewTy) { + Constant *New; + switch (OldC->getOpcode()) { + case Instruction::Trunc: + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::BitCast: + New = ConstantExpr::getCast(OldC->getOpcode(), OldC->getOperand(0), + NewTy); + break; + case Instruction::Select: + New = ConstantExpr::getSelectTy(NewTy, OldC->getOperand(0), + OldC->getOperand(1), + OldC->getOperand(2)); + break; + default: + assert(OldC->getOpcode() >= Instruction::BinaryOpsBegin && + OldC->getOpcode() < Instruction::BinaryOpsEnd); + New = ConstantExpr::getTy(NewTy, OldC->getOpcode(), OldC->getOperand(0), + OldC->getOperand(1)); + break; + case Instruction::GetElementPtr: + // Make everyone now use a constant of the new type... + std::vector<Value*> Idx(OldC->op_begin()+1, OldC->op_end()); + New = ConstantExpr::getGetElementPtrTy(NewTy, OldC->getOperand(0), + &Idx[0], Idx.size()); + break; + } + + assert(New != OldC && "Didn't replace constant??"); + OldC->uncheckedReplaceAllUsesWith(New); + OldC->destroyConstant(); // This constant is now dead, destroy it. + } +}; + // ConstantAggregateZero does not take extra "value" argument... template<class ValType> struct ConstantCreator<ConstantAggregateZero, Type, ValType> { @@ -458,7 +840,7 @@ struct DenseMapAPFloatKeyInfo { static bool isPod() { return false; } }; -class LLVMContextImpl { +struct LLVMContextImpl { sys::SmartRWMutex<true> ConstantsLock; typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, @@ -491,25 +873,16 @@ class LLVMContextImpl { ValueMap<char, Type, UndefValue> UndefValueConstants; + ValueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants; + LLVMContext &Context; ConstantInt *TheTrueVal; ConstantInt *TheFalseVal; + LLVMContextImpl(LLVMContext &C); +private: LLVMContextImpl(); LLVMContextImpl(const LLVMContextImpl&); - - friend class ConstantInt; - friend class ConstantFP; - friend class ConstantStruct; - friend class ConstantArray; - friend class ConstantVector; - friend class ConstantAggregateZero; - friend class MDNode; - friend class MDString; - friend class ConstantPointerNull; - friend class UndefValue; -public: - LLVMContextImpl(LLVMContext &C); }; } |