refactor handling of ocuvector lvalue->rvalue codegen into its own method.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40780 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp
index dad4b86..31b9e2f 100644
--- a/CodeGen/CGExpr.cpp
+++ b/CodeGen/CGExpr.cpp
@@ -285,58 +285,65 @@
 
   // If this is a reference to a subset of the elements of a vector, either
   // shuffle the input or extract/insert them as appropriate.
-  if (LV.isOCUVectorComp()) {
-    llvm::Value *Vec = Builder.CreateLoad(LV.getOCUVectorAddr(), "tmp");
-
-    unsigned EncFields = LV.getOCUVectorComp();
-
-    // If the result of the expression is a non-vector type, we must be
-    // extracting a single element.  Just codegen as an extractelement.
-    if (!isa<VectorType>(ExprType)) {
-      unsigned InIdx = OCUVectorComponent::getAccessedFieldNo(0, EncFields);
-      llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
-      return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
-    }
-    
-    // If the source and destination have the same number of elements, use a
-    // vector shuffle instead of insert/extracts.
-    unsigned NumResultElts = cast<VectorType>(ExprType)->getNumElements();
-    unsigned NumSourceElts =
-      cast<llvm::VectorType>(Vec->getType())->getNumElements();
-    
-    if (NumResultElts == NumSourceElts) {
-      llvm::SmallVector<llvm::Constant*, 4> Mask;
-      for (unsigned i = 0; i != NumResultElts; ++i) {
-        unsigned InIdx = OCUVectorComponent::getAccessedFieldNo(i, EncFields);
-        Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
-      }
-      
-      llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
-      Vec = Builder.CreateShuffleVector(Vec,
-                                        llvm::UndefValue::get(Vec->getType()),
-                                        MaskV, "tmp");
-      return RValue::get(Vec);
-    }
-    
-    // Start out with an undef of the result type.
-    llvm::Value *Result = llvm::UndefValue::get(ConvertType(ExprType));
-    
-    // Extract/Insert each element of the result.
-    for (unsigned i = 0; i != NumResultElts; ++i) {
-      unsigned InIdx = OCUVectorComponent::getAccessedFieldNo(i, EncFields);
-      llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
-      Elt = Builder.CreateExtractElement(Vec, Elt, "tmp");
-
-      llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
-      Result = Builder.CreateInsertElement(Result, Elt, OutIdx, "tmp");
-    }
-    
-    return RValue::get(Result);
-  }
+  if (LV.isOCUVectorComp())
+    return EmitLoadOfOCUComponentLValue(LV, ExprType);
   
   assert(0 && "Bitfield ref not impl!");
 }
 
+// If this is a reference to a subset of the elements of a vector, either
+// shuffle the input or extract/insert them as appropriate.
+RValue CodeGenFunction::EmitLoadOfOCUComponentLValue(LValue LV,
+                                                     QualType ExprType) {
+  llvm::Value *Vec = Builder.CreateLoad(LV.getOCUVectorAddr(), "tmp");
+  
+  unsigned EncFields = LV.getOCUVectorComp();
+  
+  // If the result of the expression is a non-vector type, we must be
+  // extracting a single element.  Just codegen as an extractelement.
+  if (!isa<VectorType>(ExprType)) {
+    unsigned InIdx = OCUVectorComponent::getAccessedFieldNo(0, EncFields);
+    llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
+    return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
+  }
+  
+  // If the source and destination have the same number of elements, use a
+  // vector shuffle instead of insert/extracts.
+  unsigned NumResultElts = cast<VectorType>(ExprType)->getNumElements();
+  unsigned NumSourceElts =
+    cast<llvm::VectorType>(Vec->getType())->getNumElements();
+  
+  if (NumResultElts == NumSourceElts) {
+    llvm::SmallVector<llvm::Constant*, 4> Mask;
+    for (unsigned i = 0; i != NumResultElts; ++i) {
+      unsigned InIdx = OCUVectorComponent::getAccessedFieldNo(i, EncFields);
+      Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
+    }
+    
+    llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+    Vec = Builder.CreateShuffleVector(Vec,
+                                      llvm::UndefValue::get(Vec->getType()),
+                                      MaskV, "tmp");
+    return RValue::get(Vec);
+  }
+  
+  // Start out with an undef of the result type.
+  llvm::Value *Result = llvm::UndefValue::get(ConvertType(ExprType));
+  
+  // Extract/Insert each element of the result.
+  for (unsigned i = 0; i != NumResultElts; ++i) {
+    unsigned InIdx = OCUVectorComponent::getAccessedFieldNo(i, EncFields);
+    llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
+    Elt = Builder.CreateExtractElement(Vec, Elt, "tmp");
+    
+    llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
+    Result = Builder.CreateInsertElement(Result, Elt, OutIdx, "tmp");
+  }
+  
+  return RValue::get(Result);
+}
+
+
 RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) {
   return EmitLoadOfLValue(EmitLValue(E), E->getType());
 }