671 Commits

Author SHA1 Message Date
Arthur Eubanks
82505fbfc8
[Inliner] Put inline history into IR as !inline_history metadata (#190700)
(Reland of #190092 with verifier change to look through GlobalAliases)

So that it's preserved across all inline invocations rather than just
one inliner pass run.

This prevents cases where devirtualization in the simplification
pipeline uncovers inlining opportunities that should be discarded due to
inline history, but we dropped the inline history between inliner pass
runs, causing code size to blow up, sometimes exponentially.

For compile time reasons, we want to limit this to only call sites that
have the potential to inline through SCCs, potentially with the help of
devirtualization. This means that the callee is in a non-trivial
(Ref)SCC, or the call site was previously an indirect call, which can
potentially be devirtualized to call any function.

The CGSCCUpdater::InlinedInternalEdges logic still seems to be relevant
even with this change, as monster_scc.ll blows up if I remove that code.


http://llvm-compile-time-tracker.com/compare.php?from=e830d88e8ae5f44a97cc76136a0a4e83aa9157c0&to=ed535e732fc41b79ab8efda2417886cbd0812f7f&stat=instructions:u

Fixes #186926.
2026-04-06 17:31:43 -07:00
Arthur Eubanks
70d3dcaa64
Revert "[Inliner] Put inline history into IR as !inline_history metadata" (#190666)
Reverts llvm/llvm-project#190092

Crashes reported in
https://github.com/llvm/llvm-project/pull/190092#issuecomment-4194546908
2026-04-06 20:31:54 +00:00
Arthur Eubanks
72d4ce9889
[Inliner] Put inline history into IR as !inline_history metadata (#190092)
So that it's preserved across all inline invocations rather than just
one inliner pass run.

This prevents cases where devirtualization in the simplification
pipeline uncovers inlining opportunities that should be discarded due to
inline history, but we dropped the inline history between inliner pass
runs, causing code size to blow up, sometimes exponentially.

For compile time reasons, we want to limit this to only call sites that
have the potential to inline through SCCs, potentially with the help of
devirtualization. This means that the callee is in a non-trivial
(Ref)SCC, or the call site was previously an indirect call, which can
potentially be devirtualized to call any function.

The CGSCCUpdater::InlinedInternalEdges logic still seems to be relevant
even with this change, as monster_scc.ll blows up if I remove that code.


http://llvm-compile-time-tracker.com/compare.php?from=e830d88e8ae5f44a97cc76136a0a4e83aa9157c0&to=ed535e732fc41b79ab8efda2417886cbd0812f7f&stat=instructions:u

Fixes #186926.
2026-04-06 10:24:41 -07:00
Justin Stitt
f9ad232421
[Clang] Show inlining hints for __attribute__((warning/error)) (#174892)
When functions marked with `[[gnu::warning/error]]` are called through inlined functions, we now show the inlining chain that led to the call when ``-fdiagnostics-show-inlining-chain`` is enabled.

With this flag, two modes are possible:

- **heuristic** mode: Uses `srcloc` and `inlined.from` metadata to reconstruct the inlining chain. Functions that are `inline`, `static`, `always_inline`, or in anonymous namespaces get `srcloc` metadata attached. This mode emits a note suggesting `-gline-directives-only` for more accurate locations.

- **debug** mode: Automatically used instead of heuristic when building with at least `-gline-directives-only` (implied by `-g1` or higher). Leverages `DILocation` debug info for reliable source locations.

Fixes: https://github.com/ClangBuiltLinux/linux/issues/1571
2026-03-27 13:52:31 -07:00
Grigory Pastukhov
f66bd8e81a
[LLVM] Add flatten function attribute to LLVM IR and implement recursive inlining in AlwaysInliner (#174899)
This adds a new function-level `flatten` LLVM IR attribute and
implements support for it in the AlwaysInliner pass, bringing LLVM's
behavior in line with GCC.

Previously, the `flatten` attribute only existed as a Clang attribute,
which was lowered to `alwaysinline` on individual call sites. Per the
RFC discussion [1], the consensus was to match GCC semantics:
recursively inline the entire call tree into the
flattened function, rather than just immediate call sites.

This PR:
- Adds the `flatten` function attribute to LLVM IR
- Implements recursive inlining of all viable callees in AlwaysInliner
- Uses inline history tracking to detect and stop at recursive call
cycles
- Emits optimization remarks when inlining is skipped due to recursion

A follow-up patch will update Clang to emit the LLVM `flatten` attribute
on
functions instead of marking individual call sites with `alwaysinline`.

[1]
https://discourse.llvm.org/t/rfc-function-level-flatten-depth-attribute-for-depth-limited-inlining
2026-03-19 11:25:46 -07:00
Yunbo Ni
ddaaf4fa7a
[Inliner] Fix return attribute propagation across multiple return sites (#186076)
Fixes #185159 

This patch fixes a bug in `AddReturnAttributes()` where propagated
return attributes could incorrectly leak across multiple return sites in
the callee being inlined.

`AddReturnAttributes()` walks the callee's return instructions and tries
to backward-propagate return attributes from the callsite to the
returned call when the callee directly returns a call result. However,
the propagated attribute builders were updated in-place while iterating
over return sites. As a result, attributes refined for one return site
could be reused when
processing a later return site. This is incorrect because each return
site should be handled independently, starting from the original
callsite attributes.

This patch ensures that propagated return attributes are reinitialized
for each return site, so propagation is computed independently per
returned call.
2026-03-16 22:14:11 +01:00
Alexis Engelke
e2fef479f8
[Transforms/Utils][NFC] Drop uses of BranchInst (#186586) 2026-03-14 12:47:10 +01:00
Alexis Engelke
4fd826d1f9
[IR] Split Br into UncondBr and CondBr (#184027)
BranchInst currently represents both unconditional and conditional
branches. However, these are quite different operations that are often
handled separately. Therefore, split them into separate opcodes and
classes to allow distinguishing these operations in the type system.
Additionally, this also slightly improves compile-time performance.
2026-03-11 12:31:10 +00:00
Matt Arsenault
91f39535c7
Inliner: Handle nofpclass return attributes (#179776)
Follow along with how range is handled.
2026-02-05 20:27:46 +01:00
Sean Fertile
b6212a4caf
XCOFF associated metadata (#159096)
Add a new metadata node `!implicit.ref` to represent an implicit
dependency between 2 symbols. The metadata is unique to AIX and gets
lowered to a relocation that adds an explicit link between the section
the global that the metadata is placed on is allocated in, to the
asscoiated symbol. This relocation will cause the associated symbol to
remain live if the section is not garbage collected. This is used mainly
for compiler features where there is some hidden runtime dependency
between the symbols that isn't otherwise obvious to the linker.
2026-01-09 13:49:21 -05:00
Kazu Hirata
cbf5af9668
[llvm] Remove unused includes (NFC) (#154051)
These are identified by misc-include-cleaner.  I've filtered out those
that break builds.  Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
2025-08-17 23:46:35 -07:00
Nikita Popov
c23b4fbdbb
[IR] Remove size argument from lifetime intrinsics (#150248)
Now that #149310 has restricted lifetime intrinsics to only work on
allocas, we can also drop the explicit size argument. Instead, the size
is implied by the alloca.

This removes the ability to only mark a prefix of an alloca alive/dead.
We never used that capability, so we should remove the need to handle
that possibility everywhere (though many key places, including stack
coloring, did not actually respect this).
2025-08-08 11:09:34 +02:00
Matt Arsenault
1110e2ff9f
InlineFunction: Split inlining into predicate and apply functions (#134213)
This is to support a new inline function reduction in llvm-reduce,
which should pre-filter callsites that are not eligible for inlining.

This code was mostly structured as a match and apply, with a few
exceptions. The ugliest piece is for propagating and verifying
compatible
getGC and personalities. Also collection of EHPad and the convergence
token
to use are now cached in InlineFunctionInfo.

I was initially confused by the split between the checks performed here
and isInlineViable, so better document how this system is supposed to
work.
It turns out this split does make sense, in that isInlineViable checks
if it's possible based on the callee content and the ultimate inline
depended on the callsite context. I think more renames of these
functions
would help, and isInlineViable should probably move out of InlineCost to
be
with these transfoms.
2025-08-07 16:13:36 +09:00
Jeremy Morse
2a1869b981
[DebugInfo] Shave even more users of DbgVariableIntrinsic from LLVM (#149136)
At this stage I'm just opportunistically deleting any code using
debug-intrinsic types, largely adjacent to calls to findDbgUsers. I'll
get to deleting that in probably one or more two commits.
2025-07-18 08:25:10 +01:00
Kazu Hirata
3d5903c4d8
[llvm] Use llvm::is_contained (NFC) (#145844)
llvm::is_contained is shorter than llvm::all_of plus a lambda.
2025-06-26 08:41:18 -07:00
Kazu Hirata
21def215b5
[Utils] Drop const from a return type (NFC) (#145838)
We don't need const on the return type.
2025-06-26 18:57:34 +08:00
Jeremy Morse
9eb0020555
[DebugInfo][RemoveDIs] Remove a swathe of debug-intrinsic code (#144389)
Seeing how we can't generate any debug intrinsics any more: delete a
variety of codepaths where they're handled. For the most part these are
plain deletions, in others I've tweaked comments to remain coherent, or
added a type to (what was) type-generic-lambdas.

This isn't all the DbgInfoIntrinsic call sites but it's most of the
simple scenarios.

Co-authored-by: Nikita Popov <github@npopov.com>
2025-06-17 15:55:14 +01:00
Stephen Tozer
aa8a1fa6f5
[DLCov][NFC] Annotate intentionally-blank DebugLocs in existing code (#136192)
Following the work in PR #107279, this patch applies the annotative
DebugLocs, which indicate that a particular instruction is intentionally
missing a location for a given reason, to existing sites in the compiler
where their conditions apply. This is NFC in ordinary LLVM builds (each
function `DebugLoc::getFoo()` is inlined as `DebugLoc()`), but marks the
instruction in coverage-tracking builds so that it will be ignored by
Debugify, allowing only real errors to be reported. From a developer
standpoint, it also communicates the intentionality and reason for a
missing DebugLoc.

Some notes for reviewers:

- The difference between `I->dropLocation()` and
`I->setDebugLoc(DebugLoc::getDropped())` is that the former _may_ decide
to keep some debug info alive, while the latter will always be empty; in
this patch, I always used the latter (even if the former could
technically be correct), because the former could result in some
(barely) different output, and I'd prefer to keep this patch purely NFC.
- I've generally documented the uses of `DebugLoc::getUnknown()`, with
the exception of the vectorizers - in summary, they are a huge cause of
dropped source locations, and I don't have the time or the domain
knowledge currently to solve that, so I've plastered it all over them as
a form of "fixme".
2025-06-11 17:42:10 +01:00
Teresa Johnson
49d48c32e0
[MemProf] Emit remarks when hinting allocations not needing cloning (#141859)
The context disambiguation code already emits remarks when hinting
allocations (by adding hotness attributes) during cloning. However,
we did not yet emit hints when applying the hotness attributes during
building of the metadata (during matching and again after inlining).
Add remarks when we apply the hint attributes for these
non-context-sensitive allocations.
2025-05-28 16:44:44 -07:00
Nikita Popov
904d0c293e
[Inline] Only consider provenance captures for scoped alias metadata (#138540)
When determining whether an escape source may alias with a noalias
argument, only take provenance captures into account. If only the
address of the argument was captured, an access through the escape
source is not legal.
2025-05-27 15:15:57 +02:00
Kazu Hirata
6e4f501b1b
[Utils] Remove redundant calls to std::unique_ptr<T>::get (NFC) (#139352) 2025-05-10 07:27:29 -07:00
Orlando Cazalet-Hyams
5be080edf7
[KeyInstr][Inline] Don't propagate atoms to inlined nodebug instructions (#133485)
RFC: https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668
2025-05-07 11:54:57 +01:00
Orlando Cazalet-Hyams
73a7a3dc00
[KeyInstr] Inline atom info (#133481)
Source atom groups are identified by an atom group number and inlined-at pair,
so we simply can copy the atom numbers into the caller when inlining.

RFC:
https://discourse.llvm.org/t/rfc-improving-is-stmt-placement-for-better-interactive-debugging/82668
2025-05-06 14:38:41 +01:00
sallto
419a2cb218
[Inliner] Preserve alignment of byval arguments (#137455)
Previously the inliner always produced a memcpy with alignment 1 for src
and destination, leading to potentially suboptimal Codegen.

Since the Src ptr alignment is only available through the CallBase it
has to be passed to HandleByValArgumentInit. Dst Alignment is already
known so it doesn't have to be passed along.

If there is no specified Src Alignment my changes cause the ptr to have
no align data attached instead of align 1 as before (see
inline-tail.ll), I believe this is fine but since I'm a first time
contributor, please confirm.

My changes are already covered by 4 existing regression tests, so I did
not add any additional ones.

The example from #45778 now results in:
```C
opt -S -passes=inline,instcombine,sroa,instcombine test.ll

define dso_local i32 @test(ptr %t) {
entry:
  %.sroa.0.0.copyload = load ptr, ptr %t, align 8       # this used to be align 1 in the original issue
  %arrayidx.i = getelementptr inbounds nuw i8, ptr %.sroa.0.0.copyload, i64 24
  %0 = load i32, ptr %arrayidx.i, align 4
  ret i32 %0
}
```

Fixes #45778.
2025-04-26 21:38:58 +02:00
Matt Arsenault
cf766f5210
InlineFunction: Use use_empty instead of hasNUses(0) (#137347) 2025-04-25 19:01:20 +02:00
Matt Arsenault
f819f46284
Reapply "Inline: Propagate callsite nofpclass attribute" (#135018)
This reverts commit 3f38cd07d820248fd2043efb1341fabaac2d84a6.

Fix case where inner callsite has nofpclass but callsite does not.
2025-04-10 07:15:58 +02:00
Stephen Tozer
9344b2196c
[DebugInfo][Inlining] Propagate inlined resume source loc to new br (#134826)
As part of inlining an invoke instruction, we may replace an inlined
resume instruction with a simple branch to the landing pad block. When
this happens, we should also propagate the resume's DILocation to this
branch, which this patch enables.

Found using https://github.com/llvm/llvm-project/pull/107279.
2025-04-09 16:42:06 +01:00
Matt Arsenault
3f38cd07d8 Revert "Inline: Propagate callsite nofpclass attribute"
This reverts commit b0cb672b9968eeee6eb022e98476957dbdf8e6e2.

Breaks bot
2025-04-08 23:15:00 +07:00
Matt Arsenault
b0cb672b99
Inline: Propagate callsite nofpclass attribute
(#134800)

Fixes #134070
2025-04-08 22:53:17 +07:00
Mircea Trofin
f1bb2fe356
[ctxprof] Use isInSpecializedModule as criteria for using contextual profile (#134468)
After #134340, the availability of contextual profile isn't in itself an indication of compiling the module containing all the functions covered by that profile.
2025-04-07 19:55:00 -07:00
Rahul Joshi
74b7abf154
[IRBuilder] Add new overload for CreateIntrinsic (#131942)
Add a new `CreateIntrinsic` overload with no `Types`, useful for
creating calls to non-overloaded intrinsics that don't need additional
mangling.
2025-03-31 08:10:34 -07:00
Kazu Hirata
73dc2afd2c
[Transforms] Use *Set::insert_range (NFC) (#132652)
We can use *Set::insert_range to collapse:

  for (auto Elem : Range)
    Set.insert(E);

down to:

  Set.insert_range(Range);

In some cases, we can further fold that into the set declaration.
2025-03-23 19:42:53 -07:00
Mircea Trofin
2068a18c86
[ctxprof][nfc] Prepare CtxProfAnalysis for flat profiles (#129623)
Mostly remove the equivalence "no contexts == no CtxProfAnalysis result", and instead check explicitly there are no contextual profiles.
2025-03-04 16:42:47 -08:00
Nikita Popov
9cbdcfcafd [CaptureTracking] Remove StoreCaptures parameter (NFC)
The implementation doesn't use it, and is unlikely to use it in
the future.

The places that do set StoreCaptures=false, do so incorrectly and
would be broken if the parameter actually did anything.
2025-02-24 12:00:57 +01:00
Yingwei Zheng
9fbd5fbcc6
[IR][NFC] Switch to use LifetimeIntrinsic (#125528) 2025-02-04 02:18:33 +08:00
Jeremy Morse
e14962a39c
[NFC][DebugInfo] Use iterators for instruction insertion in more places (#124291)
As part of the "RemoveDIs" work to eliminate debug intrinsics, we're
replacing methods that use Instruction*'s as positions with iterators.
This patch changes some more complex call-sites, those crossing file
boundaries and where I've had to perform some minor rewrites.
2025-01-27 15:25:17 +00:00
Jeremy Morse
6292a808b3
[NFC][DebugInfo] Use iterator-flavour getFirstNonPHI at many call-sites (#123737)
As part of the "RemoveDIs" project, BasicBlock::iterator now carries a
debug-info bit that's needed when getFirstNonPHI and similar feed into
instruction insertion positions. Call-sites where that's necessary were
updated a year ago; but to ensure some type safety however, we'd like to
have all calls to getFirstNonPHI use the iterator-returning version.

This patch changes a bunch of call-sites calling getFirstNonPHI to use
getFirstNonPHIIt, which returns an iterator. All these call sites are
where it's obviously safe to fetch the iterator then dereference it. A
follow-up patch will contain less-obviously-safe changes.

We'll eventually deprecate and remove the instruction-pointer
getFirstNonPHI, but not before adding concise documentation of what
considerations are needed (very few).

---------

Co-authored-by: Stephen Tozer <Melamoto@gmail.com>
2025-01-24 13:27:56 +00:00
Harald van Dijk
ccaded2b1d
[Inliner] Prevent adding pointer attributes to non-pointer arguments (#115569)
Fixes a crash seen after #114311
2024-11-09 16:17:16 +00:00
Steven Perron
f405c683ba
[OPT] Search whole BB for convergence token. (#112728)
The spec for llvm.experimental.convergence.entry says that is must be in
the entry block for a function, and must preceed any other convergent
operation. It does not have to be the first instruction in the entry
block.

Inlining assumes that the call to llvm.experimental.convergence.entry
will be the first instruction after any phi instructions. This commit
modifies inlining to search the entire block for the call.
2024-10-30 11:19:23 -04:00
goldsteinn
69a798a996
Reapply "[Inliner] Propagate more attributes to params when inlining (#91101)" (2nd Attempt) (#112749)
Root cause of the bug was code hanging onto `range` attr after
changing BitWidth. This was fixed in PR #112633.
2024-10-17 20:28:47 -05:00
goldsteinn
c85611e858
[SimplifyLibCall][Attribute] Fix bug where we may keep range attr with incompatible type (#112649)
In a variety of places we change the bitwidth of a parameter but don't
update the attributes.

The issue in this case is from the `range` attribute when inlining
`__memset_chk`. `optimizeMemSetChk` will replace an `i32` with an
`i8`, and if the `i32` had a `range` attr assosiated it will cause an
error.

Fixes #112633
2024-10-17 10:32:55 -05:00
Jay Foad
85c17e4092
[LLVM] Make more use of IRBuilder::CreateIntrinsic. NFC. (#112706)
Convert many instances of:
  Fn = Intrinsic::getOrInsertDeclaration(...);
  CreateCall(Fn, ...)
to the equivalent CreateIntrinsic call.
2024-10-17 16:20:43 +01:00
Arthur Eubanks
9e6d24f61f Revert "[Inliner] Propagate more attributes to params when inlining (#91101)"
This reverts commit ae778ae7ce72219270c30d5c8b3d88c9a4803f81.

Creates broken IR, see comments in #91101.
2024-10-16 21:21:34 +00:00
goldsteinn
ae778ae7ce
[Inliner] Propagate more attributes to params when inlining (#91101)
- **[Inliner] Add tests for propagating more parameter attributes; NFC**
- **[Inliner] Propagate more attributes to params when inlining**

Add support for propagating:
        - `derefereancable`
        - `derefereancable_or_null`
        - `align`
        - `nonnull`
        - `range`
    
These are only propagated if the parameter to the to-be-inlined callsite
match the exact parameter used in the to-be-inlined function.
2024-10-16 11:53:21 -05:00
goldsteinn
3c777f04f0
[Inliner] Don't propagate access attr to byval params (#112256)
- **[Inliner] Add tests for bad propagationg of access attr for `byval`
param; NFC**
- **[Inliner] Don't propagate access attr to `byval` params**

We previously only handled the case where the `byval` attr was in the
callbase's param attr list. This PR also handles the case if the
`ByVal` was a param attr on the function's param attr list.
2024-10-15 09:25:16 -05:00
Rahul Joshi
fa789dffb1
[NFC] Rename Intrinsic::getDeclaration to getOrInsertDeclaration (#111752)
Rename the function to reflect its correct behavior and to be consistent
with `Module::getOrInsertFunction`. This is also in preparation of
adding a new `Intrinsic::getDeclaration` that will have behavior similar
to `Module::getFunction` (i.e, just lookup, no creation).
2024-10-11 05:26:03 -07:00
Mircea Trofin
c4952e513f
[nfc][ctx_prof] Efficient profile traversal and update (#110052)
This optimizes profile updates and visits, where we want to access contexts for a specific function. These are all the current update cases. We do so by maintaining a list of contexts for each function, preserving preorder traversal. The list is updated whenever contexts are `std::move`-d or deleted.
2024-09-27 08:09:10 -07:00
Mircea Trofin
783bac7ffb
[ctx_prof] Handle select and its step instrumentation (#109185)
The `step` instrumentation shouldn't be treated, during use, like an `increment`. The latter is treated as a BB ID. The step isn't that, it's more of a type of value profiling. We need to distinguish between the 2 when really looking for BB IDs (==increments), and handle appropriately `step`s. In particular, we need to know when to elide them because `select`s may get elided by function cloning, if the condition of the select is statically known.
2024-09-23 15:21:25 -07:00
goldsteinn
a9352a0d31
[Inliner] Fix bug where attributes are propagated incorrectly (#109347)
- **[Inliner] Add tests for incorrect propagation of return attrs; NFC**
- **[Inliner] Fix bug where attributes are propagated incorrectly**

The bug stems from the fact that we assume the new (inlined) callsite
is calling the same function as the original (callee) callsite. While
this is typically the case, since `VMap` simplifies the new
instructions, callee intrinsics callsites can end up not corresponding
with the same function.

This can lead to buggy propagation.
2024-09-20 19:57:35 -05:00
Jay Foad
e03f427196
[LLVM] Use {} instead of std::nullopt to initialize empty ArrayRef (#109133)
It is almost always simpler to use {} instead of std::nullopt to
initialize an empty ArrayRef. This patch changes all occurrences I could
find in LLVM itself. In future the ArrayRef(std::nullopt_t) constructor
could be deprecated or removed.
2024-09-19 16:16:38 +01:00