The attached patch implements code generation of byval arguments on
the callee. For now only the case were the struct is in the stack is
handle correctly.

With the patch, the function
---------------------------------------------------
%struct.s = type { i64, i64, i64 }

define i64 @f(%struct.s* byval %a) {
entry:
        %tmp2 = getelementptr %struct.s* %a, i32 0, i32 0]
        %tmp3 = load i64* %tmp2
        ret i64 %tmp3
}
------------------------
Correctly compiles to

f:
        movq    8(%rsp), %rax
        ret

There is still a lot to implement and debug, but I would like to know
any comments one might have.

Cheers,
-- 
Rafael Avila de Espindola

Google Ireland Ltd.
Gordon House
Barrow Street
Dublin 4
Ireland

Registered in Dublin, Ireland
Registration Number: 368047
Index: include/llvm/CodeGen/SelectionDAGNodes.h
===================================================================
--- include/llvm/CodeGen/SelectionDAGNodes.h	(revision 40777)
+++ include/llvm/CodeGen/SelectionDAGNodes.h	(working copy)
@@ -68,6 +68,10 @@
     ByValOffs         = 4,
     Nest              = 1<<5,  ///< Parameter is nested function static chain
     NestOffs          = 5,
+    ByValAlign        = 0xF << 6, //< The alignment of the struct
+    ByValAlignOffs    = 6,
+    ByValSize         = 0x1ffff << 10, //< The size of the struct
+    ByValSizeOffs     = 10,
     OrigAlignment     = 0x1F<<27,
     OrigAlignmentOffs = 27
   };
@@ -200,6 +204,10 @@
     /// Bit 0 - signness
     /// Bit 1 - 'inreg' attribute
     /// Bit 2 - 'sret' attribute
+    /// Bit 4 - 'byval' attribute
+    /// Bit 5 - 'nest' attribute
+    /// Bit 6-9 - alignment of byval structures
+    /// Bit 10-26 - size of byval structures
     /// Bits 31:27 - argument ABI alignment in the first argument piece and
     /// alignment '1' in other argument pieces.
     CALL,
Index: include/llvm/CodeGen/CallingConvLower.h
===================================================================
--- include/llvm/CodeGen/CallingConvLower.h	(revision 40777)
+++ include/llvm/CodeGen/CallingConvLower.h	(working copy)
@@ -190,6 +190,10 @@
     StackOffset += Size;
     return Result;
   }
+
+  void HandleStruct(unsigned ValNo, MVT::ValueType ValVT,
+                    MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,
+                    unsigned ArgFlags);
 private:
   /// MarkAllocated - Mark a register and all of its aliases as allocated.
   void MarkAllocated(unsigned Reg);
Index: utils/TableGen/CallingConvEmitter.cpp
===================================================================
--- utils/TableGen/CallingConvEmitter.cpp	(revision 40777)
+++ utils/TableGen/CallingConvEmitter.cpp	(working copy)
@@ -130,7 +130,9 @@
         << IndentStr << "else\n"
         << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
     } else if (Action->isSubClassOf("CCStructAssign")) {
-      O << "assert(0 && \"Not Implemented\");\n";
+      O << IndentStr <<
+          "State.HandleStruct(ValNo, ValVT, LocVT, LocInfo, ArgFlags);\n";
+      O << IndentStr << "return false;\n";
     } else {
       Action->dump();
       throw "Unknown CCAction!";
Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	(revision 40777)
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	(working copy)
@@ -3848,8 +3848,15 @@
       Flags |= ISD::ParamFlags::InReg;
     if (Attrs && Attrs->paramHasAttr(j, ParamAttr::StructRet))
       Flags |= ISD::ParamFlags::StructReturn;
-    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal))
+    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal)) {
       Flags |= ISD::ParamFlags::ByVal;
+      const PointerType *Ty = cast<PointerType>(I->getType());
+      const StructType *STy = cast<StructType>(Ty->getElementType());
+      unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
+      unsigned StructSize  = getTargetData()->getTypeSize(STy);
+      Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
+      Flags |= (StructSize  << ISD::ParamFlags::ByValSizeOffs);
+    }
     if (Attrs && Attrs->paramHasAttr(j, ParamAttr::Nest))
       Flags |= ISD::ParamFlags::Nest;
     Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
Index: lib/CodeGen/SelectionDAG/CallingConvLower.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/CallingConvLower.cpp	(revision 40777)
+++ lib/CodeGen/SelectionDAG/CallingConvLower.cpp	(working copy)
@@ -28,7 +28,18 @@
   UsedRegs.resize(MRI.getNumRegs());
 }
 
+void CCState::HandleStruct(unsigned ValNo, MVT::ValueType ValVT,
+                           MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,
+                           unsigned ArgFlags) {
+  unsigned Align  = 1 << ((ArgFlags & ISD::ParamFlags::ByValAlign) >>
+                          ISD::ParamFlags::ByValAlignOffs);
+  unsigned Size   = (ArgFlags & ISD::ParamFlags::ByValSize) >>
+      ISD::ParamFlags::ByValSizeOffs;
+  unsigned Offset = AllocateStack(Size, Align);
 
+  addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
+}
+
 /// MarkAllocated - Mark a register and all of its aliases as allocated.
 void CCState::MarkAllocated(unsigned Reg) {
   UsedRegs[Reg/32] |= 1 << (Reg&31);
@@ -99,4 +110,3 @@
     }
   }
 }
-
Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp	(revision 40777)
+++ lib/Target/X86/X86ISelLowering.cpp	(working copy)
@@ -1245,7 +1245,12 @@
       int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
                                       VA.getLocMemOffset());
       SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
-      ArgValues.push_back(DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0));
+
+      unsigned Flags =  cast<ConstantSDNode>(Op.getOperand(3 + i))->getValue();
+      if (Flags & ISD::ParamFlags::ByVal)
+        ArgValues.push_back(FIN);
+      else
+        ArgValues.push_back(DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0));
     }
   }
   
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to