From 1aa7efbd2c98e761f50992197473304b99257ca9 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 6 Jul 2007 10:57:03 +0000 Subject: [PATCH] Add the byval attribute git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37940 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAGNodes.h | 2 ++ include/llvm/ParameterAttributes.h | 3 ++- lib/AsmParser/Lexer.l | 1 + lib/AsmParser/llvmAsmParser.y | 3 ++- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 ++ lib/Target/TargetCallingConv.td | 12 +++++++++++- lib/Target/X86/X86CallingConv.td | 4 ++-- lib/VMCore/Function.cpp | 2 ++ lib/VMCore/Verifier.cpp | 3 +++ utils/TableGen/CallingConvEmitter.cpp | 3 ++- 10 files changed, 29 insertions(+), 6 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index d22ffca2ddb..a85ec039871 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -63,6 +63,8 @@ namespace ISD { InRegOffs = 2, StructReturn = 1<<3, ///< Hidden struct-return pointer StructReturnOffs = 3, + ByVal = 1<<4, ///< Struct passed by value + ByValOffs = 4, OrigAlignment = 0x1F<<27, OrigAlignmentOffs = 27 }; diff --git a/include/llvm/ParameterAttributes.h b/include/llvm/ParameterAttributes.h index c2d60786c25..b1cb966e0af 100644 --- a/include/llvm/ParameterAttributes.h +++ b/include/llvm/ParameterAttributes.h @@ -36,7 +36,8 @@ enum Attributes { InReg = 1 << 3, ///< force argument to be passed in register StructRet = 1 << 4, ///< hidden pointer to structure to return NoUnwind = 1 << 5, ///< Function doesn't unwind stack - NoAlias = 1 << 6 ///< Considered to not alias after call. + NoAlias = 1 << 6, ///< Considered to not alias after call. + ByVal = 1 << 7 ///< Pass structure by value }; } diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 6391d17a52e..bc61e97ca95 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -230,6 +230,7 @@ sret { return SRET; } 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/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 94aeecaf831..c8790819d33 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -1101,7 +1101,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %token 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 @@ ParamAttr : ZEXT { $$ = ParamAttr::ZExt; } | INREG { $$ = ParamAttr::InReg; } | SRET { $$ = ParamAttr::StructRet; } | NOALIAS { $$ = ParamAttr::NoAlias; } + | BYVAL { $$ = ParamAttr::ByVal; } ; OptParamAttrs : /* empty */ { $$ = ParamAttr::None; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 182063fac28..8af76b1cd18 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3789,6 +3789,8 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { 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/lib/Target/TargetCallingConv.td b/lib/Target/TargetCallingConv.td index e710ad08e77..94193200eaa 100644 --- a/lib/Target/TargetCallingConv.td +++ b/lib/Target/TargetCallingConv.td @@ -32,6 +32,11 @@ class CCIf : CCPredicateAction { string Predicate = predicate; } +/// CCIfStruct - If the current argument is a struct, apply +/// Action A. +class CCIfStruct : CCIf<"ArgFlags & ISD::ParamFlags::ByVal", A> { +} + /// CCIfCC - Match of the current calling convention is 'CC'. class CCIfCC : CCIf {} @@ -57,6 +62,12 @@ class CCAssignToStack : CCAction { 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 regList> : CCAction { + list RegList = regList; +} /// CCPromoteToType - If applied, this promotes the specified current value to /// the specified type. @@ -75,4 +86,3 @@ class CCDelegateTo : CCAction { class CallingConv actions> { list Actions = actions; } - diff --git a/lib/Target/X86/X86CallingConv.td b/lib/Target/X86/X86CallingConv.td index c98b3a2aec5..39811bd7409 100644 --- a/lib/Target/X86/X86CallingConv.td +++ b/lib/Target/X86/X86CallingConv.td @@ -94,6 +94,8 @@ def CC_X86_64_C : CallingConv<[ // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType>, + CCIfStruct>, + // 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 @@ def CC_X86_32_FastCall : CallingConv<[ // Otherwise, same as everything else. CCDelegateTo ]>; - - diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index c10f8d75bd4..ab12ae8bfe2 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -103,6 +103,8 @@ ParamAttrsList::getParamAttrsText(uint16_t Attrs) { Result += "noalias "; if (Attrs & ParamAttr::StructRet) Result += "sret "; + if (Attrs & ParamAttr::ByVal) + Result += "byval "; return Result; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 3442149401c..16e87f4f7a1 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -370,6 +370,9 @@ void Verifier::visitFunction(Function &F) { if (Attrs->paramHasAttr(Idx, ParamAttr::NoAlias)) Assert1(isa(FT->getParamType(Idx-1)), "Attribute NoAlias should only apply to Pointer type!", &F); + if (Attrs->paramHasAttr(Idx, ParamAttr::ByVal)) + Assert1(isa(FT->getParamType(Idx-1)), + "Attribute ByVal should only apply to Pointer type!", &F); } } diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp index ae7dc91fc70..2929aba820b 100644 --- a/utils/TableGen/CallingConvEmitter.cpp +++ b/utils/TableGen/CallingConvEmitter.cpp @@ -129,10 +129,11 @@ void CallingConvEmitter::EmitAction(Record *Action, << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n" << IndentStr << "else\n" << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n"; + } else if (Action->isSubClassOf("CCStructAssign")) { + O << "assert(0 && \"Not Implemented\");\n"; } else { Action->dump(); throw "Unknown CCAction!"; } } } - -- 2.34.1