Index: lib/CodeGen/MachineBlockPlacement.cpp =================================================================== --- lib/CodeGen/MachineBlockPlacement.cpp +++ lib/CodeGen/MachineBlockPlacement.cpp @@ -78,10 +78,14 @@ "over the original exit to be considered the new exit."), cl::init(0), cl::Hidden); +// Definition: +// - Outlining: placement of a basic block outside the chain or hot path. + static cl::opt OutlineOptionalBranches( "outline-optional-branches", - cl::desc("Put completely optional branches, i.e. branches with a common " - "post dominator, out of line."), + cl::desc("Outlining optional branches will place blocks that are optional " + "branches, i.e. branches with a common post dominator, outside " + "the hot path or chain"), cl::init(false), cl::Hidden); static cl::opt OutlineOptionalThreshold( @@ -562,15 +566,26 @@ // | Pred // | / // Succ - // In this case, we are evaluating whether to select edge -> Succ, e.g. - // set Succ as the layout successor of BB. Picking Succ as BB's - // successor breaks the CFG constraints (FIXME: define these constraints). + // + // Here, we are evaluating to select Succ or Pred as a successor of BB. + // If we choose Succ, then we break the topological ordering and Pred needs + // to be outlined which is shown here: + // + // ---<---- + // | | + // BB-->Succ Pred + // | | + // ------>------ + // + // The cost = taken_branch(BB->Pred) + taken_back_branch(Pred->Succ) + + // uncond_branch(Pred->Succ) + // // With this layout, Pred BB // is forced to be outlined, so the overall cost will be cost of the // branch taken from BB to Pred, plus the cost of back taken branch // from Pred to Succ, as well as the additional cost associated // with the needed unconditional jump instruction from Pred To Succ. - + // // The cost of the topological order layout is the taken branch cost // from BB to Succ, so to make BB->Succ a viable candidate, the following // must hold: @@ -632,8 +647,10 @@ // Forward checking. For case 2, SuccProb will be 1. if (SuccProb < HotProb) { - DEBUG(dbgs() << " " << getBlockName(Succ) << " -> " << SuccProb - << " (prob) (CFG conflict)\n"); + DEBUG(dbgs() << " Not a candidate: " << getBlockName(Succ) << " " + << "Respecting topological ordering because " + << "probability is less than prob treshold: " + << SuccProb << "\n"); return true; } @@ -669,7 +686,7 @@ } if (BadCFGConflict) { - DEBUG(dbgs() << " " << getBlockName(Succ) << " -> " << SuccProb + DEBUG(dbgs() << " Not a candidate: " << getBlockName(Succ) << " -> " << SuccProb << " (prob) (non-cold CFG conflict)\n"); return true; } @@ -699,7 +716,7 @@ auto AdjustedSumProb = collectViableSuccessors(BB, Chain, BlockFilter, Successors); - DEBUG(dbgs() << "Attempting merge from: " << getBlockName(BB) << "\n"); + DEBUG(dbgs() << "Selecting best successor for: " << getBlockName(BB) << "\n"); for (MachineBasicBlock *Succ : Successors) { auto RealSuccProb = MBPI->getEdgeProbability(BB, Succ); BranchProbability SuccProb = @@ -718,15 +735,23 @@ continue; DEBUG( - dbgs() << " " << getBlockName(Succ) << " -> " << SuccProb - << " (prob)" + dbgs() << " Candidate: " << getBlockName(Succ) << ", probability: " + << SuccProb << (SuccChain.UnscheduledPredecessors != 0 ? " (CFG break)" : "") << "\n"); - if (BestSucc && BestProb >= SuccProb) + + if (BestSucc && BestProb >= SuccProb) { + DEBUG(dbgs() << " Not the best candidate, continuing\n"); continue; + } + + DEBUG(dbgs() << " Setting it as best candidate\n"); BestSucc = Succ; BestProb = SuccProb; } + if (BestSucc) + DEBUG(dbgs() << " Selected: " << getBlockName(BestSucc) << "\n"); + return BestSucc; } @@ -937,7 +962,7 @@ for (MachineBasicBlock *Pred : L.getHeader()->predecessors()) { if (!LoopBlockSet.count(Pred)) continue; - DEBUG(dbgs() << " header pred: " << getBlockName(Pred) << ", " + DEBUG(dbgs() << " header pred: " << getBlockName(Pred) << ", has " << Pred->succ_size() << " successors, "; MBFI->printBlockFreq(dbgs(), Pred) << " freq\n"); if (Pred->succ_size() > 1) @@ -1066,8 +1091,14 @@ } // Without a candidate exiting block or with only a single block in the // loop, just use the loop header to layout the loop. - if (!ExitingBB || L.getNumBlocks() == 1) + if (!ExitingBB) { + DEBUG(dbgs() << " No other candidate exit blocks, using loop header\n"); return nullptr; + } + if (L.getNumBlocks() == 1) { + DEBUG(dbgs() << " Loop has 1 block, using loop header as exit\n"); + return nullptr; + } // Also, if we have exit blocks which lead to outer loops but didn't select // one of them as the exiting block we are rotating toward, disable loop