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

Dan Gohman djg at cray.com
Thu Jun 28 16:30:11 PDT 2007



Changes in directory llvm/lib/CodeGen/SelectionDAG:

SelectionDAGISel.cpp updated: 1.471 -> 1.472
TargetLowering.cpp updated: 1.123 -> 1.124
---
Log message:

Add new TargetLowering code to provide the final register type that an
illegal value type will be transformed to, for code that needs the
register type after all transformations instead of just after the first
transformation.

Factor out the code that uses this information to do copy-from-regs and
copy-to-regs for various purposes into separate functions so that they
are done consistently.


---
Diffs of the changes:  (+355 -453)

 SelectionDAGISel.cpp |  642 ++++++++++++++++++++++-----------------------------
 TargetLowering.cpp   |  166 +++++--------
 2 files changed, 355 insertions(+), 453 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.471 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.472
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.471	Wed Jun 27 13:45:32 2007
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Thu Jun 28 18:29:44 2007
@@ -90,7 +90,7 @@
   /// This is needed because values can be promoted into larger registers and
   /// expanded into multiple smaller registers than the value.
   struct VISIBILITY_HIDDEN RegsForValue {
-    /// Regs - This list hold the register (for legal and promoted values)
+    /// Regs - This list holds the register (for legal and promoted values)
     /// or register set (for expanded values) that the value should be assigned
     /// to.
     std::vector<unsigned> Regs;
@@ -117,15 +117,16 @@
     /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
     /// this value and returns the result as a ValueVT value.  This uses 
     /// Chain/Flag as the input and updates them for the output Chain/Flag.
+    /// If the Flag pointer is NULL, no flag is used.
     SDOperand getCopyFromRegs(SelectionDAG &DAG,
-                              SDOperand &Chain, SDOperand &Flag) const;
+                              SDOperand &Chain, SDOperand *Flag) const;
 
     /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
     /// specified value into the registers specified by this object.  This uses 
     /// Chain/Flag as the input and updates them for the output Chain/Flag.
+    /// If the Flag pointer is NULL, no flag is used.
     void getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
-                       SDOperand &Chain, SDOperand &Flag,
-                       MVT::ValueType PtrVT) const;
+                       SDOperand &Chain, SDOperand *Flag) const;
     
     /// AddInlineAsmOperands - Add this value to the specified inlineasm node
     /// operand list.  This adds the code marker and includes the number of 
@@ -306,15 +307,8 @@
 unsigned FunctionLoweringInfo::CreateRegForValue(const Value *V) {
   MVT::ValueType VT = TLI.getValueType(V->getType());
   
-  unsigned NumRegisters;
-  MVT::ValueType RegisterVT;
-  if (MVT::isVector(VT)) {
-    MVT::ValueType ElementVT;
-    NumRegisters = TLI.getVectorTypeBreakdown(VT, ElementVT, RegisterVT);
-  } else {
-    RegisterVT = TLI.getTypeToTransformTo(VT);
-    NumRegisters = TLI.getNumRegisters(VT);
-  }
+  unsigned NumRegisters = TLI.getNumRegisters(VT);
+  MVT::ValueType RegisterVT = TLI.getRegisterType(VT);
 
   unsigned R = MakeReg(RegisterVT);
   for (unsigned i = 1; i != NumRegisters; ++i)
@@ -695,79 +689,17 @@
   unsigned InReg = FuncInfo.ValueMap[V];
   assert(InReg && "Value not in map!");
   
-  // If this type is not legal, make it so now.
-  if (!MVT::isVector(VT)) {
-    if (TLI.getTypeAction(VT) == TargetLowering::Expand) {
-      // Source must be expanded.  This input value is actually coming from the
-      // register pair InReg and InReg+1.
-      MVT::ValueType DestVT = TLI.getTypeToExpandTo(VT);
-      unsigned NumVals = TLI.getNumRegisters(VT);
-      N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
-      if (NumVals == 1)
-        N = DAG.getNode(ISD::BIT_CONVERT, VT, N);
-      else {
-        assert(NumVals == 2 && "1 to 4 (and more) expansion not implemented!");
-        N = DAG.getNode(ISD::BUILD_PAIR, VT, N,
-                        DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT));
-      }
-    } else {
-      MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT);
-      N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
-      if (TLI.getTypeAction(VT) == TargetLowering::Promote) // Promotion case
-        N = MVT::isFloatingPoint(VT)
-          ? DAG.getNode(ISD::FP_ROUND, VT, N)
-          : DAG.getNode(ISD::TRUNCATE, VT, N);
-    }
-  } else {
-    // Otherwise, if this is a vector, make it available as a vector
-    // here.
-    MVT::ValueType ElementVT, LegalElementVT;
-    unsigned NE = TLI.getVectorTypeBreakdown(VT, ElementVT,
-                                             LegalElementVT);
-
-    // Build a BUILD_VECTOR or CONCAT_VECTORS with the input registers.
-    SmallVector<SDOperand, 8> Ops;
-    if (ElementVT == LegalElementVT) {
-      // If the value types are legal, just BUILD the CopyFromReg nodes.
-      for (unsigned i = 0; i != NE; ++i)
-        Ops.push_back(DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
-                                         ElementVT));
-    } else if (ElementVT < LegalElementVT) {
-      // If the register was promoted, use TRUNCATE or FP_ROUND as appropriate.
-      for (unsigned i = 0; i != NE; ++i) {
-        SDOperand Op = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
-                                          LegalElementVT);
-        if (MVT::isFloatingPoint(ElementVT))
-          Op = DAG.getNode(ISD::FP_ROUND, ElementVT, Op);
-        else
-          Op = DAG.getNode(ISD::TRUNCATE, ElementVT, Op);
-        Ops.push_back(Op);
-      }
-    } else {
-      // If the register was expanded, use BUILD_PAIR.
-      assert((NE & 1) == 0 && "Must expand into a multiple of 2 elements!");
-      for (unsigned i = 0; i != NE; ++i) {
-        SDOperand Op0 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
-                                           LegalElementVT);
-        SDOperand Op1 = DAG.getCopyFromReg(DAG.getEntryNode(), InReg++, 
-                                           LegalElementVT);
-        Ops.push_back(DAG.getNode(ISD::BUILD_PAIR, ElementVT, Op0, Op1));
-      }
-    }
-    
-    if (MVT::isVector(ElementVT)) {
-      N = DAG.getNode(ISD::CONCAT_VECTORS,
-                      MVT::getVectorType(MVT::getVectorElementType(ElementVT),
-                                         NE * MVT::getVectorNumElements(ElementVT)),
-                      &Ops[0], Ops.size());
-    } else {
-      N = DAG.getNode(ISD::BUILD_VECTOR,
-                      MVT::getVectorType(ElementVT, NE),
-                      &Ops[0], Ops.size());
-    }
-  }
-  
-  return N;
+  MVT::ValueType RegisterVT = TLI.getRegisterType(VT);
+  unsigned NumRegs = TLI.getNumRegisters(VT);
+
+  std::vector<unsigned> Regs(NumRegs);
+  for (unsigned i = 0; i != NumRegs; ++i)
+    Regs[i] = InReg + i;
+
+  RegsForValue RFV(Regs, RegisterVT, VT);
+  SDOperand Chain = DAG.getEntryNode();
+
+  return RFV.getCopyFromRegs(DAG, Chain, NULL);
 }
 
 
