[cfe-commits] r39724 - in /cfe/cfe/trunk/CodeGen: CGExpr.cpp CGStmt.cpp CodeGenFunction.h
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:47:33 PDT 2007
Author: clattner
Date: Wed Jul 11 11:47:33 2007
New Revision: 39724
URL: http://llvm.org/viewvc/llvm-project?rev=39724&view=rev
Log:
Add support for codegen'ing vector subscripts, at least when they are lvalues.
Modified:
cfe/cfe/trunk/CodeGen/CGExpr.cpp
cfe/cfe/trunk/CodeGen/CGStmt.cpp
cfe/cfe/trunk/CodeGen/CodeGenFunction.h
Modified: cfe/cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGExpr.cpp?rev=39724&r1=39723&r2=39724&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGExpr.cpp Wed Jul 11 11:47:33 2007
@@ -238,7 +238,7 @@
default:
fprintf(stderr, "Unimplemented lvalue expr!\n");
E->dump();
- return LValue::getAddr(llvm::UndefValue::get(
+ return LValue::MakeAddr(llvm::UndefValue::get(
llvm::PointerType::get(llvm::Type::Int32Ty)));
case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast<DeclRefExpr>(E));
@@ -259,18 +259,26 @@
RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
ExprType = ExprType.getCanonicalType();
- // FIXME: this is silly and obviously wrong for non-scalars.
- assert(!LV.isBitfield());
- llvm::Value *Ptr = LV.getAddress();
- const llvm::Type *EltTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
-
- // Simple scalar l-value.
- if (EltTy->isFirstClassType())
- return RValue::get(Builder.CreateLoad(Ptr, "tmp"));
+ if (LV.isSimple()) {
+ llvm::Value *Ptr = LV.getAddress();
+ const llvm::Type *EltTy =
+ cast<llvm::PointerType>(Ptr->getType())->getElementType();
+
+ // Simple scalar l-value.
+ if (EltTy->isFirstClassType())
+ return RValue::get(Builder.CreateLoad(Ptr, "tmp"));
+
+ // Otherwise, we have an aggregate lvalue.
+ return RValue::getAggregate(Ptr);
+ }
+
+ if (LV.isVectorElt()) {
+ llvm::Value *Vec = Builder.CreateLoad(LV.getVectorAddr(), "tmp");
+ return RValue::get(Builder.CreateExtractElement(Vec, LV.getVectorIdx(),
+ "vecext"));
+ }
- // Otherwise, we have an aggregate lvalue.
- return RValue::getAggregate(Ptr);
+ assert(0 && "Bitfield ref not impl!");
}
RValue CodeGenFunction::EmitLoadOfLValue(const Expr *E) {
@@ -283,7 +291,17 @@
/// is 'Ty'.
void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
QualType Ty) {
- assert(!Dst.isBitfield() && "FIXME: Don't support store to bitfield yet");
+ if (Dst.isVectorElt()) {
+ // Read/modify/write the vector, inserting the new element.
+ // FIXME: Volatility.
+ llvm::Value *Vec = Builder.CreateLoad(Dst.getVectorAddr(), "tmp");
+ Vec = Builder.CreateInsertElement(Vec, Src.getVal(),
+ Dst.getVectorIdx(), "vecins");
+ Builder.CreateStore(Vec, Dst.getVectorAddr());
+ return;
+ }
+
+ assert(Dst.isSimple() && "FIXME: Don't support store to bitfield yet");
llvm::Value *DstAddr = Dst.getAddress();
if (Src.isScalar()) {
@@ -336,9 +354,9 @@
if (isa<BlockVarDecl>(D) || isa<ParmVarDecl>(D)) {
llvm::Value *V = LocalDeclMap[D];
assert(V && "BlockVarDecl not entered in LocalDeclMap?");
- return LValue::getAddr(V);
+ return LValue::MakeAddr(V);
} else if (isa<FunctionDecl>(D) || isa<FileVarDecl>(D)) {
- return LValue::getAddr(CGM.GetAddrOfGlobalDecl(D));
+ return LValue::MakeAddr(CGM.GetAddrOfGlobalDecl(D));
}
assert(0 && "Unimp declref");
}
@@ -350,7 +368,7 @@
assert(E->getOpcode() == UnaryOperator::Deref &&
"'*' is the only unary operator that produces an lvalue");
- return LValue::getAddr(EmitExpr(E->getSubExpr()).getVal());
+ return LValue::MakeAddr(EmitExpr(E->getSubExpr()).getVal());
}
LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {
@@ -368,19 +386,32 @@
llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
llvm::Constant *Zeros[] = { Zero, Zero };
C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
- return LValue::getAddr(C);
+ return LValue::MakeAddr(C);
}
LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
- // The base and index must be pointers or integers, neither of which are
- // aggregates. Emit them.
- QualType BaseTy;
- llvm::Value *Base =
- EmitExprWithUsualUnaryConversions(E->getBase(), BaseTy).getVal();
+ // The index must always be a pointer or integer, neither of which is an
+ // aggregate. Emit it.
QualType IdxTy;
llvm::Value *Idx =
EmitExprWithUsualUnaryConversions(E->getIdx(), IdxTy).getVal();
+ // If the base is a vector type, then we are forming a vector element lvalue
+ // with this subscript.
+ if (E->getBase()->getType()->isVectorType()) {
+ // Emit the vector as an lvalue to get its address.
+ LValue Base = EmitLValue(E->getBase());
+ assert(Base.isSimple() && "Can only subscript lvalue vectors here!");
+ // FIXME: This should properly sign/zero/extend or truncate Idx to i32.
+ return LValue::MakeVectorElt(Base.getAddress(), Idx);
+ }
+
+ // At this point, the base must be a pointer or integer, neither of which are
+ // aggregates. Emit it.
+ QualType BaseTy;
+ llvm::Value *Base =
+ EmitExprWithUsualUnaryConversions(E->getBase(), BaseTy).getVal();
+
// Usually the base is the pointer type, but sometimes it is the index.
// Canonicalize to have the pointer as the base.
if (isa<llvm::PointerType>(Idx->getType())) {
@@ -400,7 +431,7 @@
// size is a VLA.
if (!E->getType()->isConstantSizeType())
assert(0 && "VLA idx not implemented");
- return LValue::getAddr(Builder.CreateGEP(Base, Idx, "arrayidx"));
+ return LValue::MakeAddr(Builder.CreateGEP(Base, Idx, "arrayidx"));
}
//===--------------------------------------------------------------------===//
Modified: cfe/cfe/trunk/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGStmt.cpp?rev=39724&r1=39723&r2=39724&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CGStmt.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGStmt.cpp Wed Jul 11 11:47:33 2007
@@ -269,7 +269,7 @@
Builder.CreateRet(RetVal.getVal());
} else {
llvm::Value *SRetPtr = CurFn->arg_begin();
- EmitStoreThroughLValue(RetVal, LValue::getAddr(SRetPtr), FnRetTy);
+ EmitStoreThroughLValue(RetVal, LValue::MakeAddr(SRetPtr), FnRetTy);
}
}
Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39724&r1=39723&r2=39724&view=diff
==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:47:33 2007
@@ -110,17 +110,44 @@
class LValue {
// FIXME: Volatility. Restrict?
// alignment?
+
+ enum {
+ Simple, // This is a normal l-value, use getAddress().
+ VectorElt, // This is a vector element l-value (V[i]), use getVector*
+ BitField // This is a bitfield l-value, use getBitfield*.
+ } LVType;
+
llvm::Value *V;
-public:
- bool isBitfield() const { return false; }
- llvm::Value *getAddress() const { assert(!isBitfield()); return V; }
+ union {
+ llvm::Value *VectorIdx;
+ };
+public:
+ bool isSimple() const { return LVType == Simple; }
+ bool isVectorElt() const { return LVType == VectorElt; }
+ bool isBitfield() const { return LVType == BitField; }
+
+ // simple lvalue
+ llvm::Value *getAddress() const { assert(isSimple()); return V; }
+ // vector elt lvalue
+ llvm::Value *getVectorAddr() const { assert(isVectorElt()); return V; }
+ llvm::Value *getVectorIdx() const { assert(isVectorElt()); return VectorIdx; }
- static LValue getAddr(llvm::Value *V) {
+ static LValue MakeAddr(llvm::Value *V) {
LValue R;
+ R.LVType = Simple;
R.V = V;
return R;
}
+
+ static LValue MakeVectorElt(llvm::Value *Vec, llvm::Value *Idx) {
+ LValue R;
+ R.LVType = VectorElt;
+ R.V = Vec;
+ R.VectorIdx = Idx;
+ return R;
+ }
+
};
/// CodeGenFunction - This class organizes the per-function state that is used
More information about the cfe-commits
mailing list