From eb1819d1e5d6790c24bd92e4cce2058f81a5791a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 4 Dec 2007 07:48:46 +0000 Subject: [PATCH] Implement framework for scalarizing node results. This is sufficient to codegen this: define float @test_extract_elt(<1 x float> * %P) { %p = load <1 x float>* %P %R = extractelement <1 x float> %p, i32 0 ret float %R } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44570 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp | 91 ++++++++++++++++--- 1 file changed, 80 insertions(+), 11 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp index 1227973804d..d2bc58b5fdb 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp @@ -202,6 +202,11 @@ private: SDOperand &Lo, SDOperand &Hi); bool ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi); + // Result Vector Scalarization: <1 x ty> -> ty. + void ScalarizeResult(SDNode *N, unsigned OpNo); + SDOperand ScalarizeRes_UNDEF(SDNode *N); + SDOperand ScalarizeRes_LOAD(LoadSDNode *N); + // Operand Promotion. bool PromoteOperand(SDNode *N, unsigned OperandNo); SDOperand PromoteOperand_ANY_EXTEND(SDNode *N); @@ -232,7 +237,7 @@ private: void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, ISD::CondCode &CCCode); - // Operand Vector Scalarization <1 x ty> -> ty. + // Operand Vector Scalarization: <1 x ty> -> ty. bool ScalarizeOperand(SDNode *N, unsigned OpNo); SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo); @@ -278,12 +283,20 @@ void DAGTypeLegalizer::run() { unsigned i = 0; unsigned NumResults = N->getNumValues(); do { - LegalizeAction Action = getTypeAction(N->getValueType(i)); + MVT::ValueType ResultVT = N->getValueType(i); + LegalizeAction Action = getTypeAction(ResultVT); if (Action == Promote) { PromoteResult(N, i); goto NodeDone; } else if (Action == Expand) { - ExpandResult(N, i); + // Expand can mean 1) split integer in half 2) scalarize single-element + // vector 3) split vector in half. + if (!MVT::isVector(ResultVT)) + ExpandResult(N, i); + else if (MVT::getVectorNumElements(ResultVT) == 1) + ScalarizeResult(N, i); // Scalarize the single-element vector. + else // Split the vector in half. + assert(0 && "Vector splitting not implemented"); goto NodeDone; } else { assert(Action == Legal && "Unknown action!"); @@ -306,15 +319,12 @@ void DAGTypeLegalizer::run() { // vector 3) split vector in half. if (!MVT::isVector(OpVT)) { NeedsRevisit = ExpandOperand(N, i); + } else if (MVT::getVectorNumElements(OpVT) == 1) { + // Scalarize the single-element vector. + NeedsRevisit = ScalarizeOperand(N, i); } else { - unsigned NumElts = MVT::getVectorNumElements(OpVT); - if (NumElts == 1) { - // Scalarize the single-element vector. - NeedsRevisit = ScalarizeOperand(N, i); - } else { - // Split the vector in half. - assert(0 && "Vector splitting not implemented"); - } + // Split the vector in half. + assert(0 && "Vector splitting not implemented"); } break; } else { @@ -1584,6 +1594,65 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) { return true; } +//===----------------------------------------------------------------------===// +// Result Vector Scalarization: <1 x ty> -> ty. +//===----------------------------------------------------------------------===// + + +void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { + DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG); + cerr << "\n"); + SDOperand R = SDOperand(); + + // FIXME: Custom lowering for scalarization? +#if 0 + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) { + // If the target wants to, allow it to lower this itself. + if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + // Everything that once used N now uses P. We are guaranteed that the + // result value types of N and the result value types of P match. + ReplaceNodeWith(N, P); + return; + } + } +#endif + + switch (N->getOpcode()) { + default: +#ifndef NDEBUG + cerr << "ScalarizeResult #" << ResNo << ": "; + N->dump(&DAG); cerr << "\n"; +#endif + assert(0 && "Do not know how to expand the result of this operator!"); + abort(); + + case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break; + case ISD::LOAD: R = ScalarizeRes_LOAD(cast(N)); break; + } + + // If R is null, the sub-method took care of registering the resul. + if (R.Val) + SetScalarizedOp(SDOperand(N, ResNo), R); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) { + return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(N->getValueType(0))); +} + +SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) { + SDOperand Result = DAG.getLoad(MVT::getVectorElementType(N->getValueType(0)), + N->getChain(), N->getBasePtr(), + N->getSrcValue(), N->getSrcValueOffset(), + N->isVolatile(), N->getAlignment()); + + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDOperand(N, 1), Result.getValue(1)); + return Result; +} + //===----------------------------------------------------------------------===// // Operand Promotion