From: Daniel Dunbar Date: Thu, 16 Sep 2010 20:42:02 +0000 (+0000) Subject: IRgen/ABI: Add support for realigning structures which are passed by indirect X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cf3b6f2504596812db1fcef0df8ce5b3449c4aac;p=clang IRgen/ABI: Add support for realigning structures which are passed by indirect reference. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114114 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h index 91b7742557..c90c84a352 100644 --- a/lib/CodeGen/ABIInfo.h +++ b/lib/CodeGen/ABIInfo.h @@ -70,11 +70,12 @@ namespace clang { Kind TheKind; llvm::PATypeHolder TypeData; unsigned UIntData; - bool BoolData; + bool BoolData0; + bool BoolData1; ABIArgInfo(Kind K, const llvm::Type *TD=0, - unsigned UI=0, bool B = false) - : TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {} + unsigned UI=0, bool B0 = false, bool B1 = false) + : TheKind(K), TypeData(TD), UIntData(UI), BoolData0(B0), BoolData1(B1) {} public: ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} @@ -88,8 +89,9 @@ namespace clang { static ABIArgInfo getIgnore() { return ABIArgInfo(Ignore); } - static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) { - return ABIArgInfo(Indirect, 0, Alignment, ByVal); + static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true + , bool Realign = false) { + return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign); } static ABIArgInfo getExpand() { return ABIArgInfo(Expand); @@ -129,7 +131,12 @@ namespace clang { bool getIndirectByVal() const { assert(TheKind == Indirect && "Invalid kind!"); - return BoolData; + return BoolData0; + } + + bool getIndirectRealign() const { + assert(TheKind == Indirect && "Invalid kind!"); + return BoolData1; } void dump() const; diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 475dfa5c10..ae00040ec7 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -866,9 +866,29 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, switch (ArgI.getKind()) { case ABIArgInfo::Indirect: { llvm::Value *V = AI; + if (hasAggregateLLVMType(Ty)) { - // Do nothing, aggregates and complex variables are accessed by - // reference. + // Aggregates and complex variables are accessed by reference. All we + // need to do is realign the value, if requested + if (ArgI.getIndirectRealign()) { + llvm::Value *AlignedTemp = CreateMemTemp(Ty, "coerce"); + + // Copy from the incoming argument pointer to the temporary with the + // appropriate alignment. + // + // FIXME: We should have a common utility for generating an aggregate + // copy. + const llvm::Type *I8PtrTy = llvm::Type::getInt8PtrTy(VMContext, 0); + unsigned Size = getContext().getTypeSize(Ty) / 8; + Builder.CreateCall5(CGM.getMemCpyFn(I8PtrTy, I8PtrTy, IntPtrTy), + Builder.CreateBitCast(AlignedTemp, I8PtrTy), + Builder.CreateBitCast(V, I8PtrTy), + llvm::ConstantInt::get(IntPtrTy, Size), + Builder.getInt32(ArgI.getIndirectAlign()), + /*Volatile=*/Builder.getInt1(false)); + + V = AlignedTemp; + } } else { // Load scalar value from indirect argument. unsigned Alignment = getContext().getTypeAlignInChars(Ty).getQuantity(); diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index ab6f7c7dd0..3ee4d1ad6d 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -75,7 +75,8 @@ void ABIArgInfo::dump() const { break; case Indirect: OS << "Indirect Align=" << getIndirectAlign() - << " Byal=" << getIndirectByVal(); + << " Byal=" << getIndirectByVal() + << " Realign=" << getIndirectRealign(); break; case Expand: OS << "Expand";