@@ -2819,88 +2751,239 @@
 }
 
 
-SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
-                                        SDOperand &Chain, SDOperand &Flag)const{
-  SDOperand Val = DAG.getCopyFromReg(Chain, Regs[0], RegVT, Flag);
-  Chain = Val.getValue(1);
-  Flag  = Val.getValue(2);
-  
-  // If the result was expanded, copy from the top part.
-  if (Regs.size() > 1) {
-    assert(Regs.size() == 2 &&
-           "Cannot expand to more than 2 elts yet!");
-    SDOperand Hi = DAG.getCopyFromReg(Chain, Regs[1], RegVT, Flag);
-    Chain = Hi.getValue(1);
-    Flag  = Hi.getValue(2);
-    if (DAG.getTargetLoweringInfo().isLittleEndian())
+/// getCopyFromParts - Create a value that contains the
+/// specified legal parts combined into the value they represent.
+static SDOperand getCopyFromParts(SelectionDAG &DAG,
+                                  const SDOperand *Parts,
+                                  unsigned NumParts,
+                                  MVT::ValueType PartVT,
+                                  MVT::ValueType ValueVT,
+                                  ISD::NodeType AssertOp = ISD::DELETED_NODE) {
+  if (!MVT::isVector(ValueVT) || NumParts == 1) {
+    SDOperand Val = Parts[0];
+
+    // If the value was expanded, copy from the top part.
+    if (NumParts > 1) {
+      assert(NumParts == 2 &&
+             "Cannot expand to more than 2 elts yet!");
+      SDOperand Hi = Parts[1];
       return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Val, Hi);
-    else
-      return DAG.getNode(ISD::BUILD_PAIR, ValueVT, Hi, Val);
-  }
+    }
 
-  // Otherwise, if the return value was promoted or extended, truncate it to the
-  // appropriate type.
-  if (RegVT == ValueVT)
-    return Val;
+    // Otherwise, if the value was promoted or extended, truncate it to the
+    // appropriate type.
+    if (PartVT == ValueVT)
+      return Val;
+  
+    if (MVT::isVector(PartVT)) {
+      assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
+      return DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+    }
+  
+    if (MVT::isInteger(PartVT) &&
+        MVT::isInteger(ValueVT)) {
+      if (ValueVT < PartVT) {
+        // For a truncate, see if we have any information to
+        // indicate whether the truncated bits will always be
+        // zero or sign-extension.
+        if (AssertOp != ISD::DELETED_NODE)
+          Val = DAG.getNode(AssertOp, PartVT, Val,
+                            DAG.getValueType(ValueVT));
+        return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+      } else {
+        return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+      }
+    }
   
-  if (MVT::isVector(RegVT)) {
-    assert(MVT::isVector(ValueVT) && "Unknown vector conversion!");
-    return DAG.getNode(ISD::BIT_CONVERT, RegVT, Val);
+    if (MVT::isFloatingPoint(PartVT) &&
+        MVT::isFloatingPoint(ValueVT))
+      return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
+
+    if (MVT::getSizeInBits(PartVT) == 
+        MVT::getSizeInBits(ValueVT))
+      return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
+
+    assert(0 && "Unknown mismatch!");
+  }
+
+  // Handle a multi-element vector.
+  MVT::ValueType IntermediateVT, RegisterVT;
+  unsigned NumIntermediates;
+  unsigned NumRegs =
+    DAG.getTargetLoweringInfo()
+      .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+                              RegisterVT);
+
+  assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+  assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+  assert(RegisterVT == Parts[0].getValueType() &&
+         "Part type doesn't match part!");
+
+  // Assemble the parts into intermediate operands.
+  SmallVector<SDOperand, 8> Ops(NumIntermediates);
+  if (NumIntermediates == NumParts) {
+    // If the register was not expanded, truncate or copy the value,
+    // as appropriate.
+    for (unsigned i = 0; i != NumParts; ++i)
+      Ops[i] = getCopyFromParts(DAG, &Parts[i], 1, PartVT, IntermediateVT);
+  } else if (NumParts > 0) {
+    // If the intermediate type was expanded, build the intermediate operands
+    // from the parts.
+    assert(NumIntermediates % NumParts == 0 &&
+           "Must expand into a divisible number of parts!");
+    unsigned Factor = NumIntermediates / NumParts;
+    for (unsigned i = 0; i != NumIntermediates; ++i)
+      Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor,
+                                PartVT, IntermediateVT);
+  }
+  
+  // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate
+  // operands.
+  return DAG.getNode(MVT::isVector(IntermediateVT) ?
+                       ISD::CONCAT_VECTORS :
+                       ISD::BUILD_VECTOR,
+                     ValueVT, &Ops[0], NumParts);
+}
+
+/// getCopyToParts - Create a series of nodes that contain the
+/// specified value split into legal parts.
+static void getCopyToParts(SelectionDAG &DAG,
+                           SDOperand Val,
+                           SDOperand *Parts,
+                           unsigned NumParts,
+                           MVT::ValueType PartVT) {
+  MVT::ValueType ValueVT = Val.getValueType();
+
+  if (!MVT::isVector(ValueVT) || NumParts == 1) {
+    // If the value was expanded, copy from the parts.
+    if (NumParts > 1) {
+      for (unsigned i = 0; i < NumParts; ++i)
+        Parts[i] = DAG.getNode(ISD::EXTRACT_ELEMENT, PartVT, Val,
+                               DAG.getConstant(i, MVT::i32));
+      return;
+    }
+
+    // If there is a single part and the types differ, this must be
+    // a promotion.
+    if (PartVT != ValueVT) {
+      if (MVT::isVector(PartVT)) {
+        assert(MVT::isVector(ValueVT) &&
+               "Not a vector-vector cast?");
+        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+      } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) {
+        if (PartVT < ValueVT)
+          Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val);
+        else
+          Val = DAG.getNode(ISD::ANY_EXTEND, PartVT, Val);
+      } else if (MVT::isFloatingPoint(PartVT) &&
+                 MVT::isFloatingPoint(ValueVT)) {
+        Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
+      } else if (MVT::getSizeInBits(PartVT) == 
+                 MVT::getSizeInBits(ValueVT)) {
+        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
+      } else {
+        assert(0 && "Unknown mismatch!");
+      }
+    }
+    Parts[0] = Val;
+    return;
   }
