10bf841acSMarina Yatsina //===- LoopTraversal.cpp - Optimal basic block traversal order --*- C++ -*-===// 20bf841acSMarina Yatsina // 30bf841acSMarina Yatsina // The LLVM Compiler Infrastructure 40bf841acSMarina Yatsina // 50bf841acSMarina Yatsina // This file is distributed under the University of Illinois Open Source 60bf841acSMarina Yatsina // License. See LICENSE.TXT for details. 70bf841acSMarina Yatsina // 80bf841acSMarina Yatsina //===----------------------------------------------------------------------===// 90bf841acSMarina Yatsina 100bf841acSMarina Yatsina #include "llvm/CodeGen/LoopTraversal.h" 110bf841acSMarina Yatsina #include "llvm/ADT/PostOrderIterator.h" 120bf841acSMarina Yatsina #include "llvm/CodeGen/MachineFunction.h" 130bf841acSMarina Yatsina 140bf841acSMarina Yatsina using namespace llvm; 150bf841acSMarina Yatsina 160bf841acSMarina Yatsina bool LoopTraversal::isBlockDone(MachineBasicBlock *MBB) { 17*e4d63a49SMarina Yatsina unsigned MBBNumber = MBB->getNumber(); 180bf841acSMarina Yatsina assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number."); 190bf841acSMarina Yatsina return MBBInfos[MBBNumber].PrimaryCompleted && 200bf841acSMarina Yatsina MBBInfos[MBBNumber].IncomingCompleted == 210bf841acSMarina Yatsina MBBInfos[MBBNumber].PrimaryIncoming && 220bf841acSMarina Yatsina MBBInfos[MBBNumber].IncomingProcessed == MBB->pred_size(); 230bf841acSMarina Yatsina } 240bf841acSMarina Yatsina 250bf841acSMarina Yatsina LoopTraversal::TraversalOrder LoopTraversal::traverse(MachineFunction &MF) { 260bf841acSMarina Yatsina // Initialize the MMBInfos 270bf841acSMarina Yatsina MBBInfos.assign(MF.getNumBlockIDs(), MBBInfo()); 280bf841acSMarina Yatsina 290bf841acSMarina Yatsina MachineBasicBlock *Entry = &*MF.begin(); 300bf841acSMarina Yatsina ReversePostOrderTraversal<MachineBasicBlock *> RPOT(Entry); 310bf841acSMarina Yatsina SmallVector<MachineBasicBlock *, 4> Workqueue; 320bf841acSMarina Yatsina SmallVector<TraversedMBBInfo, 4> MBBTraversalOrder; 330bf841acSMarina Yatsina for (MachineBasicBlock *MBB : RPOT) { 340bf841acSMarina Yatsina // N.B: IncomingProcessed and IncomingCompleted were already updated while 350bf841acSMarina Yatsina // processing this block's predecessors. 36*e4d63a49SMarina Yatsina unsigned MBBNumber = MBB->getNumber(); 370bf841acSMarina Yatsina assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number."); 380bf841acSMarina Yatsina MBBInfos[MBBNumber].PrimaryCompleted = true; 390bf841acSMarina Yatsina MBBInfos[MBBNumber].PrimaryIncoming = MBBInfos[MBBNumber].IncomingProcessed; 400bf841acSMarina Yatsina bool Primary = true; 410bf841acSMarina Yatsina Workqueue.push_back(MBB); 420bf841acSMarina Yatsina while (!Workqueue.empty()) { 430bf841acSMarina Yatsina MachineBasicBlock *ActiveMBB = &*Workqueue.back(); 440bf841acSMarina Yatsina Workqueue.pop_back(); 450bf841acSMarina Yatsina bool Done = isBlockDone(ActiveMBB); 460bf841acSMarina Yatsina MBBTraversalOrder.push_back(TraversedMBBInfo(ActiveMBB, Primary, Done)); 470bf841acSMarina Yatsina for (MachineBasicBlock *Succ : ActiveMBB->successors()) { 48*e4d63a49SMarina Yatsina unsigned SuccNumber = Succ->getNumber(); 490bf841acSMarina Yatsina assert(SuccNumber < MBBInfos.size() && 500bf841acSMarina Yatsina "Unexpected basic block number."); 510bf841acSMarina Yatsina if (!isBlockDone(Succ)) { 520bf841acSMarina Yatsina if (Primary) 530bf841acSMarina Yatsina MBBInfos[SuccNumber].IncomingProcessed++; 540bf841acSMarina Yatsina if (Done) 550bf841acSMarina Yatsina MBBInfos[SuccNumber].IncomingCompleted++; 560bf841acSMarina Yatsina if (isBlockDone(Succ)) 570bf841acSMarina Yatsina Workqueue.push_back(Succ); 580bf841acSMarina Yatsina } 590bf841acSMarina Yatsina } 600bf841acSMarina Yatsina Primary = false; 610bf841acSMarina Yatsina } 620bf841acSMarina Yatsina } 630bf841acSMarina Yatsina 640bf841acSMarina Yatsina // We need to go through again and finalize any blocks that are not done yet. 650bf841acSMarina Yatsina // This is possible if blocks have dead predecessors, so we didn't visit them 660bf841acSMarina Yatsina // above. 670bf841acSMarina Yatsina for (MachineBasicBlock *MBB : RPOT) { 680bf841acSMarina Yatsina if (!isBlockDone(MBB)) 690bf841acSMarina Yatsina MBBTraversalOrder.push_back(TraversedMBBInfo(MBB, false, true)); 700bf841acSMarina Yatsina // Don't update successors here. We'll get to them anyway through this 710bf841acSMarina Yatsina // loop. 720bf841acSMarina Yatsina } 730bf841acSMarina Yatsina 740bf841acSMarina Yatsina MBBInfos.clear(); 750bf841acSMarina Yatsina 760bf841acSMarina Yatsina return MBBTraversalOrder; 770bf841acSMarina Yatsina } 78