[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