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