Go to the documentation of this file.
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))
137 if (II->getOpcode() == TargetOpcode::KILL)
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())) {
184 if (localBegin ==
skip)
187 if (localBegin->modifiesRegister(
Reg,
TRI) ||
188 localBegin->readsRegister(
Reg,
TRI))
221 if (MII->getOpcode() == TargetOpcode::KILL ||
222 MII->getOpcode() == TargetOpcode::PHI ||
223 MII->getOpcode() == TargetOpcode::COPY)
230 if (MII->getOpcode() == Hexagon::LDriw_pred ||
231 MII->getOpcode() == Hexagon::STriw_pred)
258 switch (
MI.getOpcode()) {
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;
280 cmpReg1 =
MI.getOperand(1).getReg();
283 cmpOp2 =
MI.getOperand(2).getReg();
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,
348 switch (
MI->getOpcode()) {
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(
430 switch (
MI.getOpcode()) {
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;
498 if (
MI.isDebugInstr()) {
502 if ((nvjCount == 0) || (nvjCount > -1 && nvjCount <= nvjGenerated))
507 if (!foundJump && (
MI.getOpcode() == Hexagon::J2_jumpt ||
508 MI.getOpcode() == Hexagon::J2_jumptpt ||
509 MI.getOpcode() == Hexagon::J2_jumpf ||
510 MI.getOpcode() == Hexagon::J2_jumpfpt ||
511 MI.getOpcode() == Hexagon::J2_jumptnewpt ||
512 MI.getOpcode() == Hexagon::J2_jumptnew ||
513 MI.getOpcode() == Hexagon::J2_jumpfnewpt ||
514 MI.getOpcode() == Hexagon::J2_jumpfnew)) {
519 predReg =
MI.getOperand(0).getReg();
537 bool predLive =
false;
548 if (!
MI.getOperand(1).isMBB())
550 jmpTarget =
MI.getOperand(1).getMBB();
552 if (
MI.getOpcode() == Hexagon::J2_jumpf ||
553 MI.getOpcode() == Hexagon::J2_jumpfnewpt ||
554 MI.getOpcode() == Hexagon::J2_jumpfnew) {
555 invertPredicate =
true;
563 if (foundJump &&
MI.getNumOperands() == 0)
566 if (foundJump && !foundCompare &&
MI.getOperand(0).isReg() &&
567 MI.getOperand(0).getReg() == predReg) {
569 if (isNewValueJumpCandidate(
MI)) {
571 (
MI.getDesc().isCompare()) &&
572 "Only compare instruction can be collapsed into New Value Jump");
573 isSecondOpReg =
MI.getOperand(2).isReg();
576 afterRA, jmpPos, MF))
585 cmpReg1 =
MI.getOperand(1).getReg();
588 cmpOp2 =
MI.getOperand(2).getReg();
590 cmpOp2 =
MI.getOperand(2).getImm();
595 if (foundCompare && foundJump) {
600 bool foundFeeder =
false;
602 if (
MI.getOperand(0).isReg() &&
MI.getOperand(0).isDef() &&
603 (
MI.getOperand(0).getReg() == cmpReg1 ||
605 MI.getOperand(0).getReg() == (
unsigned)cmpOp2))) {
607 Register feederReg =
MI.getOperand(0).getReg();
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())
656 for (
auto I = std::next(
MI.getIterator());
I != jmpPos; ++
I) {
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 MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
FunctionPass * createHexagonNewValueJump()
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual const TargetInstrInfo * getInstrInfo() const
return AArch64::GPR64RegClass contains(Reg)
void setIsKill(bool Val=true)
static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, bool secondRegNewified, MachineBasicBlock *jmpTarget, const MachineBranchProbabilityInfo *MBPI)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const_iterator end(StringRef path)
Get end iterator over path.
Properties which a MachineFunction may have at a given point in time.
alloca< 16 x float >, align 16 %tmp2=alloca< 16 x float >, align 16 store< 16 x float > %A,< 16 x float > *%tmp %s=bitcast< 16 x float > *%tmp to i8 *%s2=bitcast< 16 x float > *%tmp2 to i8 *call void @llvm.memcpy.i64(i8 *%s, i8 *%s2, i64 64, i32 16) %R=load< 16 x float > *%tmp2 ret< 16 x float > %R } declare void @llvm.memcpy.i64(i8 *nocapture, i8 *nocapture, i64, i32) nounwind which compiles to:_foo:subl $140, %esp movaps %xmm3, 112(%esp) movaps %xmm2, 96(%esp) movaps %xmm1, 80(%esp) movaps %xmm0, 64(%esp) movl 60(%esp), %eax movl %eax, 124(%esp) movl 56(%esp), %eax movl %eax, 120(%esp) movl 52(%esp), %eax< many many more 32-bit copies > movaps(%esp), %xmm0 movaps 16(%esp), %xmm1 movaps 32(%esp), %xmm2 movaps 48(%esp), %xmm3 addl $140, %esp ret On Nehalem, it may even be cheaper to just use movups when unaligned than to fall back to lower-granularity chunks. Implement processor-specific optimizations for parity with GCC on these processors. GCC does two optimizations:1. ix86_pad_returns inserts a noop before ret instructions if immediately preceded by a conditional branch or is the target of a jump. 2. ix86_avoid_jump_misspredicts inserts noops in cases where a 16-byte block of code contains more than 3 branches. The first one is done for all AMDs, Core2, and "Generic" The second one is done for:Atom, Pentium Pro, all AMDs, Pentium 4, Nocona, Core 2, and "Generic" Testcase:int x(int a) { return(a &0xf0)> >4 tmp
unsigned const TargetRegisterInfo * TRI
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const MachineOperand & getOperand(unsigned i) const
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Represent the analysis usage information of a pass.
bool useNewValueJumps() const
static bool skip(DataExtractor &Data, uint64_t &Offset, bool SkippedRanges)
Skip an InlineInfo object in the specified data at the specified offset.
MachineOperand class - Representation of each machine instruction operand.
MachineFunctionProperties & set(Property P)
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
STATISTIC(NumFunctions, "Total number of functions")
hexagon Hexagon NewValueJump
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void initializeHexagonNewValueJumpPass(PassRegistry &)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
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"))
initializer< Ty > init(const Ty &Val)
hexagon Hexagon static false bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII, const TargetRegisterInfo *TRI, MachineBasicBlock::iterator II, MachineBasicBlock::iterator end, MachineBasicBlock::iterator skip, MachineFunction &MF)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
succ_iterator succ_begin()
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
StringRef - Represent a constant reference to a string, i.e.
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 '...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII, const TargetRegisterInfo *TRI, MachineBasicBlock::iterator II, unsigned pReg, bool secondReg, bool optLocation, MachineBasicBlock::iterator end, MachineFunction &MF)
Function & getFunction()
Return the LLVM function that this machine code represents.
INITIALIZE_PASS_BEGIN(HexagonNewValueJump, "hexagon-nvj", "Hexagon NewValueJump", false, false) INITIALIZE_PASS_END(HexagonNewValueJump
Iterator for intrusive lists based on ilist_node.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned getKillRegState(bool B)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static cl::opt< bool > DisableNewValueJumps("disable-nvjump", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable New Value Jumps"))
std::vector< MachineBasicBlock * >::const_iterator const_succ_iterator
FunctionPass class - This class is used to implement most global optimizations.
AnalysisUsage & addRequired()
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
static bool commonChecksToProhibitNewValueJump(bool afterRA, MachineBasicBlock::iterator MII)