-  
-  if (MVT::isInteger(RegVT)) {
-    if (ValueVT < RegVT)
-      return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
+
+  // Handle a multi-element vector.
+  MVT::ValueType IntermediateVT, RegisterVT;
+  unsigned NumIntermediates;
+  unsigned NumRegs =
+    DAG.getTargetLoweringInfo()
+      .getVectorTypeBreakdown(ValueVT, IntermediateVT, NumIntermediates,
+                              RegisterVT);
+  unsigned NumElements = MVT::getVectorNumElements(ValueVT);
+
+  assert(NumRegs == NumParts && "Part count doesn't match vector breakdown!");
+  assert(RegisterVT == PartVT && "Part type doesn't match vector breakdown!");
+
+  // Split the vector into intermediate operands.
+  SmallVector<SDOperand, 8> Ops(NumIntermediates);
+  for (unsigned i = 0; i != NumIntermediates; ++i)
+    if (MVT::isVector(IntermediateVT))
+      Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
+                           IntermediateVT, Val,
+                           DAG.getConstant(i * (NumElements / NumIntermediates),
+                                           MVT::i32));
     else
-      return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
+      Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
+                           IntermediateVT, Val, 
+                           DAG.getConstant(i, MVT::i32));
+
+  // Split the intermediate operands into legal parts.
+  if (NumParts == NumIntermediates) {
+    // If the register was not expanded, promote or copy the value,
+    // as appropriate.
+    for (unsigned i = 0; i != NumParts; ++i)
+      getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT);
+  } else if (NumParts > 0) {
+    // If the intermediate type was expanded, split each the value into
+    // legal parts.
+    assert(NumParts % NumIntermediates == 0 &&
+           "Must expand into a divisible number of parts!");
+    unsigned Factor = NumParts / NumIntermediates;
+    for (unsigned i = 0; i != NumIntermediates; ++i)
+      getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT);
+  }
+}
+
+
+/// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
+/// this value and returns the result as a ValueVT value.  This uses 
+/// Chain/Flag as the input and updates them for the output Chain/Flag.
+/// If the Flag pointer is NULL, no flag is used.
+SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
+                                        SDOperand &Chain, SDOperand *Flag)const{
+  // Get the list of registers, in the appropriate order.
+  std::vector<unsigned> R(Regs);
+  if (!DAG.getTargetLoweringInfo().isLittleEndian())
+    std::reverse(R.begin(), R.end());
+
+  // Copy the legal parts from the registers.
+  unsigned NumParts = Regs.size();
+  SmallVector<SDOperand, 8> Parts(NumParts);
+  for (unsigned i = 0; i < NumParts; ++i) {
+    SDOperand Part = Flag ?
+                     DAG.getCopyFromReg(Chain, Regs[i], RegVT, *Flag) :
+                     DAG.getCopyFromReg(Chain, Regs[i], RegVT);
+    Chain = Part.getValue(1);
+    if (Flag)
+      *Flag = Part.getValue(2);
+    Parts[i] = Part;
   }
   
-  assert(MVT::isFloatingPoint(RegVT) && MVT::isFloatingPoint(ValueVT));
-  return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
+  // Assemble the legal parts into the final value.
+  return getCopyFromParts(DAG, &Parts[0], NumParts, RegVT, ValueVT);
 }
 
 /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
 /// specified value into the registers specified by this object.  This uses 
 /// Chain/Flag as the input and updates them for the output Chain/Flag.
