OSDN Git Service

teach "convert from scalar" to handle loads of fca's.
authorChris Lattner <sabre@nondot.org>
Tue, 3 Feb 2009 21:08:45 +0000 (21:08 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 3 Feb 2009 21:08:45 +0000 (21:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63659 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/ScalarReplAggregates.cpp
test/Transforms/ScalarRepl/sroa-fca.ll

index ce646a1..c1c8e03 100644 (file)
@@ -1423,6 +1423,31 @@ Value *SROA::ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType,
       V = Builder.CreateBitCast(V, ToType, "tmp");
     return V;
   }
+  
+  // If ToType is a first class aggregate, extract out each of the pieces and
+  // use insertvalue's to form the FCA.
+  if (const StructType *ST = dyn_cast<StructType>(ToType)) {
+    const StructLayout &Layout = *TD->getStructLayout(ST);
+    Value *Res = UndefValue::get(ST);
+    for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
+      Value *Elt = ConvertScalar_ExtractValue(FromVal, ST->getElementType(i),
+                                              Offset+Layout.getElementOffset(i),
+                                              Builder);
+      Res = Builder.CreateInsertValue(Res, Elt, i, "tmp");
+    }
+    return Res;
+  }
+  
+  if (const ArrayType *AT = dyn_cast<ArrayType>(ToType)) {
+    uint64_t EltSize = TD->getTypePaddedSizeInBits(AT->getElementType());
+    Value *Res = UndefValue::get(AT);
+    for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
+      Value *Elt = ConvertScalar_ExtractValue(FromVal, AT->getElementType(),
+                                              Offset+i*EltSize, Builder);
+      Res = Builder.CreateInsertValue(Res, Elt, i, "tmp");
+    }
+    return Res;
+  }
 
   // Otherwise, this must be a union that was converted to an integer value.
   const IntegerType *NTy = cast<IntegerType>(FromVal->getType());
@@ -1444,9 +1469,11 @@ Value *SROA::ConvertScalar_ExtractValue(Value *FromVal, const Type *ToType,
   // 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())
-    FromVal = Builder.CreateLShr(FromVal, ConstantInt::get(FromVal->getType(), ShAmt), "tmp");
+    FromVal = Builder.CreateLShr(FromVal, ConstantInt::get(FromVal->getType(),
+                                                           ShAmt), "tmp");
   else if (ShAmt < 0 && (unsigned)-ShAmt < NTy->getBitWidth())
-    FromVal = Builder.CreateShl(FromVal, ConstantInt::get(FromVal->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(ToType);
index a7ec3a1..1bfdacc 100644 (file)
@@ -10,3 +10,12 @@ define i64 @test({i32, i32} %A) {
        ret i64 %Q
 }
 
+define {i32,i32} @test2(i64 %A) {
+       %X = alloca i64
+       %Y = bitcast i64* %X to {i32,i32}*
+       store i64 %A, i64* %X
+       
+       %Q = load {i32,i32}* %Y
+       ret {i32,i32} %Q
+}
+