diff options
-rw-r--r-- | include/llvm/Constants.h | 56 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 106 |
2 files changed, 106 insertions, 56 deletions
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 0921cbb21b..6a02c5df21 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -309,6 +309,36 @@ public: } }; +//===--------------------------------------------------------------------------- +/// ConstantAggregateZero - All zero aggregate value +/// +class ConstantAggregateZero : public Constant { + friend struct ConstantCreator<ConstantAggregateZero, Type, char>; + ConstantAggregateZero(const ConstantAggregateZero &); // DO NOT IMPLEMENT +protected: + ConstantAggregateZero(const Type *Ty) : Constant(Ty) {} +public: + /// get() - static factory method for creating a null aggregate. It is + /// illegal to call this method with a non-aggregate type. + static Constant *get(const Type *Ty); + + /// isNullValue - Return true if this is the value that would be returned by + /// getNullValue. + virtual bool isNullValue() const { return true; } + + virtual void destroyConstant(); + virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking = false); + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + /// + static inline bool classof(const ConstantAggregateZero *) { return true; } + static bool classof(const Constant *CPV); + static inline bool classof(const Value *V) { + return isa<Constant>(V) && classof(cast<Constant>(V)); + } +}; + //===--------------------------------------------------------------------------- /// ConstantArray - Constant Array Declarations @@ -345,19 +375,9 @@ public: inline const std::vector<Use> &getValues() const { return Operands; } /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. - virtual bool isNullValue() const { - // FIXME: This should be made to be MUCH faster. Just check against well - // known null value! - if (getNumOperands()) { - const Constant *First = cast<Constant>(getOperand(0)); - if (!First->isNullValue()) return false; - for (unsigned i = 1, e = getNumOperands(); i != e; ++i) - if (cast<Constant>(getOperand(i)) != First) - return false; - } - return true; - } + /// getNullValue. This always returns false because zero arrays are always + /// created as ConstantAggregateZero objects. + virtual bool isNullValue() const { return false; } virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, @@ -395,14 +415,10 @@ public: inline const std::vector<Use> &getValues() const { return Operands; } /// isNullValue - Return true if this is the value that would be returned by - /// getNullValue. + /// getNullValue. This always returns false because zero structs are always + /// created as ConstantAggregateZero objects. virtual bool isNullValue() const { - // FIXME: This should be made to be MUCH faster. Just check against well - // known null value! - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (!cast<Constant>(getOperand(i))->isNullValue()) - return false; - return true; + return false; } virtual void destroyConstant(); diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index e13a1daad5..dac23aea55 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -64,8 +64,6 @@ void Constant::destroyConstantImpl() { delete this; } -static std::map<const Type *, Constant*> NullValues; - // Static constructor to create a '0' constant of arbitrary type... Constant *Constant::getNullValue(const Type *Ty) { switch (Ty->getPrimitiveID()) { @@ -118,35 +116,9 @@ Constant *Constant::getNullValue(const Type *Ty) { case Type::PointerTyID: return ConstantPointerNull::get(cast<PointerType>(Ty)); - case Type::StructTyID: { - if (!Ty->isAbstract()) - if (Constant *V = NullValues[Ty]) - return V; - - const StructType *ST = cast<StructType>(Ty); - std::vector<Constant*> Elements; - Elements.resize(ST->getNumElements()); - for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) - Elements[i] = Constant::getNullValue(ST->getElementType(i)); - Constant *Ret = ConstantStruct::get(ST, Elements); - if (!Ty->isAbstract()) - NullValues[Ty] = Ret; - return Ret; - } - case Type::ArrayTyID: { - if (!Ty->isAbstract()) - if (Constant *V = NullValues[Ty]) - return V; - - const ArrayType *AT = cast<ArrayType>(Ty); - Constant *El = Constant::getNullValue(AT->getElementType()); - unsigned NumElements = AT->getNumElements(); - Constant *Ret = ConstantArray::get(AT, - std::vector<Constant*>(NumElements, El)); - if (!Ty->isAbstract()) - NullValues[Ty] = Ret; - return Ret; - } + case Type::StructTyID: + case Type::ArrayTyID: + return ConstantAggregateZero::get(Ty); default: // Function, Type, Label, or Opaque type? assert(0 && "Cannot create a null constant of that type!"); @@ -347,11 +319,15 @@ bool ConstantFP::classof(const Constant *CPV) { return ((Ty == Type::FloatTy || Ty == Type::DoubleTy) && !isa<ConstantExpr>(CPV)); } +bool ConstantAggregateZero::classof(const Constant *CPV) { + return (isa<ArrayType>(CPV->getType()) || isa<StructType>(CPV->getType())) && + CPV->isNullValue(); +} bool ConstantArray::classof(const Constant *CPV) { - return isa<ArrayType>(CPV->getType()) && !isa<ConstantExpr>(CPV); + return isa<ArrayType>(CPV->getType()) && !CPV->isNullValue(); } bool ConstantStruct::classof(const Constant *CPV) { - return isa<StructType>(CPV->getType()) && !isa<ConstantExpr>(CPV); + return isa<StructType>(CPV->getType()) && !CPV->isNullValue(); } bool ConstantPointerNull::classof(const Constant *CPV) { @@ -765,6 +741,50 @@ ConstantFP *ConstantFP::get(const Type *Ty, double V) { } } +//---- ConstantAggregateZero::get() implementation... +// +namespace llvm { + // ConstantAggregateZero does not take extra "value" argument... + template<class ValType> + struct ConstantCreator<ConstantAggregateZero, Type, ValType> { + static ConstantAggregateZero *create(const Type *Ty, const ValType &V){ + return new ConstantAggregateZero(Ty); + } + }; + + template<> + struct ConvertConstantType<ConstantAggregateZero, Type> { + static void convert(ConstantAggregateZero *OldC, const Type *NewTy) { + // Make everyone now use a constant of the new type... + Constant *New = ConstantAggregateZero::get(NewTy); + assert(New != OldC && "Didn't replace constant??"); + OldC->uncheckedReplaceAllUsesWith(New); + OldC->destroyConstant(); // This constant is now dead, destroy it. + } + }; +} + +static ValueMap<char, Type, ConstantAggregateZero> AggZeroConstants; + +Constant *ConstantAggregateZero::get(const Type *Ty) { + return AggZeroConstants.getOrCreate(Ty, 0); +} + +// destroyConstant - Remove the constant from the constant table... +// +void ConstantAggregateZero::destroyConstant() { + AggZeroConstants.remove(this); + destroyConstantImpl(); +} + +void ConstantAggregateZero::replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking) { + assert(0 && "No uses!"); + abort(); +} + + + //---- ConstantArray::get() implementation... // namespace llvm { @@ -787,8 +807,17 @@ static ValueMap<std::vector<Constant*>, ArrayType, ConstantArray> ArrayConstants; Constant *ConstantArray::get(const ArrayType *Ty, - const std::vector<Constant*> &V) { - return ArrayConstants.getOrCreate(Ty, V); + const std::vector<Constant*> &V) { + // If this is an all-zero array, return a ConstantAggregateZero object + if (!V.empty()) { + Constant *C = V[0]; + if (!C->isNullValue()) + return ArrayConstants.getOrCreate(Ty, V); + for (unsigned i = 1, e = V.size(); i != e; ++i) + if (V[i] != C) + return ArrayConstants.getOrCreate(Ty, V); + } + return ConstantAggregateZero::get(Ty); } // destroyConstant - Remove the constant from the constant table... @@ -868,7 +897,12 @@ static ValueMap<std::vector<Constant*>, StructType, Constant *ConstantStruct::get(const StructType *Ty, const std::vector<Constant*> &V) { - return StructConstants.getOrCreate(Ty, V); + // Create a ConstantAggregateZero value if all elements are zeros... + for (unsigned i = 0, e = V.size(); i != e; ++i) + if (!V[i]->isNullValue()) + return StructConstants.getOrCreate(Ty, V); + + return ConstantAggregateZero::get(Ty); } // destroyConstant - Remove the constant from the constant table... |