[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