aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp')
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp205
1 files changed, 110 insertions, 95 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp
index e93f075f4ccd..ffa447cc1311 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonNewValueJump.cpp
@@ -1,4 +1,4 @@
-//===----- HexagonNewValueJump.cpp - Hexagon Backend New Value Jump -------===//
+//===- HexagonNewValueJump.cpp - Hexagon Backend New Value Jump -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -19,54 +19,60 @@
// all, it collapses compare and jump instruction into a new valu jump
// intstructions.
//
-//
//===----------------------------------------------------------------------===//
+
#include "Hexagon.h"
#include "HexagonInstrInfo.h"
-#include "HexagonMachineFunctionInfo.h"
#include "HexagonRegisterInfo.h"
-#include "HexagonSubtarget.h"
-#include "HexagonTargetMachine.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/LiveVariables.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/ScheduleDAGInstrs.h"
-#include "llvm/PassSupport.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+
using namespace llvm;
#define DEBUG_TYPE "hexagon-nvj"
STATISTIC(NumNVJGenerated, "Number of New Value Jump Instructions created");
-static cl::opt<int>
-DbgNVJCount("nvj-count", cl::init(-1), cl::Hidden, cl::desc(
- "Maximum number of predicated jumps to be converted to New Value Jump"));
+static cl::opt<int> DbgNVJCount("nvj-count", cl::init(-1), cl::Hidden,
+ cl::desc("Maximum number of predicated jumps to be converted to "
+ "New Value Jump"));
static cl::opt<bool> DisableNewValueJumps("disable-nvjump", cl::Hidden,
cl::ZeroOrMore, cl::init(false),
cl::desc("Disable New Value Jumps"));
namespace llvm {
- FunctionPass *createHexagonNewValueJump();
- void initializeHexagonNewValueJumpPass(PassRegistry&);
-}
+FunctionPass *createHexagonNewValueJump();
+void initializeHexagonNewValueJumpPass(PassRegistry&);
+
+} // end namespace llvm
namespace {
- struct HexagonNewValueJump : public MachineFunctionPass {
- const HexagonInstrInfo *QII;
- const HexagonRegisterInfo *QRI;
- public:
+ struct HexagonNewValueJump : public MachineFunctionPass {
static char ID;
HexagonNewValueJump() : MachineFunctionPass(ID) {}
@@ -79,19 +85,23 @@ namespace {
StringRef getPassName() const override { return "Hexagon NewValueJump"; }
bool runOnMachineFunction(MachineFunction &Fn) override;
+
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs);
}
private:
+ const HexagonInstrInfo *QII;
+ const HexagonRegisterInfo *QRI;
+
/// \brief A handle to the branch probability pass.
const MachineBranchProbabilityInfo *MBPI;
bool isNewValueJumpCandidate(const MachineInstr &MI) const;
};
-} // end of anonymous namespace
+} // end anonymous namespace
char HexagonNewValueJump::ID = 0;
@@ -101,7 +111,6 @@ INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
INITIALIZE_PASS_END(HexagonNewValueJump, "hexagon-nvj",
"Hexagon NewValueJump", false, false)
-
// We have identified this II could be feeder to NVJ,
// verify that it can be.
static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
@@ -110,7 +119,6 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
MachineBasicBlock::iterator end,
MachineBasicBlock::iterator skip,
MachineFunction &MF) {
-
// Predicated instruction can not be feeder to NVJ.
if (QII->isPredicated(*II))
return false;
@@ -121,9 +129,9 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
// using -- if (QRI->isSubRegister(feederReg, cmpReg1) logic
// before the callsite of this function
// But we can not as it comes in the following fashion.
- // %D0<def> = Hexagon_S2_lsr_r_p %D0<kill>, %R2<kill>
- // %R0<def> = KILL %R0, %D0<imp-use,kill>
- // %P0<def> = CMPEQri %R0<kill>, 0
+ // %d0 = Hexagon_S2_lsr_r_p killed %d0, killed %r2
+ // %r0 = KILL %r0, implicit killed %d0
+ // %p0 = CMPEQri killed %r0, 0
// Hence, we need to check if it's a KILL instruction.
if (II->getOpcode() == TargetOpcode::KILL)
return false;
@@ -131,6 +139,9 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
if (II->isImplicitDef())
return false;
+ if (QII->isSolo(*II))
+ return false;
+
// Make sure there there is no 'def' or 'use' of any of the uses of
// feeder insn between it's definition, this MI and jump, jmpInst
// skipping compare, cmpInst.
@@ -145,16 +156,16 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
// p0 = cmp.eq(r21, #0)
// if (p0.new) jump:t .LBB29_45
// and result WAR hazards if converted to New Value Jump.
-
for (unsigned i = 0; i < II->getNumOperands(); ++i) {
if (II->getOperand(i).isReg() &&
(II->getOperand(i).isUse() || II->getOperand(i).isDef())) {
MachineBasicBlock::iterator localII = II;
++localII;
unsigned Reg = II->getOperand(i).getReg();
- for (MachineBasicBlock::iterator localBegin = localII;
- localBegin != end; ++localBegin) {
- if (localBegin == skip ) continue;
+ for (MachineBasicBlock::iterator localBegin = localII; localBegin != end;
+ ++localBegin) {
+ if (localBegin == skip)
+ continue;
// Check for Subregisters too.
if (localBegin->modifiesRegister(Reg, TRI) ||
localBegin->readsRegister(Reg, TRI))
@@ -171,9 +182,8 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
// 2. feeder to the compare instruction can be moved before jump.
static bool commonChecksToProhibitNewValueJump(bool afterRA,
MachineBasicBlock::iterator MII) {
-
// If store in path, bail out.
- if (MII->getDesc().mayStore())
+ if (MII->mayStore())
return false;
// if call in path, bail out.
@@ -186,13 +196,13 @@ static bool commonChecksToProhibitNewValueJump(bool afterRA,
// to new value jump. If they are in the path, bail out.
// KILL sets kill flag on the opcode. It also sets up a
// single register, out of pair.
- // %D0<def> = S2_lsr_r_p %D0<kill>, %R2<kill>
- // %R0<def> = KILL %R0, %D0<imp-use,kill>
- // %P0<def> = C2_cmpeqi %R0<kill>, 0
+ // %d0 = S2_lsr_r_p killed %d0, killed %r2
+ // %r0 = KILL %r0, implicit killed %d0
+ // %p0 = C2_cmpeqi killed %r0, 0
// PHI can be anything after RA.
// COPY can remateriaze things in between feeder, compare and nvj.
if (MII->getOpcode() == TargetOpcode::KILL ||
- MII->getOpcode() == TargetOpcode::PHI ||
+ MII->getOpcode() == TargetOpcode::PHI ||
MII->getOpcode() == TargetOpcode::COPY)
return false;
@@ -216,21 +226,27 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
bool optLocation,
MachineBasicBlock::iterator end,
MachineFunction &MF) {
-
MachineInstr &MI = *II;
// If the second operand of the compare is an imm, make sure it's in the
// range specified by the arch.
if (!secondReg) {
- int64_t v = MI.getOperand(2).getImm();
+ const MachineOperand &Op2 = MI.getOperand(2);
+ if (!Op2.isImm())
+ return false;
+
+ int64_t v = Op2.getImm();
bool Valid = false;
switch (MI.getOpcode()) {
case Hexagon::C2_cmpeqi:
+ case Hexagon::C4_cmpneqi:
case Hexagon::C2_cmpgti:
+ case Hexagon::C4_cmpltei:
Valid = (isUInt<5>(v) || v == -1);
break;
case Hexagon::C2_cmpgtui:
+ case Hexagon::C4_cmplteui:
Valid = isUInt<5>(v);
break;
case Hexagon::S2_tstbit_i:
@@ -267,9 +283,8 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
// Walk the instructions after the compare (predicate def) to the jump,
// and satisfy the following conditions.
- ++II ;
- for (MachineBasicBlock::iterator localII = II; localII != end;
- ++localII) {
+ ++II;
+ for (MachineBasicBlock::iterator localII = II; localII != end; ++localII) {
if (localII->isDebugValue())
continue;
@@ -298,7 +313,6 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
return true;
}
-
// Given a compare operator, return a matching New Value Jump compare operator.
// Make sure that MI here is included in isNewValueJumpCandidate.
static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
@@ -319,41 +333,40 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
return taken ? Hexagon::J4_cmpeq_t_jumpnv_t
: Hexagon::J4_cmpeq_t_jumpnv_nt;
- case Hexagon::C2_cmpeqi: {
+ case Hexagon::C2_cmpeqi:
if (reg >= 0)
return taken ? Hexagon::J4_cmpeqi_t_jumpnv_t
: Hexagon::J4_cmpeqi_t_jumpnv_nt;
- else
- return taken ? Hexagon::J4_cmpeqn1_t_jumpnv_t
- : Hexagon::J4_cmpeqn1_t_jumpnv_nt;
- }
+ return taken ? Hexagon::J4_cmpeqn1_t_jumpnv_t
+ : Hexagon::J4_cmpeqn1_t_jumpnv_nt;
+
+ case Hexagon::C4_cmpneqi:
+ if (reg >= 0)
+ return taken ? Hexagon::J4_cmpeqi_f_jumpnv_t
+ : Hexagon::J4_cmpeqi_f_jumpnv_nt;
+ return taken ? Hexagon::J4_cmpeqn1_f_jumpnv_t :
+ Hexagon::J4_cmpeqn1_f_jumpnv_nt;
- case Hexagon::C2_cmpgt: {
+ case Hexagon::C2_cmpgt:
if (secondRegNewified)
return taken ? Hexagon::J4_cmplt_t_jumpnv_t
: Hexagon::J4_cmplt_t_jumpnv_nt;
- else
- return taken ? Hexagon::J4_cmpgt_t_jumpnv_t
- : Hexagon::J4_cmpgt_t_jumpnv_nt;
- }
+ return taken ? Hexagon::J4_cmpgt_t_jumpnv_t
+ : Hexagon::J4_cmpgt_t_jumpnv_nt;
- case Hexagon::C2_cmpgti: {
+ case Hexagon::C2_cmpgti:
if (reg >= 0)
return taken ? Hexagon::J4_cmpgti_t_jumpnv_t
: Hexagon::J4_cmpgti_t_jumpnv_nt;
- else
- return taken ? Hexagon::J4_cmpgtn1_t_jumpnv_t
- : Hexagon::J4_cmpgtn1_t_jumpnv_nt;
- }
+ return taken ? Hexagon::J4_cmpgtn1_t_jumpnv_t
+ : Hexagon::J4_cmpgtn1_t_jumpnv_nt;
- case Hexagon::C2_cmpgtu: {
+ case Hexagon::C2_cmpgtu:
if (secondRegNewified)
return taken ? Hexagon::J4_cmpltu_t_jumpnv_t
: Hexagon::J4_cmpltu_t_jumpnv_nt;
- else
- return taken ? Hexagon::J4_cmpgtu_t_jumpnv_t
- : Hexagon::J4_cmpgtu_t_jumpnv_nt;
- }
+ return taken ? Hexagon::J4_cmpgtu_t_jumpnv_t
+ : Hexagon::J4_cmpgtu_t_jumpnv_nt;
case Hexagon::C2_cmpgtui:
return taken ? Hexagon::J4_cmpgtui_t_jumpnv_t
@@ -377,6 +390,17 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
return taken ? Hexagon::J4_cmpgtu_f_jumpnv_t
: Hexagon::J4_cmpgtu_f_jumpnv_nt;
+ case Hexagon::C4_cmpltei:
+ if (reg >= 0)
+ return taken ? Hexagon::J4_cmpgti_f_jumpnv_t
+ : Hexagon::J4_cmpgti_f_jumpnv_nt;
+ return taken ? Hexagon::J4_cmpgtn1_f_jumpnv_t
+ : Hexagon::J4_cmpgtn1_f_jumpnv_nt;
+
+ case Hexagon::C4_cmplteui:
+ return taken ? Hexagon::J4_cmpgtui_f_jumpnv_t
+ : Hexagon::J4_cmpgtui_f_jumpnv_nt;
+
default:
llvm_unreachable("Could not find matching New Value Jump instruction.");
}
@@ -394,8 +418,11 @@ bool HexagonNewValueJump::isNewValueJumpCandidate(
case Hexagon::C2_cmpgtu:
case Hexagon::C2_cmpgtui:
case Hexagon::C4_cmpneq:
+ case Hexagon::C4_cmpneqi:
case Hexagon::C4_cmplte:
case Hexagon::C4_cmplteu:
+ case Hexagon::C4_cmpltei:
+ case Hexagon::C4_cmplteui:
return true;
default:
@@ -403,14 +430,11 @@ bool HexagonNewValueJump::isNewValueJumpCandidate(
}
}
-
bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
-
DEBUG(dbgs() << "********** Hexagon New Value Jump **********\n"
- << "********** Function: "
- << MF.getName() << "\n");
+ << "********** Function: " << MF.getName() << "\n");
- if (skipFunction(*MF.getFunction()))
+ if (skipFunction(MF.getFunction()))
return false;
// If we move NewValueJump before register allocation we'll need live variable
@@ -430,11 +454,10 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
// Loop through all the bb's of the function
for (MachineFunction::iterator MBBb = MF.begin(), MBBe = MF.end();
- MBBb != MBBe; ++MBBb) {
+ MBBb != MBBe; ++MBBb) {
MachineBasicBlock *MBB = &*MBBb;
- DEBUG(dbgs() << "** dumping bb ** "
- << MBB->getNumber() << "\n");
+ DEBUG(dbgs() << "** dumping bb ** " << MBB->getNumber() << "\n");
DEBUG(MBB->dump());
DEBUG(dbgs() << "\n" << "********** dumping instr bottom up **********\n");
bool foundJump = false;
@@ -452,7 +475,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
bool isSecondOpNewified = false;
// Traverse the basic block - bottom up
for (MachineBasicBlock::iterator MII = MBB->end(), E = MBB->begin();
- MII != E;) {
+ MII != E;) {
MachineInstr &MI = *--MII;
if (MI.isDebugValue()) {
continue;
@@ -495,11 +518,11 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
// at the BB level.
bool predLive = false;
for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
- SIE = MBB->succ_end(); SI != SIE; ++SI) {
- MachineBasicBlock* succMBB = *SI;
- if (succMBB->isLiveIn(predReg)) {
+ SIE = MBB->succ_end();
+ SI != SIE; ++SI) {
+ MachineBasicBlock *succMBB = *SI;
+ if (succMBB->isLiveIn(predReg))
predLive = true;
- }
}
if (predLive)
break;
@@ -524,10 +547,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
if (foundJump && !foundCompare && MI.getOperand(0).isReg() &&
MI.getOperand(0).getReg() == predReg) {
-
// Not all compares can be new value compare. Arch Spec: 7.6.1.1
if (isNewValueJumpCandidate(MI)) {
-
assert(
(MI.getDesc().isCompare()) &&
"Only compare instruction can be collapsed into New Value Jump");
@@ -554,7 +575,6 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
}
if (foundCompare && foundJump) {
-
// If "common" checks fail, bail out on this BB.
if (!commonChecksToProhibitNewValueJump(afterRA, MII))
break;
@@ -584,9 +604,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
foundFeeder = true;
}
- if (!foundFeeder &&
- isSecondOpReg &&
- feederReg == (unsigned) cmpOp2)
+ if (!foundFeeder && isSecondOpReg && feederReg == (unsigned)cmpOp2)
if (!canBeFeederToNewValueJump(QII, QRI, MII, jmpPos, cmpPos, MF))
break;
@@ -595,7 +613,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
// to newify, swap the operands.
unsigned COp = cmpInstr->getOpcode();
if ((COp == Hexagon::C2_cmpeq || COp == Hexagon::C4_cmpneq) &&
- (feederReg == (unsigned) cmpOp2)) {
+ (feederReg == (unsigned)cmpOp2)) {
unsigned tmp = cmpReg1;
cmpReg1 = cmpOp2;
cmpOp2 = tmp;
@@ -654,18 +672,16 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
opc = QII->getInvertedPredicatedOpcode(opc);
if (isSecondOpReg)
- NewMI = BuildMI(*MBB, jmpPos, dl,
- QII->get(opc))
- .addReg(cmpReg1, getKillRegState(MO1IsKill))
- .addReg(cmpOp2, getKillRegState(MO2IsKill))
- .addMBB(jmpTarget);
+ NewMI = BuildMI(*MBB, jmpPos, dl, QII->get(opc))
+ .addReg(cmpReg1, getKillRegState(MO1IsKill))
+ .addReg(cmpOp2, getKillRegState(MO2IsKill))
+ .addMBB(jmpTarget);
else
- NewMI = BuildMI(*MBB, jmpPos, dl,
- QII->get(opc))
- .addReg(cmpReg1, getKillRegState(MO1IsKill))
- .addImm(cmpOp2)
- .addMBB(jmpTarget);
+ NewMI = BuildMI(*MBB, jmpPos, dl, QII->get(opc))
+ .addReg(cmpReg1, getKillRegState(MO1IsKill))
+ .addImm(cmpOp2)
+ .addMBB(jmpTarget);
assert(NewMI && "New Value Jump Instruction Not created!");
(void)NewMI;
@@ -686,7 +702,6 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
}
return true;
-
}
FunctionPass *llvm::createHexagonNewValueJump() {