55#define DEBUG_TYPE "hexagon-nvj"
57STATISTIC(NumNVJGenerated,
"Number of New Value Jump Instructions created");
60 cl::desc(
"Maximum number of predicated jumps to be converted to "
64 cl::desc(
"Disable New Value Jumps"));
98char HexagonNewValueJump::ID = 0;
101 "Hexagon NewValueJump",
false,
false)
115 if (QII->isPredicated(*
II))
128 if (
II->getOpcode() == TargetOpcode::KILL)
131 if (
II->isImplicitDef())
134 if (QII->isSolo(*
II))
137 if (QII->isFloat(*
II))
143 if (!
Op.isReg() || !
Op.isDef())
148 if (!Hexagon::IntRegsRegClass.
contains(
Op.getReg()))
167 for (
unsigned i = 0; i <
II->getNumOperands(); ++i) {
168 if (
II->getOperand(i).isReg() &&
169 (
II->getOperand(i).isUse() ||
II->getOperand(i).isDef())) {
175 if (localBegin ==
skip)
178 if (localBegin->modifiesRegister(Reg,
TRI) ||
179 localBegin->readsRegister(Reg,
TRI))
212 if (MII->getOpcode() == TargetOpcode::KILL ||
213 MII->getOpcode() == TargetOpcode::PHI ||
214 MII->getOpcode() == TargetOpcode::COPY)
221 if (MII->getOpcode() == Hexagon::LDriw_pred ||
222 MII->getOpcode() == Hexagon::STriw_pred)
249 switch (
MI.getOpcode()) {
250 case Hexagon::C2_cmpeqi:
251 case Hexagon::C4_cmpneqi:
252 case Hexagon::C2_cmpgti:
253 case Hexagon::C4_cmpltei:
254 Valid = (isUInt<5>(v) || v == -1);
256 case Hexagon::C2_cmpgtui:
257 case Hexagon::C4_cmplteui:
258 Valid = isUInt<5>(v);
260 case Hexagon::S2_tstbit_i:
261 case Hexagon::S4_ntstbit_i:
270 unsigned cmpReg1, cmpOp2 = 0;
271 cmpReg1 =
MI.getOperand(1).getReg();
274 cmpOp2 =
MI.getOperand(2).getReg();
278 if (cmpReg1 == cmpOp2)
287 if (def->
getOpcode() == TargetOpcode::COPY)
296 if (localII->isDebugInstr())
306 if (localII->modifiesRegister(pReg,
TRI) ||
307 localII->readsRegister(pReg,
TRI))
317 if (localII->modifiesRegister(cmpReg1,
TRI) ||
318 (secondReg && localII->modifiesRegister(cmpOp2,
TRI)))
327 bool secondRegNewified,
339 switch (
MI->getOpcode()) {
340 case Hexagon::C2_cmpeq:
341 return taken ? Hexagon::J4_cmpeq_t_jumpnv_t
342 : Hexagon::J4_cmpeq_t_jumpnv_nt;
344 case Hexagon::C2_cmpeqi:
346 return taken ? Hexagon::J4_cmpeqi_t_jumpnv_t
347 : Hexagon::J4_cmpeqi_t_jumpnv_nt;
348 return taken ? Hexagon::J4_cmpeqn1_t_jumpnv_t
349 : Hexagon::J4_cmpeqn1_t_jumpnv_nt;
351 case Hexagon::C4_cmpneqi:
353 return taken ? Hexagon::J4_cmpeqi_f_jumpnv_t
354 : Hexagon::J4_cmpeqi_f_jumpnv_nt;
355 return taken ? Hexagon::J4_cmpeqn1_f_jumpnv_t :
356 Hexagon::J4_cmpeqn1_f_jumpnv_nt;
358 case Hexagon::C2_cmpgt:
359 if (secondRegNewified)
360 return taken ? Hexagon::J4_cmplt_t_jumpnv_t
361 : Hexagon::J4_cmplt_t_jumpnv_nt;
362 return taken ? Hexagon::J4_cmpgt_t_jumpnv_t
363 : Hexagon::J4_cmpgt_t_jumpnv_nt;
365 case Hexagon::C2_cmpgti:
367 return taken ? Hexagon::J4_cmpgti_t_jumpnv_t
368 : Hexagon::J4_cmpgti_t_jumpnv_nt;
369 return taken ? Hexagon::J4_cmpgtn1_t_jumpnv_t
370 : Hexagon::J4_cmpgtn1_t_jumpnv_nt;
372 case Hexagon::C2_cmpgtu:
373 if (secondRegNewified)
374 return taken ? Hexagon::J4_cmpltu_t_jumpnv_t
375 : Hexagon::J4_cmpltu_t_jumpnv_nt;
376 return taken ? Hexagon::J4_cmpgtu_t_jumpnv_t
377 : Hexagon::J4_cmpgtu_t_jumpnv_nt;
379 case Hexagon::C2_cmpgtui:
380 return taken ? Hexagon::J4_cmpgtui_t_jumpnv_t
381 : Hexagon::J4_cmpgtui_t_jumpnv_nt;
383 case Hexagon::C4_cmpneq:
384 return taken ? Hexagon::J4_cmpeq_f_jumpnv_t
385 : Hexagon::J4_cmpeq_f_jumpnv_nt;
387 case Hexagon::C4_cmplte:
388 if (secondRegNewified)
389 return taken ? Hexagon::J4_cmplt_f_jumpnv_t
390 : Hexagon::J4_cmplt_f_jumpnv_nt;
391 return taken ? Hexagon::J4_cmpgt_f_jumpnv_t
392 : Hexagon::J4_cmpgt_f_jumpnv_nt;
394 case Hexagon::C4_cmplteu:
395 if (secondRegNewified)
396 return taken ? Hexagon::J4_cmpltu_f_jumpnv_t
397 : Hexagon::J4_cmpltu_f_jumpnv_nt;
398 return taken ? Hexagon::J4_cmpgtu_f_jumpnv_t
399 : Hexagon::J4_cmpgtu_f_jumpnv_nt;
401 case Hexagon::C4_cmpltei:
403 return taken ? Hexagon::J4_cmpgti_f_jumpnv_t
404 : Hexagon::J4_cmpgti_f_jumpnv_nt;
405 return taken ? Hexagon::J4_cmpgtn1_f_jumpnv_t
406 : Hexagon::J4_cmpgtn1_f_jumpnv_nt;
408 case Hexagon::C4_cmplteui:
409 return taken ? Hexagon::J4_cmpgtui_f_jumpnv_t
410 : Hexagon::J4_cmpgtui_f_jumpnv_nt;
419bool HexagonNewValueJump::isNewValueJumpCandidate(
421 switch (
MI.getOpcode()) {
422 case Hexagon::C2_cmpeq:
423 case Hexagon::C2_cmpeqi:
424 case Hexagon::C2_cmpgt:
425 case Hexagon::C2_cmpgti:
426 case Hexagon::C2_cmpgtu:
427 case Hexagon::C2_cmpgtui:
428 case Hexagon::C4_cmpneq:
429 case Hexagon::C4_cmpneqi:
430 case Hexagon::C4_cmplte:
431 case Hexagon::C4_cmplteu:
432 case Hexagon::C4_cmpltei:
433 case Hexagon::C4_cmplteui:
442 LLVM_DEBUG(
dbgs() <<
"********** Hexagon New Value Jump **********\n"
443 <<
"********** Function: " << MF.
getName() <<
"\n");
454 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
461 int nvjGenerated = 0;
465 MBBb != MBBe; ++MBBb) {
471 <<
"********** dumping instr bottom up **********\n");
472 bool foundJump =
false;
473 bool foundCompare =
false;
474 bool invertPredicate =
false;
475 unsigned predReg = 0;
476 unsigned cmpReg1 = 0;
482 bool afterRA =
false;
483 bool isSecondOpReg =
false;
484 bool isSecondOpNewified =
false;
489 if (
MI.isDebugInstr()) {
493 if ((nvjCount == 0) || (nvjCount > -1 && nvjCount <= nvjGenerated))
498 if (!foundJump && (
MI.getOpcode() == Hexagon::J2_jumpt ||
499 MI.getOpcode() == Hexagon::J2_jumptpt ||
500 MI.getOpcode() == Hexagon::J2_jumpf ||
501 MI.getOpcode() == Hexagon::J2_jumpfpt ||
502 MI.getOpcode() == Hexagon::J2_jumptnewpt ||
503 MI.getOpcode() == Hexagon::J2_jumptnew ||
504 MI.getOpcode() == Hexagon::J2_jumpfnewpt ||
505 MI.getOpcode() == Hexagon::J2_jumpfnew)) {
510 predReg =
MI.getOperand(0).getReg();
528 bool predLive =
false;
530 if (SuccMBB->isLiveIn(predReg))
535 if (!
MI.getOperand(1).isMBB())
537 jmpTarget =
MI.getOperand(1).getMBB();
539 if (
MI.getOpcode() == Hexagon::J2_jumpf ||
540 MI.getOpcode() == Hexagon::J2_jumpfnewpt ||
541 MI.getOpcode() == Hexagon::J2_jumpfnew) {
542 invertPredicate =
true;
550 if (foundJump &&
MI.getNumOperands() == 0)
553 if (foundJump && !foundCompare &&
MI.getOperand(0).isReg() &&
554 MI.getOperand(0).getReg() == predReg) {
556 if (isNewValueJumpCandidate(
MI)) {
558 (
MI.getDesc().isCompare()) &&
559 "Only compare instruction can be collapsed into New Value Jump");
560 isSecondOpReg =
MI.getOperand(2).isReg();
563 afterRA, jmpPos, MF))
572 cmpReg1 =
MI.getOperand(1).getReg();
575 cmpOp2 =
MI.getOperand(2).getReg();
577 cmpOp2 =
MI.getOperand(2).getImm();
582 if (foundCompare && foundJump) {
587 bool foundFeeder =
false;
589 if (
MI.getOperand(0).isReg() &&
MI.getOperand(0).isDef() &&
590 (
MI.getOperand(0).getReg() == cmpReg1 ||
592 MI.getOperand(0).getReg() == (
unsigned)cmpOp2))) {
594 Register feederReg =
MI.getOperand(0).getReg();
602 if (feederReg == cmpReg1) {
612 if (!foundFeeder && isSecondOpReg && feederReg == (
unsigned)cmpOp2)
620 if ((COp == Hexagon::C2_cmpeq || COp == Hexagon::C4_cmpneq) &&
621 (feederReg == (
unsigned)cmpOp2)) {
622 unsigned tmp = cmpReg1;
630 if (feederReg == (
unsigned)cmpOp2)
631 isSecondOpNewified =
true;
640 if (!MO.isReg() || !MO.isUse())
643 for (
auto I = std::next(
MI.getIterator());
I != jmpPos; ++
I) {
647 if (!
Op.isReg() || !
Op.isUse() || !
Op.isKill())
649 if (
Op.getReg() != UseR)
661 TransferKills(*feederPos);
662 TransferKills(*cmpPos);
663 bool MO1IsKill = cmpPos->killsRegister(cmpReg1, QRI);
664 bool MO2IsKill = isSecondOpReg && cmpPos->killsRegister(cmpOp2, QRI);
671 assert((isNewValueJumpCandidate(*cmpInstr)) &&
672 "This compare is not a New Value Jump candidate.");
677 opc = QII->getInvertedPredicatedOpcode(opc);
680 NewMI =
BuildMI(*
MBB, jmpPos, dl, QII->get(opc))
686 NewMI =
BuildMI(*
MBB, jmpPos, dl, QII->get(opc))
691 assert(NewMI &&
"New Value Jump Instruction Not created!");
700 jmpInstr->eraseFromParent();
713 return new HexagonNewValueJump();
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > DisableNewValueJumps("disable-nvjump", cl::Hidden, cl::desc("Disable New Value Jumps"))
static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII, const TargetRegisterInfo *TRI, MachineBasicBlock::iterator II, unsigned pReg, bool secondReg, bool optLocation, MachineBasicBlock::iterator end, MachineFunction &MF)
static bool commonChecksToProhibitNewValueJump(bool afterRA, MachineBasicBlock::iterator MII)
hexagon Hexagon static false bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII, const TargetRegisterInfo *TRI, MachineBasicBlock::iterator II, MachineBasicBlock::iterator end, MachineBasicBlock::iterator skip, MachineFunction &MF)
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"))
hexagon Hexagon NewValueJump
static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, bool secondRegNewified, MachineBasicBlock *jmpTarget, const MachineBranchProbabilityInfo *MBPI)
static bool skip(DataExtractor &Data, uint64_t &Offset, bool SkippedRanges)
Skip an InlineInfo object in the specified data at the specified offset.
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
bool useNewValueJumps() const
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI void dump() const
iterator_range< succ_iterator > successors()
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 '...
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createHexagonNewValueJump()
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getKillRegState(bool B)