50 #define DEBUG_TYPE "hexagon-nvj"
52 STATISTIC(NumNVJGenerated,
"Number of New Value Jump Instructions created");
56 "Maximum number of predicated jumps to be converted to New Value Jump"));
60 cl::desc(
"Disable New Value Jumps"));
85 const char *getPassName()
const override {
86 return "Hexagon NewValueJump";
102 "Hexagon NewValueJump",
false,
false)
118 if (QII->isPredicated(II))
150 for (
unsigned i = 0; i < II->getNumOperands(); ++i) {
151 if (II->getOperand(i).isReg() &&
152 (II->getOperand(i).isUse() || II->getOperand(i).isDef())) {
155 unsigned Reg = II->getOperand(i).getReg();
157 localBegin !=
end; ++localBegin) {
158 if (localBegin == skip )
continue;
160 if (localBegin->modifiesRegister(Reg, TRI) ||
161 localBegin->readsRegister(Reg, TRI))
177 if (MII->getDesc().mayStore())
181 if (MII->getOpcode() == Hexagon::J2_call)
204 if (MII->getOpcode() == Hexagon::LDriw_pred ||
205 MII->getOpcode() == Hexagon::STriw_pred)
228 if (!(isUInt<5>(v) ||
229 ((MI->
getOpcode() == Hexagon::C2_cmpeqi ||
230 MI->
getOpcode() == Hexagon::C2_cmpgti) &&
235 unsigned cmpReg1, cmpOp2 = 0;
265 if (localII->modifiesRegister(pReg, TRI) ||
266 localII->readsRegister(pReg, TRI))
276 if (localII->modifiesRegister(cmpReg1, TRI) ||
277 (secondReg && localII->modifiesRegister(cmpOp2, TRI)))
287 bool secondRegNewified,
300 case Hexagon::C2_cmpeq:
301 return taken ? Hexagon::J4_cmpeq_t_jumpnv_t
302 : Hexagon::J4_cmpeq_t_jumpnv_nt;
304 case Hexagon::C2_cmpeqi: {
306 return taken ? Hexagon::J4_cmpeqi_t_jumpnv_t
307 : Hexagon::J4_cmpeqi_t_jumpnv_nt;
309 return taken ? Hexagon::J4_cmpeqn1_t_jumpnv_t
310 : Hexagon::J4_cmpeqn1_t_jumpnv_nt;
313 case Hexagon::C2_cmpgt: {
314 if (secondRegNewified)
315 return taken ? Hexagon::J4_cmplt_t_jumpnv_t
316 : Hexagon::J4_cmplt_t_jumpnv_nt;
318 return taken ? Hexagon::J4_cmpgt_t_jumpnv_t
319 : Hexagon::J4_cmpgt_t_jumpnv_nt;
322 case Hexagon::C2_cmpgti: {
324 return taken ? Hexagon::J4_cmpgti_t_jumpnv_t
325 : Hexagon::J4_cmpgti_t_jumpnv_nt;
327 return taken ? Hexagon::J4_cmpgtn1_t_jumpnv_t
328 : Hexagon::J4_cmpgtn1_t_jumpnv_nt;
331 case Hexagon::C2_cmpgtu: {
332 if (secondRegNewified)
333 return taken ? Hexagon::J4_cmpltu_t_jumpnv_t
334 : Hexagon::J4_cmpltu_t_jumpnv_nt;
336 return taken ? Hexagon::J4_cmpgtu_t_jumpnv_t
337 : Hexagon::J4_cmpgtu_t_jumpnv_nt;
340 case Hexagon::C2_cmpgtui:
341 return taken ? Hexagon::J4_cmpgtui_t_jumpnv_t
342 : Hexagon::J4_cmpgtui_t_jumpnv_nt;
353 DEBUG(
dbgs() <<
"********** Hexagon New Value Jump **********\n"
354 <<
"********** Function: "
363 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
370 int nvjGenerated = 0;
374 MBBb != MBBe; ++MBBb) {
380 DEBUG(
dbgs() <<
"\n" <<
"********** dumping instr bottom up **********\n");
381 bool foundJump =
false;
382 bool foundCompare =
false;
383 bool invertPredicate =
false;
384 unsigned predReg = 0;
385 unsigned cmpReg1 = 0;
387 bool MO1IsKill =
false;
388 bool MO2IsKill =
false;
393 bool afterRA =
false;
394 bool isSecondOpReg =
false;
395 bool isSecondOpNewified =
false;
404 if ((nvjCount == 0) || (nvjCount > -1 && nvjCount <= nvjGenerated))
412 MI->
getOpcode() == Hexagon::J2_jumptnewpt ||
413 MI->
getOpcode() == Hexagon::J2_jumptnew ||
414 MI->
getOpcode() == Hexagon::J2_jumpfnewpt ||
415 MI->
getOpcode() == Hexagon::J2_jumpfnew)) {
438 bool predLive =
false;
451 if (MI->
getOpcode() == Hexagon::J2_jumpf ||
452 MI->
getOpcode() == Hexagon::J2_jumpfnewpt ||
453 MI->
getOpcode() == Hexagon::J2_jumpfnew) {
454 invertPredicate =
true;
471 if (QII->isNewValueJumpCandidate(MI)) {
474 "Only compare instruction can be collapsed into New Value Jump");
478 afterRA, jmpPos, MF))
501 if (foundCompare && foundJump) {
507 bool foundFeeder =
false;
523 if (feederReg == cmpReg1) {
535 feederReg == (
unsigned) cmpOp2)
542 if (cmpInstr->
getOpcode() == Hexagon::C2_cmpeq &&
544 unsigned tmp = cmpReg1;
545 bool tmpIsKill = MO1IsKill;
547 MO1IsKill = MO2IsKill;
549 MO2IsKill = tmpIsKill;
555 if (feederReg == (
unsigned)cmpOp2)
556 isSecondOpNewified =
true;
563 bool updatedIsKill =
false;
567 unsigned feederReg = MO.
getReg();
569 end = jmpPos; localII !=
end; localII++) {
579 updatedIsKill =
true;
583 if (updatedIsKill)
break;
586 if (updatedIsKill)
break;
594 assert((QII->isNewValueJumpCandidate(cmpInstr)) &&
595 "This compare is not a New Value Jump candidate.");
600 opc = QII->getInvertedPredicatedOpcode(opc);
603 NewMI =
BuildMI(*MBB, jmpPos, dl,
609 else if ((cmpInstr->
getOpcode() == Hexagon::C2_cmpeqi ||
610 cmpInstr->
getOpcode() == Hexagon::C2_cmpgti) &&
614 NewMI =
BuildMI(*MBB, jmpPos, dl,
620 NewMI =
BuildMI(*MBB, jmpPos, dl,
626 assert(NewMI &&
"New Value Jump Instruction Not created!");
635 jmpInstr->eraseFromParent();
649 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
getNumber - MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a M...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void skip(CollectionType &C)
COPY - Target-independent register copy.
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...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
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.
const MachineBasicBlock * getParent() const
bool isDebugValue() const
bundle_iterator< MachineInstr, instr_iterator > iterator
static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg, bool secondRegNewified, MachineBasicBlock *jmpTarget, const MachineBranchProbabilityInfo *MBPI)
initializer< Ty > init(const Ty &Val)
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.
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
succ_iterator succ_begin()
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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()
MachineOperand class - Representation of each machine instruction operand.
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.
KILL - This instruction is a noop that is used only to adjust the liveness of registers.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
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 '...
bool isLiveIn(unsigned Reg) const
isLiveIn - Return true if the specified register is in the live in set.
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
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.
std::vector< MachineBasicBlock * >::const_iterator const_succ_iterator
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
BasicBlockListType::iterator iterator
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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
static cl::opt< bool > DisableNewValueJumps("disable-nvjump", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable New Value Jumps"))