diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-04-12 17:37:20 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-04-12 17:37:20 +0000 | 
| commit | 74cf9ff761bcb8755af8c08d9ab0ec62ba33195d (patch) | |
| tree | 238a68a2a2729e7306d3d8645a72392df9b96a37 /llvm/lib/Target/PowerPC | |
| parent | 21d74e7287a90440825f0f8e330fb50fe7c1c60e (diff) | |
| download | bcm5719-llvm-74cf9ff761bcb8755af8c08d9ab0ec62ba33195d.tar.gz bcm5719-llvm-74cf9ff761bcb8755af8c08d9ab0ec62ba33195d.zip | |
Rename get_VSPLI_elt -> get_VSPLTI_elt
Canonicalize BUILD_VECTOR's that match VSPLTI's into a single type for each
form, eliminating a bunch of Pat patterns in the .td file and allowing us to
CSE stuff more aggressively.  This implements
PowerPC/buildvec_canonicalize.ll:VSPLTI
llvm-svn: 27614
Diffstat (limited to 'llvm/lib/Target/PowerPC')
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 35 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.h | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrAltivec.td | 33 | 
3 files changed, 40 insertions, 32 deletions
| diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 5a33d6ab7f6..80f9cc053bd 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -429,11 +429,11 @@ unsigned PPC::getVSPLTImmediate(SDNode *N, unsigned EltSize) {    return cast<ConstantSDNode>(N->getOperand(0))->getValue() / EltSize;  } -/// get_VSPLI_elt - If this is a build_vector of constants which can be formed +/// get_VSPLTI_elt - If this is a build_vector of constants which can be formed  /// by using a vspltis[bhw] instruction of the specified element size, return  /// the constant being splatted.  The ByteSize field indicates the number of  /// bytes of each element [124] -> [bhw]. -SDOperand PPC::get_VSPLI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) { +SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {    SDOperand OpVal(0, 0);    // If ByteSize of the splat is bigger than the element size of the @@ -920,7 +920,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {      // Load it out.      return DAG.getLoad(Op.getValueType(), Store, FIdx, DAG.getSrcValue(NULL));    } -  case ISD::BUILD_VECTOR: +  case ISD::BUILD_VECTOR: {      // If this is a case we can't handle, return null and let the default      // expansion code take care of it.  If we CAN select this case, return Op. @@ -937,13 +937,34 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {        return Op;      } -    if (PPC::get_VSPLI_elt(Op.Val, 1, DAG).Val ||    // vspltisb -        PPC::get_VSPLI_elt(Op.Val, 2, DAG).Val ||    // vspltish -        PPC::get_VSPLI_elt(Op.Val, 4, DAG).Val)      // vspltisw +    // Check to see if this is something we can use VSPLTI* to form. +    MVT::ValueType CanonicalVT = MVT::Other; +    SDNode *CST = 0; +     +    if ((CST = PPC::get_VSPLTI_elt(Op.Val, 4, DAG).Val))       // vspltisw +      CanonicalVT = MVT::v4i32; +    else if ((CST = PPC::get_VSPLTI_elt(Op.Val, 2, DAG).Val))  // vspltish +      CanonicalVT = MVT::v8i16; +    else if ((CST = PPC::get_VSPLTI_elt(Op.Val, 1, DAG).Val))  // vspltisb +      CanonicalVT = MVT::v16i8; + +    // If this matches one of the vsplti* patterns, force it to the canonical +    // type for the pattern. +    if (CST) { +      if (Op.getValueType() != CanonicalVT) { +        // Convert the splatted element to the right element type. +        SDOperand Elt = DAG.getNode(ISD::TRUNCATE,  +                                    MVT::getVectorBaseType(CanonicalVT),  +                                    SDOperand(CST, 0)); +        std::vector<SDOperand> Ops(MVT::getVectorNumElements(CanonicalVT), Elt); +        SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT, Ops); +        Op = DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res); +      }        return Op; +    }      return SDOperand(); -     +  }    case ISD::VECTOR_SHUFFLE: {      SDOperand V1 = Op.getOperand(0);      SDOperand V2 = Op.getOperand(1); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h index 48f9e1aa428..e4304efe02a 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.h +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h @@ -131,11 +131,11 @@ namespace llvm {      /// specified isSplatShuffleMask VECTOR_SHUFFLE mask.      unsigned getVSPLTImmediate(SDNode *N, unsigned EltSize); -    /// get_VSPLI_elt - If this is a build_vector of constants which can be +    /// get_VSPLTI_elt - If this is a build_vector of constants which can be      /// formed by using a vspltis[bhw] instruction of the specified element      /// size, return the constant being splatted.  The ByteSize field indicates      /// the number of bytes of each element [124] -> [bhw]. -    SDOperand get_VSPLI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG); +    SDOperand get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG);    }    class PPCTargetLowering : public TargetLowering { diff --git a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td index 39304c876f5..9fdf4ee1251 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td +++ b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td @@ -111,26 +111,26 @@ def VSPLTW_shuffle_mask : PatLeaf<(build_vector), [{  // VSPLTISB_get_imm xform function: convert build_vector to VSPLTISB imm.  def VSPLTISB_get_imm : SDNodeXForm<build_vector, [{ -  return PPC::get_VSPLI_elt(N, 1, *CurDAG); +  return PPC::get_VSPLTI_elt(N, 1, *CurDAG);  }]>;  def vecspltisb : PatLeaf<(build_vector), [{ -  return PPC::get_VSPLI_elt(N, 1, *CurDAG).Val != 0; +  return PPC::get_VSPLTI_elt(N, 1, *CurDAG).Val != 0;  }], VSPLTISB_get_imm>;  // VSPLTISH_get_imm xform function: convert build_vector to VSPLTISH imm.  def VSPLTISH_get_imm : SDNodeXForm<build_vector, [{ -  return PPC::get_VSPLI_elt(N, 2, *CurDAG); +  return PPC::get_VSPLTI_elt(N, 2, *CurDAG);  }]>;  def vecspltish : PatLeaf<(build_vector), [{ -  return PPC::get_VSPLI_elt(N, 2, *CurDAG).Val != 0; +  return PPC::get_VSPLTI_elt(N, 2, *CurDAG).Val != 0;  }], VSPLTISH_get_imm>;  // VSPLTISW_get_imm xform function: convert build_vector to VSPLTISW imm.  def VSPLTISW_get_imm : SDNodeXForm<build_vector, [{ -  return PPC::get_VSPLI_elt(N, 4, *CurDAG); +  return PPC::get_VSPLTI_elt(N, 4, *CurDAG);  }]>;  def vecspltisw : PatLeaf<(build_vector), [{ -  return PPC::get_VSPLI_elt(N, 4, *CurDAG).Val != 0; +  return PPC::get_VSPLTI_elt(N, 4, *CurDAG).Val != 0;  }], VSPLTISW_get_imm>;  //===----------------------------------------------------------------------===// @@ -439,13 +439,13 @@ def VSRW   : VX1_Int< 644, "vsrw" , int_ppc_altivec_vsrw>;  def VSPLTISB : VXForm_3<780, (ops VRRC:$vD, s5imm:$SIMM),                         "vspltisb $vD, $SIMM", VecPerm, -                       [(set VRRC:$vD, (v4f32 vecspltisb:$SIMM))]>; +                       [(set VRRC:$vD, (v16i8 vecspltisb:$SIMM))]>;  def VSPLTISH : VXForm_3<844, (ops VRRC:$vD, s5imm:$SIMM),                         "vspltish $vD, $SIMM", VecPerm, -                       [(set VRRC:$vD, (v4f32 vecspltish:$SIMM))]>; +                       [(set VRRC:$vD, (v8i16 vecspltish:$SIMM))]>;  def VSPLTISW : VXForm_3<908, (ops VRRC:$vD, s5imm:$SIMM),                         "vspltisw $vD, $SIMM", VecPerm, -                       [(set VRRC:$vD, (v4f32 vecspltisw:$SIMM))]>; +                       [(set VRRC:$vD, (v4i32 vecspltisw:$SIMM))]>;  // Vector Pack.  def VPKPX   : VX1_Int<782, "vpkpx", int_ppc_altivec_vpkpx>; @@ -540,7 +540,7 @@ def : Pat<(int_ppc_altivec_dstst GPRC:$rA, GPRC:$rB, imm:$STRM),  def : Pat<(int_ppc_altivec_dststt GPRC:$rA, GPRC:$rB, imm:$STRM),            (DSTST 1, imm:$STRM, GPRC:$rA, GPRC:$rB)>; -// Undef/Zero. +// Undef.  def : Pat<(v16i8 (undef)), (v16i8 (IMPLICIT_DEF_VRRC))>;  def : Pat<(v8i16 (undef)), (v8i16 (IMPLICIT_DEF_VRRC))>;  def : Pat<(v4i32 (undef)), (v4i32 (IMPLICIT_DEF_VRRC))>; @@ -602,19 +602,6 @@ def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHH_unary_shuffle_mask:$in),  def:Pat<(vector_shuffle (v16i8 VRRC:$vA), undef, VMRGHW_unary_shuffle_mask:$in),          (VMRGHW VRRC:$vA, VRRC:$vA)>; -// Immediate vector formation with vsplti*. -def : Pat<(v16i8 vecspltisb:$invec), (v16i8 (VSPLTISB vecspltisb:$invec))>; -def : Pat<(v16i8 vecspltish:$invec), (v16i8 (VSPLTISH vecspltish:$invec))>; -def : Pat<(v16i8 vecspltisw:$invec), (v16i8 (VSPLTISW vecspltisw:$invec))>; - -def : Pat<(v8i16 vecspltisb:$invec), (v8i16 (VSPLTISB vecspltisb:$invec))>; -def : Pat<(v8i16 vecspltish:$invec), (v8i16 (VSPLTISH vecspltish:$invec))>; -def : Pat<(v8i16 vecspltisw:$invec), (v8i16 (VSPLTISW vecspltisw:$invec))>; - -def : Pat<(v4i32 vecspltisb:$invec), (v4i32 (VSPLTISB vecspltisb:$invec))>; -def : Pat<(v4i32 vecspltish:$invec), (v4i32 (VSPLTISH vecspltish:$invec))>; -def : Pat<(v4i32 vecspltisw:$invec), (v4i32 (VSPLTISW vecspltisw:$invec))>; -  // Logical Operations  def : Pat<(v16i8 (vnot VRRC:$vA)), (v16i8 (VNOR VRRC:$vA, VRRC:$vA))>;  def : Pat<(v8i16 (vnot VRRC:$vA)), (v8i16 (VNOR VRRC:$vA, VRRC:$vA))>; | 

