[cfe-commits] r58681 - in /cfe/trunk/lib/CodeGen: CGExprAgg.cpp CGExprScalar.cpp CodeGenFunction.cpp CodeGenFunction.h

Anders Carlsson andersca at mac.com
Mon Nov 3 21:30:00 PST 2008


Author: andersca
Date: Mon Nov  3 23:30:00 2008
New Revision: 58681

URL: http://llvm.org/viewvc/llvm-project?rev=58681&view=rev
Log:
Implement lowering of va_arg in clang directly. (This is 32-bit X86 only for now).

Modified:
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=58681&r1=58680&r2=58681&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Mon Nov  3 23:30:00 2008
@@ -256,10 +256,14 @@
 
 void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
   llvm::Value *ArgValue = CGF.EmitLValue(VE->getSubExpr()).getAddress();
-  llvm::Value *V = Builder.CreateVAArg(ArgValue, CGF.ConvertType(VE->getType()));
+  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
+
+  if (!ArgPtr)
+    CGF.ErrorUnsupported(VE, "aggregate va_arg expression");
+  
   if (DestPtr)
     // FIXME: volatility
-    Builder.CreateStore(V, DestPtr);
+    CGF.EmitAggregateCopy(DestPtr, ArgPtr, VE->getType());
 }
 
 void AggExprEmitter::EmitNonConstInit(InitListExpr *E) {

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=58681&r1=58680&r2=58681&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Nov  3 23:30:00 2008
@@ -1149,8 +1149,14 @@
 Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
   llvm::Value *ArgValue = EmitLValue(VE->getSubExpr()).getAddress();
 
-  llvm::Value *V = Builder.CreateVAArg(ArgValue, ConvertType(VE->getType()));  
-  return V;
+  llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
+
+  // If EmitVAArg fails, we fall back to the LLVM instruction.
+  if (!ArgPtr) 
+    return Builder.CreateVAArg(ArgValue, ConvertType(VE->getType()));
+
+  // FIXME: volatile?
+  return Builder.CreateLoad(ArgPtr);
 }
 
 Value *ScalarExprEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=58681&r1=58680&r2=58681&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Nov  3 23:30:00 2008
@@ -242,3 +242,38 @@
     }
   }         
 }
+
+llvm::Value *CodeGenFunction::EmitVAArg(llvm::Value *VAListAddr, QualType Ty)
+{
+  // FIXME: This entire method is hardcoded for 32-bit X86.
+  
+  const char *TargetPrefix = getContext().Target.getTargetPrefix();
+  
+  if (strcmp(TargetPrefix, "x86") != 0 ||
+      getContext().Target.getPointerWidth(0) != 32)
+    return 0;
+  
+  const llvm::Type *BP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
+
+  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, 
+                                                       "ap");
+  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+  llvm::Value *AddrTyped = 
+    Builder.CreateBitCast(Addr, 
+                          llvm::PointerType::getUnqual(ConvertType(Ty)));
+  
+  uint64_t SizeInBytes = getContext().getTypeSize(Ty) / 8;
+  const unsigned ArgumentSizeInBytes = 4;
+  if (SizeInBytes < ArgumentSizeInBytes)
+    SizeInBytes = ArgumentSizeInBytes;
+
+  llvm::Value *NextAddr = 
+    Builder.CreateGEP(Addr, 
+                      llvm::ConstantInt::get(llvm::Type::Int32Ty, SizeInBytes),
+                      "ap.next");
+  Builder.CreateStore(NextAddr, VAListAddrAsBPP);
+
+  return AddrTyped;
+}
+

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=58681&r1=58680&r2=58681&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Nov  3 23:30:00 2008
@@ -281,6 +281,12 @@
 
   /// EmitMemSetToZero - Generate code to memset a value of the given type to 0;
   void EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty);
+
+  // EmitVAArg - Generate code to get an argument from the passed in pointer
+  // and update it accordingly. The return value is a pointer to the argument.
+  // FIXME: We should be able to get rid of this method and use the va_arg
+  // instruction in LLVM instead once it works well enough.  
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty);
   
   //===--------------------------------------------------------------------===//
   //                            Declaration Emission





More information about the cfe-commits mailing list