From fdfded55888e35b76bb70231a5bb2f60877c2f6a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 12 Apr 2006 16:20:43 +0000 Subject: [PATCH] Implement support for the formal_arguments node. To get this, targets shouldcustom legalize it and remove their XXXTargetLowering::LowerArguments overload git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27604 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 11 +- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 1 + lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 119 ++++++++++++++++++ 3 files changed, 128 insertions(+), 3 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 0acaf905a2c..e6585c2d5de 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -826,7 +826,13 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Result = DAG.UpdateNodeOperands(Result, Ops); } break; - + + case ISD::FORMAL_ARGUMENTS: + // The only option for this is to custom lower it. + Result = TLI.LowerOperation(Result, DAG); + assert(Result.Val && "Target didn't custom lower ISD::FORMAL_ARGUMENTS!"); + break; + case ISD::BUILD_VECTOR: switch (TLI.getOperationAction(ISD::BUILD_VECTOR, Node->getValueType(0))) { default: assert(0 && "This action is not supported yet!"); @@ -2782,7 +2788,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) { Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(),Node->getOperand(0), Node->getOperand(1), Node->getOperand(2)); break; - + case ISD::TRUNCATE: switch (getTypeAction(Node->getOperand(0).getValueType())) { case Legal: @@ -4057,7 +4063,6 @@ SDOperand SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDOperand Op) { } } - /// ExpandOp - Expand the specified SDOperand into its two component pieces /// Lo&Hi. Note that the Op MUST be an expanded type. As a result of this, the /// LegalizeNodes map is filled in for any results that are not expanded, the diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b95a85edd26..bcdbef17ec4 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2714,6 +2714,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { case ISD::MERGE_VALUES: return "mergevalues"; case ISD::INLINEASM: return "inlineasm"; case ISD::HANDLENODE: return "handlenode"; + case ISD::FORMAL_ARGUMENTS: return "formal_arguments"; // Unary operators case ISD::FABS: return "fabs"; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index c02654175e1..e5e462bb3b4 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2230,6 +2230,125 @@ void SelectionDAGLowering::visitVACopy(CallInst &I) { DAG.getSrcValue(I.getOperand(2)))); } +/// TargetLowering::LowerArguments - This is the default LowerArguments +/// implementation, which just inserts a FORMAL_ARGUMENTS node. FIXME: When all +/// targets are migrated to using FORMAL_ARGUMENTS, this hook should be removed. +std::vector +TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { + // Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node. + std::vector Ops; + Ops.push_back(DAG.getConstant(F.getCallingConv(), getPointerTy())); + Ops.push_back(DAG.getConstant(F.isVarArg(), getPointerTy())); + + // Add one result value for each formal argument. + std::vector RetVals; + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { + MVT::ValueType VT = getValueType(I->getType()); + + switch (getTypeAction(VT)) { + default: assert(0 && "Unknown type action!"); + case Legal: + RetVals.push_back(VT); + break; + case Promote: + RetVals.push_back(getTypeToTransformTo(VT)); + break; + case Expand: + if (VT != MVT::Vector) { + // If this is a large integer, it needs to be broken up into small + // integers. Figure out what the destination type is and how many small + // integers it turns into. + MVT::ValueType NVT = getTypeToTransformTo(VT); + unsigned NumVals = MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT); + for (unsigned i = 0; i != NumVals; ++i) + RetVals.push_back(NVT); + } else { + // Otherwise, this is a vector type. We only support legal vectors + // right now. + unsigned NumElems = cast(I->getType())->getNumElements(); + const Type *EltTy = cast(I->getType())->getElementType(); + + // Figure out if there is a Packed type corresponding to this Vector + // type. If so, convert to the packed type. + MVT::ValueType TVT = MVT::getVectorType(getValueType(EltTy), NumElems); + if (TVT != MVT::Other && isTypeLegal(TVT)) { + RetVals.push_back(TVT); + } else { + assert(0 && "Don't support illegal by-val vector arguments yet!"); + } + } + break; + } + } + + // Create the node. + SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS, RetVals, Ops).Val; + + // Set up the return result vector. + Ops.clear(); + unsigned i = 0; + for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { + MVT::ValueType VT = getValueType(I->getType()); + + switch (getTypeAction(VT)) { + default: assert(0 && "Unknown type action!"); + case Legal: + Ops.push_back(SDOperand(Result, i++)); + break; + case Promote: { + SDOperand Op(Result, i++); + if (MVT::isInteger(VT)) { + unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext + : ISD::AssertZext; + Op = DAG.getNode(AssertOp, Op.getValueType(), Op, DAG.getValueType(VT)); + Op = DAG.getNode(ISD::TRUNCATE, VT, Op); + } else { + assert(MVT::isFloatingPoint(VT) && "Not int or FP?"); + Op = DAG.getNode(ISD::FP_ROUND, VT, Op); + } + Ops.push_back(Op); + break; + } + case Expand: + if (VT != MVT::Vector) { + // If this is a large integer, it needs to be reassembled from small + // integers. Figure out what the source elt type is and how many small + // integers it is. + MVT::ValueType NVT = getTypeToTransformTo(VT); + unsigned NumVals = MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT); + if (NumVals == 2) { + SDOperand Lo = SDOperand(Result, i++); + SDOperand Hi = SDOperand(Result, i++); + + if (!isLittleEndian()) + std::swap(Lo, Hi); + + Ops.push_back(DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi)); + } else { + // Value scalarized into many values. Unimp for now. + assert(0 && "Cannot expand i64 -> i16 yet!"); + } + } else { + // Otherwise, this is a vector type. We only support legal vectors + // right now. + unsigned NumElems = cast(I->getType())->getNumElements(); + const Type *EltTy = cast(I->getType())->getElementType(); + + // Figure out if there is a Packed type corresponding to this Vector + // type. If so, convert to the packed type. + MVT::ValueType TVT = MVT::getVectorType(getValueType(EltTy), NumElems); + if (TVT != MVT::Other && isTypeLegal(TVT)) { + Ops.push_back(SDOperand(Result, i++)); + } else { + assert(0 && "Don't support illegal by-val vector arguments yet!"); + } + } + break; + } + } + return Ops; +} + // It is always conservatively correct for llvm.returnaddress and // llvm.frameaddress to return 0. std::pair -- 2.34.1