[llvm-commits] [llvm] r40549 - in /llvm/trunk: docs/ include/llvm/ include/llvm/CodeGen/ include/llvm/Target/ lib/AsmParser/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/ARM/ lib/Target/Alpha/ lib/Target/IA64/ lib/Target/Mips/ lib/Target/PowerPC/ lib/Target/Sparc/ lib/VMCore/
Duncan Sands
baldrick at free.fr
Fri Jul 27 05:58:55 PDT 2007
Author: baldrick
Date: Fri Jul 27 07:58:54 2007
New Revision: 40549
URL: http://llvm.org/viewvc/llvm-project?rev=40549&view=rev
Log:
Support for trampolines, except for X86 codegen which is
still under discussion.
Modified:
llvm/trunk/docs/LangRef.html
llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
llvm/trunk/include/llvm/Intrinsics.td
llvm/trunk/include/llvm/ParameterAttributes.h
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/AsmParser/Lexer.l
llvm/trunk/lib/AsmParser/llvmAsmParser.y
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
llvm/trunk/lib/Target/ARM/ARMISelLowering.h
llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp
llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp
llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp
llvm/trunk/lib/Target/TargetCallingConv.td
llvm/trunk/lib/VMCore/Function.cpp
llvm/trunk/lib/VMCore/Verifier.cpp
Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Fri Jul 27 07:58:54 2007
@@ -200,6 +200,12 @@
<li><a href="#int_memory_barrier">'<tt>llvm.memory.barrier</tt>' Intrinsic</a></li>
</ol>
</li>
+ <li><a href="#int_trampoline">Trampoline Intrinsics</a>
+ <ol>
+ <li><a href="#int_it">'<tt>llvm.init.trampoline</tt>' Intrinsic</a></li>
+ <li><a href="#int_at">'<tt>llvm.adjust.trampoline</tt>' Intrinsic</a></li>
+ </ol>
+ </li>
<li><a href="#int_general">General intrinsics</a>
<ol>
<li><a href="#int_var_annotation">
@@ -5123,6 +5129,105 @@
<!-- ======================================================================= -->
<div class="doc_subsection">
+ <a name="int_trampoline">Trampoline Intrinsics</a>
+</div>
+
+<div class="doc_text">
+<p>
+ These intrinsics make it possible to excise one parameter, marked with
+ the <tt>nest</tt> attribute, from a function. The result is a callable
+ function pointer lacking the nest parameter - the caller does not need
+ to provide a value for it. Instead, the value to use is stored in
+ advance in a "trampoline", a block of memory usually allocated
+ on the stack, which also contains code to splice the nest value into the
+ argument list. This is used to implement the GCC nested function address
+ extension.
+</p>
+<p>
+ For example, if the function is
+ <tt>i32 f(i8* nest %c, i32 %x, i32 %y)</tt> then the resulting function
+ pointer has signature <tt>i32 (i32, i32)*</tt>. It can be created as follows:
+<pre>
+ %tramp1 = alloca [10 x i8], align 4 ; size and alignment only correct for X86
+ %tramp = getelementptr [10 x i8]* %tramp1, i32 0, i32 0
+ call void @llvm.init.trampoline( i8* %tramp, i8* bitcast (i32 (i8* nest , i32, i32)* @f to i8*), i8* %nval )
+ %adj = call i8* @llvm.adjust.trampoline( i8* %tramp )
+ %fp = bitcast i8* %adj to i32 (i32, i32)*
+</pre>
+ The call <tt>%val = call i32 %fp( i32 %x, i32 %y )</tt> is then equivalent to
+ <tt>%val = call i32 %f( i8* %nval, i32 %x, i32 %y )</tt>.
+</p>
+<p>
+ Trampolines are currently only supported on the X86 architecture.
+</p>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_it">'<tt>llvm.init.trampoline</tt>' Intrinsic</a>
+</div>
+<div class="doc_text">
+<h5>Syntax:</h5>
+<pre>
+declare void @llvm.init.trampoline(i8* <tramp>, i8* <func>, i8* <nval>)
+</pre>
+<h5>Overview:</h5>
+<p>
+ This initializes the memory pointed to by <tt>tramp</tt> as a trampoline.
+</p>
+<h5>Arguments:</h5>
+<p>
+ The <tt>llvm.init.trampoline</tt> intrinsic takes three arguments, all
+ pointers. The <tt>tramp</tt> argument must point to a sufficiently large
+ and sufficiently aligned block of memory; this memory is written to by the
+ intrinsic. Currently LLVM provides no help in determining just how big and
+ aligned the memory needs to be. The <tt>func</tt> argument must hold a
+ function bitcast to an <tt>i8*</tt>.
+</p>
+<h5>Semantics:</h5>
+<p>
+ The block of memory pointed to by <tt>tramp</tt> is filled with target
+ dependent code, turning it into a function.
+ The new function's signature is the same as that of <tt>func</tt> with
+ any arguments marked with the <tt>nest</tt> attribute removed. At most
+ one such <tt>nest</tt> argument is allowed, and it must be of pointer
+ type. Calling the new function is equivalent to calling <tt>func</tt>
+ with the same argument list, but with <tt>nval</tt> used for the missing
+ <tt>nest</tt> argument.
+</p>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_at">'<tt>llvm.adjust.trampoline</tt>' Intrinsic</a>
+</div>
+<div class="doc_text">
+<h5>Syntax:</h5>
+<pre>
+declare i8* @llvm.adjust.trampoline(i8* <tramp>)
+</pre>
+<h5>Overview:</h5>
+<p>
+ This intrinsic returns a function pointer suitable for executing
+ the trampoline code pointed to by <tt>tramp</tt>.
+</p>
+<h5>Arguments:</h5>
+<p>
+ The <tt>llvm.adjust.trampoline</tt> takes one argument, a pointer to a
+ trampoline initialized by the
+ <a href="#int_it">'<tt>llvm.init.trampoline</tt>' intrinsic</a>.
+</p>
+<h5>Semantics:</h5>
+<p>
+ A function pointer that can be used to execute the trampoline code in
+ <tt>tramp</tt> is returned. The returned value should be bitcast to an
+ <a href="#int_trampoline">appropriate function pointer type</a>
+ before being called.
+</p>
+</div>
+
+<!-- ======================================================================= -->
+<div class="doc_subsection">
<a name="int_general">General Intrinsics</a>
</div>
Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Fri Jul 27 07:58:54 2007
@@ -66,6 +66,8 @@
StructReturnOffs = 3,
ByVal = 1<<4, ///< Struct passed by value
ByValOffs = 4,
+ Nest = 1<<5, ///< Parameter is nested function static chain
+ NestOffs = 5,
OrigAlignment = 0x1F<<27,
OrigAlignmentOffs = 27
};
@@ -528,7 +530,19 @@
// number, then a column then a file id (provided by MachineModuleInfo.) It
// produces a token chain as output.
DEBUG_LOC,
-
+
+ // ADJUST_TRAMP - This corresponds to the adjust_trampoline intrinsic.
+ // It takes a value as input and returns a value as output.
+ ADJUST_TRAMP,
+
+ // TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
+ // It takes as input a token chain, the pointer to the trampoline,
+ // the pointer to the nested function, the pointer to pass for the
+ // 'nest' parameter, a SRCVALUE for the trampoline and another for
+ // the nested function (allowing targets to access the original
+ // Function*). It produces a token chain as output.
+ TRAMPOLINE,
+
// BUILTIN_OP_END - This must be the last enum value in this list.
BUILTIN_OP_END
};
Modified: llvm/trunk/include/llvm/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Intrinsics.td?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/Intrinsics.td Fri Jul 27 07:58:54 2007
@@ -247,6 +247,14 @@
llvm_ptr_ty, llvm_i32_ty],
[], "llvm.var.annotation">;
+//===------------------------ Trampoline Intrinsics -----------------------===//
+//
+def int_init_trampoline : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_ptr_ty], []>,
+ GCCBuiltin<"__builtin_init_trampoline">;
+def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty], [IntrNoMem]>,
+ GCCBuiltin<"__builtin_adjust_trampoline">;
+
//===----------------------------------------------------------------------===//
// Target-specific intrinsics
//===----------------------------------------------------------------------===//
Modified: llvm/trunk/include/llvm/ParameterAttributes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ParameterAttributes.h?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ParameterAttributes.h (original)
+++ llvm/trunk/include/llvm/ParameterAttributes.h Fri Jul 27 07:58:54 2007
@@ -30,14 +30,15 @@
/// @brief Function parameter attributes.
enum Attributes {
None = 0, ///< No attributes have been set
- ZExt = 1 << 0, ///< zero extended before/after call
- SExt = 1 << 1, ///< sign extended before/after call
- NoReturn = 1 << 2, ///< mark the function as not returning
- InReg = 1 << 3, ///< force argument to be passed in register
- StructRet = 1 << 4, ///< hidden pointer to structure to return
+ ZExt = 1 << 0, ///< Zero extended before/after call
+ SExt = 1 << 1, ///< Sign extended before/after call
+ NoReturn = 1 << 2, ///< Mark the function as not returning
+ 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.
- ByVal = 1 << 7 ///< Pass structure by value
+ NoAlias = 1 << 6, ///< Considered to not alias after call
+ ByVal = 1 << 7, ///< Pass structure by value
+ Nest = 1 << 8 ///< Nested function static chain
};
}
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Fri Jul 27 07:58:54 2007
@@ -812,8 +812,10 @@
bool isZExt;
bool isInReg;
bool isSRet;
+ bool isNest;
- ArgListEntry():isSExt(false), isZExt(false), isInReg(false), isSRet(false) { };
+ ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
+ isSRet(false), isNest(false) { };
};
typedef std::vector<ArgListEntry> ArgListTy;
virtual std::pair<SDOperand, SDOperand>
Modified: llvm/trunk/lib/AsmParser/Lexer.l
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/Lexer.l?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/Lexer.l (original)
+++ llvm/trunk/lib/AsmParser/Lexer.l Fri Jul 27 07:58:54 2007
@@ -233,6 +233,7 @@
noreturn { return NORETURN; }
noalias { return NOALIAS; }
byval { return BYVAL; }
+nest { return NEST; }
void { RET_TY(Type::VoidTy, VOID); }
float { RET_TY(Type::FloatTy, FLOAT); }
Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original)
+++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Fri Jul 27 07:58:54 2007
@@ -1101,7 +1101,7 @@
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
// Function Attributes
-%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL
+%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
// Visibility Styles
%token DEFAULT HIDDEN PROTECTED
@@ -1229,7 +1229,8 @@
| INREG { $$ = ParamAttr::InReg; }
| SRET { $$ = ParamAttr::StructRet; }
| NOALIAS { $$ = ParamAttr::NoAlias; }
- | BYVAL { $$ = ParamAttr::ByVal; }
+ | BYVAL { $$ = ParamAttr::ByVal; }
+ | NEST { $$ = ParamAttr::Nest; }
;
OptParamAttrs : /* empty */ { $$ = ParamAttr::None; }
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Jul 27 07:58:54 2007
@@ -3156,6 +3156,31 @@
}
break;
}
+ case ISD::ADJUST_TRAMP: {
+ Tmp1 = LegalizeOp(Node->getOperand(0));
+ switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Custom:
+ Result = DAG.UpdateNodeOperands(Result, Tmp1);
+ Result = TLI.LowerOperation(Result, DAG);
+ if (Result.Val) break;
+ // FALL THROUGH
+ case TargetLowering::Expand:
+ Result = Tmp1;
+ break;
+ }
+ break;
+ }
+ case ISD::TRAMPOLINE: {
+ SDOperand Ops[6];
+ for (unsigned i = 0; i != 6; ++i)
+ Ops[i] = LegalizeOp(Node->getOperand(i));
+ Result = DAG.UpdateNodeOperands(Result, Ops, 6);
+ // The only option for this node is to custom lower it.
+ Result = TLI.LowerOperation(Result, DAG);
+ assert(Result.Val && "Should always custom lower!");
+ break;
+ }
}
assert(Result.getValueType() == Op.getValueType() &&
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Jul 27 07:58:54 2007
@@ -3513,6 +3513,10 @@
case ISD::LOCATION: return "location";
case ISD::DEBUG_LOC: return "debug_loc";
+ // Trampolines
+ case ISD::ADJUST_TRAMP: return "adjust_tramp";
+ case ISD::TRAMPOLINE: return "trampoline";
+
case ISD::CONDCODE:
switch (cast<CondCodeSDNode>(this)->get()) {
default: assert(0 && "Unknown setcc condition!");
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Jul 27 07:58:54 2007
@@ -2863,6 +2863,28 @@
case Intrinsic::var_annotation:
// Discard annotate attributes
return 0;
+
+ case Intrinsic::adjust_trampoline: {
+ SDOperand Arg = getValue(I.getOperand(1));
+ setValue(&I, DAG.getNode(ISD::ADJUST_TRAMP, TLI.getPointerTy(), Arg));
+ return 0;
+ }
+
+ case Intrinsic::init_trampoline: {
+ const Function *F =
+ cast<Function>(IntrinsicInst::StripPointerCasts(I.getOperand(2)));
+
+ SDOperand Ops[6];
+ Ops[0] = getRoot();
+ Ops[1] = getValue(I.getOperand(1));
+ Ops[2] = getValue(I.getOperand(2));
+ Ops[3] = getValue(I.getOperand(3));
+ Ops[4] = DAG.getSrcValue(I.getOperand(1));
+ Ops[5] = DAG.getSrcValue(F);
+
+ DAG.setRoot(DAG.getNode(ISD::TRAMPOLINE, MVT::Other, Ops, 6));
+ return 0;
+ }
}
}
@@ -2892,6 +2914,7 @@
Entry.isZExt = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ZExt);
Entry.isInReg = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::InReg);
Entry.isSRet = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::StructRet);
+ Entry.isNest = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::Nest);
Args.push_back(Entry);
}
@@ -3827,6 +3850,8 @@
Flags |= ISD::ParamFlags::StructReturn;
if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal))
Flags |= ISD::ParamFlags::ByVal;
+ if (Attrs && Attrs->paramHasAttr(j, ParamAttr::Nest))
+ Flags |= ISD::ParamFlags::Nest;
Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
switch (getTypeAction(VT)) {
@@ -3945,6 +3970,8 @@
Flags |= ISD::ParamFlags::InReg;
if (Args[i].isSRet)
Flags |= ISD::ParamFlags::StructReturn;
+ if (Args[i].isNest)
+ Flags |= ISD::ParamFlags::Nest;
Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs;
switch (getTypeAction(VT)) {
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Jul 27 07:58:54 2007
@@ -190,7 +190,12 @@
setOperationAction(ISD::MEMSET , MVT::Other, Expand);
setOperationAction(ISD::MEMCPY , MVT::Other, Custom);
setOperationAction(ISD::MEMMOVE , MVT::Other, Expand);
-
+
+ if (Subtarget->isThumb())
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Custom);
+ else
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
+
// Use the default implementation.
setOperationAction(ISD::VASTART , MVT::Other, Expand);
setOperationAction(ISD::VAARG , MVT::Other, Expand);
@@ -1413,6 +1418,14 @@
return Chain;
}
+SDOperand ARMTargetLowering::LowerADJUST_TRAMP(SDOperand Op,
+ SelectionDAG &DAG) {
+ // Thumb trampolines should be entered in thumb mode, so set the bottom bit
+ // of the address.
+ return DAG.getNode(ISD::OR, MVT::i32, Op.getOperand(0),
+ DAG.getConstant(1, MVT::i32));
+}
+
SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
switch (Op.getOpcode()) {
default: assert(0 && "Don't know how to custom lower this!"); abort();
@@ -1444,6 +1457,7 @@
case ISD::FRAMEADDR: break;
case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG);
case ISD::MEMCPY: return LowerMEMCPY(Op, DAG);
+ case ISD::ADJUST_TRAMP: return LowerADJUST_TRAMP(Op, DAG);
}
return SDOperand();
}
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Fri Jul 27 07:58:54 2007
@@ -138,6 +138,7 @@
SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerADJUST_TRAMP(SDOperand Op, SelectionDAG &DAG);
};
}
Modified: llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Alpha/AlphaISelLowering.cpp Fri Jul 27 07:58:54 2007
@@ -124,6 +124,9 @@
setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand);
+
setOperationAction(ISD::VASTART, MVT::Other, Custom);
setOperationAction(ISD::VAEND, MVT::Other, Expand);
setOperationAction(ISD::VACOPY, MVT::Other, Custom);
Modified: llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/IA64/IA64ISelLowering.cpp Fri Jul 27 07:58:54 2007
@@ -97,6 +97,8 @@
setOperationAction(ISD::ROTR , MVT::i64 , Expand);
setOperationAction(ISD::BSWAP, MVT::i64 , Expand); // mux @rev
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand);
+
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
setOperationAction(ISD::VAARG , MVT::Other, Custom);
setOperationAction(ISD::VASTART , MVT::Other, Custom);
Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri Jul 27 07:58:54 2007
@@ -102,6 +102,8 @@
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
+
setStackPointerRegisterToSaveRestore(Mips::SP);
computeRegisterProperties();
}
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Jul 27 07:58:54 2007
@@ -169,7 +169,10 @@
// RET must be custom lowered, to meet ABI requirements
setOperationAction(ISD::RET , MVT::Other, Custom);
-
+
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand);
+
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
setOperationAction(ISD::VASTART , MVT::Other, Custom);
Modified: llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelDAGToDAG.cpp Fri Jul 27 07:58:54 2007
@@ -215,7 +215,9 @@
// RET must be custom lowered, to meet ABI requirements
setOperationAction(ISD::RET , MVT::Other, Custom);
-
+
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
+
// VASTART needs to be custom lowered to use the VarArgsFrameIndex.
setOperationAction(ISD::VASTART , MVT::Other, Custom);
// VAARG needs to be lowered to not do unaligned accesses for doubles.
Modified: llvm/trunk/lib/Target/TargetCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetCallingConv.td?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetCallingConv.td (original)
+++ llvm/trunk/lib/Target/TargetCallingConv.td Fri Jul 27 07:58:54 2007
@@ -45,6 +45,10 @@
/// the specified action.
class CCIfInReg<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::InReg", A> {}
+/// CCIfNest - If this argument is marked with the 'nest' attribute, apply
+/// the specified action.
+class CCIfNest<CCAction A> : CCIf<"ArgFlags & ISD::ParamFlags::Nest", A> {}
+
/// CCIfNotVarArg - If the current function is not vararg - apply the action
class CCIfNotVarArg<CCAction A> : CCIf<"!State.isVarArg()", A> {}
Modified: llvm/trunk/lib/VMCore/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Function.cpp (original)
+++ llvm/trunk/lib/VMCore/Function.cpp Fri Jul 27 07:58:54 2007
@@ -105,6 +105,8 @@
Result += "sret ";
if (Attrs & ParamAttr::ByVal)
Result += "byval ";
+ if (Attrs & ParamAttr::Nest)
+ Result += "nest ";
return Result;
}
Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=40549&r1=40548&r2=40549&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Fri Jul 27 07:58:54 2007
@@ -361,6 +361,7 @@
if (const ParamAttrsList *Attrs = FT->getParamAttrs()) {
unsigned Idx = 1;
+ bool SawNest = false;
Assert1(!Attrs->paramHasAttr(0, ParamAttr::ByVal),
"Attribute ByVal should not apply to functions!", &F);
@@ -368,6 +369,8 @@
"Attribute SRet should not apply to functions!", &F);
Assert1(!Attrs->paramHasAttr(0, ParamAttr::InReg),
"Attribute InReg should not apply to functions!", &F);
+ Assert1(!Attrs->paramHasAttr(0, ParamAttr::Nest),
+ "Attribute Nest should not apply to functions!", &F);
for (FunctionType::param_iterator I = FT->param_begin(),
E = FT->param_end(); I != E; ++I, ++Idx) {
@@ -391,6 +394,20 @@
"Attribute ByVal should only apply to pointer to structs!", &F);
}
+ if (Attrs->paramHasAttr(Idx, ParamAttr::Nest)) {
+ Assert1(!SawNest, "More than one parameter has attribute Nest!", &F);
+ SawNest = true;
+
+ Assert1(isa<PointerType>(FT->getParamType(Idx-1)),
+ "Attribute Nest should only apply to Pointer type!", &F);
+ Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::ByVal),
+ "Attributes Nest and ByVal are incompatible!", &F);
+ Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::InReg),
+ "Attributes Nest and InReg are incompatible!", &F);
+ Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::StructRet),
+ "Attributes Nest and StructRet are incompatible!", &F);
+ }
+
Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoReturn),
"Attribute NoReturn should only be applied to function", &F);
Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoUnwind),
More information about the llvm-commits
mailing list