void MachineBlockPlacement::placeChainsTopologically(MachineFunction &F) { MachineBasicBlock *EntryB = &F.front(); assert(BlockToChain[EntryB] && "Missing chain for entry block"); assert(*BlockToChain[EntryB]->begin() == EntryB && "Entry block is not the head of the entry block chain"); // Walk the blocks in RPO, and insert each block for a chain in order the // first time we see that chain. MachineFunction::iterator InsertPos = F.begin(); SmallPtrSet<BlockChain *, 16> VisitedChains; ReversePostOrderTraversal<MachineBasicBlock *> RPOT(EntryB); typedef ReversePostOrderTraversal<MachineBasicBlock *>::rpo_iterator rpo_iterator; for (rpo_iterator I = RPOT.begin(), E = RPOT.end(); I != E; ++I) { BlockChain *Chain = BlockToChain[*I]; assert(Chain); if(!VisitedChains.insert(Chain)) continue; for (BlockChain::iterator BI = Chain->begin(), BE = Chain->end(); BI != BE; ++BI) { DEBUG(dbgs() << (BI == Chain->begin() ? "Placing chain " : " ... ") << getBlockName(*BI) << "\n"); if (InsertPos != MachineFunction::iterator(*BI)) F.splice(InsertPos, *BI); else ++InsertPos; } } // Now that every block is in its final position, update all of the // terminators. SmallVector<MachineOperand, 4> Cond; // For AnalyzeBranch. for (MachineFunction::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { // FIXME: It would be awesome of updateTerminator would just return rather // than assert when the branch cannot be analyzed in order to remove this // boiler plate. Cond.clear(); MachineBasicBlock *TBB = 0, *FBB = 0; // For AnalyzeBranch. if (!TII->AnalyzeBranch(*FI, TBB, FBB, Cond)) FI->updateTerminator(); } }
/// \brief Merge a chain with any viable successor. /// /// This routine walks the predecessors of the current block, looking for /// viable merge candidates. It has strict rules it uses to determine when /// a predecessor can be merged with the current block, which center around /// preserving the CFG structure. It performs the merge if any viable candidate /// is found. void MachineBlockPlacement::mergeSuccessor(MachineBasicBlock *BB, BlockChain *Chain, BlockFilterSet *Filter) { assert(BB); assert(Chain); // If this block is not at the end of its chain, it cannot merge with any // other chain. if (Chain && *llvm::prior(Chain->end()) != BB) return; // Walk through the successors looking for the highest probability edge. MachineBasicBlock *Successor = 0; BranchProbability BestProb = BranchProbability::getZero(); DEBUG(dbgs() << "Attempting merge from: " << getBlockName(BB) << "\n"); for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), SE = BB->succ_end(); SI != SE; ++SI) { if (BB == *SI || (Filter && !Filter->count(*SI))) continue; BranchProbability SuccProb = MBPI->getEdgeProbability(BB, *SI); DEBUG(dbgs() << " " << getBlockName(*SI) << " -> " << SuccProb << "\n"); if (!Successor || SuccProb > BestProb || (!(SuccProb < BestProb) && BB->isLayoutSuccessor(*SI))) { Successor = *SI; BestProb = SuccProb; } } if (!Successor) return; // Grab a chain if it exists already for this successor and make sure the // successor is at the start of the chain as we can't merge mid-chain. Also, // if the successor chain is the same as our chain, we're already merged. BlockChain *SuccChain = BlockToChain[Successor]; if (SuccChain && (SuccChain == Chain || Successor != *SuccChain->begin())) return; // We only merge chains across a CFG merge when the desired merge path is // significantly hotter than the incoming edge. We define a hot edge more // strictly than the BranchProbabilityInfo does, as the two predecessor // blocks may have dramatically different incoming probabilities we need to // account for. Therefor we use the "global" edge weight which is the // branch's probability times the block frequency of the predecessor. BlockFrequency MergeWeight = MBFI->getBlockFreq(BB); MergeWeight *= MBPI->getEdgeProbability(BB, Successor); // We only want to consider breaking the CFG when the merge weight is much // higher (80% vs. 20%), so multiply it by 1/4. This will require the merged // edge to be 4x more likely before we disrupt the CFG. This number matches // the definition of "hot" in BranchProbabilityAnalysis (80% vs. 20%). MergeWeight *= BranchProbability(1, 4); for (MachineBasicBlock::pred_iterator PI = Successor->pred_begin(), PE = Successor->pred_end(); PI != PE; ++PI) { if (BB == *PI || Successor == *PI) continue; BlockFrequency PredWeight = MBFI->getBlockFreq(*PI); PredWeight *= MBPI->getEdgeProbability(*PI, Successor); // Return on the first predecessor we find which outstrips our merge weight. if (MergeWeight < PredWeight) return; DEBUG(dbgs() << "Breaking CFG edge!\n" << " Edge from " << getBlockNum(BB) << " to " << getBlockNum(Successor) << ": " << MergeWeight << "\n" << " vs. " << getBlockNum(BB) << " to " << getBlockNum(*PI) << ": " << PredWeight << "\n"); } DEBUG(dbgs() << "Merging from " << getBlockNum(BB) << " to " << getBlockNum(Successor) << "\n"); Chain->merge(Successor, SuccChain); }