From 595ec734fc08fe7e72b7c3058ed973e91176f768 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Sat, 28 Jan 2006 03:14:31 +0000 Subject: [PATCH] Implement Promote for VAARG, and allow it to be custom promoted for people who don't want the default behavior (Alpha). llvm-svn: 25726 --- llvm/include/llvm/Target/TargetLowering.h | 7 ++++- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 26 ++++++++++++++++++- .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 7 +++++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp | 11 ++++++++ llvm/lib/Target/Alpha/AlphaISelLowering.h | 1 + llvm/lib/Target/IA64/IA64ISelLowering.cpp | 2 +- 6 files changed, 51 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h index d3837eb9c64c..7201079454e6 100644 --- a/llvm/include/llvm/Target/TargetLowering.h +++ b/llvm/include/llvm/Target/TargetLowering.h @@ -369,11 +369,16 @@ public: SelectionDAG &DAG); /// LowerOperation - For operations that are unsupported by the target, and - /// which are registered to use 'custom' lowering. This callback is invoked. + /// which are registered to use 'custom' lowering, this callback is invoked. /// If the target has no operations that require custom lowering, it need not /// implement this. The default implementation of this aborts. virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + /// CustomPromoteOperation - For operations that are unsupported by the + /// target, are registered to use 'custom' lowering, and whose type needs to + /// be promoted, this callback is invoked. + virtual SDOperand CustomPromoteOperation(SDOperand Op, SelectionDAG &DAG); + /// getTargetNodeName() - This method returns the name of a target specific /// DAG node. virtual const char *getTargetNodeName(unsigned Opcode) const; diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 48231adc8c1a..5bd17d53c342 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3209,7 +3209,31 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { Tmp2 = LegalizeOp(Node->getOperand(1)); Result = DAG.getNode(ISD::SRL, NVT, Tmp1, Tmp2); break; - + + case ISD::VAARG: + Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. + Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. + if (TLI.getOperationAction(ISD::VAARG, VT) == TargetLowering::Custom) { + Tmp3 = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2)); + Result = TLI.CustomPromoteOperation(Tmp3, DAG); + } else { + 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.getExtLoad(ISD::EXTLOAD, NVT, Tmp3, VAList, + DAG.getSrcValue(0), VT); + } + // Remember that we legalized the chain. + AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); + break; + case ISD::LOAD: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index d6cdb32e1d2a..78db4554dae5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1281,6 +1281,13 @@ SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return SDOperand(); } +SDOperand TargetLowering::CustomPromoteOperation(SDOperand Op, + SelectionDAG &DAG) { + assert(0 && "CustomPromoteOperation not implemented for this target!"); + abort(); + return SDOperand(); +} + void SelectionDAGLowering::visitFrameReturnAddress(CallInst &I, bool isFrame) { unsigned Depth = (unsigned)cast(I.getOperand(1))->getValue(); std::pair Result = diff --git a/llvm/lib/Target/Alpha/AlphaISelLowering.cpp b/llvm/lib/Target/Alpha/AlphaISelLowering.cpp index ac21b563b4bd..6779b90bd3a6 100644 --- a/llvm/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/llvm/lib/Target/Alpha/AlphaISelLowering.cpp @@ -141,6 +141,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::VAEND, MVT::Other, Expand); setOperationAction(ISD::VACOPY, MVT::Other, Custom); setOperationAction(ISD::VAARG, MVT::Other, Custom); + setOperationAction(ISD::VAARG, MVT::i32, Custom); setStackPointerRegisterToSaveRestore(Alpha::R30); @@ -691,3 +692,13 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return SDOperand(); } + +SDOperand AlphaTargetLowering::CustomPromoteOperation(SDOperand Op, + SelectionDAG &DAG) { + assert(Op.getValueType() == MVT::i32 && + Op.getOpcode() == ISD::VAARG && + "Unknown node to custom promote!"); + + // The code in LowerOperation already handles i32 vaarg + return LowerOperation(Op, DAG); +} diff --git a/llvm/lib/Target/Alpha/AlphaISelLowering.h b/llvm/lib/Target/Alpha/AlphaISelLowering.h index 33f87ce8187b..fcbaaac190c4 100644 --- a/llvm/lib/Target/Alpha/AlphaISelLowering.h +++ b/llvm/lib/Target/Alpha/AlphaISelLowering.h @@ -62,6 +62,7 @@ namespace llvm { /// LowerOperation - Provide custom lowering hooks for some operations. /// virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + virtual SDOperand CustomPromoteOperation(SDOperand Op, SelectionDAG &DAG); //Friendly names for dumps const char *getTargetNodeName(unsigned Opcode) const; diff --git a/llvm/lib/Target/IA64/IA64ISelLowering.cpp b/llvm/lib/Target/IA64/IA64ISelLowering.cpp index 4e32972da42a..e939fb79b7a0 100644 --- a/llvm/lib/Target/IA64/IA64ISelLowering.cpp +++ b/llvm/lib/Target/IA64/IA64ISelLowering.cpp @@ -588,7 +588,7 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) { VAIncr = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), VAIncr, Op.getOperand(1), Op.getOperand(2)); // Load the actual argument out of the pointer VAList - return DAG.getLoad(VT, VAIncr, VAList, DAG.getSrcValue(0)); + return DAG.getLoad(Op.getValueType(), VAIncr, VAList, DAG.getSrcValue(0)); } case ISD::VASTART: { // vastart just stores the address of the VarArgsFrameIndex slot into the