diff options
author | Nate Begeman <natebegeman@mac.com> | 2006-01-25 18:21:52 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2006-01-25 18:21:52 +0000 |
commit | acc398c195a697795bff3245943d104eb19192b9 (patch) | |
tree | d5efdfaaaf3a9c0d6b467c769dee5ea884aced3c /lib/CodeGen | |
parent | 05ebc8d795f039f1b7647bb33e995aa2f5c40b73 (diff) |
First part of bug 680:
Remove TLI.LowerVA* and replace it with SDNodes that are lowered the same
way as everything else.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25606 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 157 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 33 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 69 |
3 files changed, 192 insertions, 67 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index e5dd538eb4..933aa70e88 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1115,13 +1115,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { switch (TLI.getOperationAction(Node->getOpcode(), VT)) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Custom: { - SDOperand Op = DAG.getLoad(Node->getValueType(0), - Tmp1, Tmp2, Node->getOperand(2)); + SDOperand Op = DAG.getLoad(VT, Tmp1, Tmp2, Node->getOperand(2)); SDOperand Tmp = TLI.LowerOperation(Op, DAG); if (Tmp.Val) { Result = LegalizeOp(Tmp); - // Since loads produce two values, make sure to remember that we legalized - // both of them. + // Since loads produce two values, make sure to remember that we + // legalized both of them. AddLegalizedOperand(SDOperand(Node, 0), Result); AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); return Result.getValue(Op.ResNo); @@ -1131,8 +1130,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case TargetLowering::Legal: if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) - Result = DAG.getLoad(Node->getValueType(0), Tmp1, Tmp2, - Node->getOperand(2)); + Result = DAG.getLoad(VT, Tmp1, Tmp2, Node->getOperand(2)); else Result = SDOperand(Node, 0); @@ -2222,6 +2220,140 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { } break; + case ISD::VAARG: { + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + + MVT::ValueType VT = Node->getValueType(0); + switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Op = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2)); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) + Result = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2)); + else + Result = SDOperand(Node, 0); + break; + case TargetLowering::Expand: { + SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, + Node->getOperand(2)); + // Increment the pointer, VAList, to the next vaarg + Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, + DAG.getConstant(MVT::getSizeInBits(VT)/8, + TLI.getPointerTy())); + // Store the incremented VAList to the legalized pointer + Tmp3 = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), Tmp3, Tmp2, + Node->getOperand(2)); + // Load the actual argument out of the pointer VAList + Result = DAG.getLoad(VT, Tmp3, VAList, DAG.getSrcValue(0)); + Result = LegalizeOp(Result); + break; + } + } + // Since VAARG produces two values, make sure to remember that we + // legalized both of them. + AddLegalizedOperand(SDOperand(Node, 0), Result); + AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1)); + return Result.getValue(Op.ResNo); + } + + case ISD::VACOPY: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the dest pointer. + Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the source pointer. + + switch (TLI.getOperationAction(ISD::VACOPY, MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Op = DAG.getNode(ISD::VACOPY, MVT::Other, Tmp1, Tmp2, Tmp3, + Node->getOperand(3), Node->getOperand(4)); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1) || + Tmp3 != Node->getOperand(2)) + Result = DAG.getNode(ISD::VACOPY, MVT::Other, Tmp1, Tmp2, Tmp3, + Node->getOperand(3), Node->getOperand(4)); + break; + case TargetLowering::Expand: + // This defaults to loading a pointer from the input and storing it to the + // output, returning the chain. + Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, Node->getOperand(3)); + Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp4.getValue(1), Tmp4, Tmp2, + Node->getOperand(4)); + Result = LegalizeOp(Result); + break; + } + break; + + case ISD::VAEND: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + + switch (TLI.getOperationAction(ISD::VAEND, MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Op = DAG.getNode(ISD::VAEND, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) + Result = DAG.getNode(ISD::VAEND, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + break; + case TargetLowering::Expand: + Result = Tmp1; // Default to a no-op, return the chain + break; + } + break; + + case ISD::VASTART: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + + switch (TLI.getOperationAction(ISD::VASTART, MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Custom: { + SDOperand Op = DAG.getNode(ISD::VASTART, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + if (Tmp.Val) { + Result = LegalizeOp(Tmp); + break; + } + // FALLTHROUGH if the target thinks it is legal. + } + case TargetLowering::Legal: + if (Tmp1 != Node->getOperand(0) || + Tmp2 != Node->getOperand(1)) + Result = DAG.getNode(ISD::VASTART, MVT::Other, Tmp1, Tmp2, + Node->getOperand(2)); + break; + } + break; + case ISD::ROTL: case ISD::ROTR: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS @@ -3823,6 +3955,19 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ break; } + case ISD::VAARG: { + SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + Lo = DAG.getVAArg(NVT, Ch, Ptr, Node->getOperand(2)); + Hi = DAG.getVAArg(NVT, Lo.getValue(1), Ptr, Node->getOperand(2)); + + // Remember that we legalized the chain. + AddLegalizedOperand(Op.getValue(1), Hi.getValue(1)); + if (!TLI.isLittleEndian()) + std::swap(Lo, Hi); + break; + } + case ISD::LOAD: { SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain. SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ed96bd61ae..d864042537 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1348,6 +1348,20 @@ SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) { return SDOperand(N, 0); } +SDOperand SelectionDAG::getVAArg(MVT::ValueType VT, + SDOperand Chain, SDOperand Ptr, + SDOperand SV) { + std::vector<SDOperand> Ops; + Ops.reserve(3); + Ops.push_back(Chain); + Ops.push_back(Ptr); + Ops.push_back(SV); + std::vector<MVT::ValueType> VTs; + VTs.reserve(2); + VTs.push_back(VT); VTs.push_back(MVT::Other); // Add token chain. + return getNode(ISD::VAARG, VTs, Ops); +} + SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, std::vector<SDOperand> &Ops) { switch (Ops.size()) { @@ -2087,14 +2101,17 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { case ISD::CALLSEQ_END: return "callseq_end"; // Other operators - case ISD::LOAD: return "load"; - case ISD::STORE: return "store"; - case ISD::VLOAD: return "vload"; - case ISD::EXTLOAD: return "extload"; - case ISD::SEXTLOAD: return "sextload"; - case ISD::ZEXTLOAD: return "zextload"; - case ISD::TRUNCSTORE: return "truncstore"; - + case ISD::LOAD: return "load"; + case ISD::STORE: return "store"; + case ISD::VLOAD: return "vload"; + case ISD::EXTLOAD: return "extload"; + case ISD::SEXTLOAD: return "sextload"; + case ISD::ZEXTLOAD: return "zextload"; + case ISD::TRUNCSTORE: return "truncstore"; + case ISD::VAARG: return "vaarg"; + case ISD::VACOPY: return "vacopy"; + case ISD::VAEND: return "vaend"; + case ISD::VASTART: return "vastart"; case ISD::DYNAMIC_STACKALLOC: return "dynamic_stackalloc"; case ISD::EXTRACT_ELEMENT: return "extract_element"; case ISD::BUILD_PAIR: return "build_pair"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 06a3b016de..f75bdbeba7 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1204,71 +1204,34 @@ SDOperand TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); } -SDOperand TargetLowering::LowerVAStart(SDOperand Chain, - SDOperand VAListP, Value *VAListV, - SelectionDAG &DAG) { - // We have no sane default behavior, just emit a useful error message and bail - // out. - std::cerr << "Variable arguments handling not implemented on this target!\n"; - abort(); - return SDOperand(); -} - -SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand LP, Value *LV, - SelectionDAG &DAG) { - // Default to a noop. - return Chain; -} - -SDOperand TargetLowering::LowerVACopy(SDOperand Chain, - SDOperand SrcP, Value *SrcV, - SDOperand DestP, Value *DestV, - SelectionDAG &DAG) { - // Default to copying the input list. - SDOperand Val = DAG.getLoad(getPointerTy(), Chain, - SrcP, DAG.getSrcValue(SrcV)); - SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), - Val, DestP, DAG.getSrcValue(DestV)); - return Result; -} - -std::pair<SDOperand,SDOperand> -TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, - const Type *ArgTy, SelectionDAG &DAG) { - // We have no sane default behavior, just emit a useful error message and bail - // out. - std::cerr << "Variable arguments handling not implemented on this target!\n"; - abort(); - return std::make_pair(SDOperand(), SDOperand()); -} - - void SelectionDAGLowering::visitVAStart(CallInst &I) { - DAG.setRoot(TLI.LowerVAStart(getRoot(), getValue(I.getOperand(1)), - I.getOperand(1), DAG)); + DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(), + getValue(I.getOperand(1)), + DAG.getSrcValue(I.getOperand(1)))); } void SelectionDAGLowering::visitVAArg(VAArgInst &I) { - std::pair<SDOperand,SDOperand> Result = - TLI.LowerVAArg(getRoot(), getValue(I.getOperand(0)), I.getOperand(0), - I.getType(), DAG); - setValue(&I, Result.first); - DAG.setRoot(Result.second); + SDOperand V = DAG.getVAArg(TLI.getValueType(I.getType()), getRoot(), + getValue(I.getOperand(0)), + DAG.getSrcValue(I.getOperand(0))); + setValue(&I, V); + DAG.setRoot(V.getValue(1)); } void SelectionDAGLowering::visitVAEnd(CallInst &I) { - DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)), - I.getOperand(1), DAG)); + DAG.setRoot(DAG.getNode(ISD::VAEND, MVT::Other, getRoot(), + getValue(I.getOperand(1)), + DAG.getSrcValue(I.getOperand(1)))); } void SelectionDAGLowering::visitVACopy(CallInst &I) { - SDOperand Result = - TLI.LowerVACopy(getRoot(), getValue(I.getOperand(2)), I.getOperand(2), - getValue(I.getOperand(1)), I.getOperand(1), DAG); - DAG.setRoot(Result); + DAG.setRoot(DAG.getNode(ISD::VACOPY, MVT::Other, getRoot(), + getValue(I.getOperand(1)), + getValue(I.getOperand(2)), + DAG.getSrcValue(I.getOperand(1)), + DAG.getSrcValue(I.getOperand(2)))); } - // It is always conservatively correct for llvm.returnaddress and // llvm.frameaddress to return 0. std::pair<SDOperand, SDOperand> |