46 #define DEBUG_TYPE "hexagon-nvj"
48 STATISTIC(NumNVJGenerated,
"Number of New Value Jump Instructions created");
52 "Maximum number of predicated jumps to be converted to New Value Jump"));
56 cl::desc(
"Disable New Value Jumps"));
81 StringRef getPassName()
const override {
return "Hexagon NewValueJump"; }
101 "Hexagon NewValueJump",
false,
false)
117 if (QII->isPredicated(*II))
149 for (
unsigned i = 0;
i < II->getNumOperands(); ++
i) {
150 if (II->getOperand(
i).isReg() &&
151 (II->getOperand(
i).isUse() || II->getOperand(
i).isDef())) {
154 unsigned Reg = II->getOperand(
i).getReg();
156 localBegin !=
end; ++localBegin) {
157 if (localBegin == skip )
continue;
159 if (localBegin->modifiesRegister(Reg, TRI) ||
160 localBegin->readsRegister(Reg, TRI))
176 if (MII->getDesc().mayStore())
195 MII->getOpcode() == TargetOpcode::PHI ||
196 MII->getOpcode() == TargetOpcode::COPY)
203 if (MII->getOpcode() == Hexagon::LDriw_pred ||
204 MII->getOpcode() == Hexagon::STriw_pred)
229 case Hexagon::C2_cmpeqi:
230 case Hexagon::C2_cmpgti:
231 Valid = (isUInt<5>(v) || v == -1);
233 case Hexagon::C2_cmpgtui:
234 Valid = isUInt<5>(v);
236 case Hexagon::S2_tstbit_i:
237 case Hexagon::S4_ntstbit_i:
246 unsigned cmpReg1, cmpOp2 = 0;
254 if (cmpReg1 == cmpOp2)
263 if (def->
getOpcode() == TargetOpcode::COPY)
273 if (localII->isDebugValue())
283 if (localII->modifiesRegister(pReg, TRI) ||
284 localII->readsRegister(pReg, TRI))
294 if (localII->modifiesRegister(cmpReg1, TRI) ||
295 (secondReg && localII->modifiesRegister(cmpOp2, TRI)))
305 bool secondRegNewified,
318 case Hexagon::C2_cmpeq:
319 return taken ? Hexagon::J4_cmpeq_t_jumpnv_t
320 : Hexagon::J4_cmpeq_t_jumpnv_nt;
322 case Hexagon::C2_cmpeqi: {
324 return taken ? Hexagon::J4_cmpeqi_t_jumpnv_t
325 : Hexagon::J4_cmpeqi_t_jumpnv_nt;
327 return taken ? Hexagon::J4_cmpeqn1_t_jumpnv_t
328 : Hexagon::J4_cmpeqn1_t_jumpnv_nt;
331 case Hexagon::C2_cmpgt: {
332 if (secondRegNewified)
333 return taken ? Hexagon::J4_cmplt_t_jumpnv_t
334 : Hexagon::J4_cmplt_t_jumpnv_nt;
336 return taken ? Hexagon::J4_cmpgt_t_jumpnv_t
337 : Hexagon::J4_cmpgt_t_jumpnv_nt;
340 case Hexagon::C2_cmpgti: {
342 return taken ? Hexagon::J4_cmpgti_t_jumpnv_t
343 : Hexagon::J4_cmpgti_t_jumpnv_nt;
345 return taken ? Hexagon::J4_cmpgtn1_t_jumpnv_t
346 : Hexagon::J4_cmpgtn1_t_jumpnv_nt;
349 case Hexagon::C2_cmpgtu: {
350 if (secondRegNewified)
351 return taken ? Hexagon::J4_cmpltu_t_jumpnv_t
352 : Hexagon::J4_cmpltu_t_jumpnv_nt;
354 return taken ? Hexagon::J4_cmpgtu_t_jumpnv_t
355 : Hexagon::J4_cmpgtu_t_jumpnv_nt;
358 case Hexagon::C2_cmpgtui:
359 return taken ? Hexagon::J4_cmpgtui_t_jumpnv_t
360 : Hexagon::J4_cmpgtui_t_jumpnv_nt;
362 case Hexagon::C4_cmpneq:
363 return taken ? Hexagon::J4_cmpeq_f_jumpnv_t
364 : Hexagon::J4_cmpeq_f_jumpnv_nt;
366 case Hexagon::C4_cmplte:
367 if (secondRegNewified)
368 return taken ? Hexagon::J4_cmplt_f_jumpnv_t
369 : Hexagon::J4_cmplt_f_jumpnv_nt;
370 return taken ? Hexagon::J4_cmpgt_f_jumpnv_t
371 : Hexagon::J4_cmpgt_f_jumpnv_nt;
373 case Hexagon::C4_cmplteu:
374 if (secondRegNewified)
375 return taken ? Hexagon::J4_cmpltu_f_jumpnv_t
376 : Hexagon::J4_cmpltu_f_jumpnv_nt;
377 return taken ? Hexagon::J4_cmpgtu_f_jumpnv_t
378 : Hexagon::J4_cmpgtu_f_jumpnv_nt;
387 bool HexagonNewValueJump::isNewValueJumpCandidate(
390 case Hexagon::C2_cmpeq:
391 case Hexagon::C2_cmpeqi:
392 case Hexagon::C2_cmpgt:
393 case Hexagon::C2_cmpgti:
394 case Hexagon::C2_cmpgtu:
395 case Hexagon::C2_cmpgtui:
396 case Hexagon::C4_cmpneq:
397 case Hexagon::C4_cmplte:
398 case Hexagon::C4_cmplteu:
409 DEBUG(
dbgs() <<
"********** Hexagon New Value Jump **********\n"
410 <<
"********** Function: "
422 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
429 int nvjGenerated = 0;
433 MBBb != MBBe; ++MBBb) {
439 DEBUG(
dbgs() <<
"\n" <<
"********** dumping instr bottom up **********\n");
440 bool foundJump =
false;
441 bool foundCompare =
false;
442 bool invertPredicate =
false;
443 unsigned predReg = 0;
444 unsigned cmpReg1 = 0;
446 bool MO1IsKill =
false;
447 bool MO2IsKill =
false;
452 bool afterRA =
false;
453 bool isSecondOpReg =
false;
454 bool isSecondOpNewified =
false;
463 if ((nvjCount == 0) || (nvjCount > -1 && nvjCount <= nvjGenerated))
468 if (!foundJump && (MI.
getOpcode() == Hexagon::J2_jumpt ||
472 MI.
getOpcode() == Hexagon::J2_jumptnewpt ||
473 MI.
getOpcode() == Hexagon::J2_jumptnew ||
474 MI.
getOpcode() == Hexagon::J2_jumpfnewpt ||
475 MI.
getOpcode() == Hexagon::J2_jumpfnew)) {
498 bool predLive =
false;
513 if (MI.
getOpcode() == Hexagon::J2_jumpf ||
514 MI.
getOpcode() == Hexagon::J2_jumpfnewpt ||
515 MI.
getOpcode() == Hexagon::J2_jumpfnew) {
516 invertPredicate =
true;
531 if (isNewValueJumpCandidate(MI)) {
535 "Only compare instruction can be collapsed into New Value Jump");
539 afterRA, jmpPos, MF))
562 if (foundCompare && foundJump) {
568 bool foundFeeder =
false;
583 if (feederReg == cmpReg1) {
595 feederReg == (
unsigned) cmpOp2)
603 if ((COp == Hexagon::C2_cmpeq || COp == Hexagon::C4_cmpneq) &&
604 (feederReg == (
unsigned) cmpOp2)) {
605 unsigned tmp = cmpReg1;
606 bool tmpIsKill = MO1IsKill;
608 MO1IsKill = MO2IsKill;
610 MO2IsKill = tmpIsKill;
616 if (feederReg == (
unsigned)cmpOp2)
617 isSecondOpNewified =
true;
624 bool updatedIsKill =
false;
628 unsigned feederReg = MO.
getReg();
630 end = jmpPos; localII !=
end; localII++) {
640 updatedIsKill =
true;
644 if (updatedIsKill)
break;
647 if (updatedIsKill)
break;
655 assert((isNewValueJumpCandidate(*cmpInstr)) &&
656 "This compare is not a New Value Jump candidate.");
661 opc = QII->getInvertedPredicatedOpcode(opc);
664 NewMI =
BuildMI(*MBB, jmpPos, dl,
671 NewMI =
BuildMI(*MBB, jmpPos, dl,
677 assert(NewMI &&
"New Value Jump Instruction Not created!");
686 jmpInstr->eraseFromParent();
700 return new HexagonNewValueJump();
const_iterator end(StringRef path)
Get end iterator over path.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
MachineBasicBlock * getMBB() const
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
void skip(CollectionType &C)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
INITIALIZE_PASS_BEGIN(HexagonNewValueJump,"hexagon-nvj","Hexagon NewValueJump", false, false) INITIALIZE_PASS_END(HexagonNewValueJump
void initializeHexagonNewValueJumpPass(PassRegistry &)
static bool commonChecksToProhibitNewValueJump(bool afterRA, MachineBasicBlock::iterator MII)
unsigned getKillRegState(bool B)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
bool isDebugValue() const
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)
initializer< Ty > init(const Ty &Val)
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
bool isCompare() const
Return true if this instruction is a comparison.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
succ_iterator succ_begin()
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#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.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
void dump(const TargetInstrInfo *TII=nullptr) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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"))
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Representation of each machine instruction.
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.
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 isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::vector< MachineBasicBlock * >::const_iterator const_succ_iterator
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) 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"))