diff options
author | Brian Gaeke <gaeke@uiuc.edu> | 2004-08-20 06:00:58 +0000 |
---|---|---|
committer | Brian Gaeke <gaeke@uiuc.edu> | 2004-08-20 06:00:58 +0000 |
commit | 715c90ba524e736190a6380695ab337eeb5148be (patch) | |
tree | 0ab6881edc06308fc09116d695a55ccbd096cb5f /lib/VMCore | |
parent | 4e5b9e136f2eafcb2ab4c5b968307c2678e16a96 (diff) | |
download | external_llvm-715c90ba524e736190a6380695ab337eeb5148be.zip external_llvm-715c90ba524e736190a6380695ab337eeb5148be.tar.gz external_llvm-715c90ba524e736190a6380695ab337eeb5148be.tar.bz2 |
Packed types, brought to you by Brad Jones
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15938 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 23 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 92 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 6 | ||||
-rw-r--r-- | lib/VMCore/Type.cpp | 84 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 5 |
5 files changed, 206 insertions, 4 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 4cfba76..9fc772e 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -323,6 +323,13 @@ static void calcTypeName(const Type *Ty, Result += "]"; break; } + case Type::PackedTyID: { + const PackedType *PTy = cast<PackedType>(Ty); + Result += "<" + utostr(PTy->getNumElements()) + " x "; + calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result); + Result += ">"; + break; + } case Type::OpaqueTyID: Result += "opaque"; break; @@ -492,6 +499,22 @@ static void WriteConstantInt(std::ostream &Out, const Constant *CV, } Out << " }"; + } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) { + const Type *ETy = CP->getType()->getElementType(); + assert(CP->getNumOperands() > 0 && + "Number of operands for a PackedConst must be > 0"); + Out << '<'; + Out << ' '; + printTypeInt(Out, ETy, TypeTable); + WriteAsOperandInternal(Out, CP->getOperand(0), + PrintName, TypeTable, Machine); + for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { + Out << ", "; + printTypeInt(Out, ETy, TypeTable); + WriteAsOperandInternal(Out, CP->getOperand(i), PrintName, + TypeTable, Machine); + } + Out << " >"; } else if (isa<ConstantPointerNull>(CV)) { Out << "null"; diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 69f1a78..8b28c0d 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -120,6 +120,7 @@ Constant *Constant::getNullValue(const Type *Ty) { case Type::StructTyID: case Type::ArrayTyID: + case Type::PackedTyID: return ConstantAggregateZero::get(Ty); default: // Function, Label, or Opaque type? @@ -268,6 +269,17 @@ ConstantStruct::ConstantStruct(const StructType *T, } } +ConstantPacked::ConstantPacked(const PackedType *T, + const std::vector<Constant*> &V) : Constant(T) { + Operands.reserve(V.size()); + for (unsigned i = 0, e = V.size(); i != e; ++i) { + assert(V[i]->getType() == T->getElementType() || + (T->isAbstract() && + V[i]->getType()->getTypeID() == T->getElementType()->getTypeID())); + Operands.push_back(Use(V[i], this)); + } +} + ConstantExpr::ConstantExpr(unsigned Opcode, Constant *C, const Type *Ty) : Constant(Ty, ConstantExprVal), iType(Opcode) { Operands.reserve(1); @@ -484,6 +496,31 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To, destroyConstant(); } +void ConstantPacked::replaceUsesOfWithOnConstant(Value *From, Value *To, + bool DisableChecking) { + assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!"); + + std::vector<Constant*> Values; + Values.reserve(getNumOperands()); // Build replacement array... + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { + Constant *Val = getOperand(i); + if (Val == From) Val = cast<Constant>(To); + Values.push_back(Val); + } + + Constant *Replacement = ConstantPacked::get(getType(), Values); + assert(Replacement != this && "I didn't contain From!"); + + // Everyone using this now uses the replacement... + if (DisableChecking) + uncheckedReplaceAllUsesWith(Replacement); + else + replaceAllUsesWith(Replacement); + + // Delete the old constant! + destroyConstant(); +} + void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, bool DisableChecking) { assert(isa<Constant>(ToV) && "Cannot make Constant refer to non-constant!"); @@ -959,6 +996,61 @@ void ConstantStruct::destroyConstant() { destroyConstantImpl(); } +//---- ConstantPacked::get() implementation... +// +namespace llvm { + template<> + struct ConvertConstantType<ConstantPacked, PackedType> { + static void convert(ConstantPacked *OldC, const PackedType *NewTy) { + // Make everyone now use a constant of the new type... + std::vector<Constant*> C; + for (unsigned i = 0, e = OldC->getNumOperands(); i != e; ++i) + C.push_back(cast<Constant>(OldC->getOperand(i))); + Constant *New = ConstantPacked::get(NewTy, C); + assert(New != OldC && "Didn't replace constant??"); + OldC->uncheckedReplaceAllUsesWith(New); + OldC->destroyConstant(); // This constant is now dead, destroy it. + } + }; +} + +static std::vector<Constant*> getValType(ConstantPacked *CP) { + std::vector<Constant*> Elements; + Elements.reserve(CP->getNumOperands()); + for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) + Elements.push_back(CP->getOperand(i)); + return Elements; +} + +static ValueMap<std::vector<Constant*>, PackedType, + ConstantPacked> PackedConstants; + +Constant *ConstantPacked::get(const PackedType *Ty, + const std::vector<Constant*> &V) { + // If this is an all-zero packed, return a ConstantAggregateZero object + if (!V.empty()) { + Constant *C = V[0]; + if (!C->isNullValue()) + return PackedConstants.getOrCreate(Ty, V); + for (unsigned i = 1, e = V.size(); i != e; ++i) + if (V[i] != C) + return PackedConstants.getOrCreate(Ty, V); + } + return ConstantAggregateZero::get(Ty); +} + +Constant *ConstantPacked::get(const std::vector<Constant*> &V) { + assert(!V.empty() && "Cannot infer type if V is empty"); + return get(PackedType::get(V.front()->getType(),V.size()), V); +} + +// destroyConstant - Remove the constant from the constant table... +// +void ConstantPacked::destroyConstant() { + PackedConstants.remove(this); + destroyConstantImpl(); +} + //---- ConstantPointerNull::get() implementation... // diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 205f32b..74907dd 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -564,8 +564,10 @@ void BinaryOperator::init(BinaryOps iType, Value *S1, Value *S2) case Rem: assert(getType() == S1->getType() && "Arithmetic operation should return same type as operands!"); - assert((getType()->isInteger() || getType()->isFloatingPoint()) && - "Tried to create an arithmetic operation on a non-arithmetic type!"); + assert((getType()->isInteger() || + getType()->isFloatingPoint() || + isa<PackedType>(getType()) ) && + "Tried to create an arithmetic operation on a non-arithmetic type!"); break; case And: case Or: case Xor: diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index c6ce347..bd0da45 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -261,6 +261,14 @@ static std::string getTypeDescription(const Type *Ty, Result += getTypeDescription(ATy->getElementType(), TypeStack) + "]"; break; } + case Type::PackedTyID: { + const PackedType *PTy = cast<PackedType>(Ty); + unsigned NumElements = PTy->getNumElements(); + Result = "<"; + Result += utostr(NumElements) + " x "; + Result += getTypeDescription(PTy->getElementType(), TypeStack) + ">"; + break; + } default: Result = "<error>"; assert(0 && "Unhandled type in getTypeDescription!"); @@ -397,6 +405,16 @@ ArrayType::ArrayType(const Type *ElType, unsigned NumEl) setAbstract(ElType->isAbstract()); } +PackedType::PackedType(const Type *ElType, unsigned NumEl) + : SequentialType(PackedTyID, ElType) { + NumElements = NumEl; + + assert(NumEl > 0 && "NumEl of a PackedType must be greater than 0"); + assert((ElType->isIntegral() || ElType->isFloatingPoint()) && + "Elements of a PackedType must be a primitive type"); +} + + PointerType::PointerType(const Type *E) : SequentialType(PointerTyID, E) { // Calculate whether or not this type is abstract setAbstract(E->isAbstract()); @@ -503,6 +521,10 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2, const ArrayType *ATy2 = cast<ArrayType>(Ty2); return ATy->getNumElements() == ATy2->getNumElements() && TypesEqual(ATy->getElementType(), ATy2->getElementType(), EqTypes); + } else if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) { + const PackedType *PTy2 = cast<PackedType>(Ty2); + return PTy->getNumElements() == PTy2->getNumElements() && + TypesEqual(PTy->getElementType(), PTy2->getElementType(), EqTypes); } else if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) { const FunctionType *FTy2 = cast<FunctionType>(Ty2); if (FTy->isVarArg() != FTy2->isVarArg() || @@ -846,6 +868,56 @@ ArrayType *ArrayType::get(const Type *ElementType, unsigned NumElements) { return AT; } + +//===----------------------------------------------------------------------===// +// Packed Type Factory... +// +namespace llvm { +class PackedValType { + const Type *ValTy; + unsigned Size; +public: + PackedValType(const Type *val, int sz) : ValTy(val), Size(sz) {} + + static PackedValType get(const PackedType *PT) { + return PackedValType(PT->getElementType(), PT->getNumElements()); + } + + static unsigned hashTypeStructure(const PackedType *PT) { + return PT->getNumElements(); + } + + // Subclass should override this... to update self as usual + void doRefinement(const DerivedType *OldType, const Type *NewType) { + assert(ValTy == OldType); + ValTy = NewType; + } + + inline bool operator<(const PackedValType &MTV) const { + if (Size < MTV.Size) return true; + return Size == MTV.Size && ValTy < MTV.ValTy; + } +}; +} +static TypeMap<PackedValType, PackedType> PackedTypes; + + +PackedType *PackedType::get(const Type *ElementType, unsigned NumElements) { + assert(ElementType && "Can't get packed of null types!"); + + PackedValType PVT(ElementType, NumElements); + PackedType *PT = PackedTypes.get(PVT); + if (PT) return PT; // Found a match, return it! + + // Value not found. Derive a new type! + PackedTypes.add(PVT, PT = new PackedType(ElementType, NumElements)); + +#ifdef DEBUG_MERGE_TYPES + std::cerr << "Derived new type: " << *PT << "\n"; +#endif + return PT; +} + //===----------------------------------------------------------------------===// // Struct Type Factory... // @@ -1107,6 +1179,18 @@ void ArrayType::typeBecameConcrete(const DerivedType *AbsTy) { refineAbstractType(AbsTy, AbsTy); } +// refineAbstractType - Called when a contained type is found to be more +// concrete - this could potentially change us from an abstract type to a +// concrete type. +// +void PackedType::refineAbstractType(const DerivedType *OldType, + const Type *NewType) { + PackedTypes.finishRefinement(this, OldType, NewType); +} + +void PackedType::typeBecameConcrete(const DerivedType *AbsTy) { + refineAbstractType(AbsTy, AbsTy); +} // refineAbstractType - Called when a contained type is found to be more // concrete - this could potentially change us from an abstract type to a diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 2005dbf..9e99fe0 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -488,8 +488,9 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { Assert1(B.getType() == B.getOperand(0)->getType(), "Arithmetic operators must have same type for operands and result!", &B); - Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint(), - "Arithmetic operators must have integer or fp type!", &B); + Assert1(B.getType()->isInteger() || B.getType()->isFloatingPoint() || + isa<PackedType>(B.getType()), + "Arithmetic operators must have integer, fp, or packed type!", &B); } visitInstruction(B); |