[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp

Chris Lattner lattner at cs.uiuc.edu
Tue May 16 15:53:32 PDT 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.374 -> 1.375
SelectionDAG.cpp updated: 1.307 -> 1.308
SelectionDAGISel.cpp updated: 1.242 -> 1.243
---
Log message:

Add a new ISD::CALL node, make the default impl of TargetLowering::LowerCallTo
produce it.


---
Diffs of the changes:  (+143 -3)

 LegalizeDAG.cpp      |    5 +
 SelectionDAG.cpp     |    1 
 SelectionDAGISel.cpp |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 143 insertions(+), 3 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.374 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.375
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.374	Tue May 16 00:49:56 2006
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Tue May 16 17:53:20 2006
@@ -818,11 +818,12 @@
     break;
     
   case ISD::FORMAL_ARGUMENTS:
+  case ISD::CALL:
     // The only option for this is to custom lower it.
     Result = TLI.LowerOperation(Result.getValue(0), DAG);
-    assert(Result.Val && "Target didn't custom lower ISD::FORMAL_ARGUMENTS!");
+    assert(Result.Val && "Target didn't custom lower this node!");
     
-    // Since FORMAL_ARGUMENTS nodes produce multiple values, make sure to
+    // Since CALL/FORMAL_ARGUMENTS nodes produce multiple values, make sure to
     // remember that we legalized all of them, so it doesn't get relegalized.
     for (unsigned i = 0, e = Result.Val->getNumValues(); i != e; ++i) {
       Tmp1 = LegalizeOp(Result.getValue(i));


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.307 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.308
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.307	Fri May 12 13:04:28 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Tue May 16 17:53:20 2006
@@ -2841,6 +2841,7 @@
   case ISD::INLINEASM:     return "inlineasm";
   case ISD::HANDLENODE:    return "handlenode";
   case ISD::FORMAL_ARGUMENTS: return "formal_arguments";
+  case ISD::CALL:          return "call";
     
   // Unary operators
   case ISD::FABS:   return "fabs";


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.242 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.243
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.242	Tue May 16 01:45:34 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Tue May 16 17:53:20 2006
@@ -2344,7 +2344,8 @@
 
 /// 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.
+/// targets are migrated to using FORMAL_ARGUMENTS, this hook should be 
+/// integrated into SDISel.
 std::vector<SDOperand> 
 TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
   // Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node.
@@ -2477,8 +2478,145 @@
   return Ops;
 }
 
+
+/// TargetLowering::LowerCallTo - This is the default LowerCallTo
+/// implementation, which just inserts an ISD::CALL node, which is later custom
+/// lowered by the target to something concrete.  FIXME: When all targets are
+/// migrated to using ISD::CALL, this hook should be integrated into SDISel.
+std::pair<SDOperand, SDOperand>
+TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
+                            unsigned CallingConv, bool isTailCall, 
+                            SDOperand Callee,
+                            ArgListTy &Args, SelectionDAG &DAG) {
+  std::vector<SDOperand> Ops;
+  Ops.push_back(Chain);   // Op#0 - Chain
+  Ops.push_back(DAG.getConstant(CallingConv, getPointerTy())); // Op#1 - CC
+  Ops.push_back(DAG.getConstant(isVarArg, getPointerTy()));    // Op#2 - VarArg
+  Ops.push_back(DAG.getConstant(isTailCall, getPointerTy()));  // Op#3 - Tail
+  Ops.push_back(Callee);
+  
+  // Handle all of the outgoing arguments.
+  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+    MVT::ValueType VT = getValueType(Args[i].second);
+    SDOperand Op = Args[i].first;
+    switch (getTypeAction(VT)) {
+    default: assert(0 && "Unknown type action!");
+    case Legal: 
+      Ops.push_back(Op);
+      break;
+    case Promote:
+      if (MVT::isInteger(VT)) {
+        unsigned ExtOp = Args[i].second->isSigned() ? 
+                                  ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; 
+        Op = DAG.getNode(ExtOp, getTypeToTransformTo(VT), Op);
+      } else {
+        assert(MVT::isFloatingPoint(VT) && "Not int or FP?");
+        Op = DAG.getNode(ISD::FP_EXTEND, getTypeToTransformTo(VT), Op);
+      }
+      Ops.push_back(Op);
+      break;
+    case Expand:
+      if (VT != MVT::Vector) {
+        // If this is a large integer, it needs to be broken down into 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 = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Op,
+                                     DAG.getConstant(0, getPointerTy()));
+          SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Op,
+                                     DAG.getConstant(1, getPointerTy()));
+          if (!isLittleEndian())
+            std::swap(Lo, Hi);
+          
+          Ops.push_back(Lo);
+          Ops.push_back(Hi);
+        } else {
+          // Value scalarized into many values.  Unimp for now.
+          assert(0 && "Cannot expand i64 -> i16 yet!");
+        }
+      } else {
+        assert(0 && "Doesn't handle vectors yet!");
+      }
+      break;
+    }
+  }
+  
+  // Figure out the result value types.
+  std::vector<MVT::ValueType> RetTys;
+
+  if (RetTy != Type::VoidTy) {
+    MVT::ValueType VT = getValueType(RetTy);
+    switch (getTypeAction(VT)) {
+    default: assert(0 && "Unknown type action!");
+    case Legal:
+      RetTys.push_back(VT);
+      break;
+    case Promote:
+      RetTys.push_back(getTypeToTransformTo(VT));
+      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);
+        for (unsigned i = 0; i != NumVals; ++i)
+          RetTys.push_back(NVT);
+      } else {
+        assert(0 && "Doesn't handle vectors yet!");
+      }
+    }    
+  }
+  
+  RetTys.push_back(MVT::Other);  // Always has a chain.
+  
+  // Finally, create the CALL node.
+  SDOperand Res = DAG.getNode(ISD::CALL, RetTys, Ops);
+  
+  // This returns a pair of operands.  The first element is the
+  // return value for the function (if RetTy is not VoidTy).  The second
+  // element is the outgoing token chain.
+  SDOperand ResVal;
+  if (RetTys.size() != 1) {
+    MVT::ValueType VT = getValueType(RetTy);
+    if (RetTys.size() == 2) {
+      ResVal = Res;
+      
+      // If this value was promoted, truncate it down.
+      if (ResVal.getValueType() != VT) {
+        if (MVT::isInteger(VT)) {
+          unsigned AssertOp = RetTy->isSigned() ?
+                                  ISD::AssertSext : ISD::AssertZext;
+          ResVal = DAG.getNode(AssertOp, ResVal.getValueType(), ResVal, 
+                               DAG.getValueType(VT));
+          ResVal = DAG.getNode(ISD::TRUNCATE, VT, ResVal);
+        } else {
+          assert(MVT::isFloatingPoint(VT));
+          ResVal = DAG.getNode(ISD::FP_ROUND, VT, ResVal);
+        }
+      }
+    } else if (RetTys.size() == 3) {
+      ResVal = DAG.getNode(ISD::BUILD_PAIR, VT, 
+                           Res.getValue(0), Res.getValue(1));
+      
+    } else {
+      assert(0 && "Case not handled yet!");
+    }
+  }
+  
+  return std::make_pair(ResVal, Res.getValue(Res.Val->getNumValues()-1));
+}
+
+
+
 // It is always conservatively correct for llvm.returnaddress and
 // llvm.frameaddress to return 0.
+//
+// FIXME: Change this to insert a FRAMEADDR/RETURNADDR node, and have that be
+// expanded to 0 if the target wants.
 std::pair<SDOperand, SDOperand>
 TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain,
                                         unsigned Depth, SelectionDAG &DAG) {






More information about the llvm-commits mailing list