|
24 | 24 | #include "llvm/ADT/DenseMap.h"
|
25 | 25 | #include "llvm/ADT/DenseSet.h"
|
26 | 26 | #include "llvm/ADT/DepthFirstIterator.h"
|
| 27 | +#include "llvm/ADT/PostOrderIterator.h" |
27 | 28 | #include "llvm/ADT/STLExtras.h"
|
28 | 29 | #include "llvm/ADT/SetOperations.h"
|
29 | 30 | #include "llvm/ADT/SmallPtrSet.h"
|
@@ -2126,34 +2127,46 @@ MachineVerifier::visitMachineBasicBlockAfter(const MachineBasicBlock *MBB) {
|
2126 | 2127 | // can pass through an MBB live, but may not be live every time. It is assumed
|
2127 | 2128 | // that all vregsPassed sets are empty before the call.
|
2128 | 2129 | void MachineVerifier::calcRegsPassed() {
|
| 2130 | + // This is a forward dataflow, doing it in RPO. A standard map serves as a |
| 2131 | + // priority (sorting by RPO number) queue, deduplicating worklist, and an RPO |
| 2132 | + // number to MBB mapping all at once. |
| 2133 | + std::map<unsigned, const MachineBasicBlock *> RPOWorklist; |
| 2134 | + DenseMap<const MachineBasicBlock *, unsigned> RPONumbers; |
| 2135 | + if (MF->empty()) { |
| 2136 | + // ReversePostOrderTraversal doesn't handle empty functions. |
| 2137 | + return; |
| 2138 | + } |
| 2139 | + for (const MachineBasicBlock *MBB : |
| 2140 | + ReversePostOrderTraversal<const MachineFunction *>(MF)) { |
| 2141 | + // Careful with the evaluation order, fetch next number before allocating. |
| 2142 | + unsigned Number = RPONumbers.size(); |
| 2143 | + RPONumbers[MBB] = Number; |
| 2144 | + } |
2129 | 2145 | // First push live-out regs to successors' vregsPassed. Remember the MBBs that
|
2130 | 2146 | // have any vregsPassed.
|
2131 |
| - SmallPtrSet<const MachineBasicBlock*, 8> todo; |
2132 |
| - for (const auto &MBB : *MF) { |
| 2147 | + for (const MachineBasicBlock &MBB : *MF) { |
2133 | 2148 | BBInfo &MInfo = MBBInfoMap[&MBB];
|
2134 | 2149 | if (!MInfo.reachable)
|
2135 | 2150 | continue;
|
2136 |
| - for (MachineBasicBlock::const_succ_iterator SuI = MBB.succ_begin(), |
2137 |
| - SuE = MBB.succ_end(); SuI != SuE; ++SuI) { |
2138 |
| - BBInfo &SInfo = MBBInfoMap[*SuI]; |
| 2151 | + for (const MachineBasicBlock *Succ : MBB.successors()) { |
| 2152 | + BBInfo &SInfo = MBBInfoMap[Succ]; |
2139 | 2153 | if (SInfo.addPassed(MInfo.regsLiveOut))
|
2140 |
| - todo.insert(*SuI); |
| 2154 | + RPOWorklist.emplace(RPONumbers[Succ], Succ); |
2141 | 2155 | }
|
2142 | 2156 | }
|
2143 | 2157 |
|
2144 |
| - // Iteratively push vregsPassed to successors. This will converge to the same |
2145 |
| - // final state regardless of DenseSet iteration order. |
2146 |
| - while (!todo.empty()) { |
2147 |
| - const MachineBasicBlock *MBB = *todo.begin(); |
2148 |
| - todo.erase(MBB); |
| 2158 | + // Iteratively push vregsPassed to successors. |
| 2159 | + while (!RPOWorklist.empty()) { |
| 2160 | + auto Next = RPOWorklist.begin(); |
| 2161 | + const MachineBasicBlock *MBB = Next->second; |
| 2162 | + RPOWorklist.erase(Next); |
2149 | 2163 | BBInfo &MInfo = MBBInfoMap[MBB];
|
2150 |
| - for (MachineBasicBlock::const_succ_iterator SuI = MBB->succ_begin(), |
2151 |
| - SuE = MBB->succ_end(); SuI != SuE; ++SuI) { |
2152 |
| - if (*SuI == MBB) |
| 2164 | + for (const MachineBasicBlock *Succ : MBB->successors()) { |
| 2165 | + if (Succ == MBB) |
2153 | 2166 | continue;
|
2154 |
| - BBInfo &SInfo = MBBInfoMap[*SuI]; |
| 2167 | + BBInfo &SInfo = MBBInfoMap[Succ]; |
2155 | 2168 | if (SInfo.addPassed(MInfo.vregsPassed))
|
2156 |
| - todo.insert(*SuI); |
| 2169 | + RPOWorklist.emplace(RPONumbers[Succ], Succ); |
2157 | 2170 | }
|
2158 | 2171 | }
|
2159 | 2172 | }
|
|
0 commit comments