/// Splice - Move the sequence of instructions [Begin,End) to just before /// InsertPt. Update branch instructions as needed to account for broken /// fallthrough edges and to take advantage of newly exposed fallthrough /// opportunities. /// void CodePlacementOpt::Splice(MachineFunction &MF, MachineFunction::iterator InsertPt, MachineFunction::iterator Begin, MachineFunction::iterator End) { assert(Begin != MF.begin() && End != MF.begin() && InsertPt != MF.begin() && "Splice can't change the entry block!"); MachineFunction::iterator OldBeginPrior = prior(Begin); MachineFunction::iterator OldEndPrior = prior(End); MF.splice(InsertPt, Begin, End); prior(Begin)->updateTerminator(); OldBeginPrior->updateTerminator(); OldEndPrior->updateTerminator(); }
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(); } }