Allow targets to legalize operations (with illegal operands) that produces multiple...
authorSanjiv Gupta <sanjiv.gupta@microchip.com>
Wed, 21 Jan 2009 04:48:39 +0000 (04:48 +0000)
committerSanjiv Gupta <sanjiv.gupta@microchip.com>
Wed, 21 Jan 2009 04:48:39 +0000 (04:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62663 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
lib/CodeGen/SelectionDAG/LegalizeTypes.h
lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp

index 3e8a93aafcb0b7dcb7e3e6795f52a975d1e3b44f..0e9a6546f4268e38c1fe5be8f094b9f8e92bfea9 100644 (file)
@@ -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<SDValue> &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.
index 3cfaa27335f706425176e4dc8c1be5fedc781563..aae84de11354ba33a4332bf08ac602b5cccbaa08 100644 (file)
@@ -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()) {
index d84cd62b68e3674bccb41653133ad75f20612ee3..89ae2fd5b71b41c4a9099622e9fad8889fa408c1 100644 (file)
@@ -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<StoreSDNode>(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<StoreSDNode>(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<StoreSDNode>(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<StoreSDNode>(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.
index 330ea86cb06f53709f92108a2ae796bef207f4e4..ff7b8a956321f3c16c42617aa81b69fcf696e897 100644 (file)
@@ -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<SDValue, 8> 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;
index 949ee349ce2d51beb3609906390a713770110f35..d57aec00c9c73beae8ac631fa840eaa255161f0c 100644 (file)
@@ -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);
index b134b23489e4da9814e59d8315151c72f51a3d63..d0023a0476a59a919adce3b82ac388ee9d086a9d 100644 (file)
@@ -5568,6 +5568,15 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
   return std::make_pair(Res, Chain);
 }
 
+void TargetLowering::LowerOperationWrapper(SDValue Op, 
+                                          SmallVectorImpl<SDValue> &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();