19 #define DEBUG_TYPE "early-ifcvt"
47 cl::desc(
"Maximum number of instructions per speculated block."));
53 STATISTIC(NumDiamondsSeen,
"Number of diamonds");
54 STATISTIC(NumDiamondsConv,
"Number of diamonds converted");
55 STATISTIC(NumTrianglesSeen,
"Number of triangles");
56 STATISTIC(NumTrianglesConv,
"Number of triangles converted");
100 bool isTriangle()
const {
return TBB == Tail || FBB == Tail; }
113 int CondCycles, TCycles, FCycles;
116 :
PHI(phi), TReg(0), FReg(0), CondCycles(0), TCycles(0), FCycles(0) {}
144 bool findInsertionPoint();
147 void replacePHIInstrs();
150 void rewritePHIOperands();
160 ClobberedRegUnits.
clear();
161 ClobberedRegUnits.resize(TRI->getNumRegUnits());
191 unsigned InstrCount = 0;
197 if (
I->isDebugValue())
216 DEBUG(
dbgs() <<
"Won't speculate load: " << *
I);
221 bool DontMoveAcrossStore =
true;
222 if (!
I->isSafeToMove(
TII, 0, DontMoveAcrossStore)) {
229 if (MO->isRegMask()) {
230 DEBUG(
dbgs() <<
"Won't speculate regmask: " << *
I);
235 unsigned Reg = MO->getReg();
240 ClobberedRegUnits.set(*Units);
245 if (!DefMI || DefMI->
getParent() != Head)
247 if (InsertAfter.insert(DefMI))
250 DEBUG(
dbgs() <<
"Can't insert instructions below terminator.\n");
269 bool SSAIfConv::findInsertionPoint() {
280 if (InsertAfter.count(I)) {
281 DEBUG(
dbgs() <<
"Can't insert code after " << *I);
290 unsigned Reg = MO->getReg();
302 while (!Reads.
empty())
305 if (ClobberedRegUnits.test(*Units))
309 if (I != FirstTerm && I->isTerminator())
316 dbgs() <<
"Would clobber";
320 dbgs() <<
" live before " << *
I;
327 DEBUG(
dbgs() <<
"Can insert before " << *I);
330 DEBUG(
dbgs() <<
"No legal insertion point found.\n");
341 TBB = FBB = Tail = 0;
343 if (Head->succ_size() != 2)
363 DEBUG(
dbgs() <<
"\nDiamond: BB#" << Head->getNumber()
366 <<
" -> BB#" << Tail->getNumber() <<
'\n');
369 if (!Tail->livein_empty()) {
374 DEBUG(
dbgs() <<
"\nTriangle: BB#" << Head->getNumber()
376 <<
" -> BB#" << Tail->getNumber() <<
'\n');
381 if (Tail->empty() || !Tail->front().isPHI()) {
389 DEBUG(
dbgs() <<
"Branch not analyzable.\n");
395 DEBUG(
dbgs() <<
"AnalyzeBranch didn't find conditional branch.\n");
401 FBB = TBB == Succ0 ? Succ1 : Succ0;
408 I != E && I->isPHI(); ++
I) {
410 PHIInfo &PI = PHIs.back();
412 for (
unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) {
413 if (PI.PHI->getOperand(i+1).getMBB() == TPred)
414 PI.TReg = PI.PHI->getOperand(i).getReg();
415 if (PI.PHI->getOperand(i+1).getMBB() == FPred)
416 PI.FReg = PI.PHI->getOperand(i).getReg();
422 if (!
TII->canInsertSelect(*Head, Cond, PI.TReg, PI.FReg,
423 PI.CondCycles, PI.TCycles, PI.FCycles)) {
424 DEBUG(
dbgs() <<
"Can't convert: " << *PI.PHI);
431 ClobberedRegUnits.reset();
432 if (TBB != Tail && !canSpeculateInstrs(TBB))
434 if (FBB != Tail && !canSpeculateInstrs(FBB))
439 if (!findInsertionPoint())
452 void SSAIfConv::replacePHIInstrs() {
453 assert(Tail->pred_size() == 2 &&
"Cannot replace PHIs");
455 assert(FirstTerm != Head->end() &&
"No terminators");
456 DebugLoc HeadDL = FirstTerm->getDebugLoc();
459 for (
unsigned i = 0, e = PHIs.size(); i != e; ++i) {
460 PHIInfo &PI = PHIs[i];
461 DEBUG(
dbgs() <<
"If-converting " << *PI.PHI);
462 unsigned DstReg = PI.PHI->getOperand(0).getReg();
463 TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg);
465 PI.PHI->eraseFromParent();
473 void SSAIfConv::rewritePHIOperands() {
475 assert(FirstTerm != Head->end() &&
"No terminators");
476 DebugLoc HeadDL = FirstTerm->getDebugLoc();
479 for (
unsigned i = 0, e = PHIs.size(); i != e; ++i) {
480 PHIInfo &PI = PHIs[i];
481 DEBUG(
dbgs() <<
"If-converting " << *PI.PHI);
482 unsigned PHIDst = PI.PHI->getOperand(0).getReg();
484 TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg);
488 for (
unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) {
490 if (MBB == getTPred()) {
491 PI.PHI->getOperand(i-1).setMBB(Head);
492 PI.PHI->getOperand(i-2).setReg(DstReg);
493 }
else if (MBB == getFPred()) {
494 PI.PHI->RemoveOperand(i-1);
495 PI.PHI->RemoveOperand(i-2);
508 assert(Head && Tail && TBB && FBB &&
"Call canConvertIf first.");
518 Head->splice(InsertionPoint, TBB, TBB->begin(), TBB->getFirstTerminator());
520 Head->splice(InsertionPoint, FBB, FBB->begin(), FBB->getFirstTerminator());
523 bool ExtraPreds = Tail->pred_size() != 2;
525 rewritePHIOperands();
530 Head->removeSuccessor(TBB);
531 Head->removeSuccessor(FBB);
533 TBB->removeSuccessor(Tail);
535 FBB->removeSuccessor(Tail);
539 DebugLoc HeadDL = Head->getFirstTerminator()->getDebugLoc();
546 TBB->eraseFromParent();
550 FBB->eraseFromParent();
553 assert(Head->succ_empty() &&
"Additional head successors?");
554 if (!ExtraPreds && Head->isLayoutSuccessor(Tail)) {
556 DEBUG(
dbgs() <<
"Joining tail BB#" << Tail->getNumber()
557 <<
" into head BB#" << Head->getNumber() <<
'\n');
558 Head->splice(Head->end(), Tail,
559 Tail->begin(), Tail->end());
560 Head->transferSuccessorsAndUpdatePHIs(Tail);
562 Tail->eraseFromParent();
565 DEBUG(
dbgs() <<
"Converting to unconditional branch.\n");
568 Head->addSuccessor(Tail);
595 const char *getPassName()
const {
return "Early If-Conversion"; }
601 void invalidateTraces();
602 bool shouldConvertIf();
610 "early-ifcvt",
"Early If Converter",
false,
false)
617 void EarlyIfConverter::getAnalysisUsage(
AnalysisUsage &AU)
const {
634 for (
unsigned i = 0, e = Removed.
size(); i != e; ++i) {
636 assert(Node != HeadNode &&
"Cannot erase the head node");
638 assert(Node->
getBlock() == IfConv.Tail &&
"Unexpected children");
639 DomTree->changeImmediateDominator(Node->
getChildren().back(), HeadNode);
641 DomTree->eraseNode(Removed[i]);
651 for (
unsigned i = 0, e = Removed.
size(); i != e; ++i)
652 Loops->removeBlock(Removed[i]);
656 void EarlyIfConverter::invalidateTraces() {
657 Traces->verifyAnalysis();
658 Traces->invalidate(IfConv.Head);
659 Traces->invalidate(IfConv.Tail);
660 Traces->invalidate(IfConv.TBB);
661 Traces->invalidate(IfConv.FBB);
662 Traces->verifyAnalysis();
667 if (Delta < 0 && Cyc + Delta > Cyc)
675 bool EarlyIfConverter::shouldConvertIf() {
685 DEBUG(
dbgs() <<
"TBB: " << TBBTrace <<
"FBB: " << FBBTrace);
690 unsigned CritLimit = SchedModel->MispredictPenalty/2;
696 if (IfConv.TBB != IfConv.Tail)
699 DEBUG(
dbgs() <<
"Resource length " << ResLength
700 <<
", minimal critical path " << MinCrit <<
'\n');
701 if (ResLength > MinCrit + CritLimit) {
702 DEBUG(
dbgs() <<
"Not enough available ILP.\n");
710 unsigned BranchDepth =
711 HeadTrace.
getInstrCycles(IfConv.Head->getFirstTerminator()).Depth;
712 DEBUG(
dbgs() <<
"Branch depth: " << BranchDepth <<
'\n');
717 for (
unsigned i = 0, e = IfConv.PHIs.size(); i != e; ++i) {
718 SSAIfConv::PHIInfo &PI = IfConv.PHIs[i];
721 DEBUG(
dbgs() <<
"Slack " << Slack <<
":\t" << *PI.PHI);
724 unsigned CondDepth =
adjCycles(BranchDepth, PI.CondCycles);
725 if (CondDepth > MaxDepth) {
726 unsigned Extra = CondDepth -
MaxDepth;
727 DEBUG(
dbgs() <<
"Condition adds " << Extra <<
" cycles.\n");
728 if (Extra > CritLimit) {
729 DEBUG(
dbgs() <<
"Exceeds limit of " << CritLimit <<
'\n');
736 if (TDepth > MaxDepth) {
738 DEBUG(
dbgs() <<
"TBB data adds " << Extra <<
" cycles.\n");
739 if (Extra > CritLimit) {
740 DEBUG(
dbgs() <<
"Exceeds limit of " << CritLimit <<
'\n');
747 if (FDepth > MaxDepth) {
749 DEBUG(
dbgs() <<
"FBB data adds " << Extra <<
" cycles.\n");
750 if (Extra > CritLimit) {
751 DEBUG(
dbgs() <<
"Exceeds limit of " << CritLimit <<
'\n');
762 bool Changed =
false;
763 while (IfConv.canConvertIf(MBB) && shouldConvertIf()) {
767 IfConv.convertIf(RemovedBlocks);
769 updateDomTree(RemovedBlocks);
770 updateLoops(RemovedBlocks);
776 DEBUG(
dbgs() <<
"********** EARLY IF-CONVERSION **********\n"
777 <<
"********** Function: " << MF.
getName() <<
'\n');
783 DomTree = &getAnalysis<MachineDominatorTree>();
784 Loops = getAnalysisIfAvailable<MachineLoopInfo>();
785 Traces = &getAnalysis<MachineTraceMetrics>();
788 bool Changed =
false;
789 IfConv.runOnMachineFunction(MF);
797 if (tryConvertIf(I->getBlock()))
unsigned succ_size() const
void push_back(const T &Elt)
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const
static cl::opt< bool > Stress("stress-early-ifcvt", cl::Hidden, cl::desc("Turn all knobs to 11"))
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
iterator getFirstTerminator()
static bool isVirtualRegister(unsigned Reg)
unsigned getCriticalPath() const
char & EarlyIfConverterID
bool isTerminator(QueryType Type=AnyInBundle) const
#define INITIALIZE_PASS_DEPENDENCY(depName)
const HexagonInstrInfo * TII
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
po_iterator< T > po_begin(T G)
ID
LLVM Calling Convention Representation.
Select the trace through a block that has the fewest instructions.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
bool livein_empty() const
size_t size() const
size - Get the array size.
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value. See class MCOperandInfo.
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl< MachineOperand > &Cond, DebugLoc DL) const
succ_iterator succ_begin()
STATISTIC(NumDiamondsSeen,"Number of diamonds")
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
virtual const TargetInstrInfo * getInstrInfo() const
static unsigned adjCycles(unsigned Cyc, int Delta)
const STC & getSubtarget() const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
static cl::opt< unsigned > BlockInstrLimit("early-ifcvt-limit", cl::init(30), cl::Hidden, cl::desc("Maximum number of instructions per speculated block."))
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
INITIALIZE_PASS_BEGIN(EarlyIfConverter,"early-ifcvt","Early If Converter", false, false) INITIALIZE_PASS_END(EarlyIfConverter
unsigned getResourceLength(ArrayRef< const MachineBasicBlock * > Extrablocks=None, ArrayRef< const MCSchedClassDesc * > ExtraInstrs=None) const
InstrCycles getInstrCycles(const MachineInstr *MI) const
static bool isPhysicalRegister(unsigned Reg)
MachineRegisterInfo & getRegInfo()
po_iterator< T > po_end(T G)
virtual void getAnalysisUsage(AnalysisUsage &AU) const
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
bool isValid() const
isValid - Returns true until all the operands have been visited.
unsigned getPHIDepth(const MachineInstr *PHI) const
ItTy prior(ItTy it, Dist n)
const MCRegisterInfo & MRI
StringRef getName() const
unsigned pred_size() const
size_t getNumChildren() const
unsigned getInstrSlack(const MachineInstr *MI) const