+/// If the Flag pointer is NULL, no flag is used.
 void RegsForValue::getCopyToRegs(SDOperand Val, SelectionDAG &DAG,
-                                 SDOperand &Chain, SDOperand &Flag,
-                                 MVT::ValueType PtrVT) const {
-  if (Regs.size() == 1) {
-    // If there is a single register and the types differ, this must be
-    // a promotion.
-    if (RegVT != ValueVT) {
-      if (MVT::isVector(RegVT)) {
-        assert(MVT::isVector(Val.getValueType()) &&
-               "Not a vector-vector cast?");
-        Val = DAG.getNode(ISD::BIT_CONVERT, RegVT, Val);
-      } else if (MVT::isInteger(RegVT) && MVT::isInteger(Val.getValueType())) {
-        if (RegVT < ValueVT)
-          Val = DAG.getNode(ISD::TRUNCATE, RegVT, Val);
-        else
-          Val = DAG.getNode(ISD::ANY_EXTEND, RegVT, Val);
-      } else if (MVT::isFloatingPoint(RegVT) &&
-                 MVT::isFloatingPoint(Val.getValueType())) {
-        Val = DAG.getNode(ISD::FP_EXTEND, RegVT, Val);
-      } else if (MVT::getSizeInBits(RegVT) == 
-                 MVT::getSizeInBits(Val.getValueType())) {
-        Val = DAG.getNode(ISD::BIT_CONVERT, RegVT, Val);
-      } else {
-        assert(0 && "Unknown mismatch!");
-      }
-    }
-    Chain = DAG.getCopyToReg(Chain, Regs[0], Val, Flag);
-    Flag = Chain.getValue(1);
-  } else {
-    std::vector<unsigned> R(Regs);
-    if (!DAG.getTargetLoweringInfo().isLittleEndian())
-      std::reverse(R.begin(), R.end());
-    
-    for (unsigned i = 0, e = R.size(); i != e; ++i) {
-      SDOperand Part = DAG.getNode(ISD::EXTRACT_ELEMENT, RegVT, Val, 
-                                   DAG.getConstant(i, PtrVT));
-      Chain = DAG.getCopyToReg(Chain, R[i], Part, Flag);
-      Flag = Chain.getValue(1);
-    }
+                                 SDOperand &Chain, SDOperand *Flag) const {
+  // Get the list of registers, in the appropriate order.
+  std::vector<unsigned> R(Regs);
+  if (!DAG.getTargetLoweringInfo().isLittleEndian())
+    std::reverse(R.begin(), R.end());
+
+  // Get the list of the values's legal parts.
+  unsigned NumParts = Regs.size();
+  SmallVector<SDOperand, 8> Parts(NumParts);
+  getCopyToParts(DAG, Val, &Parts[0], NumParts, RegVT);
+
+  // Copy the parts into the registers.
+  for (unsigned i = 0; i < NumParts; ++i) {
+    SDOperand Part = Flag ?
+                     DAG.getCopyToReg(Chain, R[i], Parts[i], *Flag) :
+                     DAG.getCopyToReg(Chain, R[i], Parts[i]);
+    Chain = Part.getValue(0);
+    if (Flag)
+      *Flag = Part.getValue(1);
   }
 }
 
@@ -3456,8 +3539,7 @@
           }
         
           // Use the produced MatchedRegs object to 
-          MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag,
-                                    TLI.getPointerTy());
+          MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
           MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
           break;
         } else {
@@ -3508,8 +3590,7 @@
       assert(!OpInfo.AssignedRegs.Regs.empty() &&
              "Couldn't allocate input reg!");
 
-      OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag, 
-                                        TLI.getPointerTy());
+      OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag);
       
       OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG,
                                                AsmNodeOperands);
