LLVM  8.0.1
LoopTraversal.cpp
Go to the documentation of this file.
1 //===- LoopTraversal.cpp - Optimal basic block traversal order --*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
13 
14 using namespace llvm;
15 
16 bool LoopTraversal::isBlockDone(MachineBasicBlock *MBB) {
17  unsigned MBBNumber = MBB->getNumber();
18  assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number.");
19  return MBBInfos[MBBNumber].PrimaryCompleted &&
20  MBBInfos[MBBNumber].IncomingCompleted ==
21  MBBInfos[MBBNumber].PrimaryIncoming &&
22  MBBInfos[MBBNumber].IncomingProcessed == MBB->pred_size();
23 }
24 
26  // Initialize the MMBInfos
27  MBBInfos.assign(MF.getNumBlockIDs(), MBBInfo());
28 
29  MachineBasicBlock *Entry = &*MF.begin();
32  SmallVector<TraversedMBBInfo, 4> MBBTraversalOrder;
33  for (MachineBasicBlock *MBB : RPOT) {
34  // N.B: IncomingProcessed and IncomingCompleted were already updated while
35  // processing this block's predecessors.
36  unsigned MBBNumber = MBB->getNumber();
37  assert(MBBNumber < MBBInfos.size() && "Unexpected basic block number.");
38  MBBInfos[MBBNumber].PrimaryCompleted = true;
39  MBBInfos[MBBNumber].PrimaryIncoming = MBBInfos[MBBNumber].IncomingProcessed;
40  bool Primary = true;
41  Workqueue.push_back(MBB);
42  while (!Workqueue.empty()) {
43  MachineBasicBlock *ActiveMBB = &*Workqueue.back();
44  Workqueue.pop_back();
45  bool Done = isBlockDone(ActiveMBB);
46  MBBTraversalOrder.push_back(TraversedMBBInfo(ActiveMBB, Primary, Done));
47  for (MachineBasicBlock *Succ : ActiveMBB->successors()) {
48  unsigned SuccNumber = Succ->getNumber();
49  assert(SuccNumber < MBBInfos.size() &&
50  "Unexpected basic block number.");
51  if (!isBlockDone(Succ)) {
52  if (Primary)
53  MBBInfos[SuccNumber].IncomingProcessed++;
54  if (Done)
55  MBBInfos[SuccNumber].IncomingCompleted++;
56  if (isBlockDone(Succ))
57  Workqueue.push_back(Succ);
58  }
59  }
60  Primary = false;
61  }
62  }
63 
64  // We need to go through again and finalize any blocks that are not done yet.
65  // This is possible if blocks have dead predecessors, so we didn't visit them
66  // above.
67  for (MachineBasicBlock *MBB : RPOT) {
68  if (!isBlockDone(MBB))
69  MBBTraversalOrder.push_back(TraversedMBBInfo(MBB, false, true));
70  // Don't update successors here. We'll get to them anyway through this
71  // loop.
72  }
73 
74  MBBInfos.clear();
75 
76  return MBBTraversalOrder;
77 }
This class represents lattice values for constants.
Definition: AllocatorList.h:24
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID&#39;s allocated.
iterator_range< succ_iterator > successors()
void assign(size_type NumElts, const T &Elt)
Definition: SmallVector.h:423
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they&#39;re not in a MachineFuncti...
size_t size() const
Definition: SmallVector.h:53
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
unsigned pred_size() const
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
TraversalOrder traverse(MachineFunction &MF)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())