[llvm] [FunctionAttrs] deduce attr `cold` on functions if all CG paths call a `cold` function (PR #101298)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 31 01:08:38 PDT 2024


================
@@ -1760,6 +1762,70 @@ static void addNoReturnAttrs(const SCCNodeSet &SCCNodes,
   }
 }
 
+static bool
+allBBPathsGoThroughCold(BasicBlock *BB,
+                        SmallDenseMap<BasicBlock *, bool, 16> &Visited) {
+  // If BB contains a cold callsite this path through the CG is cold.
+  if (any_of(*BB, [](Instruction &I) {
+        if (auto *CB = dyn_cast<CallBase>(&I))
+          return CB->hasFnAttr(Attribute::Cold);
+        return false;
+      })) {
+    Visited[BB] = true;
+    return true;
+  }
+
+  auto Succs = successors(BB);
+  // We found a path that doesn't go through any cold callsite.
+  if (Succs.empty())
+    return false;
+
+  // We didn't find a cold callsite in this BB, so check that all successors
+  // contain a cold callsite (or that their successors do).
+  // Potential TODO: We could use static branch hints to assume certain
+  // successor paths are inherently cold, irrespective of if they contain a cold
+  // callsite.
+  for (auto *Succ : Succs) {
+    // Start with false, this is necessary to ensure we don't turn loops into
+    // cold.
+    auto R = Visited.try_emplace(Succ, false);
+    if (!R.second) {
+      if (R.first->second)
+        continue;
+      return false;
+    }
+    if (!allBBPathsGoThroughCold(Succ, Visited))
+      return false;
+    Visited[Succ] = true;
+  }
+
+  return true;
+}
+
+static bool allPathsGoThroughCold(Function &F) {
+  SmallDenseMap<BasicBlock *, bool, 16> Visited;
----------------
dtcxzyw wrote:

It would be simpler to turn this into a BFS traversal?
```
SmallVector<BB> WorkList, Visited;
WorkList.push(entryBB);

while(!WorkList.empty()) {
  BB = WorkList.pop();
  if (BB contains cold calls)
     continue;

  if (BB contains return/calls without willreturn)
     return true;

   Visited.insert(BB);
  
   for (auto *SuccBB: successors(BB))
       if (!Visited.contains(SuccBB))
           WorkList.push_back(SuccBB);
}
return false;
```


https://github.com/llvm/llvm-project/pull/101298


More information about the llvm-commits mailing list