From: Chris Lattner Date: Sun, 8 Oct 2006 23:53:04 +0000 (+0000) Subject: Implement SROA of unions with mixed pointers/integers in them. This implements X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c836333c3b0a18c398436ae00667a8fb5e476129;p=oota-llvm.git Implement SROA of unions with mixed pointers/integers in them. This implements PR892 and Transforms/ScalarRepl/union-pointer.ll:test2 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30825 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 3955cb8dbb1..87952bef5e8 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -433,8 +433,7 @@ static bool MergeInType(const Type *In, const Type *&Accum, if (In->getTypeID() > Accum->getTypeID()) Accum = In; } else if (isa(In) && isa(Accum)) { - // Pointer unions just stay as a pointer. - // Nothing. + // Pointer unions just stay as one of the pointers. } else if ((PTy = dyn_cast(Accum)) && PTy->getElementType() == In) { // Accum is a vector, and we are accessing an element: ok. @@ -442,6 +441,13 @@ static bool MergeInType(const Type *In, const Type *&Accum, PTy->getElementType() == Accum) { // In is a vector, and accum is an element: ok, remember In. Accum = In; + } else if (isa(In) && Accum->isIntegral()) { + // Pointer/Integer unions merge together as integers. + return MergeInType(TD.getIntPtrType(), Accum, TD); + } else if (isa(Accum) && In->isIntegral()) { + // Pointer/Integer unions merge together as integers. + Accum = TD.getIntPtrType(); + return MergeInType(In, Accum, TD); } else { return true; } @@ -503,7 +509,7 @@ const Type *SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial) { if (SubElt == 0) return 0; if (SubElt != Type::VoidTy && SubElt->isInteger()) { const Type *NewTy = - getUIntAtLeastAsBitAs(SubElt->getPrimitiveSizeInBits()+BitOffset); + getUIntAtLeastAsBitAs(TD.getTypeSize(SubElt)*8+BitOffset); if (NewTy == 0 || MergeInType(NewTy, UsedType, TD)) return 0; continue; } @@ -591,6 +597,7 @@ void SROA::ConvertToScalar(AllocationInst *AI, const Type *ActualTy) { /// shifted to the right. By the end of this, there should be no uses of Ptr. void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { bool isVectorInsert = isa(NewAI->getType()->getElementType()); + const TargetData &TD = getAnalysis(); while (!Ptr->use_empty()) { Instruction *User = cast(Ptr->use_back()); @@ -600,12 +607,12 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { if (NV->getType() != LI->getType()) { if (const PackedType *PTy = dyn_cast(NV->getType())) { // Must be an element access. - unsigned Elt = Offset/PTy->getElementType()->getPrimitiveSizeInBits(); + unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8); NV = new ExtractElementInst(NV, ConstantUInt::get(Type::UIntTy, Elt), "tmp", LI); } else { assert(NV->getType()->isInteger() && "Unknown promotion!"); - if (Offset && Offset < NV->getType()->getPrimitiveSizeInBits()) + if (Offset && Offset < TD.getTypeSize(NV->getType())*8) NV = new ShiftInst(Instruction::Shr, NV, ConstantUInt::get(Type::UByteTy, Offset), LI->getName(), LI); @@ -626,7 +633,7 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { if (const PackedType *PTy = dyn_cast(AllocaType)) { // Must be an element insertion. - unsigned Elt = Offset/PTy->getElementType()->getPrimitiveSizeInBits(); + unsigned Elt = Offset/(TD.getTypeSize(PTy->getElementType())*8); SV = new InsertElementInst(Old, SV, ConstantUInt::get(Type::UIntTy, Elt), "tmp", SI); @@ -637,14 +644,13 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { SV = new CastInst(SV, SV->getType()->getUnsignedVersion(), SV->getName(), SI); SV = new CastInst(SV, Old->getType(), SV->getName(), SI); - if (Offset && Offset < SV->getType()->getPrimitiveSizeInBits()) + if (Offset && Offset < TD.getTypeSize(SV->getType())*8) SV = new ShiftInst(Instruction::Shl, SV, ConstantUInt::get(Type::UByteTy, Offset), SV->getName()+".adj", SI); // Mask out the bits we are about to insert from the old value. - unsigned TotalBits = SV->getType()->getPrimitiveSizeInBits(); - unsigned InsertBits = - SI->getOperand(0)->getType()->getPrimitiveSizeInBits(); + unsigned TotalBits = TD.getTypeSize(SV->getType())*8; + unsigned InsertBits = TD.getTypeSize(SI->getOperand(0)->getType())*8; if (TotalBits != InsertBits) { assert(TotalBits > InsertBits); uint64_t Mask = ~(((1ULL << InsertBits)-1) << Offset);