diff options
Diffstat (limited to 'lib/Target/Hexagon/HexagonNewValueJump.cpp')
| -rw-r--r-- | lib/Target/Hexagon/HexagonNewValueJump.cpp | 205 |
1 files changed, 110 insertions, 95 deletions
diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp index e93f075f4ccd..ffa447cc1311 100644 --- a/lib/Target/Hexagon/HexagonNewValueJump.cpp +++ b/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() { |
