From: Sanjiv Gupta Date: Wed, 21 Jan 2009 04:48:39 +0000 (+0000) Subject: Allow targets to legalize operations (with illegal operands) that produces multiple... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bb326bbe88d0b243d5d9d224308eb0c028d4d4af;p=oota-llvm.git Allow targets to legalize operations (with illegal operands) that produces multiple values. For example, a load with an illegal operand (a load produces two values, a value and chain). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62663 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 3e8a93aafcb..0e9a6546f42 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1131,6 +1131,23 @@ public: return SDValue(); } + /// LowerOperationWrapper - This callback is invoked by the type legalizer + /// to legalize operation with illegal operand types but legal result types; + /// It replaces the LowerOperation callback in the type Legalizer. + /// The reason we can not do away with LowerOperation entirely is that + /// LegalizeDAG isn't yet ready to use this callback. + + /// The target places new result values for the node in Results (their number + /// and types must exactly match those of the original return values of + /// the node), or leaves Results empty, which indicates that the node is not + /// to be custom lowered after all. + /// In its default implementation it calls the LowerOperation. + + virtual void LowerOperationWrapper(SDValue Op, + SmallVectorImpl &Results, + SelectionDAG &DAG); + + /// LowerOperation - This callback is invoked for operations that are /// unsupported by the target, which are registered to use 'custom' lowering, /// and whose defined values are all legal. diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 3cfaa27335f..aae84de1135 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -722,7 +722,7 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { Lo = Hi = SDValue(); // See if the target wants to custom expand this node. - if (CustomLowerResults(N, ResNo)) + if (CustomLowerResults(N, ResNo, true)) return; switch (N->getOpcode()) { diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index d84cd62b68e..89ae2fd5b71 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -34,7 +34,7 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { SDValue Result = SDValue(); // See if the target wants to custom expand this node. - if (CustomLowerResults(N, ResNo)) + if (CustomLowerResults(N, ResNo, true)) return; switch (N->getOpcode()) { @@ -623,45 +623,42 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Promote integer operand: "; N->dump(&DAG); cerr << "\n"); SDValue Res = SDValue(); - if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) - == TargetLowering::Custom) - Res = TLI.LowerOperation(SDValue(N, 0), DAG); + if (CustomLowerResults(N, OpNo, false)) + return false; - if (Res.getNode() == 0) { - switch (N->getOpcode()) { - default: + switch (N->getOpcode()) { + default: #ifndef NDEBUG - cerr << "PromoteIntegerOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; + cerr << "PromoteIntegerOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; #endif - assert(0 && "Do not know how to promote this operator's operand!"); - abort(); - - case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; - case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; - case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; - case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break; - case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; - case ISD::CONVERT_RNDSAT: - Res = PromoteIntOp_CONVERT_RNDSAT(N); break; - case ISD::INSERT_VECTOR_ELT: - Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break; - case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; - case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; - case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; - case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; - case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; - case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break; - case ISD::STORE: Res = PromoteIntOp_STORE(cast(N), - OpNo); break; - case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; - case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break; - case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; - } - } + assert(0 && "Do not know how to promote this operator's operand!"); + abort(); + case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; + case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; + case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; + case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break; + case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break; + case ISD::CONVERT_RNDSAT: + Res = PromoteIntOp_CONVERT_RNDSAT(N); break; + case ISD::INSERT_VECTOR_ELT: + Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);break; + case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; + case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; + case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; + case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; + case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break; + case ISD::SINT_TO_FP: Res = PromoteIntOp_SINT_TO_FP(N); break; + case ISD::STORE: Res = PromoteIntOp_STORE(cast(N), + OpNo); break; + case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; + case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break; + case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; + } + // If the result is null, the sub-method took care of registering results etc. - if (!Res.getNode()) return false; + if (! Res.getNode()) return false; // If the result is N, the sub-method updated N in place. Tell the legalizer // core about this. @@ -921,7 +918,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { Lo = Hi = SDValue(); // See if the target wants to custom expand this node. - if (CustomLowerResults(N, ResNo)) + if (CustomLowerResults(N, ResNo, true)) return; switch (N->getOpcode()) { @@ -1851,35 +1848,32 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Expand integer operand: "; N->dump(&DAG); cerr << "\n"); SDValue Res = SDValue(); - if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) - == TargetLowering::Custom) - Res = TLI.LowerOperation(SDValue(N, 0), DAG); + if (CustomLowerResults(N, OpNo, false)) + return false; - if (Res.getNode() == 0) { - switch (N->getOpcode()) { - default: + switch (N->getOpcode()) { + default: #ifndef NDEBUG - cerr << "ExpandIntegerOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; + cerr << "ExpandIntegerOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; #endif - assert(0 && "Do not know how to expand this operator's operand!"); - abort(); - - case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; - case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; - case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; - case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break; - case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break; - - case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break; - case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break; - case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break; - case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break; - case ISD::STORE: Res = ExpandIntOp_STORE(cast(N), OpNo); - break; - case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break; - case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break; - } + assert(0 && "Do not know how to expand this operator's operand!"); + abort(); + + case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; + case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; + case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; + case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break; + case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break; + + case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break; + case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break; + case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break; + case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break; + case ISD::STORE: Res = ExpandIntOp_STORE(cast(N), OpNo); + break; + case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break; + case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break; } // If the result is null, the sub-method took care of registering results etc. diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 330ea86cb06..ff7b8a95632 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -848,14 +848,28 @@ SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op, /// CustomLowerResults - Replace the node's results with custom code provided /// by the target and return "true", or do nothing and return "false". -bool DAGTypeLegalizer::CustomLowerResults(SDNode *N, unsigned ResNo) { +/// The last parameter is FALSE if we are dealing with a node with legal +/// result types and illegal operand. The second parameter denotes the illegal +/// OperandNo in that case. +/// The last parameter being TRUE means we are dealing with a +/// node with illegal result types. The second parameter denotes the illegal +/// ResNo in that case. +bool DAGTypeLegalizer::CustomLowerResults(SDNode *N, unsigned Num, + bool LegalizeResult) { + // Get the type of illegal Result or Operand. + MVT ValueTy = (LegalizeResult) ? N->getValueType(Num) + : N->getOperand(Num).getValueType(); + // See if the target wants to custom lower this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) != - TargetLowering::Custom) + if (TLI.getOperationAction(N->getOpcode(), ValueTy) != TargetLowering::Custom) return false; SmallVector Results; - TLI.ReplaceNodeResults(N, Results, DAG); + if (LegalizeResult) + TLI.ReplaceNodeResults(N, Results, DAG); + else + TLI.LowerOperationWrapper(SDValue(N, 0), Results, DAG); + if (Results.empty()) // The target didn't want to custom lower it after all. return false; diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 949ee349ce2..d57aec00c9c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -191,7 +191,7 @@ private: // Common routines. SDValue BitConvertToInteger(SDValue Op); SDValue CreateStackStoreLoad(SDValue Op, MVT DestVT); - bool CustomLowerResults(SDNode *N, unsigned ResNo); + bool CustomLowerResults(SDNode *N, unsigned ResNo, bool LegalizeResult); SDValue GetVectorElementPointer(SDValue VecPtr, MVT EltVT, SDValue Index); SDValue JoinIntegers(SDValue Lo, SDValue Hi); SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index b134b23489e..d0023a0476a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -5568,6 +5568,15 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, return std::make_pair(Res, Chain); } +void TargetLowering::LowerOperationWrapper(SDValue Op, + SmallVectorImpl &Results, + SelectionDAG &DAG) { + SDValue Res; + Res = LowerOperation(Op, DAG); + if (Res.getNode()) + Results.push_back(Res); +} + SDValue TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { assert(0 && "LowerOperation not implemented for this target!"); abort();