|
16 | 16 | #include "llvm/ADT/STLExtras.h" |
17 | 17 | #include "llvm/ADT/SmallVector.h" |
18 | 18 | #include "llvm/Analysis/LoopInfo.h" |
| 19 | +#include "llvm/Analysis/PostDominators.h" |
19 | 20 | #include "llvm/Analysis/TargetLibraryInfo.h" |
20 | 21 | #include "llvm/IR/Attributes.h" |
21 | 22 | #include "llvm/IR/BasicBlock.h" |
@@ -146,69 +147,83 @@ static const uint32_t IH_TAKEN_WEIGHT = 1024 * 1024 - 1; |
146 | 147 | /// instruction. This is essentially never taken. |
147 | 148 | static const uint32_t IH_NONTAKEN_WEIGHT = 1; |
148 | 149 |
|
149 | | -/// Add \p BB to PostDominatedByUnreachable set if applicable. |
150 | | -void |
151 | | -BranchProbabilityInfo::updatePostDominatedByUnreachable(const BasicBlock *BB) { |
152 | | - const Instruction *TI = BB->getTerminator(); |
153 | | - if (TI->getNumSuccessors() == 0) { |
154 | | - if (isa<UnreachableInst>(TI) || |
155 | | - // If this block is terminated by a call to |
156 | | - // @llvm.experimental.deoptimize then treat it like an unreachable since |
157 | | - // the @llvm.experimental.deoptimize call is expected to practically |
158 | | - // never execute. |
159 | | - BB->getTerminatingDeoptimizeCall()) |
160 | | - PostDominatedByUnreachable.insert(BB); |
161 | | - return; |
162 | | - } |
| 150 | +static void UpdatePDTWorklist(const BasicBlock *BB, PostDominatorTree *PDT, |
| 151 | + SmallVectorImpl<const BasicBlock *> &WorkList, |
| 152 | + SmallPtrSetImpl<const BasicBlock *> &TargetSet) { |
| 153 | + SmallVector<BasicBlock *, 8> Descendants; |
| 154 | + SmallPtrSet<const BasicBlock *, 16> NewItems; |
| 155 | + |
| 156 | + PDT->getDescendants(const_cast<BasicBlock *>(BB), Descendants); |
| 157 | + for (auto *BB : Descendants) |
| 158 | + if (TargetSet.insert(BB).second) |
| 159 | + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) |
| 160 | + if (!TargetSet.count(*PI)) |
| 161 | + NewItems.insert(*PI); |
| 162 | + WorkList.insert(WorkList.end(), NewItems.begin(), NewItems.end()); |
| 163 | +} |
163 | 164 |
|
164 | | - // If the terminator is an InvokeInst, check only the normal destination block |
165 | | - // as the unwind edge of InvokeInst is also very unlikely taken. |
166 | | - if (auto *II = dyn_cast<InvokeInst>(TI)) { |
167 | | - if (PostDominatedByUnreachable.count(II->getNormalDest())) |
168 | | - PostDominatedByUnreachable.insert(BB); |
169 | | - return; |
| 165 | +/// Compute a set of basic blocks that are post-dominated by unreachables. |
| 166 | +void BranchProbabilityInfo::computePostDominatedByUnreachable( |
| 167 | + const Function &F, PostDominatorTree *PDT) { |
| 168 | + SmallVector<const BasicBlock *, 8> WorkList; |
| 169 | + for (auto &BB : F) { |
| 170 | + const Instruction *TI = BB.getTerminator(); |
| 171 | + if (TI->getNumSuccessors() == 0) { |
| 172 | + if (isa<UnreachableInst>(TI) || |
| 173 | + // If this block is terminated by a call to |
| 174 | + // @llvm.experimental.deoptimize then treat it like an unreachable |
| 175 | + // since the @llvm.experimental.deoptimize call is expected to |
| 176 | + // practically never execute. |
| 177 | + BB.getTerminatingDeoptimizeCall()) |
| 178 | + UpdatePDTWorklist(&BB, PDT, WorkList, PostDominatedByUnreachable); |
| 179 | + } |
170 | 180 | } |
171 | 181 |
|
172 | | - for (auto *I : successors(BB)) |
173 | | - // If any of successor is not post dominated then BB is also not. |
174 | | - if (!PostDominatedByUnreachable.count(I)) |
175 | | - return; |
176 | | - |
177 | | - PostDominatedByUnreachable.insert(BB); |
| 182 | + while (!WorkList.empty()) { |
| 183 | + const BasicBlock *BB = WorkList.pop_back_val(); |
| 184 | + if (PostDominatedByUnreachable.count(BB)) |
| 185 | + continue; |
| 186 | + // If the terminator is an InvokeInst, check only the normal destination |
| 187 | + // block as the unwind edge of InvokeInst is also very unlikely taken. |
| 188 | + if (auto *II = dyn_cast<InvokeInst>(BB->getTerminator())) { |
| 189 | + if (PostDominatedByUnreachable.count(II->getNormalDest())) |
| 190 | + UpdatePDTWorklist(BB, PDT, WorkList, PostDominatedByUnreachable); |
| 191 | + } |
| 192 | + // If all the successors are unreachable, BB is unreachable as well. |
| 193 | + else if (!successors(BB).empty() && |
| 194 | + llvm::all_of(successors(BB), [this](const BasicBlock *Succ) { |
| 195 | + return PostDominatedByUnreachable.count(Succ); |
| 196 | + })) |
| 197 | + UpdatePDTWorklist(BB, PDT, WorkList, PostDominatedByUnreachable); |
| 198 | + } |
178 | 199 | } |
179 | 200 |
|
180 | | -/// Add \p BB to PostDominatedByColdCall set if applicable. |
181 | | -void |
182 | | -BranchProbabilityInfo::updatePostDominatedByColdCall(const BasicBlock *BB) { |
183 | | - assert(!PostDominatedByColdCall.count(BB)); |
184 | | - const Instruction *TI = BB->getTerminator(); |
185 | | - if (TI->getNumSuccessors() == 0) |
186 | | - return; |
| 201 | +/// compute a set of basic blocks that are post-dominated by ColdCalls. |
| 202 | +void BranchProbabilityInfo::computePostDominatedByColdCall( |
| 203 | + const Function &F, PostDominatorTree *PDT) { |
| 204 | + SmallVector<const BasicBlock *, 8> WorkList; |
| 205 | + for (auto &BB : F) |
| 206 | + for (auto &I : BB) |
| 207 | + if (const CallInst *CI = dyn_cast<CallInst>(&I)) |
| 208 | + if (CI->hasFnAttr(Attribute::Cold)) |
| 209 | + UpdatePDTWorklist(&BB, PDT, WorkList, PostDominatedByColdCall); |
187 | 210 |
|
188 | | - // If all of successor are post dominated then BB is also done. |
189 | | - if (llvm::all_of(successors(BB), [&](const BasicBlock *SuccBB) { |
190 | | - return PostDominatedByColdCall.count(SuccBB); |
191 | | - })) { |
192 | | - PostDominatedByColdCall.insert(BB); |
193 | | - return; |
194 | | - } |
| 211 | + while (!WorkList.empty()) { |
| 212 | + const BasicBlock *BB = WorkList.pop_back_val(); |
195 | 213 |
|
196 | | - // If the terminator is an InvokeInst, check only the normal destination |
197 | | - // block as the unwind edge of InvokeInst is also very unlikely taken. |
198 | | - if (auto *II = dyn_cast<InvokeInst>(TI)) |
199 | | - if (PostDominatedByColdCall.count(II->getNormalDest())) { |
200 | | - PostDominatedByColdCall.insert(BB); |
201 | | - return; |
| 214 | + // If the terminator is an InvokeInst, check only the normal destination |
| 215 | + // block as the unwind edge of InvokeInst is also very unlikely taken. |
| 216 | + if (auto *II = dyn_cast<InvokeInst>(BB->getTerminator())) { |
| 217 | + if (PostDominatedByColdCall.count(II->getNormalDest())) |
| 218 | + UpdatePDTWorklist(BB, PDT, WorkList, PostDominatedByColdCall); |
202 | 219 | } |
203 | | - |
204 | | - // Otherwise, if the block itself contains a cold function, add it to the |
205 | | - // set of blocks post-dominated by a cold call. |
206 | | - for (auto &I : *BB) |
207 | | - if (const CallInst *CI = dyn_cast<CallInst>(&I)) |
208 | | - if (CI->hasFnAttr(Attribute::Cold)) { |
209 | | - PostDominatedByColdCall.insert(BB); |
210 | | - return; |
211 | | - } |
| 220 | + // If all of successor are post dominated then BB is also done. |
| 221 | + else if (!successors(BB).empty() && |
| 222 | + llvm::all_of(successors(BB), [this](const BasicBlock *Succ) { |
| 223 | + return PostDominatedByColdCall.count(Succ); |
| 224 | + })) |
| 225 | + UpdatePDTWorklist(BB, PDT, WorkList, PostDominatedByColdCall); |
| 226 | + } |
212 | 227 | } |
213 | 228 |
|
214 | 229 | /// Calculate edge weights for successors lead to unreachable. |
@@ -983,13 +998,16 @@ void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI, |
983 | 998 | LLVM_DEBUG(dbgs() << "\n"); |
984 | 999 | } |
985 | 1000 |
|
| 1001 | + std::unique_ptr<PostDominatorTree> PDT = |
| 1002 | + std::make_unique<PostDominatorTree>(const_cast<Function &>(F)); |
| 1003 | + computePostDominatedByUnreachable(F, PDT.get()); |
| 1004 | + computePostDominatedByColdCall(F, PDT.get()); |
| 1005 | + |
986 | 1006 | // Walk the basic blocks in post-order so that we can build up state about |
987 | 1007 | // the successors of a block iteratively. |
988 | 1008 | for (auto BB : post_order(&F.getEntryBlock())) { |
989 | 1009 | LLVM_DEBUG(dbgs() << "Computing probabilities for " << BB->getName() |
990 | 1010 | << "\n"); |
991 | | - updatePostDominatedByUnreachable(BB); |
992 | | - updatePostDominatedByColdCall(BB); |
993 | 1011 | // If there is no at least two successors, no sense to set probability. |
994 | 1012 | if (BB->getTerminator()->getNumSuccessors() < 2) |
995 | 1013 | continue; |
|
0 commit comments