|
19 | 19 | #include "llvm/Analysis/BlockFrequencyInfo.h" |
20 | 20 | #include "llvm/Analysis/BranchProbabilityInfo.h" |
21 | 21 | #include "llvm/Analysis/CFG.h" |
| 22 | +#include "llvm/Analysis/LoopInfo.h" |
22 | 23 | #include "llvm/IR/Instructions.h" |
23 | 24 | #include "llvm/IR/IntrinsicInst.h" |
24 | 25 | #include "llvm/Support/BranchProbability.h" |
@@ -52,10 +53,14 @@ template <class Edge, class BBInfo> class CFGMST { |
52 | 53 |
|
53 | 54 | BranchProbabilityInfo *const BPI; |
54 | 55 | BlockFrequencyInfo *const BFI; |
| 56 | + LoopInfo *const LI; |
55 | 57 |
|
56 | 58 | // If function entry will be always instrumented. |
57 | 59 | const bool InstrumentFuncEntry; |
58 | 60 |
|
| 61 | + // If true loop entries will be always instrumented. |
| 62 | + const bool InstrumentLoopEntries; |
| 63 | + |
59 | 64 | // Find the root group of the G and compress the path from G to the root. |
60 | 65 | BBInfo *findAndCompressGroup(BBInfo *G) { |
61 | 66 | if (G->Group != G) |
@@ -154,6 +159,16 @@ template <class Edge, class BBInfo> class CFGMST { |
154 | 159 | } |
155 | 160 | if (BPI != nullptr) |
156 | 161 | Weight = BPI->getEdgeProbability(&BB, TargetBB).scale(scaleFactor); |
| 162 | + // If InstrumentLoopEntries is on and the current edge leads to a loop |
| 163 | + // (i.e., TargetBB is a loop head and BB is outside its loop), set |
| 164 | + // Weight to be minimal, so that the edge won't be chosen for the MST |
| 165 | + // and will be instrumented. |
| 166 | + if (InstrumentLoopEntries && LI->isLoopHeader(TargetBB)) { |
| 167 | + Loop *TargetLoop = LI->getLoopFor(TargetBB); |
| 168 | + assert(TargetLoop); |
| 169 | + if (!TargetLoop->contains(&BB)) |
| 170 | + Weight = 0; |
| 171 | + } |
157 | 172 | if (Weight == 0) |
158 | 173 | Weight++; |
159 | 174 | auto *E = &addEdge(&BB, TargetBB, Weight); |
@@ -252,6 +267,19 @@ template <class Edge, class BBInfo> class CFGMST { |
252 | 267 | } |
253 | 268 | } |
254 | 269 |
|
| 270 | + [[maybe_unused]] bool validateLoopEntryInstrumentation() { |
| 271 | + if (!InstrumentLoopEntries) |
| 272 | + return true; |
| 273 | + for (auto &Ei : AllEdges) { |
| 274 | + if (Ei->Removed) |
| 275 | + continue; |
| 276 | + if (Ei->DestBB && LI->isLoopHeader(Ei->DestBB) && |
| 277 | + !LI->getLoopFor(Ei->DestBB)->contains(Ei->SrcBB) && Ei->InMST) |
| 278 | + return false; |
| 279 | + } |
| 280 | + return true; |
| 281 | + } |
| 282 | + |
255 | 283 | public: |
256 | 284 | // Dump the Debug information about the instrumentation. |
257 | 285 | void dumpEdges(raw_ostream &OS, const Twine &Message) const { |
@@ -291,13 +319,20 @@ template <class Edge, class BBInfo> class CFGMST { |
291 | 319 | return *AllEdges.back(); |
292 | 320 | } |
293 | 321 |
|
294 | | - CFGMST(Function &Func, bool InstrumentFuncEntry, |
| 322 | + CFGMST(Function &Func, bool InstrumentFuncEntry, bool InstrumentLoopEntries, |
295 | 323 | BranchProbabilityInfo *BPI = nullptr, |
296 | | - BlockFrequencyInfo *BFI = nullptr) |
297 | | - : F(Func), BPI(BPI), BFI(BFI), InstrumentFuncEntry(InstrumentFuncEntry) { |
| 324 | + BlockFrequencyInfo *BFI = nullptr, LoopInfo *LI = nullptr) |
| 325 | + : F(Func), BPI(BPI), BFI(BFI), LI(LI), |
| 326 | + InstrumentFuncEntry(InstrumentFuncEntry), |
| 327 | + InstrumentLoopEntries(InstrumentLoopEntries) { |
| 328 | + assert(!(InstrumentLoopEntries && !LI) && |
| 329 | + "expected a LoopInfo to instrumenting loop entries"); |
298 | 330 | buildEdges(); |
299 | 331 | sortEdgesByWeight(); |
300 | 332 | computeMinimumSpanningTree(); |
| 333 | + assert(validateLoopEntryInstrumentation() && |
| 334 | + "Loop entries should not be in MST when " |
| 335 | + "InstrumentLoopEntries is on"); |
301 | 336 | if (AllEdges.size() > 1 && InstrumentFuncEntry) |
302 | 337 | std::iter_swap(std::move(AllEdges.begin()), |
303 | 338 | std::move(AllEdges.begin() + AllEdges.size() - 1)); |
|
0 commit comments