[llvm-commits] [llvm] r113670 - in /llvm/trunk: include/llvm/Target/TargetInstrInfo.h lib/CodeGen/PeepholeOptimizer.cpp lib/Target/ARM/ARMBaseInstrInfo.cpp lib/Target/ARM/ARMBaseInstrInfo.h

Bill Wendling wendling at apple.com
Mon Sep 13 13:22:05 PDT 2010


On Sep 13, 2010, at 1:05 PM, Gabor Greif wrote:

>> Here's your patch from another email. My comments are in-line:
>> 
>> gabor at google8:~/llvm-build$ svn diff /home/gabor/llvm/lib/Target/ARM/
>> ARMBaseInstrInfo.cpp
>> Index: /home/gabor/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
>> ===================================================================
>> --- /home/gabor/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
>> (revision 113747)
>> +++ /home/gabor/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
>> (working copy)
>> @@ -1372,6 +1372,19 @@
>>    SrcReg = MI->getOperand(0).getReg();
>>    CmpValue = MI->getOperand(1).getImm();
>>    return true;
>> +  case ARM::TSTri: {
>> +      if (MI->getParent()->begin() ==
>> MachineBasicBlock::const_iterator(MI))
>> +        return false;
>> +      const MachineInstr *AND = llvm::prior(MI);
>> 
>> The AND doesn't have to be the immediately prior instruction. I could happen
>> further up in the BB just as long as there isn't an intervening instruction
>> which sets CPSR.
> 
> Yes, but the instruction selector tends to create sequences like this:
> 
>  rN = ...
>  rM = and rN, #mask
>  ... ; intervening instructions
>  tst rN, #mask
> 
> Note that both "and" and "tst" consume rN! But if we want to change
> the form of "and" to "andS" we have to find it. My first guess is to
> look immediately before the "tst". I may relax that (to, say 5
> predecessors), but do not want to risk a quadratic algorithm.
> 
The algorithm is only O(n), where n is the number of instructions in the basic block. But limiting it to 5 or so is probably not bad. My guess is that the back-end generates the AND directly before the TST in most cases.

>> +      if (AND->getOpcode() != ARM::ANDri)
>> +        return false;
>> +      if (MI->getOperand(0).getReg() == AND->getOperand(1).getReg() && //
>> FIXME: or == AND
>> +          MI->getOperand(1).getImm() == AND->getOperand(2).getImm()) {//
>> FIXME: subset
>> +        SrcReg = AND->getOperand(0).getReg();
>> +        CmpValue = 0;
>> 
>> CmpValue might not be 0 here.
> 
> Whatever the mask is, the comparison is always against zero for the
> TSTri opcode. I hope I am not terribly mistaken with this statement
> :-)
> 
The CmpValue here means the mask value in this case. The terminology is messing us up.

>> 
>> +        return true;
>> +      }
>> +    }
>> 
>> There's no need for this to be as complex here. The logic should be pretty
>> much identical to the CMP cases. In fact, I think it is identical when you
>> have a TST of an immediate. This logic should reside in
> 
> I only attempt to cover the TSTri case. I do *not* think it is just as
> easy as "CMPri", because of the search for a suitable ANDri
> instruction that feeds from the same input
> and uses the same (super-) mask. Only in this case the "andS" will be
> equivalent.
> 
But that logic should still reside in the OptimizeCompareInstr method. It will have to be modified some, but it's not complex.

>>  case ARM::SUBri:
>>  case ARM::t2ADDri:
>>  case ARM::t2SUBri:
>> 
>> To do the optimization you suggest should be almost as easy as simply adding
>> the TST* cases to the switch statements and removing the "if (CmpValue != 0)
>> return false;" from OptimizeCompareInstr. :-)
> 
> Are you talking about TSTrr and TSTrs here?
> 
TST against the immediate.

-bw





More information about the llvm-commits mailing list