From f33e9faa5d65a16c7366bfec3b11abddee9d6a08 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Fri, 3 Apr 2026 11:38:51 -0700 Subject: [PATCH] [SampleProfile] Fix FuncMappings key mismatch for renamed functions in stale profile matching (#187899) Fix a bug where `distributeIRToProfileLocationMap` fails to find location mappings from IR to profile for renamed functions because `FuncMappings` is indexed by the IR function name while `distributeIRToProfileLocationMap` looks up by the profile function name. Fixed by making `FuncMappings` to use profile function name as key. --- .../Transforms/IPO/SampleProfileMatcher.h | 4 +- .../Transforms/IPO/SampleProfileMatcher.cpp | 2 +- ...robe-stale-profile-renaming-lineshift.prof | 56 +++++++++++++++++++ .../pseudo-probe-stale-profile-renaming.ll | 24 ++++++++ 4 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/SampleProfile/Inputs/pseudo-probe-stale-profile-renaming-lineshift.prof diff --git a/llvm/include/llvm/Transforms/IPO/SampleProfileMatcher.h b/llvm/include/llvm/Transforms/IPO/SampleProfileMatcher.h index 4691600175ae..724cc91d074f 100644 --- a/llvm/include/llvm/Transforms/IPO/SampleProfileMatcher.h +++ b/llvm/include/llvm/Transforms/IPO/SampleProfileMatcher.h @@ -203,8 +203,8 @@ private: void computeAndReportProfileStaleness(); void UpdateWithSalvagedProfiles(); - LocToLocMap &getIRToProfileLocationMap(const Function &F) { - return FuncMappings[FunctionSamples::getCanonicalFnName(F.getName())]; + LocToLocMap &getIRToProfileLocationMap(const FunctionSamples &FS) { + return FuncMappings[FS.getFuncName()]; } void distributeIRToProfileLocationMap(); void distributeIRToProfileLocationMap(FunctionSamples &FS); diff --git a/llvm/lib/Transforms/IPO/SampleProfileMatcher.cpp b/llvm/lib/Transforms/IPO/SampleProfileMatcher.cpp index 36bd51f84d97..d95ae4f5278c 100644 --- a/llvm/lib/Transforms/IPO/SampleProfileMatcher.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfileMatcher.cpp @@ -424,7 +424,7 @@ void SampleProfileMatcher::runOnFunction(Function &F) { // The matching result will be saved to IRToProfileLocationMap, create a // new map for each function. - auto &IRToProfileLocationMap = getIRToProfileLocationMap(F); + auto &IRToProfileLocationMap = getIRToProfileLocationMap(*FSForMatching); runStaleProfileMatching(F, IRAnchors, ProfileAnchors, IRToProfileLocationMap, RunCFGMatching, RunCGMatching); // Find and update callsite match states after matching. diff --git a/llvm/test/Transforms/SampleProfile/Inputs/pseudo-probe-stale-profile-renaming-lineshift.prof b/llvm/test/Transforms/SampleProfile/Inputs/pseudo-probe-stale-profile-renaming-lineshift.prof new file mode 100644 index 000000000000..0dc4d0c8661c --- /dev/null +++ b/llvm/test/Transforms/SampleProfile/Inputs/pseudo-probe-stale-profile-renaming-lineshift.prof @@ -0,0 +1,56 @@ +main:47:0 + 1: 0 + 2: 2 + 3: 0 + 4: 3 + 7: 2 test_noninline:2 + 8: 2 + 9: 0 + 5: foo:24 + 2: 4 + 3: 3 bar:3 + 5: 3 bar:3 + 4: baz:15 + 1: 3 + 2: block_only:12 + 1: 3 + 3: 3 + 5: 3 + 10: 3 + !CFGChecksum: 206551239323 + !CFGChecksum: 281479271677951 + !CFGChecksum: 123456 + 6: baz:14 + 1: 3 + 2: block_only:11 + 1: 3 + 3: 3 + 5: 3 + 10: 2 + !CFGChecksum: 206551239323 + !CFGChecksum: 281479271677951 + 10: cold_func:0 + 1: 0 + 2: 0 block_only:0 + !CFGChecksum: 281479271677951 + !CFGChecksum: 1126003093360596 +test_noninline:22:2 + 1: 2 + 2: foo:20 + 2: 3 + 3: 2 bar:3 + 5: 3 bar:3 + 4: baz:13 + 1: 2 + 2: block_only:11 + 1: 2 + 3: 3 + 5: 3 + 10: 3 + !CFGChecksum: 206551239323 + !CFGChecksum: 281479271677951 + !CFGChecksum: 123456 + !CFGChecksum: 281479271677951 +bar:12:12 + 1: 12 + !CFGChecksum: 4294967295 diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-renaming.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-renaming.ll index c09fdc467def..426c761f0647 100644 --- a/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-renaming.ll +++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-stale-profile-renaming.ll @@ -3,6 +3,12 @@ ; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/pseudo-probe-stale-profile-renaming.prof --salvage-stale-profile --salvage-unused-profile -S --debug-only=sample-profile,sample-profile-matcher,sample-profile-impl --min-call-count-for-cg-matching=10 --min-func-count-for-cg-matching=10 2>&1 | FileCheck %s --check-prefix=TINY-FUNC ; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/pseudo-probe-stale-profile-renaming.prof --salvage-stale-profile --salvage-unused-profile --salvage-unused-profile-max-functions=1 -S --debug-only=sample-profile-matcher 2>&1 | FileCheck %s --check-prefix=SKIP-SALVAGE +;; Test that stale profile matching (CFG matching) works correctly for a renamed +;; function whose profile has shifted probe locations. This exercises the fix +;; that uses the profile name (not IR name) to index FuncMappings, ensuring +;; distributeIRToProfileLocationMap can find the mapping. +; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/pseudo-probe-stale-profile-renaming-lineshift.prof --salvage-stale-profile --salvage-unused-profile -S --debug-only=sample-profile,sample-profile-matcher,sample-profile-impl -pass-remarks=inline --min-call-count-for-cg-matching=0 --min-func-count-for-cg-matching=0 --func-profile-similarity-threshold=70 2>&1 | FileCheck %s --check-prefix=LINESHIFT + ; Verify find new IR functions. ; SKIP-SALVAGE: define dso_local i32 @main() ; SKIP-SALVAGE-NOT: Function new_block_only is not in profile or profile symbol list. @@ -33,6 +39,24 @@ ; TINY-FUNC-NOT: Function:new_foo matches profile:foo ; TINY-FUNC-NOT: Function:new_block_only matches profile:block_only +;; Verify CG matching still works with the shifted profile. +; LINESHIFT: Function:new_foo matches profile:foo +; LINESHIFT: Function:new_block_only matches profile:block_only + +;; Verify CFG matching produces non-identity location remappings for the +;; renamed function new_foo (IR probes 1-4 matched to profile probes 2-5). +; LINESHIFT: Run stale profile matching for new_foo +; LINESHIFT-NEXT: Location is matched from 1 to 1 +; LINESHIFT-NEXT: Callsite with callee:bar is matched from 2 to 3 +; LINESHIFT-NEXT: Callsite with callee:baz is matched from 3 to 4 +; LINESHIFT-NEXT: Callsite with callee:bar is matched from 4 to 5 + +;; Verify the renamed+shifted function is still inlined correctly, which +;; requires the location mapping to be distributed to the FunctionSamples. +; LINESHIFT: 'new_foo' inlined into 'main' to match profiling context with (cost=110, threshold=3000) at callsite main:2:7.5; +; LINESHIFT: 'new_block_only' inlined into 'main' to match profiling context with (cost=75, threshold=3000) at callsite baz:1:3.2 @ new_foo:2:3.3 @ main:2:7.5; +; LINESHIFT: 'new_foo' inlined into 'test_noninline' to match profiling context with (cost=110, threshold=3000) at callsite test_noninline:1:3.2; + @x = dso_local global i32 0, align 4, !dbg !0