[cfe-dev] Why isn't __builtin_va_arg an intrinsics?

Jaemin Park jm.j.park at samsung.com
Mon May 21 04:45:10 PDT 2012


Hello, 

 

Each TargetABI, /clang/lib/CodeGen/TargetInfo.cpp, should define a target-
specific IR. 

This causes to generate a target-specific IR, which prevents IR from having
target-neutrality. 

 

For example, 

On  X86, 

llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,

                                      CodeGenFunction &CGF) const {

  llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());

  llvm::Type *BPP = llvm::PointerType::getUnqual(BP);

 

  CGBuilderTy &Builder = CGF.Builder;

  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,

                                                       "ap");

  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");

  llvm::Type *PTy =

    llvm::PointerType::getUnqual(CGF.ConvertType(Ty));

  llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);

 

  uint64_t Offset =

    llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4);

  llvm::Value *NextAddr =

    Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset),

                      "ap.next");

  Builder.CreateStore(NextAddr, VAListAddrAsBPP);

 

  return AddrTyped;

}

However, on ARM, the highlighted code is arm-specific, which breaks the
portability. 

 

llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,

                                   CodeGenFunction &CGF) const {

…

  // Handle address alignment for type alignment > 32 bits

  uint64_t TyAlign = CGF.getContext().getTypeAlign(Ty) / 8;

  if (TyAlign > 4) {

    assert((TyAlign & (TyAlign - 1)) == 0 &&

           "Alignment is not power of 2!");

    llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int32Ty);

    AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt32(TyAlign - 1));

    AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt32(~(TyAlign -
1)));

    Addr = Builder.CreateIntToPtr(AddrAsInt, BP);

  }

…

}

 

Any other builtins, __builtin_va_start, __builtin_va_end, and
__builtin_va_copy, are of instrinsics, which would be translated to machine
code later. 

Is there any reason why __builtin_va_arg is generated in IR, not in an
intrinsic?

 

Sincerely yours, 

Jaemin Park. 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120521/728bf2c2/attachment.html>


More information about the cfe-dev mailing list