78 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===- LoopTraversal.cpp - Optimal basic block traversal order --*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/CodeGen/LoopTraversal.h"
 | |
| #include "llvm/ADT/PostOrderIterator.h"
 | |
| #include "llvm/CodeGen/MachineFunction.h"
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| bool LoopTraversal::isBlockDone(MachineBasicBlock *MBB) {
 | |
|   unsigned MBBNumber = MBB->getNumber();
 | |
|   assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number.");
 | |
|   return MBBInfos[MBBNumber].PrimaryCompleted &&
 | |
|          MBBInfos[MBBNumber].IncomingCompleted ==
 | |
|              MBBInfos[MBBNumber].PrimaryIncoming &&
 | |
|          MBBInfos[MBBNumber].IncomingProcessed == MBB->pred_size();
 | |
| }
 | |
| 
 | |
| LoopTraversal::TraversalOrder LoopTraversal::traverse(MachineFunction &MF) {
 | |
|   // Initialize the MMBInfos
 | |
|   MBBInfos.assign(MF.getNumBlockIDs(), MBBInfo());
 | |
| 
 | |
|   MachineBasicBlock *Entry = &*MF.begin();
 | |
|   ReversePostOrderTraversal<MachineBasicBlock *> RPOT(Entry);
 | |
|   SmallVector<MachineBasicBlock *, 4> Workqueue;
 | |
|   SmallVector<TraversedMBBInfo, 4> MBBTraversalOrder;
 | |
|   for (MachineBasicBlock *MBB : RPOT) {
 | |
|     // N.B: IncomingProcessed and IncomingCompleted were already updated while
 | |
|     // processing this block's predecessors.
 | |
|     unsigned MBBNumber = MBB->getNumber();
 | |
|     assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number.");
 | |
|     MBBInfos[MBBNumber].PrimaryCompleted = true;
 | |
|     MBBInfos[MBBNumber].PrimaryIncoming = MBBInfos[MBBNumber].IncomingProcessed;
 | |
|     bool Primary = true;
 | |
|     Workqueue.push_back(MBB);
 | |
|     while (!Workqueue.empty()) {
 | |
|       MachineBasicBlock *ActiveMBB = &*Workqueue.back();
 | |
|       Workqueue.pop_back();
 | |
|       bool Done = isBlockDone(ActiveMBB);
 | |
|       MBBTraversalOrder.push_back(TraversedMBBInfo(ActiveMBB, Primary, Done));
 | |
|       for (MachineBasicBlock *Succ : ActiveMBB->successors()) {
 | |
|         unsigned SuccNumber = Succ->getNumber();
 | |
|         assert(SuccNumber < MBBInfos.size() &&
 | |
|                "Unexpected basic block number.");
 | |
|         if (!isBlockDone(Succ)) {
 | |
|           if (Primary)
 | |
|             MBBInfos[SuccNumber].IncomingProcessed++;
 | |
|           if (Done)
 | |
|             MBBInfos[SuccNumber].IncomingCompleted++;
 | |
|           if (isBlockDone(Succ))
 | |
|             Workqueue.push_back(Succ);
 | |
|         }
 | |
|       }
 | |
|       Primary = false;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // We need to go through again and finalize any blocks that are not done yet.
 | |
|   // This is possible if blocks have dead predecessors, so we didn't visit them
 | |
|   // above.
 | |
|   for (MachineBasicBlock *MBB : RPOT) {
 | |
|     if (!isBlockDone(MBB))
 | |
|       MBBTraversalOrder.push_back(TraversedMBBInfo(MBB, false, true));
 | |
|     // Don't update successors here. We'll get to them anyway through this
 | |
|     // loop.
 | |
|   }
 | |
| 
 | |
|   MBBInfos.clear();
 | |
| 
 | |
|   return MBBTraversalOrder;
 | |
| }
 |