aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2008-05-09 06:41:27 +0000
committerNate Begeman <natebegeman@mac.com>2008-05-09 06:41:27 +0000
commitf322eabbce14ca5c96a022d5ab2a2d8837cbccd9 (patch)
treebdd0a06e7473ee920f7d505648e2badfc91f8491 /clang/lib/CodeGen
parentba7a6c14edf259e306c3ecbf0b9fa7b024bf2534 (diff)
downloadllvm-f322eabbce14ca5c96a022d5ab2a2d8837cbccd9.zip
llvm-f322eabbce14ca5c96a022d5ab2a2d8837cbccd9.tar.gz
llvm-f322eabbce14ca5c96a022d5ab2a2d8837cbccd9.tar.bz2
Extend vector member references to include {.hi, .lo, .e, .o} which return a
vector of the same element type and half the width, with the high, low, even, and odd elements respectively. Allow member references to member references, so that .hi.hi gives you the high quarter of a vector. This is fairly convenient syntax for some insert/extract operations. Remove some unnecessary methods/types in the ExtVectorElementExpr class. llvm-svn: 50892
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp35
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h14
2 files changed, 36 insertions, 13 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 3c1ab74..043cfa1 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -182,13 +182,13 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
QualType ExprType) {
llvm::Value *Vec = Builder.CreateLoad(LV.getExtVectorAddr(), "tmp");
- unsigned EncFields = LV.getExtVectorElts();
+ const llvm::Constant *Elts = LV.getExtVectorElts();
// If the result of the expression is a non-vector type, we must be
// extracting a single element. Just codegen as an extractelement.
const VectorType *ExprVT = ExprType->getAsVectorType();
if (!ExprVT) {
- unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(0, EncFields);
+ unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(0, Elts);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
return RValue::get(Builder.CreateExtractElement(Vec, Elt, "tmp"));
}
@@ -202,7 +202,7 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
if (NumResultElts == NumSourceElts) {
llvm::SmallVector<llvm::Constant*, 4> Mask;
for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(i, EncFields);
+ unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(i, Elts);
Mask.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx));
}
@@ -218,7 +218,7 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
// Extract/Insert each element of the result.
for (unsigned i = 0; i != NumResultElts; ++i) {
- unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(i, EncFields);
+ unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(i, Elts);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
Elt = Builder.CreateExtractElement(Vec, Elt, "tmp");
@@ -312,7 +312,7 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
// value now.
llvm::Value *Vec = Builder.CreateLoad(Dst.getExtVectorAddr(), "tmp");
// FIXME: Volatility.
- unsigned EncFields = Dst.getExtVectorElts();
+ const llvm::Constant *Elts = Dst.getExtVectorElts();
llvm::Value *SrcVal = Src.getScalarVal();
@@ -324,13 +324,13 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, i);
Elt = Builder.CreateExtractElement(SrcVal, Elt, "tmp");
- unsigned Idx = ExtVectorElementExpr::getAccessedFieldNo(i, EncFields);
+ unsigned Idx = ExtVectorElementExpr::getAccessedFieldNo(i, Elts);
llvm::Value *OutIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, Idx);
Vec = Builder.CreateInsertElement(Vec, Elt, OutIdx, "tmp");
}
} else {
// If the Src is a scalar (not a vector) it must be updating one element.
- unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(0, EncFields);
+ unsigned InIdx = ExtVectorElementExpr::getAccessedFieldNo(0, Elts);
llvm::Value *Elt = llvm::ConstantInt::get(llvm::Type::Int32Ty, InIdx);
Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt, "tmp");
}
@@ -460,9 +460,28 @@ LValue CodeGenFunction::
EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
// Emit the base vector as an l-value.
LValue Base = EmitLValue(E->getBase());
+
+ if (Base.isExtVectorElt()) {
+ llvm::Constant *BaseElts = Base.getExtVectorElts();
+ llvm::Constant *ExprElts = E->getEncodedElementAccess();
+
+ llvm::SmallVector<llvm::Constant *, 8> Indices;
+
+ for (unsigned i = 0, e = E->getNumElements(); i != e; ++i) {
+ unsigned Idx = ExtVectorElementExpr::getAccessedFieldNo(i, ExprElts);
+
+ if (isa<llvm::ConstantAggregateZero>(BaseElts))
+ Indices.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0));
+ else
+ Indices.push_back(cast<llvm::ConstantInt>(BaseElts->getOperand(Idx)));
+ }
+ llvm::Constant *NewElts = llvm::ConstantVector::get(&Indices[0], Indices.size());
+ return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), NewElts);
+ }
+
assert(Base.isSimple() && "Can only subscript lvalue vectors here!");
- return LValue::MakeExtVectorElt(Base.getAddress(),
+ return LValue::MakeExtVectorElt(Base.getAddress(),
E->getEncodedElementAccess());
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index a6caa37..f067a0e 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -161,8 +161,12 @@ class LValue {
llvm::Value *V;
union {
- llvm::Value *VectorIdx; // Index into a vector subscript: V[i]
- unsigned VectorElts; // Encoded ExtVector element subset: V.xyx
+ // Index into a vector subscript: V[i]
+ llvm::Value *VectorIdx;
+
+ // ExtVector element subset: V.xyx
+ llvm::Constant *VectorElts;
+
struct {
unsigned short StartBit;
unsigned short Size;
@@ -182,7 +186,7 @@ public:
llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
// extended vector elements.
llvm::Value *getExtVectorAddr() const { assert(isExtVectorElt()); return V; }
- unsigned getExtVectorElts() const {
+ llvm::Constant *getExtVectorElts() const {
assert(isExtVectorElt());
return VectorElts;
}
@@ -216,11 +220,11 @@ public:
return R;
}
- static LValue MakeExtVectorElt(llvm::Value *Vec, unsigned Elements) {
+ static LValue MakeExtVectorElt(llvm::Value *Vec, llvm::Constant *Elts) {
LValue R;
R.LVType = ExtVectorElt;
R.V = Vec;
- R.VectorElts = Elements;
+ R.VectorElts = Elts;
return R;
}