[cfe-dev] var-arg handling
Robert Lytton
robert at xmos.com
Tue Aug 13 03:28:20 PDT 2013
Hi,
Currently the XCore target passes the va_arg IR instruction to the back-end to handle
- using the default DefaultABIInfo.
However, this does mean that aggregate types are not handled.
I assume to support aggregate types, I must lower them within clang.
The question is should I:
1. lower all types;
2. just the aggregate types, passing all other types as var_arg instructions.
On the surface, lowering all types does seem to allow better optimization - but may be this points to lack else where.
Example code to to both (viz XCORE_USE_INST_VAR_ARG) is below & suitable patch+tests attached.
Any comments on the correct way to handle var args welcome.
Thank you
Robert
//#define XCORE_USE_INST_VAR_ARG
llvm::Value *XCoreABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CGF) const {
ABIArgInfo AI = classifyArgumentType(Ty);
#ifdef XCORE_USE_INST_VAR_ARG
if (AI.getKind() != ABIArgInfo::Indirect)
return 0; // use built in 'va_arg' instruction
#endif
CGBuilderTy &Builder = CGF.Builder;
llvm::Type *ArgTy = CGT.ConvertType(Ty);
if (AI.canHaveCoerceToType() && !AI.getCoerceToType())
AI.setCoerceToType(ArgTy);
// handle the VAList
llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr,
CGF.Int8PtrPtrTy, "ap");
llvm::Value *AP = Builder.CreateLoad(VAListAddrAsBPP, "indirect");
llvm::Value *APN = Builder.CreateConstGEP1_32(AP, 4, "ap.next");
Builder.CreateStore(APN, VAListAddrAsBPP);
// handle the argument
llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy);
#ifdef XCORE_USE_INST_VAR_ARG
llvm::Value *ArgAddr;
ArgAddr = Builder.CreateBitCast(AP, llvm::PointerType::getUnqual(ArgPtrTy),
"indirect");
ArgAddr = Builder.CreateLoad(ArgAddr, "arg");
return Builder.CreatePointerCast(ArgAddr, ArgPtrTy, "arg");
#else
switch (AI.getKind()) {
default:
case ABIArgInfo::Expand:
case ABIArgInfo::Extend:
llvm_unreachable("Unsupported ABI kind for va_arg");
case ABIArgInfo::Ignore:
return llvm::UndefValue::get(ArgPtrTy);
case ABIArgInfo::Direct:
return Builder.CreatePointerCast(AP, ArgPtrTy, "arg");
case ABIArgInfo::Indirect:
llvm::Value *ArgAddr;
ArgAddr = Builder.CreateBitCast(AP, llvm::PointerType::getUnqual(ArgPtrTy),
"indirect");
ArgAddr = Builder.CreateLoad(ArgAddr, "arg");
return Builder.CreatePointerCast(ArgAddr, ArgPtrTy, "arg");
}
#endif
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130813/33aab318/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PatchVararg
Type: application/octet-stream
Size: 6587 bytes
Desc: PatchVararg
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130813/33aab318/attachment.obj>
More information about the cfe-dev
mailing list