summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp53
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:
OpenPOWER on IntegriCloud