From f5df53cb465d6034710792a9bde9da20b9b028e2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 3 Feb 2009 21:01:03 +0000 Subject: [PATCH] refactor the interface to ConvertUsesOfLoadToScalar, renaming it to ConvertScalar_ExtractValue llvm-svn: 63658 --- .../Scalar/ScalarReplAggregates.cpp | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 4e5cb682149a..ce646a172b40 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -129,7 +129,7 @@ namespace { bool CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy, bool &SawVec, uint64_t Offset, unsigned AllocaSize); void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset); - Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, + Value *ConvertScalar_ExtractValue(Value *NV, const Type *ToType, uint64_t Offset, IRBuilder<> &Builder); Value *ConvertScalar_InsertValue(Value *StoredVal, Value *ExistingVal, uint64_t Offset, IRBuilder<> &Builder); @@ -1338,8 +1338,11 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) { IRBuilder<> Builder(User->getParent(), User); if (LoadInst *LI = dyn_cast(User)) { - Value *LoadVal = ConvertUsesOfLoadToScalar(LI, NewAI, Offset, Builder); - LI->replaceAllUsesWith(LoadVal); + // The load is a bit extract from NewAI shifted right by Offset bits. + Value *LoadedVal = Builder.CreateLoad(NewAI, "tmp"); + Value *NewLoadVal + = ConvertScalar_ExtractValue(LoadedVal, LI->getType(), Offset, Builder); + LI->replaceAllUsesWith(NewLoadVal); LI->eraseFromParent(); continue; } @@ -1383,28 +1386,27 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) { } } -/// ConvertUsesOfLoadToScalar - Convert all of the users of the specified load -/// to use the new alloca directly, returning the value that should replace the -/// load. This happens when we are converting an "integer union" to a single +/// ConvertScalar_ExtractValue - Extract a value of type ToType from an integer +/// or vector value FromVal, extracting the bits from the offset specified by +/// Offset. This returns the value, which is of type ToType. +/// +/// This happens when we are converting an "integer union" to a single /// integer scalar, or when we are converting a "vector union" to a vector with /// insert/extractelement instructions. /// /// Offset is an offset from the original alloca, in bits that need to be -/// shifted to the right. By the end of this, there should be no uses of Ptr. -Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, - uint64_t Offset, IRBuilder<> &Builder) { - // The load is a bit extract from NewAI shifted right by Offset bits. - Value *NV = Builder.CreateLoad(NewAI, "tmp"); - +/// shifted to the right. +Value *SROA::ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType, + uint64_t Offset, IRBuilder<> &Builder) { // If the load is of the whole new alloca, no conversion is needed. - if (NV->getType() == LI->getType() && Offset == 0) - return NV; + if (FromVal->getType() == ToType && Offset == 0) + return FromVal; // If the result alloca is a vector type, this is either an element // access or a bitcast to another vector type of the same size. - if (const VectorType *VTy = dyn_cast(NV->getType())) { - if (isa(LI->getType())) - return Builder.CreateBitCast(NV, LI->getType(), "tmp"); + if (const VectorType *VTy = dyn_cast(FromVal->getType())) { + if (isa(ToType)) + return Builder.CreateBitCast(FromVal, ToType, "tmp"); // Otherwise it must be an element access. unsigned Elt = 0; @@ -1414,16 +1416,16 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, assert(EltSize*Elt == Offset && "Invalid modulus in validity checking"); } // Return the element extracted out of it. - Value *V = Builder.CreateExtractElement(NV, + Value *V = Builder.CreateExtractElement(FromVal, ConstantInt::get(Type::Int32Ty,Elt), "tmp"); - if (V->getType() != LI->getType()) - V = Builder.CreateBitCast(V, LI->getType(), "tmp"); + if (V->getType() != ToType) + V = Builder.CreateBitCast(V, ToType, "tmp"); return V; } // Otherwise, this must be a union that was converted to an integer value. - const IntegerType *NTy = cast(NV->getType()); + const IntegerType *NTy = cast(FromVal->getType()); // If this is a big-endian system and the load is narrower than the // full alloca type, we need to do a shift to get the right bits. @@ -1433,7 +1435,7 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, // from the pointer given by getTypeStoreSizeInBits. This matters for // integers with a bitwidth that is not a multiple of 8. ShAmt = TD->getTypeStoreSizeInBits(NTy) - - TD->getTypeStoreSizeInBits(LI->getType()) - Offset; + TD->getTypeStoreSizeInBits(ToType) - Offset; } else { ShAmt = Offset; } @@ -1442,30 +1444,29 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, // We do this to support (f.e.) loads off the end of a structure where // only some bits are used. if (ShAmt > 0 && (unsigned)ShAmt < NTy->getBitWidth()) - NV = Builder.CreateLShr(NV, ConstantInt::get(NV->getType(), ShAmt), "tmp"); + FromVal = Builder.CreateLShr(FromVal, ConstantInt::get(FromVal->getType(), ShAmt), "tmp"); else if (ShAmt < 0 && (unsigned)-ShAmt < NTy->getBitWidth()) - NV = Builder.CreateShl(NV, ConstantInt::get(NV->getType(), -ShAmt), "tmp"); + FromVal = Builder.CreateShl(FromVal, ConstantInt::get(FromVal->getType(), -ShAmt), "tmp"); // Finally, unconditionally truncate the integer to the right width. - unsigned LIBitWidth = TD->getTypeSizeInBits(LI->getType()); + unsigned LIBitWidth = TD->getTypeSizeInBits(ToType); if (LIBitWidth < NTy->getBitWidth()) - NV = Builder.CreateTrunc(NV, IntegerType::get(LIBitWidth), "tmp"); + FromVal = Builder.CreateTrunc(FromVal, IntegerType::get(LIBitWidth), "tmp"); else if (LIBitWidth > NTy->getBitWidth()) - NV = Builder.CreateZExt(NV, IntegerType::get(LIBitWidth), "tmp"); + FromVal = Builder.CreateZExt(FromVal, IntegerType::get(LIBitWidth), "tmp"); // If the result is an integer, this is a trunc or bitcast. - if (isa(LI->getType())) { + if (isa(ToType)) { // Should be done. - } else if (LI->getType()->isFloatingPoint() || - isa(LI->getType())) { + } else if (ToType->isFloatingPoint() || isa(ToType)) { // Just do a bitcast, we know the sizes match up. - NV = Builder.CreateBitCast(NV, LI->getType(), "tmp"); + FromVal = Builder.CreateBitCast(FromVal, ToType, "tmp"); } else { // Otherwise must be a pointer. - NV = Builder.CreateIntToPtr(NV, LI->getType(), "tmp"); + FromVal = Builder.CreateIntToPtr(FromVal, ToType, "tmp"); } - assert(NV->getType() == LI->getType() && "Didn't convert right?"); - return NV; + assert(FromVal->getType() == ToType && "Didn't convert right?"); + return FromVal; }