1*0bf841acSMarina Yatsina //===- LoopTraversal.cpp - Optimal basic block traversal order --*- C++ -*-===// 2*0bf841acSMarina Yatsina // 3*0bf841acSMarina Yatsina // The LLVM Compiler Infrastructure 4*0bf841acSMarina Yatsina // 5*0bf841acSMarina Yatsina // This file is distributed under the University of Illinois Open Source 6*0bf841acSMarina Yatsina // License. See LICENSE.TXT for details. 7*0bf841acSMarina Yatsina // 8*0bf841acSMarina Yatsina //===----------------------------------------------------------------------===// 9*0bf841acSMarina Yatsina 10*0bf841acSMarina Yatsina #include "llvm/CodeGen/LoopTraversal.h" 11*0bf841acSMarina Yatsina #include "llvm/ADT/PostOrderIterator.h" 12*0bf841acSMarina Yatsina #include "llvm/CodeGen/MachineFunction.h" 13*0bf841acSMarina Yatsina 14*0bf841acSMarina Yatsina using namespace llvm; 15*0bf841acSMarina Yatsina 16*0bf841acSMarina Yatsina bool LoopTraversal::isBlockDone(MachineBasicBlock *MBB) { 17*0bf841acSMarina Yatsina int MBBNumber = MBB->getNumber(); 18*0bf841acSMarina Yatsina assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number."); 19*0bf841acSMarina Yatsina return MBBInfos[MBBNumber].PrimaryCompleted && 20*0bf841acSMarina Yatsina MBBInfos[MBBNumber].IncomingCompleted == 21*0bf841acSMarina Yatsina MBBInfos[MBBNumber].PrimaryIncoming && 22*0bf841acSMarina Yatsina MBBInfos[MBBNumber].IncomingProcessed == MBB->pred_size(); 23*0bf841acSMarina Yatsina } 24*0bf841acSMarina Yatsina 25*0bf841acSMarina Yatsina LoopTraversal::TraversalOrder LoopTraversal::traverse(MachineFunction &MF) { 26*0bf841acSMarina Yatsina // Initialize the MMBInfos 27*0bf841acSMarina Yatsina MBBInfos.assign(MF.getNumBlockIDs(), MBBInfo()); 28*0bf841acSMarina Yatsina 29*0bf841acSMarina Yatsina MachineBasicBlock *Entry = &*MF.begin(); 30*0bf841acSMarina Yatsina ReversePostOrderTraversal<MachineBasicBlock *> RPOT(Entry); 31*0bf841acSMarina Yatsina SmallVector<MachineBasicBlock *, 4> Workqueue; 32*0bf841acSMarina Yatsina SmallVector<TraversedMBBInfo, 4> MBBTraversalOrder; 33*0bf841acSMarina Yatsina for (MachineBasicBlock *MBB : RPOT) { 34*0bf841acSMarina Yatsina // N.B: IncomingProcessed and IncomingCompleted were already updated while 35*0bf841acSMarina Yatsina // processing this block's predecessors. 36*0bf841acSMarina Yatsina int MBBNumber = MBB->getNumber(); 37*0bf841acSMarina Yatsina assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number."); 38*0bf841acSMarina Yatsina MBBInfos[MBBNumber].PrimaryCompleted = true; 39*0bf841acSMarina Yatsina MBBInfos[MBBNumber].PrimaryIncoming = MBBInfos[MBBNumber].IncomingProcessed; 40*0bf841acSMarina Yatsina bool Primary = true; 41*0bf841acSMarina Yatsina Workqueue.push_back(MBB); 42*0bf841acSMarina Yatsina while (!Workqueue.empty()) { 43*0bf841acSMarina Yatsina MachineBasicBlock *ActiveMBB = &*Workqueue.back(); 44*0bf841acSMarina Yatsina Workqueue.pop_back(); 45*0bf841acSMarina Yatsina bool Done = isBlockDone(ActiveMBB); 46*0bf841acSMarina Yatsina MBBTraversalOrder.push_back(TraversedMBBInfo(ActiveMBB, Primary, Done)); 47*0bf841acSMarina Yatsina for (MachineBasicBlock *Succ : ActiveMBB->successors()) { 48*0bf841acSMarina Yatsina int SuccNumber = Succ->getNumber(); 49*0bf841acSMarina Yatsina assert(SuccNumber < MBBInfos.size() && 50*0bf841acSMarina Yatsina "Unexpected basic block number."); 51*0bf841acSMarina Yatsina if (!isBlockDone(Succ)) { 52*0bf841acSMarina Yatsina if (Primary) 53*0bf841acSMarina Yatsina MBBInfos[SuccNumber].IncomingProcessed++; 54*0bf841acSMarina Yatsina if (Done) 55*0bf841acSMarina Yatsina MBBInfos[SuccNumber].IncomingCompleted++; 56*0bf841acSMarina Yatsina if (isBlockDone(Succ)) 57*0bf841acSMarina Yatsina Workqueue.push_back(Succ); 58*0bf841acSMarina Yatsina } 59*0bf841acSMarina Yatsina } 60*0bf841acSMarina Yatsina Primary = false; 61*0bf841acSMarina Yatsina } 62*0bf841acSMarina Yatsina } 63*0bf841acSMarina Yatsina 64*0bf841acSMarina Yatsina // We need to go through again and finalize any blocks that are not done yet. 65*0bf841acSMarina Yatsina // This is possible if blocks have dead predecessors, so we didn't visit them 66*0bf841acSMarina Yatsina // above. 67*0bf841acSMarina Yatsina for (MachineBasicBlock *MBB : RPOT) { 68*0bf841acSMarina Yatsina if (!isBlockDone(MBB)) 69*0bf841acSMarina Yatsina MBBTraversalOrder.push_back(TraversedMBBInfo(MBB, false, true)); 70*0bf841acSMarina Yatsina // Don't update successors here. We'll get to them anyway through this 71*0bf841acSMarina Yatsina // loop. 72*0bf841acSMarina Yatsina } 73*0bf841acSMarina Yatsina 74*0bf841acSMarina Yatsina MBBInfos.clear(); 75*0bf841acSMarina Yatsina 76*0bf841acSMarina Yatsina return MBBTraversalOrder; 77*0bf841acSMarina Yatsina } 78