@@ -3538,7 +3619,7 @@
   // If this asm returns a register value, copy the result from that register
   // and set it as the value of the call.
   if (!RetValRegs.Regs.empty()) {
-    SDOperand Val = RetValRegs.getCopyFromRegs(DAG, Chain, Flag);
+    SDOperand Val = RetValRegs.getCopyFromRegs(DAG, Chain, &Flag);
     
     // If the result of the inline asm is a vector, it may have the wrong
     // width/num elts.  Make sure to convert it to the right type with
@@ -3560,7 +3641,7 @@
   for (unsigned i = 0, e = IndirectStoresToEmit.size(); i != e; ++i) {
     RegsForValue &OutRegs = IndirectStoresToEmit[i].first;
     Value *Ptr = IndirectStoresToEmit[i].second;
-    SDOperand OutVal = OutRegs.getCopyFromRegs(DAG, Chain, Flag);
+    SDOperand OutVal = OutRegs.getCopyFromRegs(DAG, Chain, &Flag);
     StoresToEmit.push_back(std::make_pair(OutVal, Ptr));
   }
   
@@ -3733,40 +3814,22 @@
       RetVals.push_back(getTypeToTransformTo(VT));
       Ops.push_back(DAG.getConstant(Flags, MVT::i32));
       break;
-    case Expand:
-      if (!MVT::isVector(VT)) {
-        // 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 = getTypeToExpandTo(VT);
-        unsigned NumVals = getNumRegisters(VT);
-        for (unsigned i = 0; i != NumVals; ++i) {
-          RetVals.push_back(NVT);
-          // if it isn't first piece, alignment must be 1
-          if (i > 0)
-            Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
-              (1 << ISD::ParamFlags::OrigAlignmentOffs);
-          Ops.push_back(DAG.getConstant(Flags, MVT::i32));
-        }
-      } else {
-        // Otherwise, this is a vector type.  We only support legal vectors
-        // right now.
-        unsigned NumElems = cast<VectorType>(I->getType())->getNumElements();
-        const Type *EltTy = cast<VectorType>(I->getType())->getElementType();
-
-        // Figure out if there is a Packed type corresponding to this Vector
-        // type.  If so, convert to the vector type.
-        MVT::ValueType TVT =
-          MVT::getVectorType(getValueType(EltTy), NumElems);
-        if (TVT != MVT::Other && isTypeLegal(TVT)) {
-          RetVals.push_back(TVT);
-          Ops.push_back(DAG.getConstant(Flags, MVT::i32));
-        } else {
-          assert(0 && "Don't support illegal by-val vector arguments yet!");
-        }
+    case Expand: {
+      // If this is an illegal type, it needs to be broken up to fit into 
+      // registers.
+      MVT::ValueType RegisterVT = getRegisterType(VT);
+      unsigned NumRegs = getNumRegisters(VT);
+      for (unsigned i = 0; i != NumRegs; ++i) {
+        RetVals.push_back(RegisterVT);
+        // if it isn't first piece, alignment must be 1
+        if (i > 0)
+          Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
+            (1 << ISD::ParamFlags::OrigAlignmentOffs);
+        Ops.push_back(DAG.getConstant(Flags, MVT::i32));
       }
       break;
     }
+    }
   }
 
   RetVals.push_back(MVT::Other);
@@ -3979,108 +4042,33 @@
   }
   
   // Figure out the result value types.
-  SmallVector<MVT::ValueType, 4> 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 (!MVT::isVector(VT)) {
-        // 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 = getTypeToExpandTo(VT);
-        unsigned NumVals = getNumRegisters(VT);
-        for (unsigned i = 0; i != NumVals; ++i)
-          RetTys.push_back(NVT);
-      } else {
-        // Otherwise, this is a vector type.  We only support legal vectors
-        // right now.
-        const VectorType *PTy = cast<VectorType>(RetTy);
-        unsigned NumElems = PTy->getNumElements();
-        const Type *EltTy = PTy->getElementType();
-        
-        // Figure out if there is a Packed type corresponding to this Vector
-        // type.  If so, convert to the vector type.
-        MVT::ValueType TVT =
-          MVT::getVectorType(getValueType(EltTy), NumElems);
-        if (TVT != MVT::Other && isTypeLegal(TVT)) {
-          RetTys.push_back(TVT);
-        } else {
-          assert(0 && "Don't support illegal by-val vector call results yet!");
-          abort();
-        }
-      }
-    }    
-  }
+  MVT::ValueType VT = getValueType(RetTy);
+  MVT::ValueType RegisterVT = getRegisterType(VT);
+  unsigned NumRegs = getNumRegisters(VT);
+  SmallVector<MVT::ValueType, 4> RetTys(NumRegs);
+  for (unsigned i = 0; i != NumRegs; ++i)
+    RetTys[i] = RegisterVT;
   
   RetTys.push_back(MVT::Other);  // Always has a chain.
   
-  // Finally, create the CALL node.
+  // Create the CALL node.
   SDOperand Res = DAG.getNode(ISD::CALL,
-                              DAG.getVTList(&RetTys[0], RetTys.size()),
+                              DAG.getVTList(&RetTys[0], NumRegs + 1),
                               &Ops[0], Ops.size());
-  
-  // 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::isVector(VT)) {
-          // Insert a BIT_CONVERT to convert from the packed result type to the
-          // new vector type.
-          unsigned NumElems = cast<VectorType>(RetTy)->getNumElements();
-          const Type *EltTy = cast<VectorType>(RetTy)->getElementType();
-          
-          // Figure out if there is a Packed type corresponding to this Vector
-          // type.  If so, convert to the vector type.
-          MVT::ValueType TVT =
-            MVT::getVectorType(getValueType(EltTy),NumElems);
-          if (TVT != MVT::Other && isTypeLegal(TVT)) {
-            // Insert a BIT_CONVERT of the FORMAL_ARGUMENTS to a
-            // "N x PTyElementVT" vector type.
-            ResVal = DAG.getNode(ISD::BIT_CONVERT, TVT, ResVal);
-          } else {
-            abort();
-          }
-        } else if (MVT::isInteger(VT)) {
-          unsigned AssertOp = ISD::AssertSext;
-          if (!RetTyIsSigned)
-            AssertOp = ISD::AssertZext;
-          ResVal = DAG.getNode(AssertOp, ResVal.getValueType(), ResVal, 
-                               DAG.getValueType(VT));
-          ResVal = DAG.getNode(ISD::TRUNCATE, VT, ResVal);
-        } else {
-          assert(MVT::isFloatingPoint(VT));
-          if (getTypeAction(VT) == Expand)
-            ResVal = DAG.getNode(ISD::BIT_CONVERT, VT, ResVal);
-          else
-            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!");
-    }
+  SDOperand Chain = Res.getValue(NumRegs);
+
+  // Gather up the call result into a single value.
+  if (RetTy != Type::VoidTy) {
+    ISD::NodeType AssertOp = ISD::AssertSext;
+    if (!RetTyIsSigned)
+      AssertOp = ISD::AssertZext;
+    SmallVector<SDOperand, 4> Results(NumRegs);
+    for (unsigned i = 0; i != NumRegs; ++i)
+      Results[i] = Res.getValue(i);
+    Res = getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT, AssertOp);
   }
