[llvm-commits] [llvm] r47672 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeTypes.cpp LegalizeTypes.h LegalizeTypesExpand.cpp LegalizeTypesPromote.cpp LegalizeTypesScalarize.cpp LegalizeTypesSplit.cpp

Evan Cheng evan.cheng at apple.com
Wed Feb 27 12:42:00 PST 2008


Very nice! Thanks.

Evan

On Feb 27, 2008, at 5:34 AM, Duncan Sands wrote:

> Author: baldrick
> Date: Wed Feb 27 07:34:40 2008
> New Revision: 47672
>
> URL: http://llvm.org/viewvc/llvm-project?rev=47672&view=rev
> Log:
> LegalizeTypes support for EXTRACT_VECTOR_ELT.  The
> approach taken is different to that in LegalizeDAG
> when it is a question of expanding or promoting the
> result type: for example, if extracting an i64 from
> a <2 x i64>, when i64 needs expanding, it bitcasts
> the vector to <4 x i32>, extracts the appropriate
> two i32's, and uses those for the Lo and Hi parts.
> Likewise, when extracting an i16 from a <4 x i16>,
> and i16 needs promoting, it bitcasts the vector to
> <2 x i32>, extracts the appropriate i32, twiddles
> the bits if necessary, and uses that as the promoted
> value.  This puts more pressure on bitcast legalization,
> and I've added the appropriate cases.  They needed to
> be added anyway since users can generate such bitcasts
> too if they want to.  Also, when considering various
> cases (Legal, Promote, Expand, Scalarize, Split) it is
> a pain that expand can correspond to Expand, Scalarize
> or Split, so I've changed the LegalizeTypes enum so it
> lists those different cases - now Expand only means
> splitting a scalar in two.
> The code produced is the same as by LegalizeDAG for
> all relevant testcases, except for
> 2007-10-31-extractelement-i64.ll, where the code seems
> to have improved (see below; can an expert please tell
> me if it is better or not).
> Before < vs after >.
>
> <       subl    $92, %esp
> <       movaps  %xmm0, 64(%esp)
> <       movaps  %xmm0, (%esp)
> <       movl    4(%esp), %eax
> <       movl    %eax, 28(%esp)
> <       movl    (%esp), %eax
> <       movl    %eax, 24(%esp)
> <       movq    24(%esp), %mm0
> <       movq    %mm0, 56(%esp)
> ---
>>      subl    $44, %esp
>>      movaps  %xmm0, 16(%esp)
>>      pshufd  $1, %xmm0, %xmm1
>>      movd    %xmm1, 4(%esp)
>>      movd    %xmm0, (%esp)
>>      movq    (%esp), %mm0
>>      movq    %mm0, 8(%esp)
>
> <       subl    $92, %esp
> <       movaps  %xmm0, 64(%esp)
> <       movaps  %xmm0, (%esp)
> <       movl    12(%esp), %eax
> <       movl    %eax, 28(%esp)
> <       movl    8(%esp), %eax
> <       movl    %eax, 24(%esp)
> <       movq    24(%esp), %mm0
> <       movq    %mm0, 56(%esp)
> ---
>>      subl    $44, %esp
>>      movaps  %xmm0, 16(%esp)
>>      pshufd  $3, %xmm0, %xmm1
>>      movd    %xmm1, 4(%esp)
>>      movhlps %xmm0, %xmm0
>>      movd    %xmm0, (%esp)
>>      movq    (%esp), %mm0
>>      movq    %mm0, 8(%esp)
>
> <       subl    $92, %esp
> <       movaps  %xmm0, 64(%esp)
> ---
>>      subl    $44, %esp
>
> <       movl    16(%esp), %eax
> <       movl    %eax, 48(%esp)
> <       movl    20(%esp), %eax
> <       movl    %eax, 52(%esp)
> <       movaps  %xmm0, (%esp)
> <       movl    4(%esp), %eax
> <       movl    %eax, 60(%esp)
> <       movl    (%esp), %eax
> <       movl    %eax, 56(%esp)
> ---
>>      pshufd  $1, %xmm0, %xmm1
>>      movd    %xmm1, 4(%esp)
>>      movd    %xmm0, (%esp)
>>      movd    %xmm1, 12(%esp)
>>      movd    %xmm0, 8(%esp)
>
> <       subl    $92, %esp
> <       movaps  %xmm0, 64(%esp)
> ---
>>      subl    $44, %esp
>
> <       movl    24(%esp), %eax
> <       movl    %eax, 48(%esp)
> <       movl    28(%esp), %eax
> <       movl    %eax, 52(%esp)
> <       movaps  %xmm0, (%esp)
> <       movl    12(%esp), %eax
> <       movl    %eax, 60(%esp)
> <       movl    8(%esp), %eax
> <       movl    %eax, 56(%esp)
> ---
>>      pshufd  $3, %xmm0, %xmm1
>>      movd    %xmm1, 4(%esp)
>>      movhlps %xmm0, %xmm0
>>      movd    %xmm0, (%esp)
>>      movd    %xmm1, 12(%esp)
>>      movd    %xmm0, 8(%esp)
>
> Modified:
>    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
>    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=47672&r1=47671&r2=47672&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Wed Feb 27  
> 07:34:40 2008
> @@ -68,25 +68,26 @@
>     unsigned NumResults = N->getNumValues();
>     do {
>       MVT::ValueType ResultVT = N->getValueType(i);
> -      LegalizeAction Action = getTypeAction(ResultVT);
> -      if (Action == Promote) {
> +      switch (getTypeAction(ResultVT)) {
> +      default:
> +        assert(false && "Unknown action!");
> +      case Legal:
> +        break;
> +      case Promote:
>         PromoteResult(N, i);
>         goto NodeDone;
> -      } else if (Action == Expand) {
> -        // 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
> -          SplitResult(N, i);         // Split the vector in half.
> +      case Expand:
> +        ExpandResult(N, i);
> +        goto NodeDone;
> +      case Scalarize:
> +        ScalarizeResult(N, i);
> +        goto NodeDone;
> +      case Split:
> +        SplitResult(N, i);
>         goto NodeDone;
> -      } else {
> -        assert(Action == Legal && "Unknown action!");
>       }
>     } while (++i < NumResults);
> -
> +
>     // Scan the operand list for the node, handling any nodes with  
> operands that
>     // are illegal.
>     {
> @@ -94,25 +95,25 @@
>     bool NeedsRevisit = false;
>     for (i = 0; i != NumOperands; ++i) {
>       MVT::ValueType OpVT = N->getOperand(i).getValueType();
> -      LegalizeAction Action = getTypeAction(OpVT);
> -      if (Action == Promote) {
> +      switch (getTypeAction(OpVT)) {
> +      default:
> +        assert(false && "Unknown action!");
> +      case Legal:
> +        continue;
> +      case Promote:
>         NeedsRevisit = PromoteOperand(N, i);
>         break;
> -      } else if (Action == Expand) {
> -        // Expand can mean 1) split integer in half 2) scalarize  
> single-element
> -        // 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 {
> -          NeedsRevisit = SplitOperand(N, i); // Split the vector in  
> half.
> -        }
> +      case Expand:
> +        NeedsRevisit = ExpandOperand(N, i);
> +        break;
> +      case Scalarize:
> +        NeedsRevisit = ScalarizeOperand(N, i);
> +        break;
> +      case Split:
> +        NeedsRevisit = SplitOperand(N, i);
>         break;
> -      } else {
> -        assert(Action == Legal && "Unknown action!");
>       }
> +      break;
>     }
>
>     // If the node needs revisiting, don't add all users to the  
> worklist etc.
> @@ -432,7 +433,7 @@
>   case Legal: break;
>   case Promote: Op2 = GetPromotedOp(Op2); break;
>   }
> -
> +
>   // The length could have any action required.
>   SDOperand Length = N->getOperand(3);
>   switch (getTypeAction(Length.getValueType())) {
> @@ -444,21 +445,21 @@
>     GetExpandedOp(Length, Length, Dummy);
>     break;
>   }
> -
> +
>   SDOperand Align = N->getOperand(4);
>   switch (getTypeAction(Align.getValueType())) {
>   default: assert(0 && "Unknown action for memop operand");
>   case Legal: break;
>   case Promote: Align = GetPromotedZExtOp(Align); break;
>   }
> -
> +
>   SDOperand AlwaysInline = N->getOperand(5);
>   switch (getTypeAction(AlwaysInline.getValueType())) {
>   default: assert(0 && "Unknown action for memop operand");
>   case Legal: break;
>   case Promote: AlwaysInline = GetPromotedZExtOp(AlwaysInline); break;
>   }
> -
> +
>   SDOperand Ops[] = { Chain, Ptr, Op2, Length, Align, AlwaysInline };
>   return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6);
> }
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=47672&r1=47671&r2=47672&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Wed Feb 27  
> 07:34:40 2008
> @@ -61,27 +61,46 @@
>   enum LegalizeAction {
>     Legal,      // The target natively supports this type.
>     Promote,    // This type should be executed in a larger type.
> -    Expand      // This type should be split into two types of half  
> the size.
> +    Expand,     // This type should be split into two types of half  
> the size.
> +    Scalarize,  // Replace this one-element vector type with its  
> element type.
> +    Split       // This vector type should be split into smaller  
> vectors.
>   };
> -
> +
>   /// ValueTypeActions - This is a bitvector that contains two bits  
> for each
>   /// simple value type, where the two bits correspond to the  
> LegalizeAction
> -  /// enum.  This can be queried with "getTypeAction(VT)".
> +  /// enum from TargetLowering.  This can be queried with  
> "getTypeAction(VT)".
>   TargetLowering::ValueTypeActionImpl ValueTypeActions;
>
>   /// getTypeAction - Return how we should legalize values of this  
> type, either
> -  /// it is already legal or we need to expand it into multiple  
> registers of
> -  /// smaller integer type, or we need to promote it to a larger  
> type.
> +  /// it is already legal, or we need to promote it to a larger  
> integer type, or
> +  /// we need to expand it into multiple registers of a smaller  
> integer type, or
> +  /// we need to scalarize a one-element vector type into the  
> element type, or
> +  /// we need to split a vector type into smaller vector types.
>   LegalizeAction getTypeAction(MVT::ValueType VT) const {
> -    return (LegalizeAction)ValueTypeActions.getTypeAction(VT);
> +    switch (ValueTypeActions.getTypeAction(VT)) {
> +    default:
> +      assert(false && "Unknown legalize action!");
> +    case TargetLowering::Legal:
> +      return Legal;
> +    case TargetLowering::Promote:
> +      return Promote;
> +    case TargetLowering::Expand:
> +      // Expand can mean 1) split integer in half 2) scalarize  
> single-element
> +      // vector 3) split vector in two.
> +      if (!MVT::isVector(VT))
> +        return Expand;
> +      else if (MVT::getVectorNumElements(VT) == 1)
> +        return Scalarize;
> +      else
> +        return Split;
> +    }
>   }
> -
> +
>   /// isTypeLegal - Return true if this type is legal on this target.
> -  ///
>   bool isTypeLegal(MVT::ValueType VT) const {
> -    return getTypeAction(VT) == Legal;
> +    return ValueTypeActions.getTypeAction(VT) ==  
> TargetLowering::Legal;
>   }
> -
> +
>   /// PromotedNodes - For nodes that are below legal width, this map  
> indicates
>   /// what promoted value to use.
>   DenseMap<SDOperand, SDOperand> PromotedNodes;
> @@ -159,11 +178,13 @@
>
>   // Result Promotion.
>   void PromoteResult(SDNode *N, unsigned ResNo);
> +  SDOperand PromoteResult_BIT_CONVERT(SDNode *N);
>   SDOperand PromoteResult_BUILD_PAIR(SDNode *N);
>   SDOperand PromoteResult_Constant(SDNode *N);
>   SDOperand PromoteResult_CTLZ(SDNode *N);
>   SDOperand PromoteResult_CTPOP(SDNode *N);
>   SDOperand PromoteResult_CTTZ(SDNode *N);
> +  SDOperand PromoteResult_EXTRACT_VECTOR_ELT(SDNode *N);
>   SDOperand PromoteResult_FP_ROUND(SDNode *N);
>   SDOperand PromoteResult_FP_TO_XINT(SDNode *N);
>   SDOperand PromoteResult_INT_EXTEND(SDNode *N);
> @@ -219,6 +240,7 @@
>   void ExpandResult_CTLZ       (SDNode *N, SDOperand &Lo, SDOperand  
> &Hi);
>   void ExpandResult_CTPOP      (SDNode *N, SDOperand &Lo, SDOperand  
> &Hi);
>   void ExpandResult_CTTZ       (SDNode *N, SDOperand &Lo, SDOperand  
> &Hi);
> +  void ExpandResult_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo,  
> SDOperand &Hi);
>   void ExpandResult_LOAD       (LoadSDNode *N, SDOperand &Lo,  
> SDOperand &Hi);
>   void ExpandResult_MERGE_VALUES(SDNode *N, SDOperand &Lo, SDOperand  
> &Hi);
>   void ExpandResult_SIGN_EXTEND(SDNode *N, SDOperand &Lo, SDOperand  
> &Hi);
> @@ -283,6 +305,7 @@
>
>   // Operand Vector Scalarization: <1 x ty> -> ty.
>   bool ScalarizeOperand(SDNode *N, unsigned OpNo);
> +  SDOperand ScalarizeOp_BIT_CONVERT(SDNode *N);
>   SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N);
>   SDOperand ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo);
>
> @@ -313,7 +336,9 @@
>   // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>.
>   bool SplitOperand(SDNode *N, unsigned OpNo);
>
> +  SDOperand SplitOp_BIT_CONVERT(SDNode *N);
>   SDOperand SplitOp_EXTRACT_SUBVECTOR(SDNode *N);
> +  SDOperand SplitOp_EXTRACT_VECTOR_ELT(SDNode *N);
>   SDOperand SplitOp_RET(SDNode *N, unsigned OpNo);
>   SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo);
>   SDOperand SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo);
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp?rev=47672&r1=47671&r2=47672&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp  
> (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp Wed  
> Feb 27 07:34:40 2008
> @@ -86,6 +86,10 @@
>   case ISD::CTLZ:        ExpandResult_CTLZ(N, Lo, Hi); break;
>   case ISD::CTPOP:       ExpandResult_CTPOP(N, Lo, Hi); break;
>   case ISD::CTTZ:        ExpandResult_CTTZ(N, Lo, Hi); break;
> +
> +  case ISD::EXTRACT_VECTOR_ELT:
> +    ExpandResult_EXTRACT_VECTOR_ELT(N, Lo, Hi);
> +    break;
>   }
>
>   // If Lo/Hi is null, the sub-method took care of registering  
> results etc.
> @@ -147,7 +151,7 @@
>     // For example, extension of an i48 to an i64.  The operand type  
> necessarily
>     // promotes to the result type, so will end up being expanded too.
>     assert(getTypeAction(Op.getValueType()) == Promote &&
> -           "Don't know how to expand this result!");
> +           "Only know how to promote this result!");
>     SDOperand Res = GetPromotedOp(Op);
>     assert(Res.getValueType() == N->getValueType(0) &&
>            "Operand over promoted?");
> @@ -168,7 +172,7 @@
>     // For example, extension of an i48 to an i64.  The operand type  
> necessarily
>     // promotes to the result type, so will end up being expanded too.
>     assert(getTypeAction(Op.getValueType()) == Promote &&
> -           "Don't know how to expand this result!");
> +           "Only know how to promote this result!");
>     SDOperand Res = GetPromotedOp(Op);
>     assert(Res.getValueType() == N->getValueType(0) &&
>            "Operand over promoted?");
> @@ -195,7 +199,7 @@
>     // For example, extension of an i48 to an i64.  The operand type  
> necessarily
>     // promotes to the result type, so will end up being expanded too.
>     assert(getTypeAction(Op.getValueType()) == Promote &&
> -           "Don't know how to expand this result!");
> +           "Only know how to promote this result!");
>     SDOperand Res = GetPromotedOp(Op);
>     assert(Res.getValueType() == N->getValueType(0) &&
>            "Operand over promoted?");
> @@ -239,6 +243,8 @@
> void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N,
>                                                 SDOperand &Lo,  
> SDOperand &Hi) {
>   // Lower the bit-convert to a store/load from the stack, then  
> expand the load.
> +  // TODO: If the operand also needs expansion then this could be  
> turned into
> +  // conversion of the expanded pieces.  But there needs to be a  
> testcase first!
>   SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N- 
> >getValueType(0));
>   ExpandResult_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
> }
> @@ -666,6 +672,41 @@
>   Hi = DAG.getConstant(0, NVT);
> }
>
> +void DAGTypeLegalizer::ExpandResult_EXTRACT_VECTOR_ELT(SDNode *N,
> +                                                       SDOperand &Lo,
> +                                                       SDOperand  
> &Hi) {
> +  SDOperand OldVec = N->getOperand(0);
> +  unsigned OldElts =  
> MVT::getVectorNumElements(OldVec.getValueType());
> +
> +  // Convert to a vector of the expanded element type, for example
> +  // <2 x i64> -> <4 x i32>.
> +  MVT::ValueType OldVT = N->getValueType(0);
> +  MVT::ValueType NewVT = TLI.getTypeToTransformTo(OldVT);
> +  assert(MVT::getSizeInBits(OldVT) == 2 * MVT::getSizeInBits(NewVT)  
> &&
> +         "Do not know how to handle this expansion!");
> +
> +  SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
> +                                 MVT::getVectorType(NewVT, 2 *  
> OldElts),
> +                                 OldVec);
> +
> +  // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new  
> vector.
> +  SDOperand Idx = N->getOperand(1);
> +
> +  // Make sure the type of Idx is big enough to hold the new values.
> +  if (MVT::getSizeInBits(Idx.getValueType()) < 32)
> +    Idx = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Idx);
> +
> +  Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
> +  Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
> +
> +  Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx,
> +                    DAG.getConstant(1, Idx.getValueType()));
> +  Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
> +
> +  if (TLI.isBigEndian())
> +    std::swap(Lo, Hi);
> +}
> +
> /// ExpandShiftByConstant - N is a shift by a value that needs to be  
> expanded,
> /// and the shift amount is a constant 'Amt'.  Expand the operation.
> void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
> @@ -898,6 +939,28 @@
> }
>
> SDOperand DAGTypeLegalizer::ExpandOperand_BIT_CONVERT(SDNode *N) {
> +  if (MVT::isVector(N->getValueType(0))) {
> +    // An illegal integer type is being converted to a legal vector  
> type.
> +    // Make a two element vector out of the expanded parts and  
> convert that
> +    // instead, but only if the new vector type is legal (otherwise  
> there
> +    // is no point, and it might create expansion loops).  For  
> example, on
> +    // x86 this turns v1i64 = BIT_CONVERT i64 into v1i64 =  
> BIT_CONVERT v2i32.
> +    MVT::ValueType OVT = N->getOperand(0).getValueType();
> +    MVT::ValueType NVT =  
> MVT::getVectorType(TLI.getTypeToTransformTo(OVT), 2);
> +
> +    if (isTypeLegal(NVT)) {
> +      SDOperand Parts[2];
> +      GetExpandedOp(N->getOperand(0), Parts[0], Parts[1]);
> +
> +      if (TLI.isBigEndian())
> +        std::swap(Parts[0], Parts[1]);
> +
> +      SDOperand Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2);
> +      return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec);
> +    }
> +  }
> +
> +  // Otherwise, store to a temporary and load out again as the new  
> type.
>   return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
> }
>
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp?rev=47672&r1=47671&r2=47672&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp  
> (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp Wed  
> Feb 27 07:34:40 2008
> @@ -50,6 +50,7 @@
>   case ISD::SETCC:    Result = PromoteResult_SETCC(N); break;
>   case ISD::LOAD:     Result =  
> PromoteResult_LOAD(cast<LoadSDNode>(N)); break;
>   case ISD::BUILD_PAIR:  Result = PromoteResult_BUILD_PAIR(N); break;
> +  case ISD::BIT_CONVERT: Result = PromoteResult_BIT_CONVERT(N);  
> break;
>
>   case ISD::AND:
>   case ISD::OR:
> @@ -74,8 +75,12 @@
>   case ISD::CTLZ:     Result = PromoteResult_CTLZ(N); break;
>   case ISD::CTPOP:    Result = PromoteResult_CTPOP(N); break;
>   case ISD::CTTZ:     Result = PromoteResult_CTTZ(N); break;
> +
> +  case ISD::EXTRACT_VECTOR_ELT:
> +    Result = PromoteResult_EXTRACT_VECTOR_ELT(N);
> +    break;
>   }
> -
> +
>   // If Result is null, the sub-method took care of registering the  
> result.
>   if (Result.Val)
>     SetPromotedOp(SDOperand(N, ResNo), Result);
> @@ -214,6 +219,65 @@
>   return DAG.getNode(ISD::OR, NVT, Lo, Hi);
> }
>
> +SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) {
> +  SDOperand InOp = N->getOperand(0);
> +  MVT::ValueType InVT = InOp.getValueType();
> +  MVT::ValueType NInVT = TLI.getTypeToTransformTo(InVT);
> +  MVT::ValueType OutVT = TLI.getTypeToTransformTo(N- 
> >getValueType(0));
> +
> +  switch (getTypeAction(InVT)) {
> +  default:
> +    assert(false && "Unknown type action!");
> +    break;
> +  case Legal:
> +    break;
> +  case Promote:
> +    if (MVT::getSizeInBits(OutVT) == MVT::getSizeInBits(NInVT))
> +      // The input promotes to the same size.  Convert the promoted  
> value.
> +      return DAG.getNode(ISD::BIT_CONVERT, OutVT,  
> GetPromotedOp(InOp));
> +    break;
> +  case Expand:
> +    break;
> +  case Scalarize:
> +    // Convert the element to an integer and promote it by hand.
> +    InOp = DAG.getNode(ISD::BIT_CONVERT,
> +                       MVT::getIntegerType(MVT::getSizeInBits(InVT)),
> +                       GetScalarizedOp(InOp));
> +    InOp = DAG.getNode(ISD::ANY_EXTEND,
> +                        
> MVT::getIntegerType(MVT::getSizeInBits(OutVT)), InOp);
> +    return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
> +  case Split:
> +    // For example, i32 = BIT_CONVERT v2i16 on alpha.  Convert the  
> split
> +    // pieces of the input into integers and reassemble in the  
> final type.
> +    SDOperand Lo, Hi;
> +    GetSplitOp(N->getOperand(0), Lo, Hi);
> +
> +    unsigned LoBits = MVT::getSizeInBits(Lo.getValueType());
> +    Lo = DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerType(LoBits),  
> Lo);
> +
> +    unsigned HiBits = MVT::getSizeInBits(Hi.getValueType());
> +    Hi = DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerType(HiBits),  
> Hi);
> +
> +    if (TLI.isBigEndian())
> +      std::swap(Lo, Hi);
> +
> +    MVT::ValueType TargetTy =  
> MVT::getIntegerType(MVT::getSizeInBits(OutVT));
> +    Hi = DAG.getNode(ISD::ANY_EXTEND, TargetTy, Hi);
> +    Hi = DAG.getNode(ISD::SHL, TargetTy, Hi,
> +                      
> DAG.getConstant(MVT::getSizeInBits(Lo.getValueType()),
> +                                     TLI.getShiftAmountTy()));
> +    Lo = DAG.getNode(ISD::ZERO_EXTEND, TargetTy, Lo);
> +
> +    return DAG.getNode(ISD::BIT_CONVERT, OutVT,
> +                       DAG.getNode(ISD::OR, TargetTy, Lo, Hi));
> +  }
> +
> +  // Otherwise, lower the bit-convert to a store/load from the  
> stack, then
> +  // promote the load.
> +  SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
> +  return PromoteResult_LOAD(cast<LoadSDNode>(Op.Val));
> +}
> +
> SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) {
>   // The input may have strange things in the top bits of the  
> registers, but
>   // these operations don't care.  They may have weird bits going  
> out, but
> @@ -315,6 +379,51 @@
>   return DAG.getNode(ISD::CTTZ, NVT, Op);
> }
>
> +SDOperand DAGTypeLegalizer::PromoteResult_EXTRACT_VECTOR_ELT(SDNode  
> *N) {
> +  MVT::ValueType OldVT = N->getValueType(0);
> +  SDOperand OldVec = N->getOperand(0);
> +  unsigned OldElts =  
> MVT::getVectorNumElements(OldVec.getValueType());
> +
> +  if (OldElts == 1) {
> +    assert(!isTypeLegal(OldVec.getValueType()) &&
> +           "Legal one-element vector of a type needing promotion!");
> +    // It is tempting to follow GetScalarizedOp by a call to  
> GetPromotedOp,
> +    // but this would be wrong because the scalarized value may not  
> yet have
> +    // been processed.
> +    return DAG.getNode(ISD::ANY_EXTEND,  
> TLI.getTypeToTransformTo(OldVT),
> +                       GetScalarizedOp(OldVec));
> +  }
> +
> +  // Convert to a vector half as long with an element type of twice  
> the width,
> +  // for example <4 x i16> -> <2 x i32>.
> +  assert(!(OldElts & 1) && "Odd length vectors not supported!");
> +  MVT::ValueType NewVT = MVT::getIntegerType(2 *  
> MVT::getSizeInBits(OldVT));
> +  assert(!MVT::isExtendedVT(OldVT) && !MVT::isExtendedVT(NewVT));
> +
> +  SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
> +                                 MVT::getVectorType(NewVT,  
> OldElts / 2),
> +                                 OldVec);
> +
> +  // Extract the element at OldIdx / 2 from the new vector.
> +  SDOperand OldIdx = N->getOperand(1);
> +  SDOperand NewIdx = DAG.getNode(ISD::SRL, OldIdx.getValueType(),  
> OldIdx,
> +                                 DAG.getConstant(1,  
> TLI.getShiftAmountTy()));
> +  SDOperand Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT,  
> NewVec, NewIdx);
> +
> +  // Select the appropriate half of the element: Lo if OldIdx was  
> even,
> +  // Hi if it was odd.
> +  SDOperand Lo = Elt;
> +  SDOperand Hi = DAG.getNode(ISD::SRL, NewVT, Elt,
> +                              
> DAG.getConstant(MVT::getSizeInBits(OldVT),
> +                                              
> TLI.getShiftAmountTy()));
> +  if (TLI.isBigEndian())
> +    std::swap(Lo, Hi);
> +
> +  SDOperand Odd = DAG.getNode(ISD::AND, OldIdx.getValueType(),  
> OldIdx,
> +                              DAG.getConstant(1,  
> TLI.getShiftAmountTy()));
> +  return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
> +}
> +
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> //  Operand Promotion
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ 
> LegalizeTypesScalarize.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp?rev=47672&r1=47671&r2=47672&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp  
> (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp  
> Wed Feb 27 07:34:40 2008
> @@ -176,6 +176,9 @@
>       assert(0 && "Do not know how to scalarize this operator's  
> operand!");
>       abort();
>
> +    case ISD::BIT_CONVERT:
> +      Res = ScalarizeOp_BIT_CONVERT(N); break;
> +
>     case ISD::EXTRACT_VECTOR_ELT:
>       Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
>
> @@ -204,6 +207,13 @@
>   return false;
> }
>
> +/// ScalarizeOp_BIT_CONVERT - If the value to convert is a vector  
> that needs
> +/// to be scalarized, it must be <1 x ty>.  Convert the element  
> instead.
> +SDOperand DAGTypeLegalizer::ScalarizeOp_BIT_CONVERT(SDNode *N) {
> +  SDOperand Elt = GetScalarizedOp(N->getOperand(0));
> +  return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
> +}
> +
> /// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that  
> needs to be
> /// scalarized, it must be <1 x ty>, so just return the element,  
> ignoring the
> /// index.
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=47672&r1=47671&r2=47672&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp  
> (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp Wed  
> Feb 27 07:34:40 2008
> @@ -172,7 +172,6 @@
>   else
>     Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi,  
> ScalarOp,
>                      DAG.getConstant(Index - LoNumElts,  
> TLI.getPointerTy()));
> -
> }
>
> void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
> @@ -253,22 +252,50 @@
>                                             SDOperand &Lo, SDOperand  
> &Hi) {
>   // We know the result is a vector.  The input may be either a  
> vector or a
>   // scalar value.
> +  MVT::ValueType LoVT, HiVT;
> +  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +
>   SDOperand InOp = N->getOperand(0);
> -  if (MVT::isVector(InOp.getValueType()) &&
> -      MVT::getVectorNumElements(InOp.getValueType()) != 1) {
> -    // If this is a vector, split the vector and convert each of  
> the pieces now.
> -    GetSplitOp(InOp, Lo, Hi);
> -
> -    MVT::ValueType LoVT, HiVT;
> -    GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  MVT::ValueType InVT = InOp.getValueType();
> +  MVT::ValueType NewInVT = TLI.getTypeToTransformTo(InVT);
>
> +  switch (getTypeAction(InVT)) {
> +  default:
> +    assert(false && "Unknown type action!");
> +  case Legal:
> +    break;
> +  case Promote:
> +    break;
> +  case Scalarize:
> +    // While it is tempting to extract the scalarized operand,  
> check whether it
> +    // needs expansion, and if so process it in the Expand case  
> below, there is
> +    // no guarantee that the scalarized operand has been processed  
> yet.  If it
> +    // hasn't then the call to GetExpandedOp will abort.  So just  
> give up.
> +    break;
> +  case Expand:
> +    // A scalar to vector conversion, where the scalar needs  
> expansion.
> +    // Check that the vector is being split in two.
> +    if (MVT::getSizeInBits(NewInVT) == MVT::getSizeInBits(LoVT)) {
> +      // Convert each expanded piece of the scalar now.
> +      GetExpandedOp(InOp, Lo, Hi);
> +      if (TLI.isBigEndian())
> +        std::swap(Lo, Hi);
> +      Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
> +      Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
> +      return;
> +    }
> +    break;
> +  case Split:
> +    // If the input is a vector that needs to be split, convert  
> each split
> +    // piece of the input now.
> +    GetSplitOp(InOp, Lo, Hi);
>     Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
>     Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
>     return;
>   }
> -
> +
>   // Lower the bit-convert to a store/load from the stack, then  
> split the load.
> -  SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N- 
> >getValueType(0));
> +  SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
>   SplitRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
> }
>
> @@ -340,8 +367,11 @@
>     case ISD::STORE: Res = SplitOp_STORE(cast<StoreSDNode>(N),  
> OpNo); break;
>     case ISD::RET:   Res = SplitOp_RET(N, OpNo); break;
>
> -    case ISD::EXTRACT_SUBVECTOR: Res =  
> SplitOp_EXTRACT_SUBVECTOR(N); break;
> -    case ISD::VECTOR_SHUFFLE:    Res = SplitOp_VECTOR_SHUFFLE(N,  
> OpNo); break;
> +    case ISD::BIT_CONVERT: Res = SplitOp_BIT_CONVERT(N); break;
> +
> +    case ISD::EXTRACT_VECTOR_ELT: Res =  
> SplitOp_EXTRACT_VECTOR_ELT(N); break;
> +    case ISD::EXTRACT_SUBVECTOR:  Res =  
> SplitOp_EXTRACT_SUBVECTOR(N); break;
> +    case ISD::VECTOR_SHUFFLE:     Res = SplitOp_VECTOR_SHUFFLE(N,  
> OpNo); break;
>     }
>   }
>
> @@ -402,6 +432,72 @@
>   return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign);
> }
>
> +SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) {
> +  // For example, i64 = BIT_CONVERT v4i16 on alpha.  Typically the  
> vector will
> +  // end up being split all the way down to individual components.   
> Convert the
> +  // split pieces into integers and reassemble.
> +  SDOperand Lo, Hi;
> +  GetSplitOp(N->getOperand(0), Lo, Hi);
> +
> +  unsigned LoBits = MVT::getSizeInBits(Lo.getValueType());
> +  Lo = DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerType(LoBits),  
> Lo);
> +
> +  unsigned HiBits = MVT::getSizeInBits(Hi.getValueType());
> +  Hi = DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerType(HiBits),  
> Hi);
> +
> +  if (TLI.isBigEndian())
> +    std::swap(Lo, Hi);
> +
> +  assert(LoBits == HiBits && "Do not know how to assemble odd sized  
> vectors!");
> +
> +  return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
> +                     DAG.getNode(ISD::BUILD_PAIR,
> +                                 MVT::getIntegerType(LoBits 
> +HiBits), Lo, Hi));
> +}
> +
> +SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) {
> +  SDOperand Vec = N->getOperand(0);
> +  SDOperand Idx = N->getOperand(1);
> +  MVT::ValueType VecVT = Vec.getValueType();
> +
> +  if (isa<ConstantSDNode>(Idx)) {
> +    uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getValue();
> +    assert(IdxVal < MVT::getVectorNumElements(VecVT) &&
> +           "Invalid vector index!");
> +
> +    SDOperand Lo, Hi;
> +    GetSplitOp(Vec, Lo, Hi);
> +
> +    uint64_t LoElts = MVT::getVectorNumElements(Lo.getValueType());
> +
> +    if (IdxVal < LoElts)
> +      return DAG.UpdateNodeOperands(SDOperand(N, 0), Lo, Idx);
> +    else
> +      return DAG.UpdateNodeOperands(SDOperand(N, 0), Hi,
> +                                    DAG.getConstant(IdxVal - LoElts,
> +                                                     
> Idx.getValueType()));
> +  }
> +
> +  // Store the vector to the stack and load back the required  
> element.
> +  SDOperand StackPtr = DAG.CreateStackTemporary(VecVT);
> +  SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr,  
> NULL, 0);
> +
> +  // Add the offset to the index.
> +  MVT::ValueType EltVT = MVT::getVectorElementType(VecVT);
> +  unsigned EltSize = MVT::getSizeInBits(EltVT)/8; // FIXME: should  
> be ABI size.
> +  Idx = DAG.getNode(ISD::MUL, Idx.getValueType(), Idx,
> +                    DAG.getConstant(EltSize, Idx.getValueType()));
> +
> +  if (MVT::getSizeInBits(Idx.getValueType()) >
> +      MVT::getSizeInBits(TLI.getPointerTy()))
> +    Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Idx);
> +  else
> +    Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
> +
> +  StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx,  
> StackPtr);
> +  return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0);
> +}
> +
> SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) {
>   // We know that the extracted result type is legal.  For now,  
> assume the index
>   // is a constant.
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list