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