-  
-  return std::make_pair(ResVal, Res.getValue(Res.Val->getNumValues()-1));
+
+  return std::make_pair(Res, Chain);
 }
 
 SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -4360,75 +4348,17 @@
           cast<RegisterSDNode>(Op.getOperand(1))->getReg() != Reg) &&
          "Copy from a reg to the same reg!");
   
-  // If this type is not legal, we must make sure to not create an invalid
-  // register use.
   MVT::ValueType SrcVT = Op.getValueType();
-  MVT::ValueType DestVT = TLI.getTypeToTransformTo(SrcVT);
-  if (SrcVT == DestVT) {
-    return DAG.getCopyToReg(getRoot(), Reg, Op);
-  } else if (MVT::isVector(SrcVT)) {
-    // Handle copies from generic vectors to registers.
-    MVT::ValueType ElementVT, LegalElementVT;
-    unsigned NE = TLI.getVectorTypeBreakdown(SrcVT,
-                                             ElementVT, LegalElementVT);
-    uint64_t SrcVL = MVT::getVectorNumElements(SrcVT);
-    
-    // Loop over all of the elements of the resultant vector,
-    // EXTRACT_VECTOR_ELT'ing or EXTRACT_SUBVECTOR'ing them, converting them
-    // to LegalElementVT, then copying them into output registers.
-    SmallVector<SDOperand, 8> OutChains;
-    SDOperand Root = getRoot();
-    for (unsigned i = 0; i != NE; ++i) {
-      SDOperand Elt = MVT::isVector(ElementVT) ?
-        DAG.getNode(ISD::EXTRACT_SUBVECTOR, ElementVT,
-                    Op, DAG.getConstant(i * (SrcVL / NE), TLI.getPointerTy())) :
-        DAG.getNode(ISD::EXTRACT_VECTOR_ELT, ElementVT,
-                    Op, DAG.getConstant(i, TLI.getPointerTy()));
-      if (ElementVT == LegalElementVT) {
-        // Elements are legal.
-        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));
-      } else if (LegalElementVT > ElementVT) {
-        // Elements are promoted.
-        if (MVT::isFloatingPoint(LegalElementVT))
-          Elt = DAG.getNode(ISD::FP_EXTEND, LegalElementVT, Elt);
-        else
-          Elt = DAG.getNode(ISD::ANY_EXTEND, LegalElementVT, Elt);
-        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Elt));
-      } else {
-        // Elements are expanded.
-        // The src value is expanded into multiple registers.
-        SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, LegalElementVT,
-                                   Elt, DAG.getConstant(0, TLI.getPointerTy()));
-        SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, LegalElementVT,
-                                   Elt, DAG.getConstant(1, TLI.getPointerTy()));
-        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Lo));
-        OutChains.push_back(DAG.getCopyToReg(Root, Reg++, Hi));
-      }
-    }
-    return DAG.getNode(ISD::TokenFactor, MVT::Other,
-                       &OutChains[0], OutChains.size());
-  } else if (TLI.getTypeAction(SrcVT) == TargetLowering::Promote) {
-    // The src value is promoted to the register.
-    if (MVT::isFloatingPoint(SrcVT))
-      Op = DAG.getNode(ISD::FP_EXTEND, DestVT, Op);
-    else
-      Op = DAG.getNode(ISD::ANY_EXTEND, DestVT, Op);
-    return DAG.getCopyToReg(getRoot(), Reg, Op);
-  } else  {
-    DestVT = TLI.getTypeToExpandTo(SrcVT);
-    unsigned NumVals = TLI.getNumRegisters(SrcVT);
-    if (NumVals == 1)
-      return DAG.getCopyToReg(getRoot(), Reg,
-                              DAG.getNode(ISD::BIT_CONVERT, DestVT, Op));
-    assert(NumVals == 2 && "1 to 4 (and more) expansion not implemented!");
-    // The src value is expanded into multiple registers.
-    SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT,
-                               Op, DAG.getConstant(0, TLI.getPointerTy()));
-    SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT,
-                               Op, DAG.getConstant(1, TLI.getPointerTy()));
-    Op = DAG.getCopyToReg(getRoot(), Reg, Lo);
-    return DAG.getCopyToReg(Op, Reg+1, Hi);
-  }
+  MVT::ValueType RegisterVT = TLI.getRegisterType(SrcVT);
+  unsigned NumRegs = TLI.getNumRegisters(SrcVT);
+  SmallVector<SDOperand, 8> Regs(NumRegs);
+  SmallVector<SDOperand, 8> Chains(NumRegs);
+
+  // Copy the value by legal parts into sequential virtual registers.
+  getCopyToParts(DAG, Op, &Regs[0], NumRegs, RegisterVT);
+  for (unsigned i = 0; i < NumRegs; ++i)
+    Chains[i] = DAG.getCopyToReg(getRoot(), Reg + i, Regs[i]);
+  return DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumRegs);
 }
 
 void SelectionDAGISel::


