+rnk On Mon, Apr 25, 2016 at 5:09 PM, Jacques Pienaar via cfe-commits < cfe-commits@lists.llvm.org> wrote:
> Author: jpienaar > Date: Mon Apr 25 19:09:29 2016 > New Revision: 267496 > > URL: http://llvm.org/viewvc/llvm-project?rev=267496&view=rev > Log: > [lanai] Update handling of structs in arguments to be passed in registers. > > Previously aggregate types were passed byval, change the ABI to pass these > in registers instead. > > > Modified: > cfe/trunk/lib/CodeGen/TargetInfo.cpp > cfe/trunk/test/CodeGen/lanai-arguments.c > > Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=267496&r1=267495&r2=267496&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Mon Apr 25 19:09:29 2016 > @@ -6691,6 +6691,7 @@ public: > I.info = classifyArgumentType(I.type, State); > } > > + ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) > const; > ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const; > }; > } // end anonymous namespace > @@ -6712,21 +6713,72 @@ bool LanaiABIInfo::shouldUseInReg(QualTy > return true; > } > > +ABIArgInfo LanaiABIInfo::getIndirectResult(QualType Ty, bool ByVal, > + CCState &State) const { > + if (!ByVal) { > + if (State.FreeRegs) { > + --State.FreeRegs; // Non-byval indirects just use one pointer. > + return getNaturalAlignIndirectInReg(Ty); > + } > + return getNaturalAlignIndirect(Ty, false); > + } > + > + // Compute the byval alignment. > + constexpr unsigned MinABIStackAlignInBytes = 4; > This broke the build on Windows; C:\b\slave\sanitizer-windows\llvm\tools\clang\lib\CodeGen\TargetInfo.cpp(6727) : error C2065: 'constexpr' : undeclared identifier > + unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; > + return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), > /*ByVal=*/true, > + /*Realign=*/TypeAlign > > + MinABIStackAlignInBytes); > +} > + > ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty, > CCState &State) const { > - if (isAggregateTypeForABI(Ty)) > - return getNaturalAlignIndirect(Ty); > + // Check with the C++ ABI first. > + const RecordType *RT = Ty->getAs<RecordType>(); > + if (RT) { > + CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()); > + if (RAA == CGCXXABI::RAA_Indirect) { > + return getIndirectResult(Ty, /*ByVal=*/false, State); > + } else if (RAA == CGCXXABI::RAA_DirectInMemory) { > + return getNaturalAlignIndirect(Ty, /*ByRef=*/true); > + } > + } > + > + if (isAggregateTypeForABI(Ty)) { > + // Structures with flexible arrays are always indirect. > + if (RT && RT->getDecl()->hasFlexibleArrayMember()) > + return getIndirectResult(Ty, /*ByVal=*/true, State); > + > + // Ignore empty structs/unions. > + if (isEmptyRecord(getContext(), Ty, true)) > + return ABIArgInfo::getIgnore(); > + > + llvm::LLVMContext &LLVMContext = getVMContext(); > + unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32; > + if (SizeInRegs <= State.FreeRegs) { > + llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext); > + SmallVector<llvm::Type *, 3> Elements(SizeInRegs, Int32); > + llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements); > + State.FreeRegs -= SizeInRegs; > + return ABIArgInfo::getDirectInReg(Result); > + } else { > + State.FreeRegs = 0; > + } > + return getIndirectResult(Ty, true, State); > + } > > // Treat an enum type as its underlying type. > if (const auto *EnumTy = Ty->getAs<EnumType>()) > Ty = EnumTy->getDecl()->getIntegerType(); > > - if (shouldUseInReg(Ty, State)) > - return ABIArgInfo::getDirectInReg(); > - > - if (Ty->isPromotableIntegerType()) > + bool InReg = shouldUseInReg(Ty, State); > + if (Ty->isPromotableIntegerType()) { > + if (InReg) > + return ABIArgInfo::getDirectInReg(); > return ABIArgInfo::getExtend(); > - > + } > + if (InReg) > + return ABIArgInfo::getDirectInReg(); > return ABIArgInfo::getDirect(); > } > > > Modified: cfe/trunk/test/CodeGen/lanai-arguments.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/lanai-arguments.c?rev=267496&r1=267495&r2=267496&view=diff > > ============================================================================== > --- cfe/trunk/test/CodeGen/lanai-arguments.c (original) > +++ cfe/trunk/test/CodeGen/lanai-arguments.c Mon Apr 25 19:09:29 2016 > @@ -10,7 +10,7 @@ typedef struct { > int aa; > int bb; > } s1; > -// CHECK: define void @f1(%struct.s1* byval align 4 %i) > +// CHECK: define void @f1(i32 inreg %i.coerce0, i32 inreg %i.coerce1) > void f1(s1 i) {} > > typedef struct { > @@ -61,8 +61,8 @@ union simple_union { > int a; > char b; > }; > -// Unions should be passed as byval structs. > -// CHECK: define void @f9(%union.simple_union* byval align 4 %s) > +// Unions should be passed inreg. > +// CHECK: define void @f9(i32 inreg %s.coerce) > void f9(union simple_union s) {} > > typedef struct { > @@ -70,6 +70,6 @@ typedef struct { > int b3 : 3; > int b8 : 8; > } bitfield1; > -// Bitfields should be passed as byval structs. > -// CHECK: define void @f10(%struct.bitfield1* byval align 4 %bf1) > +// Bitfields should be passed inreg. > +// CHECK: define void @f10(i32 inreg %bf1.coerce) > void f10(bitfield1 bf1) {} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits