123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- //===- LoopTraversal.cpp - Optimal basic block traversal order --*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #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.pop_back_val();
- 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;
- }
|