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; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits