[clang] 7b85e76 - [PGO] Consider parent context when weighing branches with likelyhood.

Anton Bikineev via cfe-commits cfe-commits at lists.llvm.org
Sat Oct 8 14:49:43 PDT 2022


Author: Anton Bikineev
Date: 2022-10-08T23:49:27+02:00
New Revision: 7b85e765000df36fcc6a5191dec9a28f444245ba

URL: https://github.com/llvm/llvm-project/commit/7b85e765000df36fcc6a5191dec9a28f444245ba
DIFF: https://github.com/llvm/llvm-project/commit/7b85e765000df36fcc6a5191dec9a28f444245ba.diff

LOG: [PGO] Consider parent context when weighing branches with likelyhood.

Generally, with PGO enabled the C++20 likelyhood attributes shall be
dropped assuming the profile has a good coverage. However, currently
this is not the case for the following code:

 if (always_false()) [[likely]] {
   ...
 }

The patch fixes this and drops the attribute, if the parent context was
executed in the profile. The patch still preserves the attribute, if the
parent context was not executed, e.g. to support the cases when the
profile has insufficient coverage.

Differential Revision: https://reviews.llvm.org/D134456

Added: 
    clang/test/Profile/Inputs/cxx-never-executed-branch.proftext
    clang/test/Profile/cxx-never-executed-branch.cpp

Modified: 
    clang/lib/CodeGen/CGStmt.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 9935fcc0d3ea2..ebbc79cc8b4b6 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -815,11 +815,20 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
   // Prefer the PGO based weights over the likelihood attribute.
   // When the build isn't optimized the metadata isn't used, so don't generate
   // it.
+  // Also, 
diff erentiate between disabled PGO and a never executed branch with
+  // PGO. Assuming PGO is in use:
+  // - we want to ignore the [[likely]] attribute if the branch is never
+  // executed,
+  // - assuming the profile is poor, preserving the attribute may still be
+  // beneficial.
+  // As an approximation, preserve the attribute only if both the branch and the
+  // parent context were not executed.
   Stmt::Likelihood LH = Stmt::LH_None;
-  uint64_t Count = getProfileCount(S.getThen());
-  if (!Count && CGM.getCodeGenOpts().OptimizationLevel)
+  uint64_t ThenCount = getProfileCount(S.getThen());
+  if (!ThenCount && !getCurrentProfileCount() &&
+      CGM.getCodeGenOpts().OptimizationLevel)
     LH = Stmt::getLikelihood(S.getThen(), S.getElse());
-  EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock, Count, LH);
+  EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock, ThenCount, LH);
 
   // Emit the 'then' code.
   EmitBlock(ThenBlock);

diff  --git a/clang/test/Profile/Inputs/cxx-never-executed-branch.proftext b/clang/test/Profile/Inputs/cxx-never-executed-branch.proftext
new file mode 100644
index 0000000000000..64a55b3e52b37
--- /dev/null
+++ b/clang/test/Profile/Inputs/cxx-never-executed-branch.proftext
@@ -0,0 +1,13 @@
+_Z13is_in_profilev
+0x000000029f493458
+2
+20000
+# The branch is never executed.
+0
+
+_Z17is_not_in_profilev
+0x000000029f493458
+2
+# The function was never executed
+0
+0

diff  --git a/clang/test/Profile/cxx-never-executed-branch.cpp b/clang/test/Profile/cxx-never-executed-branch.cpp
new file mode 100644
index 0000000000000..812f65f3996d3
--- /dev/null
+++ b/clang/test/Profile/cxx-never-executed-branch.cpp
@@ -0,0 +1,32 @@
+// Test that clang doesn't emit llvm.expect when the counter is 0
+
+// RUN: llvm-profdata merge %S/Inputs/cxx-never-executed-branch.proftext -o %t.profdata
+// RUN: %clang_cc1 -std=c++20 %s -triple %itanium_abi_triple -O2 -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata -disable-llvm-passes | FileCheck %s
+
+int rand();
+
+// CHECK: define {{.*}}@_Z13is_in_profilev
+// CHECK-NOT: call {{.*}}@llvm.expect
+
+int is_in_profile() {
+  int rando = rand();
+  int x = 0;
+  if (rando == 0) [[likely]]
+    x = 2;
+  else
+    x = 3;
+  return x;
+}
+
+// CHECK: define {{.*}}@_Z17is_not_in_profilev
+// CHECK: call {{.*}}@llvm.expect
+
+int is_not_in_profile() {
+  int rando = rand();
+  int x = 0;
+  if (rando == 0) [[likely]]
+    x = 2;
+  else
+    x = 3;
+  return x;
+}


        


More information about the cfe-commits mailing list