On Feb 12, 2008, at 10:50 PM, Chris Lattner wrote:

> On Feb 12, 2008, at 4:35 PM, Dan Gohman wrote:
>>
>> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Tue Feb 12
>> 18:35:47 2008
>> @@ -556,6 +556,12 @@
>>  /// bitsets.  This code only analyzes bits in Mask, in order to
>> short-circuit
>>  /// processing.  Targets can implement the
>> computeMaskedBitsForTargetNode
>>  /// method in the TargetLowering class to allow target nodes to be
>> understood.
>> +  void ComputeMaskedBits(SDOperand Op, APInt Mask, APInt &KnownZero,
>
> Please pass Mask by const reference (likewise to the virtual method).
> APInts are somewhat cheap to copy in the common case (no malloc) but
> they aren't free, and it would be better to make the copies explicit
> so they are only done when needed.

Ok.

>
>
>>  case ISD::SRL:
>>    // (ushr X, C1) & C2 == 0   iff  (-1 >> C1) & C2 == 0
> ..
>
>> +      APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);
>>      KnownZero |= HighBits;  // High bits known zero.
>
> How about:  KnownZero |= APInt::getHighBitsSet(BitWidth, ShAmt);

Ok.

>
>
>>  case ISD::SRA:
>>    if (ConstantSDNode *SA =
>> dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
>>      unsigned ShAmt = SA->getValue();
>>
>> +      APInt InDemandedMask = (Mask << ShAmt);
>>      // If any of the demanded bits are produced by the sign
>> extension, we also
>>      // demand the input sign bit.
>> +      APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);
>> +      if (!!(HighBits & Mask))
>> +        InDemandedMask |= APInt::getSignBit(BitWidth);
>
> Heh, this is clever, but non-obvious.  How about:
>
>   if ((HighBits & Mask) != 0)
>
> or:
>   if ((HighBits & Mask).getBoolValue())
>
> which is less tricky but more obvious.  There are a couple instances
> of similar !! things.

Those are "bang bang" operators, which are quite obvious once you're
used to the idiom :-).  I'll change them if you really don't like them.

>
>
> In fact, this occurs often enough that it might be worthwhile to avoid
> the construction of the temporary APInt.  How about defining a new
> method:
>
>   X.intersect(Y)
>
> to be true if any bits in X are also set in Y?  Aka (X&Y)!=0
>
>
>
>>      ComputeMaskedBits(Op.getOperand(0), InDemandedMask, KnownZero,
>> KnownOne,
>>                        Depth+1);
>>      assert((KnownZero & KnownOne) == 0 && "Bits known to be one
>> AND zero?");
>> +      KnownZero = KnownZero.lshr(ShAmt);
>> +      KnownOne  = KnownOne.lshr(ShAmt);
>>
>>      // Handle the sign bits.
>> +      APInt SignBit = APInt::getSignBit(BitWidth);
>> +      SignBit = SignBit.lshr(ShAmt);  // Adjust to where it is now
>> in the mask.
>
> It would be better to make an APInt with the bit in the right place
> instead of starting with a sign bit and shifting it.

I don't see a way to do this in a single step with the current APInt
API. And this doesn't seem common enough to want a
specialized API call.

>
>
>> @@ -1283,14 +1274,18 @@
>>
>>    // Sign extension.  Compute the demanded bits in the result that
>> are not
>>    // present in the input.
>> -    uint64_t NewBits = ~MVT::getIntVTBitMask(EVT) & Mask;
>> +    APInt NewBits = ~APInt::getLowBitsSet(BitWidth,
>> +                                          MVT::getSizeInBits(EVT))
>> & Mask;
>
> instead of using ~lowbits, how about using getHighBitsSet?

Ok.

>
>
>>    // If the sign extended bits are demanded, we know that the sign
>>    // bit is demanded.
>> +    InSignBit.zext(BitWidth);
>
> This is another "create sign and extend".  It would be better to just
> make the apint with the bit set in the right place.

See above.

>
>
>>  case ISD::LOAD: {
>>    if (ISD::isZEXTLoad(Op.Val)) {
>>      LoadSDNode *LD = cast<LoadSDNode>(Op);
>>      MVT::ValueType VT = LD->getMemoryVT();
>> -      KnownZero |= ~MVT::getIntVTBitMask(VT) & Mask;
>> +      KnownZero |= ~APInt::getLowBitsSet(BitWidth,
>> MVT::getSizeInBits(VT)) & Mask;
>
> Instead of ~lowbits, how about using highbits?  likewise in a couple
> other places.

Ok.

>
>
>>  case ISD::SIGN_EXTEND: {
>
>>    MVT::ValueType InVT = Op.getOperand(0).getValueType();
>> +    unsigned InBits = MVT::getSizeInBits(InVT);
>> +    APInt InMask    = APInt::getLowBitsSet(BitWidth, InBits);
>> +    APInt InSignBit = APInt::getSignBit(InBits);
>> +    APInt NewBits   = (~InMask) & Mask;
>>
>>    // If any of the sign extended bits are demanded, we know that
>> the sign
>>    // bit is demanded.
>> +    InSignBit.zext(BitWidth);
>> +    if (!!(NewBits & Mask))
>> +      Mask |= InSignBit;
>
> I think this is a bug: NewBits is defined to be "... & Mask".  This is
> either a bug or this can be replaced with "NewBits != 0" which doesn't
> seem right.

It's actually right, though the code is more involved than it needs to  
be.
I simplified this.

>
>
>> @@ -1402,11 +1415,11 @@
>>    // Output known-0 bits are known if clear or set in both the low
>> clear bits
>>    // common to both LHS & RHS.  For example, 8+(X<<3) is known to
>> have the
>>    // low 3 bits clear.
>> -    uint64_t KnownZeroOut =
>> std::min(CountTrailingZeros_64(~KnownZero),
>> -
>> CountTrailingZeros_64(~KnownZero2));
>> +    unsigned KnownZeroOut =
>> std::min((~KnownZero).countTrailingZeros(),
>> +
>> (~KnownZero2).countTrailingZeros());
>
> Huh, apint has a countLeadingOnes() but no countTrailingOnes().  If it
> did, you could use it instead of ~'ing the apint. :)

Ok, it does now.

>
>
>> @@ -1416,21 +1429,23 @@
>>    // We know that the top bits of C-X are clear if X contains less
>> bits
>>    // than C (i.e. no wrap-around can happen).  For example, 20-X is
>>    // positive if we can prove that X is >= 0 and < 16.
>> +
>> +    // sign bit clear
>> +    if (!(CLHS->getAPIntValue() & APInt::getSignBit(BitWidth))) {
>
> How about: CLHS->getAPIntValue()[BitWidth-1] != 0
>
> it would be even nicer to add an APInt::getSignBit() non-static method
> that returned the signbit directly as a bool.

Such a method already existed, but was erroneously named isPositve. I've
fixed that now.

>
>
> Incidentally, I think that this method:
>
>  SDOperand SelectionDAG::getConstant(const APInt &Val, MVT::ValueType
> VT, bool isTarget = false);
>
> Can be simplified to:
>
>  SDOperand SelectionDAG::getConstant(const APInt &Val, bool isTarget
> = false);
>
> And have it infer the MVT from the width of the APInt.  We can add a
> new (explicit) method to handle the vector case.

In the interest of keeping client code simpler, I'd prefer to avoid  
having
a separate vector version.

Dan

_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to