diff options
| author | David Green <david.green@arm.com> | 2019-04-23 12:11:26 +0000 | 
|---|---|---|
| committer | David Green <david.green@arm.com> | 2019-04-23 12:11:26 +0000 | 
| commit | c519d3c403986b5e91e68c3788f1485d8072392a (patch) | |
| tree | 131684255a416133d0ff5005b7014e2bac1ac014 /llvm/lib | |
| parent | 4eda12aea51ba0600c07d5fe1584607e286600bf (diff) | |
| download | bcm5719-llvm-c519d3c403986b5e91e68c3788f1485d8072392a.tar.gz bcm5719-llvm-c519d3c403986b5e91e68c3788f1485d8072392a.zip | |
[ARM] Update check for CBZ in Ifcvt
The check for creating CBZ in constant island pass recently obtained the
ability to search backwards to find a Cmp instruction. The code in IfCvt should
mirror this to allow more conversions to the smaller form. The common code has
been pulled out into a separate function to be shared between the two places.
Differential Revision: https://reviews.llvm.org/D60090
llvm-svn: 358977
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 58 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.h | 10 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMConstantIslandPass.cpp | 34 | 
3 files changed, 59 insertions, 43 deletions
| diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index 32c0cbde3cf..b55af47d7db 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1904,19 +1904,10 @@ isProfitableToIfCvt(MachineBasicBlock &MBB,      if (!Pred->empty()) {        MachineInstr *LastMI = &*Pred->rbegin();        if (LastMI->getOpcode() == ARM::t2Bcc) { -        MachineBasicBlock::iterator CmpMI = LastMI; -        if (CmpMI != Pred->begin()) { -          --CmpMI; -          if (CmpMI->getOpcode() == ARM::tCMPi8 || -              CmpMI->getOpcode() == ARM::t2CMPri) { -            unsigned Reg = CmpMI->getOperand(0).getReg(); -            unsigned PredReg = 0; -            ARMCC::CondCodes P = getInstrPredicate(*CmpMI, PredReg); -            if (P == ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 && -                isARMLowRegister(Reg)) -              return false; -          } -        } +        const TargetRegisterInfo *TRI = &getRegisterInfo(); +        MachineInstr *CmpMI = findCMPToFoldIntoCBZ(LastMI, TRI); +        if (CmpMI) +          return false;        }      }    } @@ -5211,3 +5202,44 @@ ARMBaseInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {        {MO_NONLAZY, "arm-nonlazy"}};    return makeArrayRef(TargetFlags);  } + +bool llvm::registerDefinedBetween(unsigned Reg, +                                  MachineBasicBlock::iterator From, +                                  MachineBasicBlock::iterator To, +                                  const TargetRegisterInfo *TRI) { +  for (auto I = From; I != To; ++I) +    if (I->modifiesRegister(Reg, TRI)) +      return true; +  return false; +} + +MachineInstr *llvm::findCMPToFoldIntoCBZ(MachineInstr *Br, +                                         const TargetRegisterInfo *TRI) { +  // Search backwards to the instruction that defines CSPR. This may or not +  // be a CMP, we check that after this loop. If we find another instruction +  // that reads cpsr, we return nullptr. +  MachineBasicBlock::iterator CmpMI = Br; +  while (CmpMI != Br->getParent()->begin()) { +    --CmpMI; +    if (CmpMI->modifiesRegister(ARM::CPSR, TRI)) +      break; +    if (CmpMI->readsRegister(ARM::CPSR, TRI)) +      break; +  } + +  // Check that this inst is a CMP r[0-7], #0 and that the register +  // is not redefined between the cmp and the br. +  if (CmpMI->getOpcode() != ARM::tCMPi8 && CmpMI->getOpcode() != ARM::t2CMPri) +    return nullptr; +  unsigned Reg = CmpMI->getOperand(0).getReg(); +  unsigned PredReg = 0; +  ARMCC::CondCodes Pred = getInstrPredicate(*CmpMI, PredReg); +  if (Pred != ARMCC::AL || CmpMI->getOperand(1).getImm() != 0) +    return nullptr; +  if (!isARMLowRegister(Reg)) +    return nullptr; +  if (registerDefinedBetween(Reg, CmpMI->getNextNode(), Br, TRI)) +    return nullptr; + +  return &*CmpMI; +} diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h index 24c11e43793..2a147448d9f 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -567,6 +567,16 @@ bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,                           unsigned FrameReg, int &Offset,                           const ARMBaseInstrInfo &TII); +/// Return true if Reg is defd between From and To +bool registerDefinedBetween(unsigned Reg, MachineBasicBlock::iterator From, +                            MachineBasicBlock::iterator To, +                            const TargetRegisterInfo *TRI); + +/// Search backwards from a tBcc to find a tCMPi8 against 0, meaning +/// we can convert them to a tCBZ or tCBNZ. Return nullptr if not found. +MachineInstr *findCMPToFoldIntoCBZ(MachineInstr *Br, +                                   const TargetRegisterInfo *TRI); +  } // end namespace llvm  #endif // LLVM_LIB_TARGET_ARM_ARMBASEINSTRINFO_H diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp index 382dc44ad03..508f41b459c 100644 --- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1838,16 +1838,6 @@ bool ARMConstantIslands::optimizeThumb2Instructions() {    return MadeChange;  } -static bool registerDefinedBetween(unsigned Reg, -                                   MachineBasicBlock::iterator From, -                                   MachineBasicBlock::iterator To, -                                   const TargetRegisterInfo *TRI) { -  for (auto I = From; I != To; ++I) -    if (I->modifiesRegister(Reg, TRI)) -      return true; -  return false; -} -  bool ARMConstantIslands::optimizeThumb2Branches() {    bool MadeChange = false; @@ -1915,29 +1905,13 @@ bool ARMConstantIslands::optimizeThumb2Branches() {      if (BrOffset >= DestOffset || (DestOffset - BrOffset) > 126)        continue; -    // Search backwards to the instruction that defines CSPR. This may or not -    // be a CMP, we check that after this loop. If we find an instruction that -    // reads cpsr, we need to keep the original cmp. +    // Search backwards to find a tCMPi8      auto *TRI = STI->getRegisterInfo(); -    MachineBasicBlock::iterator CmpMI = Br.MI; -    while (CmpMI != Br.MI->getParent()->begin()) { -      --CmpMI; -      if (CmpMI->modifiesRegister(ARM::CPSR, TRI)) -        break; -      if (CmpMI->readsRegister(ARM::CPSR, TRI)) -        break; -    } - -    // Check that this inst is a CMP r[0-7], #0 and that the register -    // is not redefined between the cmp and the br. -    if (CmpMI->getOpcode() != ARM::tCMPi8) +    MachineInstr *CmpMI = findCMPToFoldIntoCBZ(Br.MI, TRI); +    if (!CmpMI || CmpMI->getOpcode() != ARM::tCMPi8)        continue; +      unsigned Reg = CmpMI->getOperand(0).getReg(); -    Pred = getInstrPredicate(*CmpMI, PredReg); -    if (Pred != ARMCC::AL || CmpMI->getOperand(1).getImm() != 0) -      continue; -    if (registerDefinedBetween(Reg, CmpMI->getNextNode(), Br.MI, TRI)) -      continue;      // Check for Kill flags on Reg. If they are present remove them and set kill      // on the new CBZ. | 

