diff options
Diffstat (limited to 'llvm/lib/Target')
| -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. |

