From 34cdc86af5b0a54084a512a1b2643365b8f5bdd2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 3 Aug 2007 16:18:34 +0000 Subject: [PATCH] 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 --- CodeGen/CGExpr.cpp | 103 ++++++++++++++++++++------------------ CodeGen/CodeGenFunction.h | 2 + 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index dad4b86a46..31b9e2f6a3 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -285,58 +285,65 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) { // 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(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(ExprType)->getNumElements(); - unsigned NumSourceElts = - cast(Vec->getType())->getNumElements(); - - if (NumResultElts == NumSourceElts) { - llvm::SmallVector 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(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(ExprType)->getNumElements(); + unsigned NumSourceElts = + cast(Vec->getType())->getNumElements(); + + if (NumResultElts == NumSourceElts) { + llvm::SmallVector 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()); } diff --git a/CodeGen/CodeGenFunction.h b/CodeGen/CodeGenFunction.h index 919e68c91d..2ac8e8035a 100644 --- a/CodeGen/CodeGenFunction.h +++ b/CodeGen/CodeGenFunction.h @@ -316,7 +316,9 @@ public: /// rvalue, returning the rvalue. RValue EmitLoadOfLValue(const Expr *E); RValue EmitLoadOfLValue(LValue V, QualType LVType); + RValue EmitLoadOfOCUComponentLValue(LValue V, QualType LVType); + /// EmitStoreThroughLValue - Store the specified rvalue into the specified /// lvalue, where both are guaranteed to the have the same type, and that type /// is 'Ty'.