[llvm-commits] [llvm] r58825 - /llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Evan Cheng evan.cheng at apple.com
Thu Nov 6 18:07:17 PST 2008


On Nov 6, 2008, at 5:53 PM, Dale Johannesen wrote:

>
> On Nov 6, 2008, at 5:50 PMPST, Evan Cheng wrote:
>
>>
>> On Nov 6, 2008, at 5:28 PM, Dale Johannesen wrote:
>>
>>> Author: johannes
>>> Date: Thu Nov  6 19:28:02 2008
>>> New Revision: 58825
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=58825&view=rev
>>> Log:
>>> When we're doing a compare of load-AND-constant to 0
>>> (e.g. a bitfield test) narrow the load as much as possible.
>>> The has the potential to avoid unnecessary partial-word
>>> load-after-store conflicts, which cause stalls on several targets.
>>> Also a size win on x86 (testb vs testl).
>>
>> This can a loss if the load is narrowed to i16 though.
>
> Why?  testw is OK.

16-bit instructions are larger because of the 0x66 prefix.

>
>
>> Assuming we
>> have the checks in place, this is probably ok. But I still wonder if
>> this is the approach we ought to take. Perhaps we need to attack all
>> of the load-after-store issues?
>
> What did you have in mind?
> Let's see how this one works.

Perhaps a pass (or at least a more generic approach to look for load- 
after-store hazards). Just thinking out loud at this point. Perhaps  
someone will come up with a better idea.

Evan

>
>
>> Evan
>>
>>>
>>>
>>>
>>> Modified:
>>>  llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
>>>
>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=58825&r1=58824&r2=58825&view=diff
>>>
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> = 
>>> ====================================================================
>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp  
>>> (original)
>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Nov
>>> 6 19:28:02 2008
>>> @@ -1352,6 +1352,52 @@
>>>                             Zero, Cond);
>>>       }
>>>     }
>>> +
>>> +      // If the LHS is '(and load, const)', the RHS is 0,
>>> +      // the test is for equality or unsigned, and all 1 bits of
>>> the const are
>>> +      // in the same partial word, see if we can shorten the load.
>>> +      if (DCI.isBeforeLegalize() &&
>>> +          N0.getOpcode() == ISD::AND && C1 == 0 &&
>>> +          isa<LoadSDNode>(N0.getOperand(0)) &&
>>> +          N0.getOperand(0).getNode()->hasOneUse() &&
>>> +          isa<ConstantSDNode>(N0.getOperand(1))) {
>>> +        LoadSDNode *Lod = cast<LoadSDNode>(N0.getOperand(0));
>>> +        uint64_t Mask = cast<ConstantSDNode>(N0.getOperand(1))-
>>>> getZExtValue();
>>> +        unsigned bestWidth = 0, bestOffset = 0;
>>> +        if (!Lod->isVolatile()) {
>>> +          unsigned origWidth = N0.getValueType().getSizeInBits();
>>> +          for (unsigned width = origWidth / 2; width>=8; width /=
>>> 2) {
>>> +            uint64_t newMask = (1ULL << width) - 1;
>>> +            for (unsigned offset=0; offset<origWidth/width; offset+
>>> +) {
>>> +              if ((newMask & Mask)==Mask) {
>>> +                bestOffset = (uint64_t)offset * (width/8);
>>> +                bestWidth = width;
>>> +                break;
>>> +              }
>>> +              newMask = newMask << width;
>>> +            }
>>> +          }
>>> +        }
>>> +        if (bestWidth) {
>>> +          MVT newVT = MVT::getIntegerVT(bestWidth);
>>> +          if (newVT.isRound()) {
>>> +            uint64_t bestMask = Mask >> (bestOffset * 8);
>>> +            MVT PtrType = Lod->getOperand(1).getValueType();
>>> +            SDValue Ptr = Lod->getBasePtr();
>>> +            if (bestOffset != 0)
>>> +              Ptr = DAG.getNode(ISD::ADD, PtrType, Lod-
>>>> getBasePtr(),
>>> +                                DAG.getConstant(bestOffset,
>>> PtrType));
>>> +            unsigned NewAlign = MinAlign(Lod->getAlignment(),
>>> bestOffset);
>>> +            SDValue NewLoad = DAG.getLoad(newVT, Lod->getChain(),
>>> Ptr,
>>> +                                          Lod->getSrcValue(),
>>> +                                          Lod->getSrcValueOffset()
>>> + bestOffset,
>>> +                                          false, NewAlign);
>>> +            return DAG.getSetCC(VT, DAG.getNode(ISD::AND, newVT,
>>> NewLoad,
>>> +
>>> DAG.getConstant(bestMask, newVT)),
>>> +                                    DAG.getConstant(0LL, newVT),
>>> Cond);
>>> +          }
>>> +        }
>>> +      }
>>>
>>>     // If the LHS is a ZERO_EXTEND, perform the comparison on the
>>> input.
>>>     if (N0.getOpcode() == ISD::ZERO_EXTEND) {
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list