aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-07-27 12:58:54 +0000
committerDuncan Sands <baldrick@free.fr>2007-07-27 12:58:54 +0000
commit36397f50343639ce9a25996f2d790c656791ab92 (patch)
treea43e609dd0de1b138d3245ac390527372b3f591c /lib
parentada779fb11eb411536aa8219a176ca0ce4d58fd1 (diff)
downloadexternal_llvm-36397f50343639ce9a25996f2d790c656791ab92.zip
external_llvm-36397f50343639ce9a25996f2d790c656791ab92.tar.gz
external_llvm-36397f50343639ce9a25996f2d790c656791ab92.tar.bz2
Support for trampolines, except for X86 codegen which is
still under discussion. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40549 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AsmParser/Lexer.l1
-rw-r--r--lib/AsmParser/llvmAsmParser.y5
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp25
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp27
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp16
-rw-r--r--lib/Target/ARM/ARMISelLowering.h1
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp3
-rw-r--r--lib/Target/IA64/IA64ISelLowering.cpp2
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp2
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp5
-rw-r--r--lib/Target/Sparc/SparcISelDAGToDAG.cpp4
-rw-r--r--lib/Target/TargetCallingConv.td4
-rw-r--r--lib/VMCore/Function.cpp2
-rw-r--r--lib/VMCore/Verifier.cpp17
15 files changed, 113 insertions, 5 deletions
diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l
index 24467cf..6b8bba5 100644
--- a/lib/AsmParser/Lexer.l
+++ b/lib/AsmParser/Lexer.l
@@ -233,6 +233,7 @@ nounwind { return NOUNWIND; }
noreturn { return NORETURN; }
noalias { return NOALIAS; }
byval { return BYVAL; }
+nest { return NEST; }
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 0936af3..0cc7a98 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -1101,7 +1101,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
%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 @@ ParamAttr : ZEROEXT { $$ = ParamAttr::ZExt; }
| INREG { $$ = ParamAttr::InReg; }
| SRET { $$ = ParamAttr::StructRet; }
| NOALIAS { $$ = ParamAttr::NoAlias; }
- | BYVAL { $$ = ParamAttr::ByVal; }
+ | BYVAL { $$ = ParamAttr::ByVal; }
+ | NEST { $$ = ParamAttr::Nest; }
;
OptParamAttrs : /* empty */ { $$ = ParamAttr::None; }
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 4131ed9..078cbf3 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -3156,6 +3156,31 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
}
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() &&
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index d4d984b..4b7863d 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -3513,6 +3513,10 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
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!");
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 05578fe..ce09eb4 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2863,6 +2863,28 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
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 @@ void SelectionDAGLowering::LowerCallTo(Instruction &I,
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 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
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 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
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)) {
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 6f63fbd..a274c14 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -190,7 +190,12 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
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 @@ SDOperand ARMTargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) {
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 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
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();
}
diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h
index 2b66f23..318657e 100644
--- a/lib/Target/ARM/ARMISelLowering.h
+++ b/lib/Target/ARM/ARMISelLowering.h
@@ -138,6 +138,7 @@ namespace llvm {
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);
};
}
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index d4777b2..adbf322 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -124,6 +124,9 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
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);
diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp
index 0237a9a..b9508a9 100644
--- a/lib/Target/IA64/IA64ISelLowering.cpp
+++ b/lib/Target/IA64/IA64ISelLowering.cpp
@@ -97,6 +97,8 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
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);
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 790cdaf..3328336 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -102,6 +102,8 @@ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM)
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
+ setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand);
+
setStackPointerRegisterToSaveRestore(Mips::SP);
computeRegisterProperties();
}
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 6c2f383..0ed1112 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -169,7 +169,10 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
// 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);
diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
index 8c8b3f8..536abc1 100644
--- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp
+++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp
@@ -215,7 +215,9 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
// 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.
diff --git a/lib/Target/TargetCallingConv.td b/lib/Target/TargetCallingConv.td
index 9419320..176a848 100644
--- a/lib/Target/TargetCallingConv.td
+++ b/lib/Target/TargetCallingConv.td
@@ -45,6 +45,10 @@ class CCIfCC<string CC, CCAction A>
/// 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> {}
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index dd78196..1374d55 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -105,6 +105,8 @@ ParamAttrsList::getParamAttrsText(uint16_t Attrs) {
Result += "sret ";
if (Attrs & ParamAttr::ByVal)
Result += "byval ";
+ if (Attrs & ParamAttr::Nest)
+ Result += "nest ";
return Result;
}
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index ffca88b..de4050d 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -361,6 +361,7 @@ void Verifier::visitFunction(Function &F) {
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 @@ void Verifier::visitFunction(Function &F) {
"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 @@ void Verifier::visitFunction(Function &F) {
"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),