From ff2b7f3cd66793e36a36500acb36b9d1a0489d4c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 24 Jan 2012 05:42:11 +0000 Subject: [PATCH] Add some accessor methods to CAZ and UndefValue that help simplify clients. Make some CDS methods public. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148785 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Constants.h | 41 ++++++++++++++++++++++--- lib/VMCore/Constants.cpp | 66 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 97 insertions(+), 10 deletions(-) diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 1fc33084943..a7480d2a890 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -310,10 +310,22 @@ protected: return User::operator new(s, 0); } public: - static ConstantAggregateZero* get(Type *Ty); + static ConstantAggregateZero *get(Type *Ty); virtual void destroyConstant(); + /// getSequentialElement - If this CAZ has array or vector type, return a zero + /// with the right element type. + Constant *getSequentialElement(); + + /// getStructElement - If this CAZ has struct type, return a zero with the + /// right element type for the specified element. + Constant *getStructElement(unsigned Elt); + + /// getElementValue - Return a zero of the right value for the specified GEP + /// index. + Constant *getElementValue(Constant *C); + /// Methods for support type inquiry through isa, cast, and dyn_cast: /// static bool classof(const ConstantAggregateZero *) { return true; } @@ -568,8 +580,12 @@ protected: } public: - virtual void destroyConstant(); - + /// isElementTypeCompatible - Return true if a ConstantDataSequential can be + /// formed with a vector or array of the specified element type. + /// ConstantDataArray only works with normal float and int types that are + /// stored densely in memory, not with things like i42 or x86_f80. + static bool isElementTypeCompatible(const Type *Ty); + /// getElementAsInteger - If this is a sequential container of integers (of /// any size), return the specified element in the low bits of a uint64_t. uint64_t getElementAsInteger(unsigned i) const; @@ -601,7 +617,13 @@ public: /// getElementType - Return the element type of the array/vector. Type *getElementType() const; + /// getElementByteSize - Return the size (in bytes) of each element in the + /// array/vector. The size of the elements is known to be a multiple of one + /// byte. + uint64_t getElementByteSize() const; + virtual void destroyConstant(); + /// Methods for support type inquiry through isa, cast, and dyn_cast: /// static bool classof(const ConstantDataSequential *) { return true; } @@ -610,7 +632,6 @@ public: V->getValueID() == ConstantDataVectorVal; } private: - uint64_t getElementByteSize() const; const char *getElementPointer(unsigned Elt) const; }; @@ -1074,6 +1095,18 @@ public: /// static UndefValue *get(Type *T); + /// getSequentialElement - If this Undef has array or vector type, return a + /// undef with the right element type. + UndefValue *getSequentialElement(); + + /// getStructElement - If this undef has struct type, return a undef with the + /// right element type for the specified element. + UndefValue *getStructElement(unsigned Elt); + + /// getElementValue - Return an undef of the right value for the specified GEP + /// index. + UndefValue *getElementValue(Constant *C); + virtual void destroyConstant(); /// Methods for support type inquiry through isa, cast, and dyn_cast: diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 86087e4efba..df98d758644 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -598,6 +598,57 @@ bool ConstantFP::isExactlyValue(const APFloat &V) const { return Val.bitwiseIsEqual(V); } +//===----------------------------------------------------------------------===// +// ConstantAggregateZero Implementation +//===----------------------------------------------------------------------===// + +/// getSequentialElement - If this CAZ has array or vector type, return a zero +/// with the right element type. +Constant *ConstantAggregateZero::getSequentialElement() { + return Constant::getNullValue( + cast(getType())->getElementType()); +} + +/// getStructElement - If this CAZ has struct type, return a zero with the +/// right element type for the specified element. +Constant *ConstantAggregateZero::getStructElement(unsigned Elt) { + return Constant::getNullValue( + cast(getType())->getElementType(Elt)); +} + +/// getElementValue - Return a zero of the right value for the specified GEP +/// index if we can, otherwise return null (e.g. if C is a ConstantExpr). +Constant *ConstantAggregateZero::getElementValue(Constant *C) { + if (isa(getType())) + return getSequentialElement(); + return getStructElement(cast(C)->getZExtValue()); +} + +//===----------------------------------------------------------------------===// +// UndefValue Implementation +//===----------------------------------------------------------------------===// + +/// getSequentialElement - If this undef has array or vector type, return an +/// undef with the right element type. +UndefValue *UndefValue::getSequentialElement() { + return UndefValue::get(cast(getType())->getElementType()); +} + +/// getStructElement - If this undef has struct type, return a zero with the +/// right element type for the specified element. +UndefValue *UndefValue::getStructElement(unsigned Elt) { + return UndefValue::get(cast(getType())->getElementType(Elt)); +} + +/// getElementValue - Return an undef of the right value for the specified GEP +/// index if we can, otherwise return null (e.g. if C is a ConstantExpr). +UndefValue *UndefValue::getElementValue(Constant *C) { + if (isa(getType())) + return getSequentialElement(); + return getStructElement(cast(C)->getZExtValue()); +} + + //===----------------------------------------------------------------------===// // ConstantXXX Classes //===----------------------------------------------------------------------===// @@ -990,6 +1041,7 @@ bool ConstantFP::isValueValidForType(Type *Ty, const APFloat& Val) { } } + //===----------------------------------------------------------------------===// // Factory Function Implementation @@ -1004,7 +1056,7 @@ ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) { return Entry; } -/// destroyConstant - Remove the constant from the constant table... +/// destroyConstant - Remove the constant from the constant table. /// void ConstantAggregateZero::destroyConstant() { getContext().pImpl->CAZConstants.erase(getType()); @@ -1924,9 +1976,11 @@ Type *ConstantDataSequential::getElementType() const { return getType()->getElementType(); } -/// isElementTypeConstantDataCompatible - Return true if this type is valid for -/// a ConstantDataSequential. This is i8/i16/i32/i64/float/double. -static bool isElementTypeConstantDataCompatible(const Type *Ty) { +/// isElementTypeCompatible - Return true if a ConstantDataSequential can be +/// formed with a vector or array of the specified element type. +/// ConstantDataArray only works with normal float and int types that are +/// stored densely in memory, not with things like i42 or x86_f80. +bool ConstantDataSequential::isElementTypeCompatible(const Type *Ty) { if (Ty->isFloatTy() || Ty->isDoubleTy()) return true; if (const IntegerType *IT = dyn_cast(Ty)) { switch (IT->getBitWidth()) { @@ -1960,13 +2014,13 @@ static bool isAllZeros(StringRef Arr) { return false; return true; } + /// getImpl - This is the underlying implementation of all of the /// ConstantDataSequential::get methods. They all thunk down to here, providing /// the correct element type. We take the bytes in as an StringRef because /// we *want* an underlying "char*" to avoid TBAA type punning violations. Constant *ConstantDataSequential::getImpl(StringRef Elements, Type *Ty) { - assert(isElementTypeConstantDataCompatible(cast(Ty)-> - getElementType())); + assert(isElementTypeCompatible(cast(Ty)->getElementType())); // If the elements are all zero, return a CAZ, which is more dense. if (isAllZeros(Elements)) return ConstantAggregateZero::get(Ty);