136 Commits

Author SHA1 Message Date
Kazu Hirata
707bab651f
[llvm] Remove redundant typename (NFC) (#166087)
Identified with readability-redundant-typename.
2025-11-02 13:15:16 -08:00
Teresa Johnson
2a7e7e2ac4
[MemProf] Convert removal of memprof attrs and metadata to a pass (#163841)
In preparation for a follow on fix that removes these attributes and
metadata in non-LTO pipelines, convert updateMemProfAttributes to a new
MemProfRemoveInfo pass that executes at the start of the LTO backend
pass pipelines when we don't have an index indicating that we linked
with a library support hot cold operator new.

This is largely NFC from an end user perspective but changes where the
removal can be observed, hence the test updates.

A follow on change will use the new pass for non-LTO pipelines (for
cases when the bitcode is initially matched with memprof data but we
decide to complete the compile without LTO).
2025-10-16 12:25:51 -07:00
Rahul Joshi
bea786d128
[NFC][LLVM] Use namespace qualifier to define DenseMapInfo specializations (#162683)
Use `llvm::DenseMapInfo` to define `DenseMapInfo` specializations
instead of surrounding it with `namespace llvm {}`.
2025-10-10 05:23:44 -07:00
Teresa Johnson
c40ee0f322
Reapply "[MemProf] Add ambigous memprof attribute" (#161717) (#161918)
Reapply llvm/llvm-project#157204 with fix and a new test for the issue
it caused (the test change provoked the assert that was converted to an
if condition).

Also, make the application of this new attribute under an (on by
default) flag, so that it can be more easily disabled if needed. Add
test for the new flag.
2025-10-05 15:57:08 -07:00
Teresa Johnson
d322ebdeab
[MemProf] Suppress duplicate clones in the LTO backend (#161551)
In some cases due to phase ordering issues with re-cloning during
function assignment, we may end up with duplicate clones in the
summaries (calling the same set of callee clones and/or allocation
hints).

Ideally we would fix this in the thin link, but for now, detect and
suppress these in the LTO backend. In order to satisfy possibly
cross-module references, make each duplicate an alias to the first
identical copy, which gets materialized.

This reduces ThinLTO backend compile times.
2025-10-03 16:35:17 -07:00
Teresa Johnson
49603bd9b8
Revert "[MemProf] Add ambigous memprof attribute" (#161717)
Reverts llvm/llvm-project#157204

This caused issues in ThinLTO binaries because of the checking here,
that didn't expect allocations needing cloning to have memprof metadata:
9133fc8cb0/llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp (L5572-L5582)

I need to move the assert into the if check and guard by that condition.
And add a more thorough test.
2025-10-02 12:17:38 -07:00
Nicolai Hähnle
11a4b2d950
Cleanup the LLVM exported symbols namespace (#161240)
There's a pattern throughout LLVM of cl::opts being exported. That in
itself is probably a bit unfortunate, but what's especially bad about it
is that a lot of those symbols are in the global namespace. Move them
into the llvm namespace.

While doing this, I noticed some other variables in the global namespace
and moved them as well.
2025-10-01 15:32:07 -07:00
Teresa Johnson
302be34a3f
[MemProf] Make sure call clones without callsite node clones get updated (#159861)
Because we may prune differing amounts of call context for different
allocation contexts during matching (we only keep enough call context to
distinguish cold from noncold paths), we can end up with different
numbers of callsite node clones for different callsites in the same
function. Any callsites that don't have node clones for all function
clones should have their copies in those other function clones updated
the same way as the version in the original function, which might be
calling a clone of the callsite.
2025-09-25 12:26:57 -07:00
Teresa Johnson
e4d7b8928b
[MemProf] Propagate function call assignments to newly cloned nodes (#159907)
There are a couple of places during function cloning where we may create
new callsite clone nodes. One of those places was correctly propagating
the assignment to which function clone it should call, and one was not.
Refactor this handling into a helper and use in both places so the newly
created callsite clones actually call the assigned callee function
clones.
2025-09-20 06:54:52 -07:00
Teresa Johnson
f74184ccc9
[MemProf] Add NodeId field to ContextNode for debugging (#158736)
This has been handy locally for debugging cloning issues. The NodeIds
are assigned sequentially on creation and included in the dumps and the
dot graphs.

No measurable memory increase was found for a large thin link.

I only changed one test
(Transforms/MemProfContextDisambiguation/basic.ll)
to actually check the emitted NodeIds, most ignore them.
2025-09-15 20:27:33 -07:00
Teresa Johnson
cf44f19e57
[MemProf] Add ambigous memprof attribute (#157204)
To help track allocations that we matched with memprof profiles but
for which we weren't able to disambiguate the different hotness
contexts, apply an "ambiguous" memprof attribute to all allocations with
matched profiles. These will be replaced if we can identify a single
hotness type, possibly after cloning.

Eventually we plan to translate this to a special hotness hint on the
allocation call.
2025-09-05 18:32:10 -07:00
Teresa Johnson
dc90472532
[MemProf] Ensure node merging happens for newly created nodes (#151593)
We weren't performing node merging on newly created nodes in some cases.
Use a simple iteration over the node and its callers until no more
opportunities are found. I confirmed that for several large codes the
max iterations is 3 (meaning we only needed to do any work on the first
2, as expected). This can potentially be made more elegant in the
future, but it is a simple and effective solution.

Also fix a bug exposed by the test case, getting the function for a call
instruction in the FullLTO handling, using an existing method to look
through aliases if needed.
2025-08-01 12:51:12 -07:00
Teresa Johnson
d4562a1991
[MemProf] Use DenseMap for call map (NFC) (#151161)
There is no reason to use std::map for the call maps maintained for
function clones during function clone assignment, as we don't iterate
over them and don't need deterministic ordering, so use the more
efficient DenseMap.
2025-07-29 08:18:31 -07:00
Kazu Hirata
255bba0136 [memprof] Fix a warning
This patch fixes:

  llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp:4771:9:
  error: non-void lambda does not return a value in all control paths
  [-Werror,-Wreturn-type]
2025-07-28 19:35:02 -07:00
Teresa Johnson
f3761ab340
Reapply "[MemProf] Ensure all callsite clones are assigned a function clone" (#150856) (#151055)
This reverts commit 314e22bcab2b0f3d208708431a14215058f0718f, reapplying
PR150735 with a fix for the unstable iteration order exposed by the new
tests (PR151039).
2025-07-28 17:04:45 -07:00
Teresa Johnson
ced3b90738
[MemProf] Change map to vector to avoid unstable iteration (#151039)
We iterate over a std::map indexed by FuncInfo, which is a pair of a
pointer and a clone number. In the ThinLTO case, this isn't an issue as
the function pointer always points to the same FunctionSummary object.
However, for regular LTO, this is a pointer to a Function object, which
is different for each clone. This will lead to unstable iteration order.

This was exposed in a test case added for PR150735, which added a new
instance of iteration over this map.

Since these function clones are added and numbered sequentially, change
this to a vector indexed by clone number, which points to a structure
containing the clone FuncInfo and the call map (the old map's key and
value, respectively).
2025-07-28 14:20:49 -07:00
Teresa Johnson
314e22bcab
Revert "[MemProf] Ensure all callsite clones are assigned a function clone" (#150856)
Reverts llvm/llvm-project#150735 due to bot failures that I need to
investigate
2025-07-27 15:55:22 -07:00
Teresa Johnson
0f2484a740
[MemProf] Ensure all callsite clones are assigned a function clone (#150735)
Fix a bug in function assignment where we were not assigning all
callsite clones to a function clone. This led to incorrect call updates
because multiple callsite clones could look like they were assigned to
the same function clone.

Add in a stat and debug message to help identify and debug cases where
this is still happening.
2025-07-27 11:48:30 -07:00
Teresa Johnson
e4963834e4
[MemProf] Include caller clone information in dot graph nodes (#150492)
We already included the assigned clone of the callsite node's callee in
the dot graph after function assignment. This adds the same information
for the enclosing caller function to aid debugging.
2025-07-25 07:29:22 -07:00
Teresa Johnson
0e42c665f9
[MemProf] Update the declaration DISubprogram linkageName for clones (#149864)
Follow up to PR145385 to also update the linkageName on any separate
DISubprogram for the clone function declaration.
2025-07-21 12:27:36 -07:00
Teresa Johnson
ac39d26dc4
[MemProf] Don't mutate the function type when calling clone (#147829)
In rare cases the declaration of a function may not match its callsite
after function importing, when the declaration was imported from a
module where the function had void return type (presumably due to
incomplete types). Instead of using setCalledFunction() to change a call
to call its clone, which updates the call's function type as well, just
call setCalledOperand directly so the only thing changed is the function
target.

Note this can't happen for the other places where we call
setCalledFunction: FullLTO requires the cloned callee to be defined in
the same FullLTO merged module; ThinLTO memprof ICP calls an ICP
facility to first perform the promotion and that will be blocked if the
function type doesn't match the callsite (the new test explicitly tests
this latter case).
2025-07-11 11:33:43 -07:00
Teresa Johnson
838701a540
MemProf: Add minimum count threshold for inlining of promoted calls (#148001)
Allow users to set the minimum absolute count for inlining of indirect
calls promoted during cloning. This is primarily meant to enable
generation of synthetic vp metadata introduced in PR141164 when
profiling memprof-optimized binaries.
2025-07-10 13:48:16 -07:00
Teresa Johnson
90a6819cfe
[MemProf] Update the DISubprogram linkageName for clones (#145385)
This corrects the debug information for the cloned functions so that it
contains the correct linkage name.
2025-06-23 18:57:22 -07:00
David Spickett
36ac72f4e3 [llvm][MemProf] Fix unused variable warning in release build
g++-13 warned that:
llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp:1645:8: warning: variable ‘PrevIterCreatedNode’ set but not used [-Wunused-but-set-variable]
 1645 |   bool PrevIterCreatedNode = false;
      |        ^~~~~~~~~~~~~~~~~~~

When asserts were not enabled.
2025-06-12 12:52:54 +00:00
Teresa Johnson
b58b3e1d36
[MemProf] Add dot graph dumping immediately after stack node update (#143025)
To aid in debugging, (optionally) dump the dot graph immediately after
the stack update phase (which matches nodes to interior callsites) and
before we cleanup mismatched callee edges (either via tail call fixup,
indirect call fixup, or nulling otherwise).
2025-06-05 13:49:11 -07:00
Teresa Johnson
3ec2de2753
[MemProf] Optionally save context size info on largest cold allocations (#142837)
Reapply PR142507 with fix for test: add in the same x86_64-linux
requirement as other tests as the stack ids are currently computed
differently on big endian systems. This will be investigated separately.

In order to allow selective reporting of context hinting during the LTO
link, and in the future to allow selective more aggressive cloning, add
an option to specify a minimum percent of the max cold size in the
profile summary. Contexts that meet that threshold will get context size
info metadata (and ThinLTO summary information) on the associated
allocations.

Specifying -memprof-report-hinted-sizes during the pre-LTO compile step
will continue to cause all contexts to receive this metadata. But
specifying -memprof-report-hinted-sizes only during the LTO link will
cause only those that meet the new threshold and have the metadata to
get reported.

To support this, because the alloc info summary and associated bitcode
requires the context size information to be in the same order as the
other context information, 0s are inserted for contexts without this
metadata. The bitcode writer uses a more compact format for the context
ids to allow better compression of the 0s.

As part of this change several helper methods are added to query whether
metadata contains context size info on any or all contexts.
2025-06-04 13:08:56 -07:00
Teresa Johnson
6c1091ea3f
Revert "[MemProf] Optionally save context size info on largest cold allocations" (#142688)
Reverts llvm/llvm-project#142507 due to buildbot failures that I will
look into tomorrow.
2025-06-03 16:05:16 -07:00
Teresa Johnson
f2adae5780
[MemProf] Optionally save context size info on largest cold allocations (#142507)
In order to allow selective reporting of context hinting during the LTO
link, and in the future to allow selective more aggressive cloning, add
an option to specify a minimum percent of the max cold size in the
profile summary. Contexts that meet that threshold will get context size
info metadata (and ThinLTO summary information) on the associated
allocations.

Specifying -memprof-report-hinted-sizes during the pre-LTO compile step
will continue to cause all contexts to receive this metadata. But
specifying -memprof-report-hinted-sizes only during the LTO link will
cause only those that meet the new threshold and have the metadata to
get reported.

To support this, because the alloc info summary and associated bitcode
requires the context size information to be in the same order as the
other context information, 0s are inserted for contexts without this
metadata. The bitcode writer uses a more compact format for the context
ids to allow better compression of the 0s.

As part of this change several helper methods are added to query whether
metadata contains context size info on any or all contexts.
2025-06-03 14:20:38 -07:00
Iris Shi
bdf03fcff3
Revert "[llvm][NFC] Use llvm::sort()" (#140668) 2025-05-20 11:27:03 +08:00
Iris Shi
061a7699f3
[llvm][NFC] Use llvm::sort() (#140335) 2025-05-17 14:49:46 +08:00
Kazu Hirata
18ecff4f65
[llvm] Use llvm::stable_sort (NFC) (#140067) 2025-05-15 12:18:18 -07:00
Teresa Johnson
7348d7eccb
[MemProf] Avoid assertion checking loop under NDEBUG (NFC) (#138985)
Guard a loop that only exists to do assertion checking of stack ids on
memprof metadata so that it isn't compiled and executed under NDEBUG.
This is similar to how callsite metadata stack id verification is
guarded further below.
2025-05-07 21:20:01 -07:00
Owen Rodley
d3d856ad84
Clean up external users of GlobalValue::getGUID(StringRef) (#129644)
See https://discourse.llvm.org/t/rfc-keep-globalvalue-guids-stable/84801
for context.

This is a non-functional change which just changes the interface of
GlobalValue, in preparation for future functional changes. This part
touches a fair few users, so is split out for ease of review. Future
changes to the GlobalValue implementation can then be focused purely on
that class.

This does the following:

* Rename GlobalValue::getGUID(StringRef) to
  getGUIDAssumingExternalLinkage. This is simply making explicit at the
  callsite what is currently implicit.
* Where possible, migrate users to directly calling getGUID on a
  GlobalValue instance.
* Otherwise, where possible, have them call the newly renamed
  getGUIDAssumingExternalLinkage, to make the assumption explicit.


There are a few cases where neither of the above are possible, as the
caller saves and reconstructs the necessary information to compute the
GUID themselves. We want to migrate these callers eventually, but for
this first step we leave them be.
2025-04-28 11:09:43 +10:00
Kazu Hirata
2e230f5685
[llvm] Use llvm::interleaved (NFC) (#137496) 2025-04-26 23:28:46 -07:00
Teresa Johnson
2cdf474f12
[MemProf] Merge callee clones as needed before assigning functions (#135702)
We perform cloning for each allocation node separately. However, this
sometimes results in a situation where the same node calls multiple
clones of the same callee, created for different allocations. This
causes issues when assigning functions to these clones, as each node can
in reality only call a single callee clone.

To address this, before assigning functions, merge callee clone nodes as
needed using a post order traversal from the allocations. We attempt to
use existing clones as the merge node when legal, and to share them
among callers with the same properties (callers calling the same set of
callee clone nodes for the same allocations).

Without this fix, in some cases incorrect function assignment will lead
to calling the wrong allocation clone. In fact, this showed up in an
existing test, that I didn't notice as it existed to test earlier parts
of the cloning process.
2025-04-21 17:05:34 -07:00
Kazu Hirata
a42ac55a79
[IPO] Avoid repeated hash lookups (NFC) (#135750) 2025-04-17 23:03:25 -07:00
Teresa Johnson
e6e56f5b6a
[MemProf] Handle recursion during stack node update (#135837)
If we are replacing a sequence of stack nodes with a single node
representing inlined IR, and the stack id sequence contains recursion,
we may have already removed some edges. Handle this case correctly by
skipping the now removed edge.
2025-04-15 12:45:18 -07:00
Kazu Hirata
20d35fe5a5
[llvm] Use llvm::is_contained (NFC) (#135566) 2025-04-13 16:35:29 -07:00
Kazu Hirata
06cb7b1e14
[Transforms] Use llvm::append_range (NFC) (#133650) 2025-03-30 12:21:59 -07:00
Kazu Hirata
0dcc201ac4
[Transforms] Use *Set::insert_range (NFC) (#132056)
DenseSet, SmallPtrSet, SmallSet, SetVector, and StringSet recently
gained C++23-style insert_range.  This patch replaces:

  Dest.insert(Src.begin(), Src.end());

with:

  Dest.insert_range(Src);

This patch does not touch custom begin like succ_begin for now.
2025-03-19 15:35:01 -07:00
chrisPyr
71f4c7dabe
[NFC]Make file-local cl::opt global variables static (#126486)
#125983
2025-03-03 13:46:33 +07:00
Teresa Johnson
6a5bb4c2f1
[MemProf] Fix handling of recursive edges during func assignment (#129066)
When we need to reclone other callees of a caller node during function
assignment due to the creation of a new function clone, we need to skip
recursive edges on that caller. We don't want to reclone the callee in
that case (which is the caller), which isn't necessary and also isn't
correct from a graph update perspective. It resulted in an assertion and
in an NDEBUG build caused an infinite loop.
2025-02-27 08:41:28 -08:00
Teresa Johnson
eb92157399
[MemProf] Add ability to export or highlight only a portion of graph (#128255)
To simplify debugging and analysis, particularly for very large
applications with large graphs, this patch adds support for either
highlighting a single context id or allocation's context ids, and/or
only exporting the nodes/edges for a single context id or allocation's
context ids. When highlighting, the specified nodes and edges are a
brighter color and larger.

This can be controlled by the new -memprof-dot-scope={all,alloc,context}
flag which controls how much to export, along with two companion flags:
	-memprof-dot-alloc-id=ID
	-memprof-dot-context-id=ID
These two are interpreted differently depending on the value of
-memprof-dot-scope (where "all" is the default).

If exporting all, one of the above flags can optionally be passed to
highlight the nodes/edges for the given context id or allocation's
context ids.

If exporting alloc scope, an alloc id must be provided. A context id can
optionally be provided to highlight that context.

If exporting context scope, a context id must be provided.

The ids to use can be obtained either by looking at the full graph, or a
context id can be identified from the -memprof-report-hinted-sizes
output after PR128188 is merged.
2025-02-22 05:42:46 -08:00
Teresa Johnson
9d6f2647de
[MemProf] Print internal context id when reporting bytes hinted (#128188)
During the whole program reporting of contexts when hinted byte
reporting is enabled via -memprof-report-hinted-sizes, also print the
internal context id. This is useful for debugging, as well as for
guiding the dot file dumping with some upcoming changes that will
accept a context id to focus the graph on a context of interest.
2025-02-22 05:42:28 -08:00
Teresa Johnson
92e02ad9dc
[MemProf] Display backedges with dotted line in dot graphs (#128235)
Add checking of this behavior in the postbuild dot graphs, facilitated
by PR128226 which marked these edges at the end of the graph building.
2025-02-21 14:49:28 -08:00
Teresa Johnson
c3d5070086
[MemProf] Refactor backedge computation and invoke earlier (#128226)
Invoke the backedge computation (refactored as a new method) at the end
of the graph construction, instead of at the start of cloning. That
makes more logical sense, and it also makes it easier to look at the
results in the postbuild dot graph with a follow on change to display
those differently.
2025-02-21 12:57:40 -08:00
Teresa Johnson
741f923fac
[MemProf] Minor fixes to dot graph printing (#128217)
Two misc cleanup/improvements to the dot printing.

Remove a redundant "style=filled" in the Node attributes. No effect on
resulting graph.

Add a "color" attribute to the Edge, with the same color name as
"fillcolor". The latter only fills in the arrowhead, and the former is
what affects the line. This makes the edge colors more visible,
previously it was a black edge with a colored in arrowhead.

For the second change, I added the new Edge color attributes to the
checking in the two "basic.ll" tests, so we get some testing coverage of
the full printing. For the other affected tests I removed the final "]'"
after the fillcolor so it matches up through that attribute and ignores
the rest of the line.
2025-02-21 12:02:06 -08:00
Kazu Hirata
6342095bce [memprof] Fix a warning
This patch fixes:

  llvm/lib/Transforms/IPO/MemProfContextDisambiguation.cpp:3409:8:
  error: unused variable 'I' [-Werror,-Wunused-variable]
2025-02-19 14:28:13 -08:00
Teresa Johnson
92b07520bc
[MemProf] Support cloning through recursive cycles (#127429)
In order to facilitate cloning of recursive cycles, we first identify
backedges using a standard DFS search from the root callers, then
initially defer recursively invoking the cloning function via those
edges. This is because the cloning opportunity along the backedge may
not be exposed until the current node is cloned for other non-backedge
callers that are cold after the earlier recursive cloning, resulting
in a cold predecessor of the backedge. So we recursively invoke the
cloning function for the backedges during the cloning of the current
node for its caller edges (which were sorted to enable handling cold
callers first).

There was no significant time or memory overhead measured for several
large applications.
2025-02-19 12:44:33 -08:00
Teresa Johnson
1dbfbb5ce6
[MemProf] Stop cloning traversal on single allocation type (#126131)
We were previously checking this after recursing on all callers, but if
we already have a single allocation type there is no need to even look
at any callers. Didn't show a significant improvement overall, but it
does reduce the count of times we enter the identifyClones and do other
checks.
2025-02-06 13:21:02 -08:00