Add the byval attribute

llvm-svn: 37940
diff --git a/llvm/lib/AsmParser/Lexer.l b/llvm/lib/AsmParser/Lexer.l
index 6391d17..bc61e97 100644
--- a/llvm/lib/AsmParser/Lexer.l
+++ b/llvm/lib/AsmParser/Lexer.l
@@ -230,6 +230,7 @@
 nounwind        { return NOUNWIND; }
 noreturn        { return NORETURN; }
 noalias         { return NOALIAS; }
+byval           { return BYVAL; }
 
 void            { RET_TY(Type::VoidTy,  VOID);  }
 float           { RET_TY(Type::FloatTy, FLOAT); }
diff --git a/llvm/lib/AsmParser/llvmAsmParser.y b/llvm/lib/AsmParser/llvmAsmParser.y
index 94aeeca..c879081 100644
--- a/llvm/lib/AsmParser/llvmAsmParser.y
+++ b/llvm/lib/AsmParser/llvmAsmParser.y
@@ -1101,7 +1101,7 @@
 %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
 
 // Function Attributes
-%token NORETURN INREG SRET NOUNWIND NOALIAS
+%token NORETURN INREG SRET NOUNWIND NOALIAS BYVAL
 
 // Visibility Styles
 %token DEFAULT HIDDEN PROTECTED
@@ -1229,6 +1229,7 @@
               | INREG   { $$ = ParamAttr::InReg;     }
               | SRET    { $$ = ParamAttr::StructRet; }
               | NOALIAS { $$ = ParamAttr::NoAlias;   }
+              | BYVAL   { $$ = ParamAttr::ByVal;   }
               ;
 
 OptParamAttrs : /* empty */  { $$ = ParamAttr::None; }
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 182063f..8af76b1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3789,6 +3789,8 @@
       Flags |= ISD::ParamFlags::InReg;
     if (Attrs && Attrs->paramHasAttr(j, ParamAttr::StructRet))
       Flags |= ISD::ParamFlags::StructReturn;
+    if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal))
+      Flags |= ISD::ParamFlags::ByVal;
     Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
     
     switch (getTypeAction(VT)) {
diff --git a/llvm/lib/Target/TargetCallingConv.td b/llvm/lib/Target/TargetCallingConv.td
index e710ad0..9419320 100644
--- a/llvm/lib/Target/TargetCallingConv.td
+++ b/llvm/lib/Target/TargetCallingConv.td
@@ -32,6 +32,11 @@
   string Predicate = predicate;
 }
 
+/// CCIfStruct - If the current argument is a struct, apply
+/// Action A.
+class CCIfStruct<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::ByVal", A> {
+}
+
 /// CCIfCC - Match of the current calling convention is 'CC'.
 class CCIfCC<string CC, CCAction A>
   : CCIf<!strconcat("State.getCallingConv() == ", CC), A> {}
@@ -57,6 +62,12 @@
   int Align = align;
 }
 
+/// CCStructAssign - This action always matches: it will use the C ABI and
+/// the register availability to decided whether to assign to a set of
+/// registers or to a stack slot.
+class CCStructAssign<list<Register> regList> : CCAction {
+  list<Register> RegList = regList;
+}
 
 /// CCPromoteToType - If applied, this promotes the specified current value to
 /// the specified type.
@@ -75,4 +86,3 @@
 class CallingConv<list<CCAction> actions> {
   list<CCAction> Actions = actions;
 }
-
diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td
index c98b3a2..39811bd7 100644
--- a/llvm/lib/Target/X86/X86CallingConv.td
+++ b/llvm/lib/Target/X86/X86CallingConv.td
@@ -94,6 +94,8 @@
   // Promote i8/i16 arguments to i32.
   CCIfType<[i8, i16], CCPromoteToType<i32>>,
   
+  CCIfStruct<CCStructAssign<[RDI, RSI, RDX, RCX, R8, R9 ]>>,
+
   // The first 6 integer arguments are passed in integer registers.
   CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D]>>,
   CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>,
@@ -168,5 +170,3 @@
   // Otherwise, same as everything else.
   CCDelegateTo<CC_X86_32_Common>
 ]>;
-
-
diff --git a/llvm/lib/VMCore/Function.cpp b/llvm/lib/VMCore/Function.cpp
index c10f8d7..ab12ae8 100644
--- a/llvm/lib/VMCore/Function.cpp
+++ b/llvm/lib/VMCore/Function.cpp
@@ -103,6 +103,8 @@
     Result += "noalias ";
   if (Attrs & ParamAttr::StructRet)
     Result += "sret ";  
+  if (Attrs & ParamAttr::ByVal)
+    Result += "byval ";
   return Result;
 }
 
diff --git a/llvm/lib/VMCore/Verifier.cpp b/llvm/lib/VMCore/Verifier.cpp
index 3442149..16e87f4 100644
--- a/llvm/lib/VMCore/Verifier.cpp
+++ b/llvm/lib/VMCore/Verifier.cpp
@@ -370,6 +370,9 @@
       if (Attrs->paramHasAttr(Idx, ParamAttr::NoAlias))
         Assert1(isa<PointerType>(FT->getParamType(Idx-1)),
                 "Attribute NoAlias should only apply to Pointer type!", &F);
+      if (Attrs->paramHasAttr(Idx, ParamAttr::ByVal))
+        Assert1(isa<PointerType>(FT->getParamType(Idx-1)),
+                "Attribute ByVal should only apply to Pointer type!", &F);
     }
   }