[llvm-commits] [llvm] r63638 - in /llvm/trunk: lib/Transforms/Scalar/ScalarReplAggregates.cpp test/Transforms/ScalarRepl/not-a-vector.ll

Chris Lattner sabre at nondot.org
Tue Feb 3 10:15:05 PST 2009


Author: lattner
Date: Tue Feb  3 12:15:05 2009
New Revision: 63638

URL: http://llvm.org/viewvc/llvm-project?rev=63638&view=rev
Log:
Make SROA produce a vector only when the alloca is actually 
accessed at least once as a vector.  This prevents it from
compiling the example in not-a-vector into:

define double @test(double %A, double %B) {
	%tmp4 = insertelement <7 x double> undef, double %A, i32 0
	%tmp = insertelement <7 x double> %tmp4, double %B, i32 4
	%tmp2 = extractelement <7 x double> %tmp, i32 4
	ret double %tmp2
}

instead, producing the integer code.  Producing vectors when they
aren't otherwise in the program is dangerous because a lot of other
code treats them carefully and doesn't want to break them down.
OTOH, many things want to break down tasty i448's.


Added:
    llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.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=63638&r1=63637&r2=63638&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ScalarReplAggregates.cpp Tue Feb  3 12:15:05 2009
@@ -126,7 +126,7 @@
                                       SmallVector<AllocaInst*, 32> &NewElts);
     
     bool CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy,
-                            uint64_t Offset, unsigned AllocaSize);
+                            bool &SawVec, uint64_t Offset, unsigned AllocaSize);
     void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset);
     Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, 
                                      uint64_t Offset);
@@ -281,10 +281,17 @@
     // but that has pointer arithmetic to set byte 3 of it or something.
     bool IsNotTrivial = false;
     const Type *VectorTy = 0;
-    if (CanConvertToScalar(AI, IsNotTrivial, VectorTy,
+    bool HadAVector = false;
+    if (CanConvertToScalar(AI, IsNotTrivial, VectorTy, HadAVector, 
                            0, unsigned(AllocaSize)) && IsNotTrivial) {
       AllocaInst *NewAI;
-      if (VectorTy && isa<VectorType>(VectorTy)) {
+      // If we were able to find a vector type that can handle this with
+      // insert/extract elements, and if there was at least one use that had
+      // a vector type, promote this to a vector.  We don't want to promote
+      // random stuff that doesn't use vectors (e.g. <9 x double>) because then
+      // we just get a lot of insert/extracts.  If at least one vector is
+      // involved, then we probably really do have a union of vector/array.
+      if (VectorTy && isa<VectorType>(VectorTy) && HadAVector) {
         DOUT << "CONVERT TO VECTOR: " << *AI << "  TYPE = " << *VectorTy <<"\n";
         
         // Create and insert the vector alloca.
@@ -1229,8 +1236,11 @@
 /// completely trivial use that mem2reg could promote, set IsNotTrivial.  Offset
 /// is the current offset from the base of the alloca being analyzed.
 ///
-bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial,
-                              const Type *&VecTy, uint64_t Offset,
+/// If we see at least one access to the value that is as a vector type, set the
+/// SawVec flag.
+///
+bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy,
+                              bool &SawVec, uint64_t Offset,
                               unsigned AllocaSize) {
   for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) {
     Instruction *User = cast<Instruction>(*UI);
@@ -1240,6 +1250,7 @@
       if (LI->isVolatile())
         return false;
       MergeInType(LI->getType(), Offset, VecTy, AllocaSize, *TD);
+      SawVec |= isa<VectorType>(LI->getType());
       continue;
     }
     
@@ -1247,11 +1258,13 @@
       // Storing the pointer, not into the value?
       if (SI->getOperand(0) == V || SI->isVolatile()) return 0;
       MergeInType(SI->getOperand(0)->getType(), Offset, VecTy, AllocaSize, *TD);
+      SawVec |= isa<VectorType>(SI->getOperand(0)->getType());
       continue;
     }
     
     if (BitCastInst *BCI = dyn_cast<BitCastInst>(User)) {
-      if (!CanConvertToScalar(BCI, IsNotTrivial, VecTy, Offset, AllocaSize))
+      if (!CanConvertToScalar(BCI, IsNotTrivial, VecTy, SawVec, Offset,
+                              AllocaSize))
         return false;
       IsNotTrivial = true;
       continue;
@@ -1267,7 +1280,7 @@
       uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(),
                                                 &Indices[0], Indices.size());
       // See if all uses can be converted.
-      if (!CanConvertToScalar(GEP, IsNotTrivial, VecTy, Offset+GEPOffset,
+      if (!CanConvertToScalar(GEP, IsNotTrivial, VecTy, SawVec,Offset+GEPOffset,
                               AllocaSize))
         return false;
       IsNotTrivial = true;

Added: llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll?rev=63638&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll (added)
+++ llvm/trunk/test/Transforms/ScalarRepl/not-a-vector.ll Tue Feb  3 12:15:05 2009
@@ -0,0 +1,19 @@
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep {7 x double}
+; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret double %B}
+
+define double @test(double %A, double %B) {
+	%ARR = alloca [7 x i64]
+	%C = bitcast [7 x i64]* %ARR to double*
+	store double %A, double* %C
+
+	%D = getelementptr [7 x i64]* %ARR, i32 0, i32 4
+	%E = bitcast i64* %D to double*
+	store double %B, double* %E
+
+	%F = getelementptr double* %C, i32 4
+	%G = load double* %F
+	ret double %G
+}
+
+





More information about the llvm-commits mailing list