Index: llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.123 llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.124
--- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp:1.123	Mon Jun 25 11:23:39 2007
+++ llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp	Thu Jun 28 18:29:44 2007
@@ -165,58 +165,19 @@
 
 TargetLowering::~TargetLowering() {}
 
-/// setValueTypeAction - Set the action for a particular value type.  This
-/// assumes an action has not already been set for this value type.
-static void SetValueTypeAction(MVT::ValueType VT,
-                               TargetLowering::LegalizeAction Action,
-                               TargetLowering &TLI,
-                               MVT::ValueType *TransformToType,
-                        TargetLowering::ValueTypeActionImpl &ValueTypeActions) {
-  ValueTypeActions.setTypeAction(VT, Action);
-  if (Action == TargetLowering::Promote) {
-    MVT::ValueType PromoteTo;
-    if (VT == MVT::f32)
-      PromoteTo = MVT::f64;
-    else {
-      unsigned LargerReg = VT+1;
-      while (!TLI.isTypeLegal((MVT::ValueType)LargerReg)) {
-        ++LargerReg;
-        assert(MVT::isInteger((MVT::ValueType)LargerReg) &&
-               "Nothing to promote to??");
-      }
-      PromoteTo = (MVT::ValueType)LargerReg;
-    }
-
-    assert(MVT::isInteger(VT) == MVT::isInteger(PromoteTo) &&
-           MVT::isFloatingPoint(VT) == MVT::isFloatingPoint(PromoteTo) &&
-           "Can only promote from int->int or fp->fp!");
-    assert(VT < PromoteTo && "Must promote to a larger type!");
-    TransformToType[VT] = PromoteTo;
-  } else if (Action == TargetLowering::Expand) {
-    // f32 and f64 is each expanded to corresponding integer type of same size.
-    if (VT == MVT::f32)
-      TransformToType[VT] = MVT::i32;
-    else if (VT == MVT::f64)
-      TransformToType[VT] = MVT::i64;
-    else {
-      assert((MVT::isVector(VT) || MVT::isInteger(VT)) && VT > MVT::i8 &&
-             "Cannot expand this type: target must support SOME integer reg!");
-      // Expand to the next smaller integer type!
-      TransformToType[VT] = (MVT::ValueType)(VT-1);
-    }
-  }
-}
-
-
 /// computeRegisterProperties - Once all of the register classes are added,
 /// this allows us to compute derived properties we expose.
 void TargetLowering::computeRegisterProperties() {
   assert(MVT::LAST_VALUETYPE <= 32 &&
          "Too many value types for ValueTypeActions to hold!");
 
-  // Everything defaults to one.
-  for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i)
+  // Everything defaults to needing one register.
+  for (unsigned i = 0; i != MVT::LAST_VALUETYPE; ++i) {
     NumRegistersForVT[i] = 1;
+    RegisterTypeForVT[i] = TransformToType[i] = i;
+  }
+  // ...except isVoid, which doesn't need any registers.
+  NumRegistersForVT[MVT::isVoid] = 0;
 
   // Find the largest integer register class.
   unsigned LargestIntReg = MVT::i128;
@@ -225,57 +186,65 @@
 
   // Every integer value type larger than this largest register takes twice as
   // many registers to represent as the previous ValueType.
-  unsigned ExpandedReg = LargestIntReg; ++LargestIntReg;
-  for (++ExpandedReg; MVT::isInteger((MVT::ValueType)ExpandedReg);++ExpandedReg)
+  for (MVT::ValueType ExpandedReg = LargestIntReg + 1;
+       MVT::isInteger(ExpandedReg); ++ExpandedReg) {
     NumRegistersForVT[ExpandedReg] = 2*NumRegistersForVT[ExpandedReg-1];
+    RegisterTypeForVT[ExpandedReg] = LargestIntReg;
+    TransformToType[ExpandedReg] = ExpandedReg - 1;
+    ValueTypeActions.setTypeAction(ExpandedReg, Expand);
+  }
 
