From 765dff4fca1026390c73a75905b862e586304c90 Mon Sep 17 00:00:00 2001 From: Madhur Amilkanthwar Date: Thu, 30 Oct 2025 23:16:42 -0700 Subject: [PATCH 1/3] [GVN][PGO] Skip GVN if entry BlockFreq is 0 This patch skips GVN is !prof metadata indicates zero frequency. --- llvm/lib/Transforms/Scalar/GVN.cpp | 12 ++++++ .../test/Transforms/GVN/skip-gvn-blockfreq.ll | 41 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 llvm/test/Transforms/GVN/skip-gvn-blockfreq.ll diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 72e1131a54a86..3dee060ee223a 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -115,6 +115,8 @@ GVNEnableSplitBackedgeInLoadPRE("enable-split-backedge-in-load-pre", static cl::opt GVNEnableMemDep("enable-gvn-memdep", cl::init(true)); static cl::opt GVNEnableMemorySSA("enable-gvn-memoryssa", cl::init(false)); +static cl::opt GVNSkipZeroEntryCount("gvn-skip-zero-entry-count", + cl::init(false)); static cl::opt MaxNumDeps( "gvn-max-num-deps", cl::Hidden, cl::init(100), @@ -894,6 +896,16 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) { MSSA = &AM.getResult(F); } auto &ORE = AM.getResult(F); + + // Skip the pass if function has zero entry count in PGO. + // This indicates that the function is never executed according to the profile data. + auto EntryCount = F.getEntryCount(); + if (GVNSkipZeroEntryCount && EntryCount && EntryCount->getCount() == 0) { + LLVM_DEBUG(dbgs() << "GVN: Skipping function '" << F.getName() + << "' with zero profile entry count\n"); + return PreservedAnalyses::all(); + } + bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE, MSSA ? &MSSA->getMSSA() : nullptr); if (!Changed) diff --git a/llvm/test/Transforms/GVN/skip-gvn-blockfreq.ll b/llvm/test/Transforms/GVN/skip-gvn-blockfreq.ll new file mode 100644 index 0000000000000..c1a33bbda1aa4 --- /dev/null +++ b/llvm/test/Transforms/GVN/skip-gvn-blockfreq.ll @@ -0,0 +1,41 @@ +; Test that GVN is skipped when function has zero entry count in PGO +; RUN: opt -passes='gvn' -gvn-skip-zero-entry-count=true -S < %s | FileCheck %s + +; Function with ZERO entry count - GVN should skip this function +; The redundant computation should remain because GVN doesn't run +; CHECK-LABEL: @zero_freq_function( +; CHECK-NEXT: entry: +; CHECK-NEXT: %a = add i32 %x, 1 +; CHECK-NEXT: %b = add i32 %a, 2 +; CHECK-NEXT: %c = add i32 %a, 2 +; CHECK-NEXT: %result = add i32 %b, %c +; CHECK-NEXT: ret i32 %result +define i32 @zero_freq_function(i32 %x) !prof !0 { +entry: + %a = add i32 %x, 1 + %b = add i32 %a, 2 + %c = add i32 %a, 2 ; Redundant - but GVN should not optimize due to zero freq + %result = add i32 %b, %c + ret i32 %result +} + +; Function with NON-ZERO entry count - GVN should run normally +; The redundant computation should be eliminated by GVN +; CHECK-LABEL: @nonzero_freq_function( +; CHECK-NEXT: entry: +; CHECK-NEXT: %a = add i32 %x, 1 +; CHECK-NEXT: %b = add i32 %a, 2 +; CHECK-NEXT: %result = add i32 %b, %b +; CHECK-NEXT: ret i32 %result +define i32 @nonzero_freq_function(i32 %x) !prof !1 { +entry: + %a = add i32 %x, 1 + %b = add i32 %a, 2 + %c = add i32 %a, 2 ; Redundant - GVN optimizes this + %result = add i32 %b, %c + ret i32 %result +} + +!0 = !{!"function_entry_count", i64 0} ; Zero frequency +!1 = !{!"function_entry_count", i64 1000} ; Non-zero frequency + From 5a4293b767a444799fa3280a354a75485ec7b072 Mon Sep 17 00:00:00 2001 From: Madhur Amilkanthwar Date: Wed, 5 Nov 2025 23:44:02 -0800 Subject: [PATCH 2/3] fixup! [GVN][PGO] Skip GVN if entry BlockFreq is 0 Run clang-format From ba95b14183f9c05c00ea2e508458065407a952be Mon Sep 17 00:00:00 2001 From: Madhur Amilkanthwar Date: Wed, 5 Nov 2025 23:49:09 -0800 Subject: [PATCH 3/3] fixup! fixup! [GVN][PGO] Skip GVN if entry BlockFreq is 0 --- llvm/lib/Transforms/Scalar/GVN.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 3dee060ee223a..e88fcdd262f35 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -898,7 +898,8 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) { auto &ORE = AM.getResult(F); // Skip the pass if function has zero entry count in PGO. - // This indicates that the function is never executed according to the profile data. + // This indicates that the function is never executed according to the profile + // data. auto EntryCount = F.getEntryCount(); if (GVNSkipZeroEntryCount && EntryCount && EntryCount->getCount() == 0) { LLVM_DEBUG(dbgs() << "GVN: Skipping function '" << F.getName()