[PATCH] D90272: [BranchProbabilityInfo] Fix eraseBlock

Kazu Hirata via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 27 15:44:54 PDT 2020


kazu created this revision.
kazu added reviewers: wmi, MaskRay, efriedma.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
kazu requested review of this revision.

This patch ensures that BranchProbabilityInfo::eraseBlock(BB) deletes
all entries in Probs associated with with BB.

Without this patch, stale entries for BB may remain in Probs after
eraseBlock(BB), leading to a situation where a newly created basic
block has an edge probability associated with it even before the pass
responsible for creating the basic block adds any edge probability to
it.

Consider the current implementation of eraseBlock(BB):

  for (const_succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
    auto MapI = Probs.find(std::make_pair(BB, I.getSuccessorIndex()));
    if (MapI != Probs.end())
      Probs.erase(MapI);
  }

Notice that it uses succ_begin(BB) and succ_end(BB), which are based
on BB->getTerminator().  This means that if the terminator changes
between calls to setEdgeProbability and eraseBlock, then we may not
examine all pairs associated with BB.

This is exactly what happens in MaybeMergeBasicBlockIntoOnlyPred,
which merges basic blocks A into B if A is the sole predecessor of B,
and B is the sole successor of A.  It replaces the terminator of A
with UnreachableInst before (indirectly) calling eraseBlock(A).

The patch fixes the problem by keeping track of all edge probablities
entered with setEdgeProbability in a map from BasicBlock* to a
successor index.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D90272

Files:
  llvm/include/llvm/Analysis/BranchProbabilityInfo.h
  llvm/lib/Analysis/BranchProbabilityInfo.cpp


Index: llvm/lib/Analysis/BranchProbabilityInfo.cpp
===================================================================
--- llvm/lib/Analysis/BranchProbabilityInfo.cpp
+++ llvm/lib/Analysis/BranchProbabilityInfo.cpp
@@ -1031,6 +1031,7 @@
 
 void BranchProbabilityInfo::releaseMemory() {
   Probs.clear();
+  MaxSuccIdx.clear();
   Handles.clear();
 }
 
@@ -1136,6 +1137,11 @@
   LLVM_DEBUG(dbgs() << "set edge " << Src->getName() << " -> "
                     << IndexInSuccessors << " successor probability to " << Prob
                     << "\n");
+
+  if (MaxSuccIdx.find(Src) == MaxSuccIdx.end())
+    MaxSuccIdx[Src] = IndexInSuccessors;
+  else
+    MaxSuccIdx[Src] = std::max(MaxSuccIdx[Src], IndexInSuccessors);
 }
 
 /// Set the edge probability for all edges at once.
@@ -1173,11 +1179,16 @@
 }
 
 void BranchProbabilityInfo::eraseBlock(const BasicBlock *BB) {
-  for (const_succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
-    auto MapI = Probs.find(std::make_pair(BB, I.getSuccessorIndex()));
+  auto It = MaxSuccIdx.find(BB);
+  if (It == MaxSuccIdx.end())
+    return;
+
+  for (unsigned I = 0, E = It->second; I <= E; ++I) {
+    auto MapI = Probs.find(std::make_pair(BB, I));
     if (MapI != Probs.end())
       Probs.erase(MapI);
   }
+  MaxSuccIdx.erase(BB);
 }
 
 void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI,
Index: llvm/include/llvm/Analysis/BranchProbabilityInfo.h
===================================================================
--- llvm/include/llvm/Analysis/BranchProbabilityInfo.h
+++ llvm/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -62,7 +62,8 @@
   }
 
   BranchProbabilityInfo(BranchProbabilityInfo &&Arg)
-      : Probs(std::move(Arg.Probs)), LastF(Arg.LastF),
+      : Probs(std::move(Arg.Probs)), MaxSuccIdx(std::move(Arg.MaxSuccIdx)),
+        LastF(Arg.LastF),
         PostDominatedByUnreachable(std::move(Arg.PostDominatedByUnreachable)),
         PostDominatedByColdCall(std::move(Arg.PostDominatedByColdCall)) {}
 
@@ -72,6 +73,7 @@
   BranchProbabilityInfo &operator=(BranchProbabilityInfo &&RHS) {
     releaseMemory();
     Probs = std::move(RHS.Probs);
+    MaxSuccIdx = std::move(RHS.MaxSuccIdx);
     PostDominatedByColdCall = std::move(RHS.PostDominatedByColdCall);
     PostDominatedByUnreachable = std::move(RHS.PostDominatedByUnreachable);
     return *this;
@@ -273,6 +275,9 @@
 
   DenseMap<Edge, BranchProbability> Probs;
 
+  // The maximum successor index ever entered for a given basic block.
+  DenseMap<const BasicBlock *, unsigned> MaxSuccIdx;
+
   /// Track the last function we run over for printing.
   const Function *LastF = nullptr;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90272.301110.patch
Type: text/x-patch
Size: 2660 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201027/9e416078/attachment.bin>


More information about the llvm-commits mailing list