summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2017-12-18 17:56:19 +0000
committerXinliang David Li <davidxl@google.com>2017-12-18 17:56:19 +0000
commit19fb5b467bb97f95eace1f3637d2d1041cebd3ce (patch)
treefd6500f725818a938f50220db18bc7d88fcc8b34 /llvm/lib/Transforms
parent5486d2472cf35afb4794a1244f25d6bd2d899f8e (diff)
downloadbcm5719-llvm-19fb5b467bb97f95eace1f3637d2d1041cebd3ce.tar.gz
bcm5719-llvm-19fb5b467bb97f95eace1f3637d2d1041cebd3ce.zip
[PGO] add MST min edge selection heuristic to ensure non-zero entry count
Differential Revision: http://reviews.llvm.org/D41059 llvm-svn: 320998
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Instrumentation/CFGMST.h74
1 files changed, 67 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/CFGMST.h b/llvm/lib/Transforms/Instrumentation/CFGMST.h
index 16e2e6b4e73..075e5672cff 100644
--- a/llvm/lib/Transforms/Instrumentation/CFGMST.h
+++ b/llvm/lib/Transforms/Instrumentation/CFGMST.h
@@ -46,6 +46,10 @@ public:
// This map records the auxiliary information for each BB.
DenseMap<const BasicBlock *, std::unique_ptr<BBInfo>> BBInfos;
+ // Whehter the function has an exit block with no successors.
+ // (For function with an infinite loop, this block may be absent)
+ bool ExitBlockFound = false;
+
// Find the root group of the G and compress the path from G to the root.
BBInfo *findAndCompressGroup(BBInfo *G) {
if (G->Group != G)
@@ -95,14 +99,20 @@ public:
void buildEdges() {
DEBUG(dbgs() << "Build Edge on " << F.getName() << "\n");
- const BasicBlock *BB = &(F.getEntryBlock());
+ const BasicBlock *Entry = &(F.getEntryBlock());
uint64_t EntryWeight = (BFI != nullptr ? BFI->getEntryFreq() : 2);
+ Edge *EntryIncoming = nullptr, *EntryOutgoing = nullptr,
+ *ExitOutgoing = nullptr, *ExitIncoming = nullptr;
+ uint64_t MaxEntryOutWeight = 0, MaxExitOutWeight = 0, MaxExitInWeight = 0;
+
// Add a fake edge to the entry.
- addEdge(nullptr, BB, EntryWeight);
+ EntryIncoming = &addEdge(nullptr, Entry, EntryWeight);
+ DEBUG(dbgs() << " Edge: from fake node to " << Entry->getName()
+ << " w = " << EntryWeight << "\n");
// Special handling for single BB functions.
- if (succ_empty(BB)) {
- addEdge(BB, nullptr, EntryWeight);
+ if (succ_empty(Entry)) {
+ addEdge(Entry, nullptr, EntryWeight);
return;
}
@@ -126,16 +136,62 @@ public:
}
if (BPI != nullptr)
Weight = BPI->getEdgeProbability(&*BB, TargetBB).scale(scaleFactor);
- addEdge(&*BB, TargetBB, Weight).IsCritical = Critical;
+ auto *E = &addEdge(&*BB, TargetBB, Weight);
+ E->IsCritical = Critical;
DEBUG(dbgs() << " Edge: from " << BB->getName() << " to "
<< TargetBB->getName() << " w=" << Weight << "\n");
+
+ // Keep track of entry/exit edges:
+ if (&*BB == Entry) {
+ if (Weight > MaxEntryOutWeight) {
+ MaxEntryOutWeight = Weight;
+ EntryOutgoing = E;
+ }
+ }
+
+ auto *TargetTI = TargetBB->getTerminator();
+ if (TargetTI && !TargetTI->getNumSuccessors()) {
+ if (Weight > MaxExitInWeight) {
+ MaxExitInWeight = Weight;
+ ExitIncoming = E;
+ }
+ }
}
} else {
- addEdge(&*BB, nullptr, BBWeight);
- DEBUG(dbgs() << " Edge: from " << BB->getName() << " to exit"
+ ExitBlockFound = true;
+ Edge *ExitO = &addEdge(&*BB, nullptr, BBWeight);
+ if (BBWeight > MaxExitOutWeight) {
+ MaxExitOutWeight = BBWeight;
+ ExitOutgoing = ExitO;
+ }
+ DEBUG(dbgs() << " Edge: from " << BB->getName() << " to fake exit"
<< " w = " << BBWeight << "\n");
}
}
+
+ // Entry/exit edge adjustment heurisitic:
+ // prefer instrumenting entry edge over exit edge
+ // if possible. Those exit edges may never have a chance to be
+ // executed (for instance the program is an event handling loop)
+ // before the profile is asynchronously dumped.
+ //
+ // If EntryIncoming and ExitOutgoing has similar weight, make sure
+ // ExitOutging is selected as the min-edge. Similarly, if EntryOutgoing
+ // and ExitIncoming has similar weight, make sure ExitIncoming becomes
+ // the min-edge.
+ uint64_t EntryInWeight = EntryWeight;
+
+ if (EntryInWeight >= MaxExitOutWeight &&
+ EntryInWeight * 2 < MaxExitOutWeight * 3) {
+ EntryIncoming->Weight = MaxExitOutWeight;
+ ExitOutgoing->Weight = EntryInWeight + 1;
+ }
+
+ if (MaxEntryOutWeight >= MaxExitInWeight &&
+ MaxEntryOutWeight * 2 < MaxExitInWeight * 3) {
+ EntryOutgoing->Weight = MaxExitInWeight;
+ ExitIncoming->Weight = MaxEntryOutWeight + 1;
+ }
}
// Sort CFG edges based on its weight.
@@ -167,6 +223,10 @@ public:
for (auto &Ei : AllEdges) {
if (Ei->Removed)
continue;
+ // If we detect infinite loops, force
+ // instrumenting the entry edge:
+ if (!ExitBlockFound && Ei->SrcBB == nullptr)
+ continue;
if (unionGroups(Ei->SrcBB, Ei->DestBB))
Ei->InMST = true;
}
OpenPOWER on IntegriCloud