[PATCH][DAG] Refactor vector splitting code in SelectionDAG

Tom Stellard tom at stellard.net
Mon Nov 18 18:35:46 PST 2013


On Sat, Nov 16, 2013 at 10:13:32PM -0800, Juergen Ributzka wrote:
> Simple refactor of the code. No functional change intended.
> 
> Cheers,
> Juergen
> 

Hi Juergen,

Thanks for working on this, I think it will be useful to have these
helper functions available in the SelectionDAG class.  This patch looks
OK to me except that you need to add the std:: prefix to all the calls to
the tie() function.

-Tom

> From bfa446543c38b801f0e9a5f92fab952e547e4c37 Mon Sep 17 00:00:00 2001
> From: Juergen Ributzka <juergen at apple.com>
> Date: Sat, 16 Nov 2013 22:03:19 -0800
> Subject: [PATCH 1/1] [DAG] Refactor vector splitting code in SelectionDAG.
> 
> ---
>  include/llvm/CodeGen/SelectionDAG.h               |  31 ++++++-
>  lib/CodeGen/SelectionDAG/LegalizeTypes.cpp        |  14 ---
>  lib/CodeGen/SelectionDAG/LegalizeTypes.h          |   4 -
>  lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp |  23 ++---
>  lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp  | 107 +++++++---------------
>  lib/CodeGen/SelectionDAG/SelectionDAG.cpp         |  38 +++++++-
>  lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp     |   3 +-
>  7 files changed, 102 insertions(+), 118 deletions(-)
> 
> diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
> index 9a9bb99..9bfa923 100644
> --- a/include/llvm/CodeGen/SelectionDAG.h
> +++ b/include/llvm/CodeGen/SelectionDAG.h
> @@ -170,6 +170,7 @@ class SelectionDAG {
>    const TargetMachine &TM;
>    const TargetSelectionDAGInfo &TSI;
>    const TargetTransformInfo *TTI;
> +  const TargetLowering *TLI;
>    MachineFunction *MF;
>    LLVMContext *Context;
>    CodeGenOpt::Level OptLevel;
> @@ -268,7 +269,8 @@ public:
>    /// init - Prepare this SelectionDAG to process code in the given
>    /// MachineFunction.
>    ///
> -  void init(MachineFunction &mf, const TargetTransformInfo *TTI);
> +  void init(MachineFunction &mf, const TargetTransformInfo *TTI,
> +            const TargetLowering *TLI);
>  
>    /// clear - Clear state and free memory necessary to make this
>    /// SelectionDAG ready to process a new block.
> @@ -277,9 +279,7 @@ public:
>  
>    MachineFunction &getMachineFunction() const { return *MF; }
>    const TargetMachine &getTarget() const { return TM; }
> -  const TargetLowering &getTargetLoweringInfo() const {
> -    return *TM.getTargetLowering();
> -  }
> +  const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
>    const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return TSI; }
>    const TargetTransformInfo *getTargetTransformInfo() const { return TTI; }
>    LLVMContext *getContext() const {return Context; }
> @@ -1130,6 +1130,29 @@ public:
>    /// it cannot be inferred.
>    unsigned InferPtrAlignment(SDValue Ptr) const;
>  
> +  /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
> +  /// which is split (or expanded) into two not necessarily identical pieces.
> +  std::pair<EVT, EVT> GetSplitDestVTs(const EVT &VT) const;
> +
> +  /// SplitVector - Split the vector with EXTRACT_SUBVECTOR using the provides
> +  /// VTs and return the low/high part.
> +  std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL,
> +                                          const EVT &LoVT, const EVT &HiVT);
> +
> +  /// SplitVector - Split the vector with EXTRACT_SUBVECTOR and return the
> +  /// low/high part.
> +  std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL) {
> +    EVT LoVT, HiVT;
> +    tie(LoVT, HiVT) = GetSplitDestVTs(N.getValueType());
> +    return SplitVector(N, DL, LoVT, HiVT);
> +  }
> +
> +  /// SplitVectorOperand - Split the node's operand with EXTRACT_SUBVECTOR and
> +  /// return the low/high part.
> +  std::pair<SDValue, SDValue> SplitVectorOperand(SDNode *N, unsigned OpNo) {
> +    return SplitVector(N->getOperand(OpNo), SDLoc(N));
> +  }
> +
>  private:
>    bool RemoveNodeFromCSEMaps(SDNode *N);
>    void AddModifiedNodeToCSEMaps(SDNode *N);
> diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
> index b078b08..fb79fa3 100644
> --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
> +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
> @@ -958,20 +958,6 @@ SDValue DAGTypeLegalizer::DisintegrateMERGE_VALUES(SDNode *N, unsigned ResNo) {
>    return SDValue(N->getOperand(ResNo));
>  }
>  
> -/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
> -/// which is split into two not necessarily identical pieces.
> -void DAGTypeLegalizer::GetSplitDestVTs(EVT InVT, EVT &LoVT, EVT &HiVT) {
> -  // Currently all types are split in half.
> -  if (!InVT.isVector()) {
> -    LoVT = HiVT = TLI.getTypeToTransformTo(*DAG.getContext(), InVT);
> -  } else {
> -    unsigned NumElements = InVT.getVectorNumElements();
> -    assert(!(NumElements & 1) && "Splitting vector, but not in half!");
> -    LoVT = HiVT = EVT::getVectorVT(*DAG.getContext(),
> -                                   InVT.getVectorElementType(), NumElements/2);
> -  }
> -}
> -
>  /// GetPairElements - Use ISD::EXTRACT_ELEMENT nodes to extract the low and
>  /// high parts of the given value.
>  void DAGTypeLegalizer::GetPairElements(SDValue Pair,
> diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
> index 05900d0..7a03f85 100644
> --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
> +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
> @@ -704,10 +704,6 @@ private:
>        GetExpandedFloat(Op, Lo, Hi);
>    }
>  
> -  /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
> -  /// which is split (or expanded) into two not necessarily identical pieces.
> -  void GetSplitDestVTs(EVT InVT, EVT &LoVT, EVT &HiVT);
> -
>    /// GetPairElements - Use ISD::EXTRACT_ELEMENT nodes to extract the low and
>    /// high parts of the given value.
>    void GetPairElements(SDValue Pair, SDValue &Lo, SDValue &Hi);
> diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
> index f1b06fc..0f2f38a 100644
> --- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
> +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
> @@ -77,13 +77,9 @@ void DAGTypeLegalizer::ExpandRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi) {
>      case TargetLowering::TypeWidenVector: {
>        assert(!(InVT.getVectorNumElements() & 1) && "Unsupported BITCAST");
>        InOp = GetWidenedVector(InOp);
> -      EVT InNVT = EVT::getVectorVT(*DAG.getContext(), InVT.getVectorElementType(),
> -                                   InVT.getVectorNumElements()/2);
> -      Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, InOp,
> -                       DAG.getConstant(0, TLI.getVectorIdxTy()));
> -      Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, InOp,
> -                       DAG.getConstant(InNVT.getVectorNumElements(),
> -                                       TLI.getVectorIdxTy()));
> +      EVT LoVT, HiVT;
> +      tie(LoVT, HiVT) = DAG.GetSplitDestVTs(InVT);
> +      tie(Lo, Hi) = DAG.SplitVector(InOp, dl, LoVT, HiVT);
>        if (TLI.isBigEndian())
>          std::swap(Lo, Hi);
>        Lo = DAG.getNode(ISD::BITCAST, dl, NOutVT, Lo);
> @@ -496,15 +492,8 @@ void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo,
>        assert(Cond.getValueType() == getSetCCResultType(N->getValueType(0)) &&
>               "Condition has not been prepared for split!");
>        GetSplitVector(Cond, CL, CH);
> -    } else {
> -      EVT ETy = Cond.getValueType().getVectorElementType();
> -      unsigned NumElements = Cond.getValueType().getVectorNumElements();
> -      EVT VCondTy = EVT::getVectorVT(*DAG.getContext(), ETy, NumElements / 2);
> -      CL = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VCondTy, Cond,
> -                       DAG.getConstant(0, TLI.getVectorIdxTy()));
> -      CH = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VCondTy, Cond,
> -                       DAG.getConstant(NumElements / 2, TLI.getVectorIdxTy()));
> -    }
> +    } else
> +      tie(CL, CH) = DAG.SplitVector(Cond, dl);
>    }
>  
>    Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), CL, LL, RL);
> @@ -526,7 +515,7 @@ void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo,
>  
>  void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) {
>    EVT LoVT, HiVT;
> -  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
>    Lo = DAG.getUNDEF(LoVT);
>    Hi = DAG.getUNDEF(HiVT);
>  }
> diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
> index a4e2fc4..294b81d 100644
> --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
> +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
> @@ -624,7 +624,7 @@ void DAGTypeLegalizer::SplitVecRes_BITCAST(SDNode *N, SDValue &Lo,
>    // We know the result is a vector.  The input may be either a vector or a
>    // scalar value.
>    EVT LoVT, HiVT;
> -  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
>    SDLoc dl(N);
>  
>    SDValue InOp = N->getOperand(0);
> @@ -679,7 +679,7 @@ void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo,
>                                                  SDValue &Hi) {
>    EVT LoVT, HiVT;
>    SDLoc dl(N);
> -  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
>    unsigned LoNumElts = LoVT.getVectorNumElements();
>    SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
>    Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, LoVT, &LoOps[0], LoOps.size());
> @@ -700,7 +700,7 @@ void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
>    }
>  
>    EVT LoVT, HiVT;
> -  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
>  
>    SmallVector<SDValue, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
>    Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, LoVT, &LoOps[0], LoOps.size());
> @@ -716,7 +716,7 @@ void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo,
>    SDLoc dl(N);
>  
>    EVT LoVT, HiVT;
> -  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
>  
>    Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx);
>    uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getZExtValue();
> @@ -740,7 +740,8 @@ void DAGTypeLegalizer::SplitVecRes_InregOp(SDNode *N, SDValue &Lo,
>    SDLoc dl(N);
>  
>    EVT LoVT, HiVT;
> -  GetSplitDestVTs(cast<VTSDNode>(N->getOperand(1))->getVT(), LoVT, HiVT);
> +  tie(LoVT, HiVT) =
> +    DAG.GetSplitDestVTs(cast<VTSDNode>(N->getOperand(1))->getVT());
>  
>    Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo,
>                     DAG.getValueType(LoVT));
> @@ -803,7 +804,7 @@ void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo,
>                                                      SDValue &Hi) {
>    EVT LoVT, HiVT;
>    SDLoc dl(N);
> -  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
>    Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LoVT, N->getOperand(0));
>    Hi = DAG.getUNDEF(HiVT);
>  }
> @@ -813,7 +814,7 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
>    assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!");
>    EVT LoVT, HiVT;
>    SDLoc dl(LD);
> -  GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(LD->getValueType(0));
>  
>    ISD::LoadExtType ExtType = LD->getExtensionType();
>    SDValue Ch = LD->getChain();
> @@ -827,7 +828,7 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo,
>    const MDNode *TBAAInfo = LD->getTBAAInfo();
>  
>    EVT LoMemVT, HiMemVT;
> -  GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT);
> +  tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
>  
>    Lo = DAG.getLoad(ISD::UNINDEXED, ExtType, LoVT, dl, Ch, Ptr, Offset,
>                     LD->getPointerInfo(), LoMemVT, isVolatile, isNonTemporal,
> @@ -858,24 +859,12 @@ void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi) {
>  
>    EVT LoVT, HiVT;
>    SDLoc DL(N);
> -  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
>  
>    // Split the input.
> -  EVT InVT = N->getOperand(0).getValueType();
>    SDValue LL, LH, RL, RH;
> -  EVT InNVT = EVT::getVectorVT(*DAG.getContext(), InVT.getVectorElementType(),
> -                               LoVT.getVectorNumElements());
> -  LL = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InNVT, N->getOperand(0),
> -                   DAG.getConstant(0, TLI.getVectorIdxTy()));
> -  LH = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InNVT, N->getOperand(0),
> -                   DAG.getConstant(InNVT.getVectorNumElements(),
> -                   TLI.getVectorIdxTy()));
> -
> -  RL = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InNVT, N->getOperand(1),
> -                   DAG.getConstant(0, TLI.getVectorIdxTy()));
> -  RH = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, InNVT, N->getOperand(1),
> -                   DAG.getConstant(InNVT.getVectorNumElements(),
> -                   TLI.getVectorIdxTy()));
> +  tie(LL, LH) = DAG.SplitVectorOperand(N, 0);
> +  tie(RL, RH) = DAG.SplitVectorOperand(N, 1);
>  
>    Lo = DAG.getNode(N->getOpcode(), DL, LoVT, LL, RL, N->getOperand(2));
>    Hi = DAG.getNode(N->getOpcode(), DL, HiVT, LH, RH, N->getOperand(2));
> @@ -886,22 +875,15 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo,
>    // Get the dest types - they may not match the input types, e.g. int_to_fp.
>    EVT LoVT, HiVT;
>    SDLoc dl(N);
> -  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
>  
>    // If the input also splits, handle it directly for a compile time speedup.
>    // Otherwise split it by hand.
>    EVT InVT = N->getOperand(0).getValueType();
> -  if (getTypeAction(InVT) == TargetLowering::TypeSplitVector) {
> +  if (getTypeAction(InVT) == TargetLowering::TypeSplitVector)
>      GetSplitVector(N->getOperand(0), Lo, Hi);
> -  } else {
> -    EVT InNVT = EVT::getVectorVT(*DAG.getContext(), InVT.getVectorElementType(),
> -                                 LoVT.getVectorNumElements());
> -    Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, N->getOperand(0),
> -                     DAG.getConstant(0, TLI.getVectorIdxTy()));
> -    Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, N->getOperand(0),
> -                     DAG.getConstant(InNVT.getVectorNumElements(),
> -                                     TLI.getVectorIdxTy()));
> -  }
> +  else
> +    tie(Lo, Hi) = DAG.SplitVectorOperand(N, 0);
>  
>    if (N->getOpcode() == ISD::FP_ROUND) {
>      Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo, N->getOperand(1));
> @@ -930,7 +912,7 @@ void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo,
>    EVT SrcVT = N->getOperand(0).getValueType();
>    EVT DestVT = N->getValueType(0);
>    EVT LoVT, HiVT;
> -  GetSplitDestVTs(DestVT, LoVT, HiVT);
> +  tie(LoVT, HiVT) = DAG.GetSplitDestVTs(DestVT);
>  
>    // We can do better than a generic split operation if the extend is doing
>    // more than just doubling the width of the elements and the following are
> @@ -956,7 +938,7 @@ void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo,
>      EVT SplitSrcVT =
>          EVT::getVectorVT(Ctx, SrcVT.getVectorElementType(), NumElements / 2);
>      EVT SplitLoVT, SplitHiVT;
> -    GetSplitDestVTs(NewSrcVT, SplitLoVT, SplitHiVT);
> +    tie(SplitLoVT, SplitHiVT) = DAG.GetSplitDestVTs(NewSrcVT);
>      if (TLI.isTypeLegal(SrcVT) && !TLI.isTypeLegal(SplitSrcVT) &&
>          TLI.isTypeLegal(NewSrcVT) && TLI.isTypeLegal(SplitLoVT)) {
>        DEBUG(dbgs() << "Split vector extend via incremental extend:";
> @@ -965,11 +947,7 @@ void DAGTypeLegalizer::SplitVecRes_ExtendOp(SDNode *N, SDValue &Lo,
>        SDValue NewSrc =
>            DAG.getNode(N->getOpcode(), dl, NewSrcVT, N->getOperand(0));
>        // Get the low and high halves of the new, extended one step, vector.
> -      Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SplitLoVT, NewSrc,
> -                       DAG.getConstant(0, TLI.getVectorIdxTy()));
> -      Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SplitHiVT, NewSrc,
> -                       DAG.getConstant(SplitLoVT.getVectorNumElements(),
> -                                       TLI.getVectorIdxTy()));
> +      tie(Lo, Hi) = DAG.SplitVector(NewSrc, dl);
>        // Extend those vector halves the rest of the way.
>        Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo);
>        Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi);
> @@ -1172,41 +1150,23 @@ SDValue DAGTypeLegalizer::SplitVecOp_VSELECT(SDNode *N, unsigned OpNo) {
>    SDValue Mask = N->getOperand(0);
>    SDValue Src0 = N->getOperand(1);
>    SDValue Src1 = N->getOperand(2);
> +  EVT Src0VT = Src0.getValueType();
>    SDLoc DL(N);
> -  EVT MaskVT = Mask.getValueType();
> -  assert(MaskVT.isVector() && "VSELECT without a vector mask?");
> +  assert(Mask.getValueType().isVector() && "VSELECT without a vector mask?");
>  
>    SDValue Lo, Hi;
>    GetSplitVector(N->getOperand(0), Lo, Hi);
>    assert(Lo.getValueType() == Hi.getValueType() &&
>           "Lo and Hi have differing types");
>  
> -  unsigned LoNumElts = Lo.getValueType().getVectorNumElements();
> -  unsigned HiNumElts = Hi.getValueType().getVectorNumElements();
> -  assert(LoNumElts == HiNumElts && "Asymmetric vector split?");
> -
> -  LLVMContext &Ctx = *DAG.getContext();
> -  SDValue Zero = DAG.getConstant(0, TLI.getVectorIdxTy());
> -  SDValue LoElts = DAG.getConstant(LoNumElts, TLI.getVectorIdxTy());
> -  EVT Src0VT = Src0.getValueType();
> -  EVT Src0EltTy = Src0VT.getVectorElementType();
> -  EVT MaskEltTy = MaskVT.getVectorElementType();
> -
> -  EVT LoOpVT = EVT::getVectorVT(Ctx, Src0EltTy, LoNumElts);
> -  EVT LoMaskVT = EVT::getVectorVT(Ctx, MaskEltTy, LoNumElts);
> -  EVT HiOpVT = EVT::getVectorVT(Ctx, Src0EltTy, HiNumElts);
> -  EVT HiMaskVT = EVT::getVectorVT(Ctx, MaskEltTy, HiNumElts);
> -
> -  SDValue LoOp0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LoOpVT, Src0, Zero);
> -  SDValue LoOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LoOpVT, Src1, Zero);
> -
> -  SDValue HiOp0 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HiOpVT, Src0, LoElts);
> -  SDValue HiOp1 = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HiOpVT, Src1, LoElts);
> +  EVT LoOpVT, HiOpVT;
> +  tie(LoOpVT, HiOpVT) = DAG.GetSplitDestVTs(Src0VT);
> +  assert(LoOpVT == HiOpVT && "Asymmetric vector split?");
>  
> -  SDValue LoMask =
> -    DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, LoMaskVT, Mask, Zero);
> -  SDValue HiMask =
> -    DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HiMaskVT, Mask, LoElts);
> +  SDValue LoOp0, HiOp0, LoOp1, HiOp1, LoMask, HiMask;
> +  tie(LoOp0, HiOp0) = DAG.SplitVector(Src0, DL);
> +  tie(LoOp1, HiOp1) = DAG.SplitVector(Src1, DL);
> +  tie(LoMask, HiMask) = DAG.SplitVector(Mask, DL);
>  
>    SDValue LoSelect =
>      DAG.getNode(ISD::VSELECT, DL, LoOpVT, LoMask, LoOp0, LoOp1);
> @@ -1321,7 +1281,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) {
>    GetSplitVector(N->getOperand(1), Lo, Hi);
>  
>    EVT LoMemVT, HiMemVT;
> -  GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT);
> +  tie(LoMemVT, HiMemVT) = DAG.GetSplitDestVTs(MemoryVT);
>  
>    unsigned IncrementSize = LoMemVT.getSizeInBits()/8;
>  
> @@ -1409,13 +1369,8 @@ SDValue DAGTypeLegalizer::SplitVecOp_TRUNCATE(SDNode *N) {
>    SDLoc DL(N);
>  
>    // Extract the halves of the input via extract_subvector.
> -  EVT SplitVT = EVT::getVectorVT(*DAG.getContext(),
> -                                 InVT.getVectorElementType(), NumElements/2);
> -  SDValue InLoVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, InVec,
> -                                DAG.getConstant(0, TLI.getVectorIdxTy()));
> -  SDValue InHiVec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, SplitVT, InVec,
> -                                DAG.getConstant(NumElements/2,
> -                                TLI.getVectorIdxTy()));
> +  SDValue InLoVec, InHiVec;
> +  tie(InLoVec, InHiVec) = DAG.SplitVector(InVec, DL);
>    // Truncate them to 1/2 the element size.
>    EVT HalfElementVT = EVT::getIntegerVT(*DAG.getContext(), InElementSize/2);
>    EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), HalfElementVT,
> diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> index 85e5494..80ca702 100644
> --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> @@ -869,7 +869,7 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
>  
>  // EntryNode could meaningfully have debug info if we can find it...
>  SelectionDAG::SelectionDAG(const TargetMachine &tm, CodeGenOpt::Level OL)
> -  : TM(tm), TSI(*tm.getSelectionDAGInfo()), TTI(0), OptLevel(OL),
> +  : TM(tm), TSI(*tm.getSelectionDAGInfo()), TTI(0), TLI(0), OptLevel(OL),
>      EntryNode(ISD::EntryToken, 0, DebugLoc(), getVTList(MVT::Other)),
>      Root(getEntryNode()), NewNodesMustHaveLegalTypes(false),
>      UpdateListeners(0) {
> @@ -877,9 +877,11 @@ SelectionDAG::SelectionDAG(const TargetMachine &tm, CodeGenOpt::Level OL)
>    DbgInfo = new SDDbgInfo();
>  }
>  
> -void SelectionDAG::init(MachineFunction &mf, const TargetTransformInfo *tti) {
> +void SelectionDAG::init(MachineFunction &mf, const TargetTransformInfo *tti,
> +                        const TargetLowering *tli) {
>    MF = &mf;
>    TTI = tti;
> +  TLI = tli;
>    Context = &mf.getFunction()->getContext();
>  }
>  
> @@ -6405,6 +6407,38 @@ unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const {
>    return 0;
>  }
>  
> +/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type
> +/// which is split (or expanded) into two not necessarily identical pieces.
> +std::pair<EVT, EVT> SelectionDAG::GetSplitDestVTs(const EVT &VT) const {
> +  // Currently all types are split in half.
> +  EVT LoVT, HiVT;
> +  if (!VT.isVector()) {
> +    LoVT = HiVT = TLI->getTypeToTransformTo(*getContext(), VT);
> +  } else {
> +    unsigned NumElements = VT.getVectorNumElements();
> +    assert(!(NumElements & 1) && "Splitting vector, but not in half!");
> +    LoVT = HiVT = EVT::getVectorVT(*getContext(), VT.getVectorElementType(),
> +                                   NumElements/2);
> +  }
> +  return std::make_pair(LoVT, HiVT);
> +}
> +
> +/// SplitVector - Split the vector with EXTRACT_SUBVECTOR and return the
> +/// low/high part.
> +std::pair<SDValue, SDValue>
> +SelectionDAG::SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT,
> +                          const EVT &HiVT) {
> +  assert(LoVT.getVectorNumElements() + HiVT.getVectorNumElements() <=
> +         N.getValueType().getVectorNumElements() &&
> +         "More vector elements requested than available!");
> +  SDValue Lo, Hi;
> +  Lo = getNode(ISD::EXTRACT_SUBVECTOR, DL, LoVT, N,
> +               getConstant(0, TLI->getVectorIdxTy()));
> +  Hi = getNode(ISD::EXTRACT_SUBVECTOR, DL, HiVT, N,
> +               getConstant(LoVT.getVectorNumElements(), TLI->getVectorIdxTy()));
> +  return std::make_pair(Lo, Hi);
> +}
> +
>  // getAddressSpace - Return the address space this GlobalAddress belongs to.
>  unsigned GlobalAddressSDNode::getAddressSpace() const {
>    return getGlobal()->getType()->getAddressSpace();
> diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> index 8bf8756..15f2ee2 100644
> --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
> @@ -356,6 +356,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
>    const Function &Fn = *mf.getFunction();
>    const TargetInstrInfo &TII = *TM.getInstrInfo();
>    const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
> +  const TargetLowering *TLI = TM.getTargetLowering();
>  
>    MF = &mf;
>    RegInfo = &MF->getRegInfo();
> @@ -373,7 +374,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
>  
>    SplitCriticalSideEffectEdges(const_cast<Function&>(Fn), this);
>  
> -  CurDAG->init(*MF, TTI);
> +  CurDAG->init(*MF, TTI, TLI);
>    FuncInfo->set(Fn, *MF);
>  
>    if (UseMBPI && OptLevel != CodeGenOpt::None)
> -- 
> 1.8.4.3
> 

> _______________________________________________
> 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