[llvm-commits] [llvm] r63649 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/sroa-fca.ll
Chris Lattner
sabre at nondot.org
Tue Feb 3 11:30:11 PST 2009
Author: lattner
Date: Tue Feb 3 13:30:11 2009
New Revision: 63649
URL: http://llvm.org/viewvc/llvm-project?rev=63649&view=rev
Log:
make scalar conversion handle stores of first class
aggregate values. loads are not yet handled (coming
soon to an sroa near you).
Added:
llvm/trunk/test/Transforms/ScalarRepl/sroa-fca.ll
Modified:
llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
Modified: llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp?rev=63649&r1=63648&r2=63649&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Feb 3 13:30:11 2009
@@ -130,8 +130,8 @@
void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset);
Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI,
uint64_t Offset);
- Value *ConvertUsesOfStoreToScalar(Value *StoredVal, AllocaInst *NewAI,
- uint64_t Offset, Instruction *InsertPt);
+ Value *ConvertScalar_InsertValue(Value *StoredVal, Value *ExistingVal,
+ uint64_t Offset, Instruction *InsertPt);
static Instruction *isOnlyCopiedFromConstantGlobal(AllocationInst *AI);
};
}
@@ -1326,8 +1326,9 @@
if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
assert(SI->getOperand(0) != Ptr && "Consistency error!");
- new StoreInst(ConvertUsesOfStoreToScalar(SI->getOperand(0), NewAI,
- Offset, SI), NewAI, SI);
+ Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI);
+ Value *New = ConvertScalar_InsertValue(SI->getOperand(0), Old, Offset,SI);
+ new StoreInst(New, NewAI, SI);
SI->eraseFromParent();
continue;
}
@@ -1363,8 +1364,10 @@
for (unsigned i = 1; i != NumBytes; ++i)
APVal |= APVal << 8;
- new StoreInst(ConvertUsesOfStoreToScalar(ConstantInt::get(APVal), NewAI,
- Offset, MSI), NewAI, MSI);
+ Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", MSI);
+ Value *New = ConvertScalar_InsertValue(ConstantInt::get(APVal), Old,
+ Offset, MSI);
+ new StoreInst(New, NewAI, MSI);
MSI->eraseFromParent();
continue;
}
@@ -1464,26 +1467,23 @@
}
-/// ConvertUsesOfStoreToScalar - Convert the specified store to a load+store
-/// pair of the new alloca directly, returning the value that should be stored
-/// to the alloca. This happens when we are converting an "integer union" to a
+/// ConvertScalar_InsertValue - Insert the value "SV" into the existing integer
+/// or vector value "Old" at the offset specified by Offset.
+///
+/// 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::ConvertUsesOfStoreToScalar(Value *SV, AllocaInst *NewAI,
- uint64_t Offset, Instruction *IP) {
+/// shifted to the right.
+Value *SROA::ConvertScalar_InsertValue(Value *SV, Value *Old,
+ uint64_t Offset, Instruction *IP) {
// Convert the stored type to the actual type, shift it left to insert
// then 'or' into place.
- const Type *AllocaType = NewAI->getType()->getElementType();
- if (SV->getType() == AllocaType && Offset == 0)
- return SV;
+ const Type *AllocaType = Old->getType();
if (const VectorType *VTy = dyn_cast<VectorType>(AllocaType)) {
- Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", IP);
-
// If the result alloca is a vector type, this is either an element
// access or a bitcast to another vector type.
if (isa<VectorType>(SV->getType())) {
@@ -1501,13 +1501,29 @@
}
return SV;
}
-
-
- Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", IP);
+
+ // If SV is a first-class aggregate value, insert each value recursively.
+ if (const StructType *ST = dyn_cast<StructType>(SV->getType())) {
+ const StructLayout &Layout = *TD->getStructLayout(ST);
+ for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
+ Value *Elt = ExtractValueInst::Create(SV, i, "tmp", IP);
+ Old = ConvertScalar_InsertValue(Elt, Old,
+ Offset+Layout.getElementOffset(i), IP);
+ }
+ return Old;
+ }
+
+ if (const ArrayType *AT = dyn_cast<ArrayType>(SV->getType())) {
+ uint64_t EltSize = TD->getTypePaddedSizeInBits(AT->getElementType());
+ for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
+ Value *Elt = ExtractValueInst::Create(SV, i, "tmp", IP);
+ Old = ConvertScalar_InsertValue(Elt, Old, Offset+i*EltSize, IP);
+ }
+ return Old;
+ }
// If SV is a float, convert it to the appropriate integer type.
- // If it is a pointer, do the same, and also handle ptr->ptr casts
- // here.
+ // If it is a pointer, do the same.
unsigned SrcWidth = TD->getTypeSizeInBits(SV->getType());
unsigned DestWidth = TD->getTypeSizeInBits(AllocaType);
unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType());
Added: llvm/trunk/test/Transforms/ScalarRepl/sroa-fca.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/sroa-fca.ll?rev=63649&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ScalarRepl/sroa-fca.ll (added)
+++ llvm/trunk/test/Transforms/ScalarRepl/sroa-fca.ll Tue Feb 3 13:30:11 2009
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis
+; Make sure that SROA "scalar conversion" can handle first class aggregates.
+
+define i64 @test({i32, i32} %A) {
+ %X = alloca i64
+ %Y = bitcast i64* %X to {i32,i32}*
+ store {i32,i32} %A, {i32,i32}* %Y
+
+ %Q = load i64* %X
+ ret i64 %Q
+}
+
More information about the llvm-commits
mailing list