diff options
author | Brendon Cahoon <bcahoon@codeaurora.org> | 2015-05-14 20:36:19 +0000 |
---|---|---|
committer | Brendon Cahoon <bcahoon@codeaurora.org> | 2015-05-14 20:36:19 +0000 |
commit | 7c8a3b0ef6172a919d760a717d819069a4b55c71 (patch) | |
tree | a3f313a8929de4daa19764aef2629cfa0bb55b17 /llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp | |
parent | 7747762df9179aa021b52a381e170307ec078569 (diff) | |
download | bcm5719-llvm-7c8a3b0ef6172a919d760a717d819069a4b55c71.tar.gz bcm5719-llvm-7c8a3b0ef6172a919d760a717d819069a4b55c71.zip |
[Hexagon] Generate hardware loop for a vectorized loop
The induction variable in the vectorized loop wasn't
recognized properly, so a hardware loop wasn't generated.
Differential Revision: http://reviews.llvm.org/D9722
llvm-svn: 237388
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp index a4cd1f14a1b..db72899388e 100644 --- a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -1719,7 +1719,52 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { // compared against an immediate, we can fix it. const RegisterBump &RB = I->second; if (CmpRegs.count(RB.first)) { - if (!CmpImmOp) + if (!CmpImmOp) { + // If both operands to the compare instruction are registers, see if + // it can be changed to use induction register as one of the operands. + MachineInstr *IndI = nullptr; + MachineInstr *nonIndI = nullptr; + MachineOperand *IndMO = nullptr; + MachineOperand *nonIndMO = nullptr; + + for (unsigned i = 1, n = PredDef->getNumOperands(); i < n; ++i) { + MachineOperand &MO = PredDef->getOperand(i); + if (MO.isReg() && MO.getReg() == RB.first) { + DEBUG(dbgs() << "\n DefMI(" << i << ") = " + << *(MRI->getVRegDef(I->first))); + if (IndI) + return false; + + IndI = MRI->getVRegDef(I->first); + IndMO = &MO; + } else if (MO.isReg()) { + DEBUG(dbgs() << "\n DefMI(" << i << ") = " + << *(MRI->getVRegDef(MO.getReg()))); + if (nonIndI) + return false; + + nonIndI = MRI->getVRegDef(MO.getReg()); + nonIndMO = &MO; + } + } + if (IndI && nonIndI && + nonIndI->getOpcode() == Hexagon::A2_addi && + nonIndI->getOperand(2).isImm() && + nonIndI->getOperand(2).getImm() == - RB.second) { + bool Order = orderBumpCompare(IndI, PredDef); + if (Order) { + IndMO->setReg(I->first); + nonIndMO->setReg(nonIndI->getOperand(1).getReg()); + return true; + } + } + return false; + } + + // It is not valid to do this transformation on an unsigned comparison + // because it may underflow. + Comparison::Kind Cmp = getComparisonKind(PredDef->getOpcode(), 0, 0, 0); + if (!Cmp || Comparison::isUnsigned(Cmp)) return false; // If the register is being compared against an immediate, try changing @@ -1739,12 +1784,6 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { if (!isImmValidForOpcode(PredDef->getOpcode(), CmpImm)) return false; - // It is not valid to do this transformation on an unsigned comparison - // because it may underflow. - Comparison::Kind Cmp = getComparisonKind(PredDef->getOpcode(), 0, 0, 0); - if (!Cmp || Comparison::isUnsigned(Cmp)) - return false; - // Make sure that the compare happens after the bump. Otherwise, // after the fixup, the compare would use a yet-undefined register. MachineInstr *BumpI = MRI->getVRegDef(I->first); |