diff options
Diffstat (limited to 'llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp index 066b385ed91..dc04c541ba3 100644 --- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -42,6 +42,7 @@ #include "ARMBaseRegisterInfo.h" #include "ARMBasicBlockInfo.h" #include "ARMSubtarget.h" +#include "Thumb2InstrInfo.h" #include "llvm/ADT/SetOperations.h" #include "llvm/ADT/SmallSet.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -346,8 +347,11 @@ bool LowOverheadLoop::ValidateTailPredicate(MachineInstr *StartInsertPt, for (auto &Block : VPTBlocks) { if (Block.IsPredicatedOn(VCTP)) continue; - if (!Block.HasNonUniformPredicate() || !isVCTP(Block.getDivergent()->MI)) + if (!Block.HasNonUniformPredicate() || !isVCTP(Block.getDivergent()->MI)) { + LLVM_DEBUG(dbgs() << "ARM Loops: Found unsupported diverging predicate: " + << *Block.getDivergent()->MI); return false; + } SmallVectorImpl<PredicatedMI> &Insts = Block.getInsts(); for (auto &PredMI : Insts) { if (PredMI.Predicates.count(VCTP) || isVCTP(PredMI.MI)) @@ -390,8 +394,11 @@ bool LowOverheadLoop::ValidateTailPredicate(MachineInstr *StartInsertPt, InsertPt->removeFromParent(); InsertBB->insertAfter(MachineBasicBlock::iterator(ElemDef), InsertPt); LLVM_DEBUG(dbgs() << "ARM Loops: Moved start past: " << *ElemDef); - } else + } else { + LLVM_DEBUG(dbgs() << "ARM Loops: Unable to move element count to loop " + << "start instruction.\n"); return false; + } } } @@ -413,13 +420,17 @@ bool LowOverheadLoop::ValidateTailPredicate(MachineInstr *StartInsertPt, // First, find the block that looks like the preheader. MachineBasicBlock *MBB = MLI->findLoopPreheader(ML, true); - if (!MBB) + if (!MBB) { + LLVM_DEBUG(dbgs() << "ARM Loops: Didn't find preheader.\n"); return false; + } // Then search backwards for a def, until we get to InsertBB. while (MBB != InsertBB) { - if (CannotProvideElements(MBB, NumElements)) + if (CannotProvideElements(MBB, NumElements)) { + LLVM_DEBUG(dbgs() << "ARM Loops: Unable to provide element count.\n"); return false; + } MBB = *MBB->pred_begin(); } @@ -512,25 +523,10 @@ bool LowOverheadLoop::RecordVPTBlocks(MachineInstr* MI) { // which means we can't remove it unless there is another // instruction, such as vcmp, that can provide the VPR def. - unsigned VPROpNum = MI->getNumOperands() - 1; bool IsUse = false; - if (MI->getOperand(VPROpNum).isReg() && - MI->getOperand(VPROpNum).getReg() == ARM::VPR && - MI->getOperand(VPROpNum).isUse()) { - // If this instruction is predicated by VPR, it will be its last - // operand. Also check that it's only 'Then' predicated. - if (!MI->getOperand(VPROpNum-1).isImm() || - MI->getOperand(VPROpNum-1).getImm() != ARMVCC::Then) { - LLVM_DEBUG(dbgs() << "ARM Loops: Found unhandled predicate on: " - << *MI); - return false; - } - CurrentBlock->addInst(MI, CurrentPredicate); - IsUse = true; - } - bool IsDef = false; - for (unsigned i = 0; i < MI->getNumOperands() - 1; ++i) { + const MCInstrDesc &MCID = MI->getDesc(); + for (int i = MI->getNumOperands() - 1; i >= 0; --i) { const MachineOperand &MO = MI->getOperand(i); if (!MO.isReg() || MO.getReg() != ARM::VPR) continue; @@ -538,6 +534,9 @@ bool LowOverheadLoop::RecordVPTBlocks(MachineInstr* MI) { if (MO.isDef()) { CurrentPredicate.insert(MI); IsDef = true; + } else if (ARM::isVpred(MCID.OpInfo[i].OperandType)) { + CurrentBlock->addInst(MI, CurrentPredicate); + IsUse = true; } else { LLVM_DEBUG(dbgs() << "ARM Loops: Found instruction using vpr: " << *MI); return false; @@ -887,11 +886,13 @@ void ARMLowOverheadLoops::RemoveLoopUpdate(LowOverheadLoop &LoLoop) { void ARMLowOverheadLoops::ConvertVPTBlocks(LowOverheadLoop &LoLoop) { auto RemovePredicate = [](MachineInstr *MI) { LLVM_DEBUG(dbgs() << "ARM Loops: Removing predicate from: " << *MI); - unsigned OpNum = MI->getNumOperands() - 1; - assert(MI->getOperand(OpNum-1).getImm() == ARMVCC::Then && - "Expected Then predicate!"); - MI->getOperand(OpNum-1).setImm(ARMVCC::None); - MI->getOperand(OpNum).setReg(0); + if (int PIdx = llvm::findFirstVPTPredOperandIdx(*MI)) { + assert(MI->getOperand(PIdx).getImm() == ARMVCC::Then && + "Expected Then predicate!"); + MI->getOperand(PIdx).setImm(ARMVCC::None); + MI->getOperand(PIdx+1).setReg(0); + } else + llvm_unreachable("trying to unpredicate a non-predicated instruction"); }; // There are a few scenarios which we have to fix up: |