55 #define DEBUG_TYPE "hexagon-nvj" 57 STATISTIC(NumNVJGenerated,
"Number of New Value Jump Instructions created");
60 cl::desc(
"Maximum number of predicated jumps to be converted to " 65 cl::desc(
"Disable New Value Jumps"));
86 StringRef getPassName()
const override {
return "Hexagon NewValueJump"; }
110 "Hexagon NewValueJump",
false,
false)
124 if (QII->isPredicated(*II))
140 if (II->isImplicitDef())
143 if (QII->isSolo(*II))
146 if (QII->isFloat(*II))
152 if (!
Op.isReg() || !
Op.isDef())
157 if (!Hexagon::IntRegsRegClass.
contains(
Op.getReg()))
176 for (
unsigned i = 0; i < II->getNumOperands(); ++i) {
177 if (II->getOperand(i).isReg() &&
178 (II->getOperand(i).isUse() || II->getOperand(i).isDef())) {
181 unsigned Reg = II->getOperand(i).getReg();
184 if (localBegin == skip)
187 if (localBegin->modifiesRegister(Reg, TRI) ||
188 localBegin->readsRegister(Reg, TRI))
222 MII->getOpcode() == TargetOpcode::PHI ||
223 MII->getOpcode() == TargetOpcode::COPY)
230 if (MII->getOpcode() == Hexagon::LDriw_pred ||
231 MII->getOpcode() == Hexagon::STriw_pred)
259 case Hexagon::C2_cmpeqi:
260 case Hexagon::C4_cmpneqi:
261 case Hexagon::C2_cmpgti:
262 case Hexagon::C4_cmpltei:
263 Valid = (isUInt<5>(v) || v == -1);
265 case Hexagon::C2_cmpgtui:
266 case Hexagon::C4_cmplteui:
267 Valid = isUInt<5>(v);
269 case Hexagon::S2_tstbit_i:
270 case Hexagon::S4_ntstbit_i:
279 unsigned cmpReg1, cmpOp2 = 0;
287 if (cmpReg1 == cmpOp2)
296 if (def->
getOpcode() == TargetOpcode::COPY)
305 if (localII->isDebugInstr())
315 if (localII->modifiesRegister(pReg, TRI) ||
316 localII->readsRegister(pReg, TRI))
326 if (localII->modifiesRegister(cmpReg1, TRI) ||
327 (secondReg && localII->modifiesRegister(cmpOp2, TRI)))
336 bool secondRegNewified,
349 case Hexagon::C2_cmpeq:
350 return taken ? Hexagon::J4_cmpeq_t_jumpnv_t
351 : Hexagon::J4_cmpeq_t_jumpnv_nt;
353 case Hexagon::C2_cmpeqi:
355 return taken ? Hexagon::J4_cmpeqi_t_jumpnv_t
356 : Hexagon::J4_cmpeqi_t_jumpnv_nt;
357 return taken ? Hexagon::J4_cmpeqn1_t_jumpnv_t
358 : Hexagon::J4_cmpeqn1_t_jumpnv_nt;
360 case Hexagon::C4_cmpneqi:
362 return taken ? Hexagon::J4_cmpeqi_f_jumpnv_t
363 : Hexagon::J4_cmpeqi_f_jumpnv_nt;
364 return taken ? Hexagon::J4_cmpeqn1_f_jumpnv_t :
365 Hexagon::J4_cmpeqn1_f_jumpnv_nt;
367 case Hexagon::C2_cmpgt:
368 if (secondRegNewified)
369 return taken ? Hexagon::J4_cmplt_t_jumpnv_t
370 : Hexagon::J4_cmplt_t_jumpnv_nt;
371 return taken ? Hexagon::J4_cmpgt_t_jumpnv_t
372 : Hexagon::J4_cmpgt_t_jumpnv_nt;
374 case Hexagon::C2_cmpgti:
376 return taken ? Hexagon::J4_cmpgti_t_jumpnv_t
377 : Hexagon::J4_cmpgti_t_jumpnv_nt;
378 return taken ? Hexagon::J4_cmpgtn1_t_jumpnv_t
379 : Hexagon::J4_cmpgtn1_t_jumpnv_nt;
381 case Hexagon::C2_cmpgtu:
382 if (secondRegNewified)
383 return taken ? Hexagon::J4_cmpltu_t_jumpnv_t
384 : Hexagon::J4_cmpltu_t_jumpnv_nt;
385 return taken ? Hexagon::J4_cmpgtu_t_jumpnv_t
386 : Hexagon::J4_cmpgtu_t_jumpnv_nt;
388 case Hexagon::C2_cmpgtui:
389 return taken ? Hexagon::J4_cmpgtui_t_jumpnv_t
390 : Hexagon::J4_cmpgtui_t_jumpnv_nt;
392 case Hexagon::C4_cmpneq:
393 return taken ? Hexagon::J4_cmpeq_f_jumpnv_t
394 : Hexagon::J4_cmpeq_f_jumpnv_nt;
396 case Hexagon::C4_cmplte:
397 if (secondRegNewified)
398 return taken ? Hexagon::J4_cmplt_f_jumpnv_t
399 : Hexagon::J4_cmplt_f_jumpnv_nt;
400 return taken ? Hexagon::J4_cmpgt_f_jumpnv_t
401 : Hexagon::J4_cmpgt_f_jumpnv_nt;
403 case Hexagon::C4_cmplteu:
404 if (secondRegNewified)
405 return taken ? Hexagon::J4_cmpltu_f_jumpnv_t
406 : Hexagon::J4_cmpltu_f_jumpnv_nt;
407 return taken ? Hexagon::J4_cmpgtu_f_jumpnv_t
408 : Hexagon::J4_cmpgtu_f_jumpnv_nt;
410 case Hexagon::C4_cmpltei:
412 return taken ? Hexagon::J4_cmpgti_f_jumpnv_t
413 : Hexagon::J4_cmpgti_f_jumpnv_nt;
414 return taken ? Hexagon::J4_cmpgtn1_f_jumpnv_t
415 : Hexagon::J4_cmpgtn1_f_jumpnv_nt;
417 case Hexagon::C4_cmplteui:
418 return taken ? Hexagon::J4_cmpgtui_f_jumpnv_t
419 : Hexagon::J4_cmpgtui_f_jumpnv_nt;
428 bool HexagonNewValueJump::isNewValueJumpCandidate(
431 case Hexagon::C2_cmpeq:
432 case Hexagon::C2_cmpeqi:
433 case Hexagon::C2_cmpgt:
434 case Hexagon::C2_cmpgti:
435 case Hexagon::C2_cmpgtu:
436 case Hexagon::C2_cmpgtui:
437 case Hexagon::C4_cmpneq:
438 case Hexagon::C4_cmpneqi:
439 case Hexagon::C4_cmplte:
440 case Hexagon::C4_cmplteu:
441 case Hexagon::C4_cmpltei:
442 case Hexagon::C4_cmplteui:
451 LLVM_DEBUG(
dbgs() <<
"********** Hexagon New Value Jump **********\n" 452 <<
"********** Function: " << MF.
getName() <<
"\n");
463 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
470 int nvjGenerated = 0;
474 MBBb != MBBe; ++MBBb) {
480 <<
"********** dumping instr bottom up **********\n");
481 bool foundJump =
false;
482 bool foundCompare =
false;
483 bool invertPredicate =
false;
484 unsigned predReg = 0;
485 unsigned cmpReg1 = 0;
491 bool afterRA =
false;
492 bool isSecondOpReg =
false;
493 bool isSecondOpNewified =
false;
502 if ((nvjCount == 0) || (nvjCount > -1 && nvjCount <= nvjGenerated))
507 if (!foundJump && (MI.
getOpcode() == Hexagon::J2_jumpt ||
511 MI.
getOpcode() == Hexagon::J2_jumptnewpt ||
512 MI.
getOpcode() == Hexagon::J2_jumptnew ||
513 MI.
getOpcode() == Hexagon::J2_jumpfnewpt ||
514 MI.
getOpcode() == Hexagon::J2_jumpfnew)) {
537 bool predLive =
false;
552 if (MI.
getOpcode() == Hexagon::J2_jumpf ||
553 MI.
getOpcode() == Hexagon::J2_jumpfnewpt ||
554 MI.
getOpcode() == Hexagon::J2_jumpfnew) {
555 invertPredicate =
true;
569 if (isNewValueJumpCandidate(MI)) {
572 "Only compare instruction can be collapsed into New Value Jump");
576 afterRA, jmpPos, MF))
595 if (foundCompare && foundJump) {
600 bool foundFeeder =
false;
615 if (feederReg == cmpReg1) {
625 if (!foundFeeder && isSecondOpReg && feederReg == (
unsigned)cmpOp2)
633 if ((COp == Hexagon::C2_cmpeq || COp == Hexagon::C4_cmpneq) &&
634 (feederReg == (
unsigned)cmpOp2)) {
635 unsigned tmp = cmpReg1;
643 if (feederReg == (
unsigned)cmpOp2)
644 isSecondOpNewified =
true;
653 if (!MO.isReg() || !MO.isUse())
655 unsigned UseR = MO.getReg();
660 if (!
Op.isReg() || !
Op.isUse() || !
Op.isKill())
662 if (
Op.getReg() != UseR)
674 TransferKills(*feederPos);
675 TransferKills(*cmpPos);
676 bool MO1IsKill = cmpPos->killsRegister(cmpReg1, QRI);
677 bool MO2IsKill = isSecondOpReg && cmpPos->killsRegister(cmpOp2, QRI);
684 assert((isNewValueJumpCandidate(*cmpInstr)) &&
685 "This compare is not a New Value Jump candidate.");
690 opc = QII->getInvertedPredicatedOpcode(opc);
693 NewMI =
BuildMI(*MBB, jmpPos, dl, QII->
get(opc))
699 NewMI =
BuildMI(*MBB, jmpPos, dl, QII->
get(opc))
704 assert(NewMI &&
"New Value Jump Instruction Not created!");
713 jmpInstr->eraseFromParent();
726 return new HexagonNewValueJump();
const_iterator end(StringRef path)
Get end iterator over path.
MachineBasicBlock * getMBB() const
This class represents lattice values for constants.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getReg() const
getReg - Returns the register number.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
void skip(CollectionType &C)
iterator_range< mop_iterator > operands()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
return AArch64::GPR64RegClass contains(Reg)
bool isCompare() const
Return true if this instruction is a comparison.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumOperands() const
Retuns the total number of operands.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void initializeHexagonNewValueJumpPass(PassRegistry &)
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
virtual const TargetInstrInfo * getInstrInfo() const
static bool commonChecksToProhibitNewValueJump(bool afterRA, MachineBasicBlock::iterator MII)
unsigned getKillRegState(bool B)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, bool secondRegNewified, MachineBasicBlock *jmpTarget, const MachineBranchProbabilityInfo *MBPI)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
initializer< Ty > init(const Ty &Val)
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
std::vector< MachineBasicBlock * >::const_iterator const_succ_iterator
self_iterator getIterator()
succ_iterator succ_begin()
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isDebugInstr() const
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
hexagon Hexagon static false bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII, const TargetRegisterInfo *TRI, MachineBasicBlock::iterator II, MachineBasicBlock::iterator end, MachineBasicBlock::iterator skip, MachineFunction &MF)
void setIsKill(bool Val=true)
FunctionPass * createHexagonNewValueJump()
Iterator for intrusive lists based on ilist_node.
MachineOperand class - Representation of each machine instruction operand.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool useNewValueJumps() const
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Representation of each machine instruction.
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 bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
INITIALIZE_PASS_BEGIN(HexagonNewValueJump, "hexagon-nvj", "Hexagon NewValueJump", false, false) INITIALIZE_PASS_END(HexagonNewValueJump
static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII, const TargetRegisterInfo *TRI, MachineBasicBlock::iterator II, unsigned pReg, bool secondReg, bool optLocation, MachineBasicBlock::iterator end, MachineFunction &MF)
hexagon Hexagon NewValueJump
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const
Properties which a MachineFunction may have at a given point in time.
static cl::opt< bool > DisableNewValueJumps("disable-nvjump", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable New Value Jumps"))