[llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp

Chris Lattner lattner at cs.uiuc.edu
Sat May 6 02:27:25 PDT 2006



Changes in directory llvm/lib/Target:

TargetLowering.cpp updated: 1.56 -> 1.57
---
Log message:

Add some really really simple code for computing sign-bit propagation.

This will certainly be enhanced in the future.


---
Diffs of the changes:  (+95 -0)

 TargetLowering.cpp |   95 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 95 insertions(+)


Index: llvm/lib/Target/TargetLowering.cpp
diff -u llvm/lib/Target/TargetLowering.cpp:1.56 llvm/lib/Target/TargetLowering.cpp:1.57
--- llvm/lib/Target/TargetLowering.cpp:1.56	Fri May  5 19:11:52 2006
+++ llvm/lib/Target/TargetLowering.cpp	Sat May  6 04:27:13 2006
@@ -995,6 +995,101 @@
   KnownOne = 0;
 }
 
+/// ComputeNumSignBits - Return the number of times the sign bit of the
+/// register is replicated into the other bits.  We know that at least 1 bit
+/// is always equal to the sign bit (itself), but other cases can give us
+/// information.  For example, immediately after an "SRA X, 2", we know that
+/// the top 3 bits are all equal to each other, so we return 3.
+unsigned TargetLowering::ComputeNumSignBits(SDOperand Op, unsigned Depth) const{
+  MVT::ValueType VT = Op.getValueType();
+  assert(MVT::isInteger(VT) && "Invalid VT!");
+  unsigned VTBits = MVT::getSizeInBits(VT);
+  unsigned Tmp, Tmp2;
+  
+  if (Depth == 6)
+    return 1;  // Limit search depth.
+
+  switch (Op.getOpcode()) {
+  default: 
+    // Allow the target to implement this method for its nodes.
+    if (Op.getOpcode() >= ISD::BUILTIN_OP_END) {
+  case ISD::INTRINSIC_WO_CHAIN:
+  case ISD::INTRINSIC_W_CHAIN:
+  case ISD::INTRINSIC_VOID:
+      unsigned NumBits = ComputeNumSignBitsForTargetNode(Op, Depth);
+      if (NumBits > 1) return NumBits;
+    }
+    
+    // FIXME: Should use computemaskedbits to look at the top bits.
+    return 1;
+    
+  case ISD::AssertSext:
+    Tmp = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(1))->getVT());
+    return VTBits-Tmp+1;
+  case ISD::AssertZext:
+    Tmp = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(1))->getVT());
+    return VTBits-Tmp;
+
+  case ISD::SIGN_EXTEND_INREG:
+    // Max of the input and what this extends.
+    Tmp = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(1))->getVT());
+    Tmp = VTBits-Tmp+1;
+    
+    Tmp2 = ComputeNumSignBits(Op.getOperand(0), Depth+1);
+    return std::max(Tmp, Tmp2);
+
+  case ISD::SRA:
+    Tmp = ComputeNumSignBits(Op.getOperand(0), Depth+1);
+    // SRA X, C   -> adds C sign bits.
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
+      Tmp += C->getValue();
+      if (Tmp > VTBits) Tmp = VTBits;
+    }
+    return Tmp;
+    
+  case ISD::ADD:
+  case ISD::SUB:
+    // Add and sub can have at most one carry bit.  Thus we know that the output
+    // is, at worst, one more bit than the inputs.
+    Tmp = ComputeNumSignBits(Op.getOperand(0), Depth+1);
+    if (Tmp == 1) return 1;
+    Tmp2 = ComputeNumSignBits(Op.getOperand(1), Depth+1);
+    if (Tmp2 == 1) return 1;
+    return std::min(Tmp, Tmp2)-1;
+    
+  //case ISD::ZEXTLOAD:   // 16 bits known
+  //case ISD::SEXTLOAD:   // 17 bits known
+  //case ISD::Constant:
+  //case ISD::SIGN_EXTEND:
+  //
+  }
+  
+#if 0
+  // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or -1
+  if (N0.getOpcode() == ISD::SETCC &&
+      TLI.getSetCCResultContents() == 
+      TargetLowering::ZeroOrNegativeOneSetCCResult)
+    return N0;
+#endif
+}
+
+
+
+/// ComputeNumSignBitsForTargetNode - This method can be implemented by
+/// targets that want to expose additional information about sign bits to the
+/// DAG Combiner.
+unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDOperand Op,
+                                                         unsigned Depth) const {
+  assert((Op.getOpcode() >= ISD::BUILTIN_OP_END ||
+          Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
+          Op.getOpcode() == ISD::INTRINSIC_W_CHAIN ||
+          Op.getOpcode() == ISD::INTRINSIC_VOID) &&
+         "Should use ComputeNumSignBits if you don't know whether Op"
+         " is a target node!");
+  return 1;
+}
+
+
 SDOperand TargetLowering::
 PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
   // Default implementation: no optimization.






More information about the llvm-commits mailing list