diff options
author | Duncan Sands <baldrick@free.fr> | 2007-07-27 12:58:54 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2007-07-27 12:58:54 +0000 |
commit | 36397f50343639ce9a25996f2d790c656791ab92 (patch) | |
tree | a43e609dd0de1b138d3245ac390527372b3f591c /lib | |
parent | ada779fb11eb411536aa8219a176ca0ce4d58fd1 (diff) | |
download | external_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.l | 1 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 25 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 27 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 16 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.h | 1 | ||||
-rw-r--r-- | lib/Target/Alpha/AlphaISelLowering.cpp | 3 | ||||
-rw-r--r-- | lib/Target/IA64/IA64ISelLowering.cpp | 2 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 5 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcISelDAGToDAG.cpp | 4 | ||||
-rw-r--r-- | lib/Target/TargetCallingConv.td | 4 | ||||
-rw-r--r-- | lib/VMCore/Function.cpp | 2 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 17 |
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), |