diff --git a/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/lib/Transforms/Scalar/ScalarReplAggregates.cpp index de02cafb37d..900d119cb40 100644 --- a/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -202,12 +202,18 @@ bool SROA::performPromotion(Function &F) { return Changed; } -/// getNumSAElements - Return the number of elements in the specific struct or -/// array. -static uint64_t getNumSAElements(const Type *T) { +/// ShouldAttemptScalarRepl - Decide if an alloca is a good candidate for +/// SROA. It must be a struct or array type with a small number of elements. +static bool ShouldAttemptScalarRepl(AllocaInst *AI) { + const Type *T = AI->getAllocatedType(); + // Do not promote any struct into more than 32 separate vars. if (const StructType *ST = dyn_cast(T)) - return ST->getNumElements(); - return cast(T)->getNumElements(); + return ST->getNumElements() <= 32; + // Arrays are much less likely to be safe for SROA; only consider + // them if they are very small. + if (const ArrayType *AT = dyn_cast(T)) + return AT->getNumElements() <= 8; + return false; } // performScalarRepl - This algorithm is a simple worklist driven algorithm, @@ -266,22 +272,18 @@ bool SROA::performScalarRepl(Function &F) { // Do not promote [0 x %struct]. if (AllocaSize == 0) continue; + // If the alloca looks like a good candidate for scalar replacement, and if + // all its users can be transformed, then split up the aggregate into its + // separate elements. + if (ShouldAttemptScalarRepl(AI) && isSafeAllocaToScalarRepl(AI)) { + DoScalarReplacement(AI, WorkList); + Changed = true; + continue; + } + // Do not promote any struct whose size is too big. if (AllocaSize > SRThreshold) continue; - if ((isa(AI->getAllocatedType()) || - isa(AI->getAllocatedType())) && - // Do not promote any struct into more than "32" separate vars. - getNumSAElements(AI->getAllocatedType()) <= SRThreshold/4) { - // Check that all of the users of the allocation are capable of being - // transformed. - if (isSafeAllocaToScalarRepl(AI)) { - DoScalarReplacement(AI, WorkList); - Changed = true; - continue; - } - } - // If we can turn this aggregate value (potentially with casts) into a // simple scalar value that can be mem2reg'd into a register value. // IsNotTrivial tracks whether this is something that mem2reg could have