[llvm-commits] [llvm] r65747 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp

Tanya Lattner lattner at apple.com
Fri Mar 6 14:23:09 PST 2009


On Feb 28, 2009, at 5:13 PM, Bob Wilson wrote:

> Author: bwilson
> Date: Sat Feb 28 19:13:55 2009
> New Revision: 65747
>
> URL: http://llvm.org/viewvc/llvm-project?rev=65747&view=rev
> Log:
> Combine PPC's GetConstantBuildVectorBits and isConstantSplat  
> functions to a new
> method in a BuildVectorSDNode "pseudo-class".
>
> Modified:
>    llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
>    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
>    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=65747&r1=65746&r2=65747&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Sat Feb 28  
> 19:13:55 2009
> @@ -1929,6 +1929,24 @@
>   }
> };
>
> +/// BuildVectorSDNode - A "pseudo-class" with methods for operating  
> on
> +/// BUILD_VECTORs.
> +class BuildVectorSDNode : public SDNode {
> +public:
> +  /// isConstantSplat - check if this is a constant splat, and if  
> so, return
> +  /// the splat element value in SplatBits.  Any undefined bits in  
> that value
> +  /// are set to zero, and the corresponding bits in the SplatUndef  
> mask are
> +  /// set.  The SplatSize value is set to the splat element size in  
> bytes.
> +  /// HasAnyUndefs is set to true if any bits in the vector are  
> undefined.
> +  bool isConstantSplat(unsigned &SplatBits, unsigned &SplatUndef,
> +                       unsigned &SplatSize, bool &HasAnyUndefs);
> +
> +  static inline bool classof(const BuildVectorSDNode *) { return  
> true; }
> +  static inline bool classof(const SDNode *N) {
> +    return N->getOpcode() == ISD::BUILD_VECTOR;
> +  }
> +};
> +

Bob,

This is breaking the build when using gcc 3.4.6 because  
BuildVectorSDNode does not have a default constructor and neither does  
its parent SDNode. I added a default constructor to SDNode which fixes  
the build, but it is not the correct thing to do. I'm not familiar  
enough with this code to add the constructor to BuildVectorSDNode, can  
you do this and then revert 66280.

Thanks,
Tanya