-  // Inspect all of the ValueType's possible, deciding how to process them.
-  for (unsigned IntReg = MVT::i1; IntReg <= MVT::i128; ++IntReg)
-    // If we are expanding this type, expand it!
-    if (getNumRegisters((MVT::ValueType)IntReg) != 1)
-      SetValueTypeAction((MVT::ValueType)IntReg, Expand, *this, TransformToType,
-                         ValueTypeActions);
-    else if (!isTypeLegal((MVT::ValueType)IntReg))
-      // Otherwise, if we don't have native support, we must promote to a
-      // larger type.
-      SetValueTypeAction((MVT::ValueType)IntReg, Promote, *this,
-                         TransformToType, ValueTypeActions);
-    else
-      TransformToType[(MVT::ValueType)IntReg] = (MVT::ValueType)IntReg;
-
-  // If the target does not have native f64 support, expand it to i64. We will
-  // be generating soft float library calls. If the target does not have native
-  // support for f32, promote it to f64 if it is legal. Otherwise, expand it to
-  // i32.
-  if (isTypeLegal(MVT::f64))
-    TransformToType[MVT::f64] = MVT::f64;  
-  else {
+  // Inspect all of the ValueType's smaller than the largest integer
+  // register to see which ones need promotion.
+  MVT::ValueType LegalIntReg = LargestIntReg;
+  for (MVT::ValueType IntReg = LargestIntReg - 1;
+       IntReg >= MVT::i1; --IntReg) {
+    if (isTypeLegal(IntReg)) {
+      LegalIntReg = IntReg;
+    } else {
+      RegisterTypeForVT[IntReg] = TransformToType[IntReg] = LegalIntReg;
+      ValueTypeActions.setTypeAction(IntReg, Promote);
+    }
+  }
+
+  // Decide how to handle f64. If the target does not have native f64 support,
+  // expand it to i64 and we will be generating soft float library calls.
+  if (!isTypeLegal(MVT::f64)) {
     NumRegistersForVT[MVT::f64] = NumRegistersForVT[MVT::i64];
-    SetValueTypeAction(MVT::f64, Expand, *this, TransformToType,
-                       ValueTypeActions);
+    RegisterTypeForVT[MVT::f64] = RegisterTypeForVT[MVT::i64];
+    TransformToType[MVT::f64] = MVT::i64;
+    ValueTypeActions.setTypeAction(MVT::f64, Expand);
   }
-  if (isTypeLegal(MVT::f32))
-    TransformToType[MVT::f32] = MVT::f32;
-  else if (isTypeLegal(MVT::f64))
-    SetValueTypeAction(MVT::f32, Promote, *this, TransformToType,
-                       ValueTypeActions);
-  else {
-    NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32];
-    SetValueTypeAction(MVT::f32, Expand, *this, TransformToType,
-                       ValueTypeActions);
-  }
-  
-  // Loop over all of the legal vector value types, specifying an identity type
-  // transformation.
-  for (unsigned i = MVT::FIRST_VECTOR_VALUETYPE;
+
+  // Decide how to handle f32. If the target does not have native support for
+  // f32, promote it to f64 if it is legal. Otherwise, expand it to i32.
+  if (!isTypeLegal(MVT::f32)) {
+    if (isTypeLegal(MVT::f64)) {
+      NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::f64];
+      RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::f64];
+      TransformToType[MVT::f32] = MVT::f64;
+      ValueTypeActions.setTypeAction(MVT::f32, Promote);
+    } else {
+      NumRegistersForVT[MVT::f32] = NumRegistersForVT[MVT::i32];
+      RegisterTypeForVT[MVT::f32] = RegisterTypeForVT[MVT::i32];
+      TransformToType[MVT::f32] = MVT::i32;
+      ValueTypeActions.setTypeAction(MVT::f32, Expand);
+    }
+  }
+  
+  // Loop over all of the vector value types to see which need transformations.
+  for (MVT::ValueType i = MVT::FIRST_VECTOR_VALUETYPE;
        i <= MVT::LAST_VECTOR_VALUETYPE; ++i) {
-    if (isTypeLegal((MVT::ValueType)i))
-      TransformToType[i] = (MVT::ValueType)i;
-    else {
-      MVT::ValueType VT1, VT2;
-      NumRegistersForVT[i] = getVectorTypeBreakdown(i, VT1, VT2);
-      SetValueTypeAction(i, Expand, *this, TransformToType,
-                         ValueTypeActions);
+    if (!isTypeLegal(i)) {
+      MVT::ValueType IntermediateVT, RegisterVT;
+      unsigned NumIntermediates;
+      NumRegistersForVT[i] =
+        getVectorTypeBreakdown(i,
+                               IntermediateVT, NumIntermediates,
+                               RegisterVT);
+      RegisterTypeForVT[i] = RegisterVT;
+      TransformToType[i] = MVT::Other; // this isn't actually used
+      ValueTypeActions.setTypeAction(i, Expand);
     }
   }
 }
@@ -290,12 +259,13 @@
 /// Similarly, MVT::v2i64 turns into 4 MVT::i32 values with both PPC and X86.
 ///
 /// This method returns the number of registers needed, and the VT for each
-/// register.  It also returns the VT of the VectorType elements before they
-/// are promoted/expanded.
+/// register.  It also returns the VT and quantity of the intermediate values
+/// before they are promoted/expanded.
 ///
 unsigned TargetLowering::getVectorTypeBreakdown(MVT::ValueType VT, 
-                                                MVT::ValueType &ElementVT,
-                                      MVT::ValueType &LegalElementVT) const {
+                                                MVT::ValueType &IntermediateVT,
+                                                unsigned &NumIntermediates,
+                                      MVT::ValueType &RegisterVT) const {
   // Figure out the right, legal destination reg to copy into.
   unsigned NumElts = MVT::getVectorNumElements(VT);
   MVT::ValueType EltTy = MVT::getVectorElementType(VT);
@@ -309,14 +279,16 @@
     NumElts >>= 1;
     NumVectorRegs <<= 1;
   }
+
+  NumIntermediates = NumVectorRegs;
   
   MVT::ValueType NewVT = MVT::getVectorType(EltTy, NumElts);
   if (!isTypeLegal(NewVT))
     NewVT = EltTy;
-  ElementVT = NewVT;
+  IntermediateVT = NewVT;
 
   MVT::ValueType DestVT = getTypeToTransformTo(NewVT);
-  LegalElementVT = DestVT;
+  RegisterVT = DestVT;
   if (DestVT < NewVT) {
     // Value is expanded, e.g. i64 -> i16.
     return NumVectorRegs*(MVT::getSizeInBits(NewVT)/MVT::getSizeInBits(DestVT));






More information about the llvm-commits mailing list