[SampleProfileMatcher] Add direct basename early matching for orphan functions (#184409)
When user code changes function signatures (e.g., adding/removing
parameters), the C++ mangled name changes while the base function name
stays the same. The existing stale profile CG matching can only recover
renamed functions when they appear as callees of already-matched
callers. If the caller has no profile (e.g., fully inlined in the
profiled binary, or from a different TU not loaded), the renamed callee
is never discovered and gets zero profile data.
Add `matchFunctionsWithoutProfileByBasename()` that pairs orphan IR
functions (no profile) with unused top-level profile functions by
demangled basename, without requiring a matched caller in the call
graph.
This direct basename matching runs before CG matching and writes to
`FuncToProfileNameMap`. CG matching can later overwrite these entries
(since `SymbolMap` is not updated until `UpdateWithSalvagedProfiles`),
so a contextually better CG match is not blocked.
An unambiguous 1:1 mapping is enforced: a basename is only matched when
exactly one orphan IR function and exactly one profile candidate share
it. This eliminates false positives from common/short basenames while
preserving matches for unique function names that are the primary target
of this optimization.