>
> /// SrcValueSDNode - An SDNode that holds an arbitrary LLVM IR  
> Value. This is
> /// used when the SelectionDAG needs to make a simple reference to  
> something
> /// in the LLVM IR representation.
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=65747&r1=65746&r2=65747&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Feb 28  
> 19:13:55 2009
> @@ -5554,3 +5554,94 @@
>     return Val.MachineCPVal->getType();
>   return Val.ConstVal->getType();
> }
> +
> +// If this is a splat (repetition) of a value across the whole  
> vector, return
> +// the smallest size that splats it.  For example,  
> "0x01010101010101..." is a
> +// splat of 0x01, 0x0101, and 0x01010101.  We return SplatBits =  
> 0x01 and
> +// SplatSize = 1 byte.
> +bool BuildVectorSDNode::isConstantSplat(unsigned &SplatBits,
> +                                        unsigned &SplatUndef,
> +                                        unsigned &SplatSize,
> +                                        bool &HasAnyUndefs) {
> +  uint64_t Bits128[2];
> +  uint64_t Undef128[2];
> +
> +  // If this is a vector of constants or undefs, get the bits.  A  
> bit in
> +  // UndefBits is set if the corresponding element of the vector is  
> an
> +  // ISD::UNDEF value.  For undefs, the corresponding VectorBits  
> values are
> +  // zero.
> +
> +  // Start with zero'd results.
> +  Bits128[0] = Bits128[1] = Undef128[0] = Undef128[1] = 0;
> +
> +  unsigned EltBitSize = getOperand(0).getValueType().getSizeInBits();
> +  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
> +    SDValue OpVal = getOperand(i);
> +
> +    unsigned PartNo = i >= e/2;     // In the upper 128 bits?
> +    unsigned SlotNo = e/2 - (i & (e/2-1))-1;  // Which subpiece of  
> the uint64_t.
> +
> +    uint64_t EltBits = 0;
> +    if (OpVal.getOpcode() == ISD::UNDEF) {
> +      uint64_t EltUndefBits = ~0U >> (32-EltBitSize);
> +      Undef128[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
> +      continue;
> +    } else if (ConstantSDNode *CN =  
> dyn_cast<ConstantSDNode>(OpVal)) {
> +      EltBits = CN->getZExtValue() & (~0U >> (32-EltBitSize));
> +    } else if (ConstantFPSDNode *CN =  
> dyn_cast<ConstantFPSDNode>(OpVal)) {
> +      assert(CN->getValueType(0) == MVT::f32 &&
> +             "Only one legal FP vector type!");
> +      EltBits = FloatToBits(CN->getValueAPF().convertToFloat());
> +    } else {
> +      // Nonconstant element.
> +      return false;
> +    }
> +
> +    Bits128[PartNo] |= EltBits << (SlotNo*EltBitSize);
> +  }
> +
> +  // Don't let undefs prevent splats from matching.  See if the top  
> 64-bits are
> +  // the same as the lower 64-bits, ignoring undefs.
> +  if ((Bits128[0] & ~Undef128[1]) != (Bits128[1] & ~Undef128[0]))
> +    return false;  // Can't be a splat if two pieces don't match.
> +
> +  uint64_t Bits64  = Bits128[0] | Bits128[1];
> +  uint64_t Undef64 = Undef128[0] & Undef128[1];
> +
> +  // Check that the top 32-bits are the same as the lower 32-bits,  
> ignoring
> +  // undefs.
> +  if ((Bits64 & (~Undef64 >> 32)) != ((Bits64 >> 32) & ~Undef64))
> +    return false;  // Can't be a splat if two pieces don't match.
> +
> +  HasAnyUndefs = (Undef128[0] | Undef128[1]) != 0;
> +
> +  uint32_t Bits32  = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
> +  uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
> +
> +  // If the top 16-bits are different than the lower 16-bits,  
> ignoring
> +  // undefs, we have an i32 splat.
> +  if ((Bits32 & (~Undef32 >> 16)) != ((Bits32 >> 16) & ~Undef32)) {
> +    SplatBits = Bits32;
> +    SplatUndef = Undef32;
> +    SplatSize = 4;
> +    return true;
> +  }
> +
> +  uint16_t Bits16  = uint16_t(Bits32)  | uint16_t(Bits32 >> 16);
> +  uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
> +
> +  // If the top 8-bits are different than the lower 8-bits, ignoring
> +  // undefs, we have an i16 splat.
> +  if ((Bits16 & (uint16_t(~Undef16) >> 8)) != ((Bits16 >> 8) &  
> ~Undef16)) {
> +    SplatBits = Bits16;
> +    SplatUndef = Undef16;
> +    SplatSize = 2;
> +    return true;
> +  }
> +
> +  // Otherwise, we have an 8-bit splat.
> +  SplatBits  = uint8_t(Bits16)  | uint8_t(Bits16 >> 8);
> +  SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
> +  SplatSize = 1;
> +  return true;
> +}
>
> Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=65747&r1=65746&r2=65747&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Sat Feb 28  
> 19:13:55 2009
> @@ -3093,100 +3093,6 @@
> // Vector related lowering.
> //
>
> -// If this is a vector of constants or undefs, get the bits.  A bit  
> in
> -// UndefBits is set if the corresponding element of the vector is an
> -// ISD::UNDEF value.  For undefs, the corresponding VectorBits  
> values are
> -// zero.   Return true if this is not an array of constants, false  
> if it is.
> -//
> -static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t  
> VectorBits[2],
> -                                       uint64_t UndefBits[2]) {
> -  // Start with zero'd results.
> -  VectorBits[0] = VectorBits[1] = UndefBits[0] = UndefBits[1] = 0;
> -
> -  unsigned EltBitSize = BV- 
> >getOperand(0).getValueType().getSizeInBits();
> -  for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) {
> -    SDValue OpVal = BV->getOperand(i);
> -
> -    unsigned PartNo = i >= e/2;     // In the upper 128 bits?
> -    unsigned SlotNo = e/2 - (i & (e/2-1))-1;  // Which subpiece of  
> the uint64_t.
> -
> -    uint64_t EltBits = 0;
> -    if (OpVal.getOpcode() == ISD::UNDEF) {
> -      uint64_t EltUndefBits = ~0U >> (32-EltBitSize);
> -      UndefBits[PartNo] |= EltUndefBits << (SlotNo*EltBitSize);
> -      continue;
> -    } else if (ConstantSDNode *CN =  
> dyn_cast<ConstantSDNode>(OpVal)) {
> -      EltBits = CN->getZExtValue() & (~0U >> (32-EltBitSize));
> -    } else if (ConstantFPSDNode *CN =  
> dyn_cast<ConstantFPSDNode>(OpVal)) {
> -      assert(CN->getValueType(0) == MVT::f32 &&
> -             "Only one legal FP vector type!");
> -      EltBits = FloatToBits(CN->getValueAPF().convertToFloat());
> -    } else {
> -      // Nonconstant element.
> -      return true;
> -    }
> -
> -    VectorBits[PartNo] |= EltBits << (SlotNo*EltBitSize);
> -  }
> -
> -  //printf("%llx %llx  %llx %llx\n",
> -  //       VectorBits[0], VectorBits[1], UndefBits[0], UndefBits[1]);
> -  return false;
> -}
> -
> -// If this is a splat (repetition) of a value across the whole  
> vector, return
> -// the smallest size that splats it.  For example,  
> "0x01010101010101..." is a
> -// splat of 0x01, 0x0101, and 0x01010101.  We return SplatBits =  
> 0x01 and
> -// SplatSize = 1 byte.
> -static bool isConstantSplat(const uint64_t Bits128[2],
> -                            const uint64_t Undef128[2],
> -                            unsigned &SplatBits, unsigned  
> &SplatUndef,
> -                            unsigned &SplatSize) {
> -
> -  // Don't let undefs prevent splats from matching.  See if the top  
> 64-bits are
> -  // the same as the lower 64-bits, ignoring undefs.
> -  if ((Bits128[0] & ~Undef128[1]) != (Bits128[1] & ~Undef128[0]))
> -    return false;  // Can't be a splat if two pieces don't match.
> -
> -  uint64_t Bits64  = Bits128[0] | Bits128[1];
> -  uint64_t Undef64 = Undef128[0] & Undef128[1];
> -
> -  // Check that the top 32-bits are the same as the lower 32-bits,  
> ignoring
> -  // undefs.
> -  if ((Bits64 & (~Undef64 >> 32)) != ((Bits64 >> 32) & ~Undef64))
> -    return false;  // Can't be a splat if two pieces don't match.
> -
> -  uint32_t Bits32  = uint32_t(Bits64) | uint32_t(Bits64 >> 32);
> -  uint32_t Undef32 = uint32_t(Undef64) & uint32_t(Undef64 >> 32);
> -
> -  // If the top 16-bits are different than the lower 16-bits,  
> ignoring
> -  // undefs, we have an i32 splat.
> -  if ((Bits32 & (~Undef32 >> 16)) != ((Bits32 >> 16) & ~Undef32)) {
> -    SplatBits = Bits32;
> -    SplatUndef = Undef32;
> -    SplatSize = 4;
> -    return true;
> -  }
> -
> -  uint16_t Bits16  = uint16_t(Bits32)  | uint16_t(Bits32 >> 16);
> -  uint16_t Undef16 = uint16_t(Undef32) & uint16_t(Undef32 >> 16);
> -
> -  // If the top 8-bits are different than the lower 8-bits, ignoring
> -  // undefs, we have an i16 splat.
> -  if ((Bits16 & (uint16_t(~Undef16) >> 8)) != ((Bits16 >> 8) &  
> ~Undef16)) {
> -    SplatBits = Bits16;
> -    SplatUndef = Undef16;
> -    SplatSize = 2;
> -    return true;
> -  }
> -
> -  // Otherwise, we have an 8-bit splat.
> -  SplatBits  = uint8_t(Bits16)  | uint8_t(Bits16 >> 8);
> -  SplatUndef = uint8_t(Undef16) & uint8_t(Undef16 >> 8);
> -  SplatSize = 1;
> -  return true;
> -}
> -
> /// BuildSplatI - Build a canonical splati of Val with an element  
> size of
> /// SplatSize.  Cast the result to VT.
> static SDValue BuildSplatI(int Val, unsigned SplatSize, MVT VT,
> @@ -3256,25 +3162,18 @@
> // selects to a single instruction, return Op.  Otherwise, if we can  
> codegen
> // this case more efficiently than a constant pool load, lower it to  
> the
> // sequence of ops that should be used.
> -SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,
> -                                               SelectionDAG &DAG) {
> -  // If this is a vector of constants or undefs, get the bits.  A  
> bit in
> -  // UndefBits is set if the corresponding element of the vector is  
> an
> -  // ISD::UNDEF value.  For undefs, the corresponding VectorBits  
> values are
> -  // zero.
> -  uint64_t VectorBits[2];
> -  uint64_t UndefBits[2];
> +SDValue PPCTargetLowering::LowerBUILD_VECTOR(SDValue Op,  
> SelectionDAG &DAG) {
>   DebugLoc dl = Op.getDebugLoc();
> -  if (GetConstantBuildVectorBits(Op.getNode(), VectorBits,  
> UndefBits))
> -    return SDValue();   // Not a constant vector.
> +  BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(Op.getNode());
> +  assert(BVN != 0 && "Expected a BuildVectorSDNode in  
> LowerBUILD_VECTOR");
>
>   // If this is a splat (repetition) of a value across the whole  
> vector, return
>   // the smallest size that splats it.  For example,  
> "0x01010101010101..." is a
>   // splat of 0x01, 0x0101, and 0x01010101.  We return SplatBits =  
> 0x01 and
>   // SplatSize = 1 byte.
>   unsigned SplatBits, SplatUndef, SplatSize;
> -  if (isConstantSplat(VectorBits, UndefBits, SplatBits, SplatUndef,  
> SplatSize)){
> -    bool HasAnyUndefs = (UndefBits[0] | UndefBits[1]) != 0;
> +  bool HasAnyUndefs;
> +  if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatSize,  
> HasAnyUndefs)) {
>
>     // First, handle single instruction cases.
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20090306/b51576a6/attachment.html>


More information about the llvm-commits mailing list