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"));
91 MachineFunctionProperties::Property::NoVRegs);
106char HexagonNewValueJump::ID = 0;
109 "Hexagon NewValueJump",
false,
false)
123 if (QII->isPredicated(*
II))
136 if (
II->getOpcode() == TargetOpcode::KILL)
139 if (
II->isImplicitDef())
142 if (QII->isSolo(*
II))
145 if (QII->isFloat(*
II))
151 if (!
Op.isReg() || !
Op.isDef())
156 if (!Hexagon::IntRegsRegClass.
contains(
Op.getReg()))
175 for (
unsigned i = 0; i <
II->getNumOperands(); ++i) {
176 if (
II->getOperand(i).isReg() &&
177 (
II->getOperand(i).isUse() ||
II->getOperand(i).isDef())) {
183 if (localBegin ==
skip)
186 if (localBegin->modifiesRegister(Reg,
TRI) ||
187 localBegin->readsRegister(Reg,
TRI))
220 if (MII->getOpcode() == TargetOpcode::KILL ||
221 MII->getOpcode() == TargetOpcode::PHI ||
222 MII->getOpcode() == TargetOpcode::COPY)
229 if (MII->getOpcode() == Hexagon::LDriw_pred ||
230 MII->getOpcode() == Hexagon::STriw_pred)
257 switch (
MI.getOpcode()) {
258 case Hexagon::C2_cmpeqi:
259 case Hexagon::C4_cmpneqi:
260 case Hexagon::C2_cmpgti:
261 case Hexagon::C4_cmpltei:
262 Valid = (isUInt<5>(v) || v == -1);
264 case Hexagon::C2_cmpgtui:
265 case Hexagon::C4_cmplteui:
266 Valid = isUInt<5>(v);
268 case Hexagon::S2_tstbit_i:
269 case Hexagon::S4_ntstbit_i:
278 unsigned cmpReg1, cmpOp2 = 0;
279 cmpReg1 =
MI.getOperand(1).getReg();
282 cmpOp2 =
MI.getOperand(2).getReg();
286 if (cmpReg1 == cmpOp2)
295 if (def->
getOpcode() == TargetOpcode::COPY)
304 if (localII->isDebugInstr())
314 if (localII->modifiesRegister(pReg,
TRI) ||
315 localII->readsRegister(pReg,
TRI))
325 if (localII->modifiesRegister(cmpReg1,
TRI) ||
326 (secondReg && localII->modifiesRegister(cmpOp2,
TRI)))
335 bool secondRegNewified,
347 switch (
MI->getOpcode()) {
348 case Hexagon::C2_cmpeq:
349 return taken ? Hexagon::J4_cmpeq_t_jumpnv_t
350 : Hexagon::J4_cmpeq_t_jumpnv_nt;
352 case Hexagon::C2_cmpeqi:
354 return taken ? Hexagon::J4_cmpeqi_t_jumpnv_t
355 : Hexagon::J4_cmpeqi_t_jumpnv_nt;
356 return taken ? Hexagon::J4_cmpeqn1_t_jumpnv_t
357 : Hexagon::J4_cmpeqn1_t_jumpnv_nt;
359 case Hexagon::C4_cmpneqi:
361 return taken ? Hexagon::J4_cmpeqi_f_jumpnv_t
362 : Hexagon::J4_cmpeqi_f_jumpnv_nt;
363 return taken ? Hexagon::J4_cmpeqn1_f_jumpnv_t :
364 Hexagon::J4_cmpeqn1_f_jumpnv_nt;
366 case Hexagon::C2_cmpgt:
367 if (secondRegNewified)
368 return taken ? Hexagon::J4_cmplt_t_jumpnv_t
369 : Hexagon::J4_cmplt_t_jumpnv_nt;
370 return taken ? Hexagon::J4_cmpgt_t_jumpnv_t
371 : Hexagon::J4_cmpgt_t_jumpnv_nt;
373 case Hexagon::C2_cmpgti:
375 return taken ? Hexagon::J4_cmpgti_t_jumpnv_t
376 : Hexagon::J4_cmpgti_t_jumpnv_nt;
377 return taken ? Hexagon::J4_cmpgtn1_t_jumpnv_t
378 : Hexagon::J4_cmpgtn1_t_jumpnv_nt;
380 case Hexagon::C2_cmpgtu:
381 if (secondRegNewified)
382 return taken ? Hexagon::J4_cmpltu_t_jumpnv_t
383 : Hexagon::J4_cmpltu_t_jumpnv_nt;
384 return taken ? Hexagon::J4_cmpgtu_t_jumpnv_t
385 : Hexagon::J4_cmpgtu_t_jumpnv_nt;
387 case Hexagon::C2_cmpgtui:
388 return taken ? Hexagon::J4_cmpgtui_t_jumpnv_t
389 : Hexagon::J4_cmpgtui_t_jumpnv_nt;
391 case Hexagon::C4_cmpneq:
392 return taken ? Hexagon::J4_cmpeq_f_jumpnv_t
393 : Hexagon::J4_cmpeq_f_jumpnv_nt;
395 case Hexagon::C4_cmplte:
396 if (secondRegNewified)
397 return taken ? Hexagon::J4_cmplt_f_jumpnv_t
398 : Hexagon::J4_cmplt_f_jumpnv_nt;
399 return taken ? Hexagon::J4_cmpgt_f_jumpnv_t
400 : Hexagon::J4_cmpgt_f_jumpnv_nt;
402 case Hexagon::C4_cmplteu:
403 if (secondRegNewified)
404 return taken ? Hexagon::J4_cmpltu_f_jumpnv_t
405 : Hexagon::J4_cmpltu_f_jumpnv_nt;
406 return taken ? Hexagon::J4_cmpgtu_f_jumpnv_t
407 : Hexagon::J4_cmpgtu_f_jumpnv_nt;
409 case Hexagon::C4_cmpltei:
411 return taken ? Hexagon::J4_cmpgti_f_jumpnv_t
412 : Hexagon::J4_cmpgti_f_jumpnv_nt;
413 return taken ? Hexagon::J4_cmpgtn1_f_jumpnv_t
414 : Hexagon::J4_cmpgtn1_f_jumpnv_nt;
416 case Hexagon::C4_cmplteui:
417 return taken ? Hexagon::J4_cmpgtui_f_jumpnv_t
418 : Hexagon::J4_cmpgtui_f_jumpnv_nt;
427bool HexagonNewValueJump::isNewValueJumpCandidate(
429 switch (
MI.getOpcode()) {
430 case Hexagon::C2_cmpeq:
431 case Hexagon::C2_cmpeqi:
432 case Hexagon::C2_cmpgt:
433 case Hexagon::C2_cmpgti:
434 case Hexagon::C2_cmpgtu:
435 case Hexagon::C2_cmpgtui:
436 case Hexagon::C4_cmpneq:
437 case Hexagon::C4_cmpneqi:
438 case Hexagon::C4_cmplte:
439 case Hexagon::C4_cmplteu:
440 case Hexagon::C4_cmpltei:
441 case Hexagon::C4_cmplteui:
450 LLVM_DEBUG(
dbgs() <<
"********** Hexagon New Value Jump **********\n"
451 <<
"********** Function: " << MF.
getName() <<
"\n");
462 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
469 int nvjGenerated = 0;
473 MBBb != MBBe; ++MBBb) {
479 <<
"********** dumping instr bottom up **********\n");
480 bool foundJump =
false;
481 bool foundCompare =
false;
482 bool invertPredicate =
false;
483 unsigned predReg = 0;
484 unsigned cmpReg1 = 0;
490 bool afterRA =
false;
491 bool isSecondOpReg =
false;
492 bool isSecondOpNewified =
false;
497 if (
MI.isDebugInstr()) {
501 if ((nvjCount == 0) || (nvjCount > -1 && nvjCount <= nvjGenerated))
506 if (!foundJump && (
MI.getOpcode() == Hexagon::J2_jumpt ||
507 MI.getOpcode() == Hexagon::J2_jumptpt ||
508 MI.getOpcode() == Hexagon::J2_jumpf ||
509 MI.getOpcode() == Hexagon::J2_jumpfpt ||
510 MI.getOpcode() == Hexagon::J2_jumptnewpt ||
511 MI.getOpcode() == Hexagon::J2_jumptnew ||
512 MI.getOpcode() == Hexagon::J2_jumpfnewpt ||
513 MI.getOpcode() == Hexagon::J2_jumpfnew)) {
518 predReg =
MI.getOperand(0).getReg();
536 bool predLive =
false;
538 if (SuccMBB->isLiveIn(predReg))
543 if (!
MI.getOperand(1).isMBB())
545 jmpTarget =
MI.getOperand(1).getMBB();
547 if (
MI.getOpcode() == Hexagon::J2_jumpf ||
548 MI.getOpcode() == Hexagon::J2_jumpfnewpt ||
549 MI.getOpcode() == Hexagon::J2_jumpfnew) {
550 invertPredicate =
true;
558 if (foundJump &&
MI.getNumOperands() == 0)
561 if (foundJump && !foundCompare &&
MI.getOperand(0).isReg() &&
562 MI.getOperand(0).getReg() == predReg) {
564 if (isNewValueJumpCandidate(
MI)) {
566 (
MI.getDesc().isCompare()) &&
567 "Only compare instruction can be collapsed into New Value Jump");
568 isSecondOpReg =
MI.getOperand(2).isReg();
571 afterRA, jmpPos, MF))
580 cmpReg1 =
MI.getOperand(1).getReg();
583 cmpOp2 =
MI.getOperand(2).getReg();
585 cmpOp2 =
MI.getOperand(2).getImm();
590 if (foundCompare && foundJump) {
595 bool foundFeeder =
false;
597 if (
MI.getOperand(0).isReg() &&
MI.getOperand(0).isDef() &&
598 (
MI.getOperand(0).getReg() == cmpReg1 ||
600 MI.getOperand(0).getReg() == (
unsigned)cmpOp2))) {
602 Register feederReg =
MI.getOperand(0).getReg();
610 if (feederReg == cmpReg1) {
620 if (!foundFeeder && isSecondOpReg && feederReg == (
unsigned)cmpOp2)
628 if ((COp == Hexagon::C2_cmpeq || COp == Hexagon::C4_cmpneq) &&
629 (feederReg == (
unsigned)cmpOp2)) {
630 unsigned tmp = cmpReg1;
638 if (feederReg == (
unsigned)cmpOp2)
639 isSecondOpNewified =
true;
648 if (!MO.isReg() || !MO.isUse())
651 for (
auto I = std::next(
MI.getIterator());
I != jmpPos; ++
I) {
655 if (!
Op.isReg() || !
Op.isUse() || !
Op.isKill())
657 if (
Op.getReg() != UseR)
669 TransferKills(*feederPos);
670 TransferKills(*cmpPos);
671 bool MO1IsKill = cmpPos->killsRegister(cmpReg1, QRI);
672 bool MO2IsKill = isSecondOpReg && cmpPos->killsRegister(cmpOp2, QRI);
679 assert((isNewValueJumpCandidate(*cmpInstr)) &&
680 "This compare is not a New Value Jump candidate.");
685 opc = QII->getInvertedPredicatedOpcode(opc);
688 NewMI =
BuildMI(*
MBB, jmpPos, dl, QII->get(opc))
694 NewMI =
BuildMI(*
MBB, jmpPos, dl, QII->get(opc))
699 assert(NewMI &&
"New Value Jump Instruction Not created!");
708 jmpInstr->eraseFromParent();
721 return new HexagonNewValueJump();
unsigned const MachineRegisterInfo * MRI
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.
unsigned 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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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...
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.
MachineFunctionProperties & set(Property P)
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.
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,...
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
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 TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
#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.
void initializeHexagonNewValueJumpPass(PassRegistry &)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createHexagonNewValueJump()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getKillRegState(bool B)