609 Commits

Author SHA1 Message Date
Tim Gymnich
049f179606
[Analysis][NFC] Extract KnownFPClass (#133457)
- extract KnownFPClass for future use inside of GISelKnownBits

---------

Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
2025-03-28 18:10:02 +01: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
Kazu Hirata
8789c0083d
[Transforms] Avoid repeated hash lookups (NFC) (#131554) 2025-03-17 07:42:21 -07:00
Johannes Doerfert
9f28621fae
[Attributor][NFC] Clang format (#129163) 2025-02-27 23:59:08 -05:00
Nikita Popov
e56a6a2683
Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880) (#128020)
Relative to the previous attempt this includes two fixes:
 * Adjust callCapturesBefore() to not skip captures(ret: address,
    provenance) arguments, as these will not count as a capture
    at the call-site.
 * When visiting uses during stack slot optimization, don't skip
    the ModRef check for passthru captures. Calls can both modref
    and be passthru for captures.

------

This extends CaptureTracking to support inferring non-trivial
CaptureInfos. The focus of this patch is to only support FunctionAttrs,
other users of CaptureTracking will be updated in followups.

The key API changes here are:

* DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC
component specifies what is captured at that Use and the ResultCC
component specifies what may be captured via the return value of the
User. Usually only one or the other will be used (corresponding to
previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for
call captures.
* The CaptureTracking::captures() extension point is passed this
UseCaptureInfo as well and then can decide what to do with it by
returning an Action, which is one of: Stop: stop traversal.
ContinueIgnoringReturn: continue traversal but don't follow the
instruction return value. Continue: continue traversal and follow the
instruction return value if it has additional CaptureComponents.

For now, this patch retains the (unsound) special logic for comparison
of null with a dereferenceable pointer. I'd like to switch key code to
take advantage of address/address_is_null before dropping it.

This PR mainly intends to introduce necessary API changes and basic
inference support, there are various possible improvements marked with
TODOs.
2025-02-27 09:38:29 +01:00
Nico Weber
e2ba1b6ffd Revert "Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)"
This reverts commit 0fab404ee874bc5b0c442d1841c7d2005c3f8729.
Seems to break LTO builds of clang on Windows, see comments on
https://github.com/llvm/llvm-project/pull/125880
2025-02-19 11:32:57 -05:00
Nikita Popov
7e3735d1a1 Reapply [CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)
Relative to the previous attempt, this adjusts isEscapeSource()
to not treat calls with captures(ret: address, provenance) or similar
arguments as escape sources. This addresses the miscompile reported at:
https://github.com/llvm/llvm-project/pull/125880#issuecomment-2656632577

The implementation uses a helper function on CallBase to make this
check a bit more efficient (e.g. by skipping the byval checks) as
checking attributes on all arguments if fairly expensive.

------

This extends CaptureTracking to support inferring non-trivial
CaptureInfos. The focus of this patch is to only support FunctionAttrs,
other users of CaptureTracking will be updated in followups.

The key API changes here are:

* DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC
component specifies what is captured at that Use and the ResultCC
component specifies what may be captured via the return value of the
User. Usually only one or the other will be used (corresponding to
previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for
call captures.
* The CaptureTracking::captures() extension point is passed this
UseCaptureInfo as well and then can decide what to do with it by
returning an Action, which is one of: Stop: stop traversal.
ContinueIgnoringReturn: continue traversal but don't follow the
instruction return value. Continue: continue traversal and follow the
instruction return value if it has additional CaptureComponents.

For now, this patch retains the (unsound) special logic for comparison
of null with a dereferenceable pointer. I'd like to switch key code to
take advantage of address/address_is_null before dropping it.

This PR mainly intends to introduce necessary API changes and basic
inference support, there are various possible improvements marked with
TODOs.
2025-02-14 12:38:04 +01:00
Nikita Popov
1e64ea9914 Revert "[CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)"
This reverts commit ee655ca27aad466bcc54f6eba03f7e564940ad5a.

A miscompilation has been reported at:
https://github.com/llvm/llvm-project/pull/125880#issuecomment-2656632577
2025-02-13 14:56:12 +01:00
Nikita Popov
ee655ca27a
[CaptureTracking][FunctionAttrs] Add support for CaptureInfo (#125880)
This extends CaptureTracking to support inferring non-trivial
CaptureInfos. The focus of this patch is to only support FunctionAttrs,
other users of CaptureTracking will be updated in followups.

The key API changes here are:

* DetermineUseCaptureKind() now returns a UseCaptureInfo where the UseCC
component specifies what is captured at that Use and the ResultCC
component specifies what may be captured via the return value of the
User. Usually only one or the other will be used (corresponding to
previous MAY_CAPTURE or PASSTHROUGH results), but both may be set for
call captures.
* The CaptureTracking::captures() extension point is passed this
UseCaptureInfo as well and then can decide what to do with it by
returning an Action, which is one of: Stop: stop traversal.
ContinueIgnoringReturn: continue traversal but don't follow the
instruction return value. Continue: continue traversal and follow the
instruction return value if it has additional CaptureComponents.

For now, this patch retains the (unsound) special logic for comparison
of null with a dereferenceable pointer. I'd like to switch key code to
take advantage of address/address_is_null before dropping it.

This PR mainly intends to introduce necessary API changes and basic
inference support, there are various possible improvements marked with
TODOs.
2025-02-13 09:36:35 +01:00
Nikita Popov
8a43d0e873 [Attributor] Check correct IRPosition in AANoCapture::isImpliedByIR()
This case is intended to check the callee argument, not the call-site.

Fixes an issue introduced in #123181.
2025-01-29 17:34:10 +01:00
Nikita Popov
29441e4f5f
[IR] Convert from nocapture to captures(none) (#123181)
This PR removes the old `nocapture` attribute, replacing it with the new
`captures` attribute introduced in #116990. This change is
intended to be essentially NFC, replacing existing uses of `nocapture`
with `captures(none)` without adding any new analysis capabilities.
Making use of non-`none` values is left for a followup.

Some notes:
* `nocapture` will be upgraded to `captures(none)` by the bitcode
   reader.
* `nocapture` will also be upgraded by the textual IR reader. This is to
   make it easier to use old IR files and somewhat reduce the test churn in
   this PR.
* Helper APIs like `doesNotCapture()` will check for `captures(none)`.
* MLIR import will convert `captures(none)` into an `llvm.nocapture`
   attribute. The representation in the LLVM IR dialect should be updated
   separately.
2025-01-29 16:56:47 +01:00
Jeremy Morse
8e70273509
[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)
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 moveBefore use iterators.

This patch adds a (guaranteed dereferenceable) iterator-taking
moveBefore, and changes a bunch of call-sites where it's obviously safe
to change to use it by just calling getIterator() on an instruction
pointer. A follow-up patch will contain less-obviously-safe changes.

We'll eventually deprecate and remove the instruction-pointer
insertBefore, but not before adding concise documentation of what
considerations are needed (very few).
2025-01-24 10:53:11 +00:00
Mats Jun Larsen
416f1c465d
[IR] Replace of PointerType::get(Type) with opaque version (NFC) (#123617)
In accordance with https://github.com/llvm/llvm-project/issues/123569

In order to keep the patch at reasonable size, this PR only covers for
the llvm subproject, unittests excluded.
2025-01-21 00:32:56 +09:00
macurtis-amd
d1a6eaa478
[Attributor][NFC] Performance improvements (#122923)
` forallInterferingAccesses` is a hotspot and for large modules these
changes make a measurable improvement in compilation time.

For LTO kernel compilation of 519.clvleaf (SPEChpc 2021) I measured the
following:
```
                    |   Measured times (s)   | Average | speedup
--------------------+------------------------+---------+---------
Baseline            | 33.268  33.332  33.275 |  33.292 |      0%
Cache "kernel"      | 30.543  30.339  30.607 |  30.496 |    9.2%
templatize callback | 30.981  30.97   30.964 |  30.972 |    7.5%
Both changes        | 29.284  29.201  29.053 |  29.179 |   14.1%
```
2025-01-14 12:51:25 -06:00
Jay Foad
f8559751fc
[llvm-project] Fix typo "propogate" (#114795) 2024-11-04 15:33:19 +00:00
Kazu Hirata
98ea1a81a2
[IPO] Remove unused includes (NFC) (#114716)
Identified with misc-include-cleaner.
2024-11-03 13:48:55 -08:00
Shilei Tian
5a74a4a667
[Attributor] Take the address space from addrspacecast directly (#108258)
Currently `AAAddressSpace` relies on identifying the address spaces of
all underlying objects. However, it might infer sub-optimal address
space when the underlying object is a function argument. In
`AMDGPUPromoteKernelArgumentsPass`, the promotion of a pointer kernel
argument is by adding a series of `addrspacecast` instructions (as shown
below), and hoping `InferAddressSpacePass` can pick it up and do the
rewriting accordingly.

Before promotion:

```
define amdgpu_kernel void @kernel(ptr %to_be_promoted) {
  %val = load i32, ptr %to_be_promoted
  ...
  ret void
}
```

After promotion:

```
define amdgpu_kernel void @kernel(ptr %to_be_promoted) {
  %ptr.cast.0 = addrspace cast ptr % to_be_promoted to ptr addrspace(1)
  %ptr.cast.1 = addrspace cast ptr addrspace(1) %ptr.cast.0 to ptr
  # all the use of %to_be_promoted will use %ptr.cast.1
  %val = load i32, ptr %ptr.cast.1
  ...
  ret void
}
```

When `AAAddressSpace` analyzes the code after promotion, it will take
`%to_be_promoted` as the underlying object of `%ptr.cast.1`, and use its
address space (which is 0) as its final address space, thus simply do
nothing in `manifest`. The attributor framework will them eliminate the
address space cast from 0 to 1 and back to 0, and replace `%ptr.cast.1`
with `%to_be_promoted`, which basically reverts all changes by
`AMDGPUPromoteKernelArgumentsPass`.

IMHO I'm not sure if `AMDGPUPromoteKernelArgumentsPass` promotes the
argument in a proper way. To improve the handling of this case, this PR
adds an extra handling when iterating over all underlying objects. If an
underlying object is a function argument, it means it reaches a terminal
such that we can't futher deduce its underlying object further. In this
case, we check all uses of the argument. If they are all `addrspacecast`
instructions and their destination address spaces are same, we take the
destination address space.

Fixes: SWDEV-482640.
2024-10-09 22:51:07 -04:00
Johannes Doerfert
335e137267
[Attributor][FIX] Track returned pointer offsets (#110534)
If the pointer returned by a function is not "the base pointer" but has
an offset, we need to track the offset such that users can apply it to
their offset chain when they create accesses.
This was reported by @ye-luo and reduced test cases are included. The
OffsetInfo was moved and the container was replaced with a set to avoid
excessive growth. Otherwise, the patch just replaces the "returns
pointer" flag with the "returned offsets", and deals with the applying
to offsets at the call site.

---------

Co-authored-by: Johannes Doerfert <jdoerfert@llnl.gov>
2024-10-01 12:41:15 -05:00
Jeremy Morse
96f37ae453
[NFC] Use initial-stack-allocations for more data structures (#110544)
This replaces some of the most frequent offenders of using a DenseMap that
cause a malloc, where the typical element-count is small enough to fit in
an initial stack allocation.

Most of these are fairly obvious, one to highlight is the collectOffset
method of GEP instructions: if there's a GEP, of course it's going to have
at least one offset, but every time we've called collectOffset we end up
calling malloc as well for the DenseMap in the MapVector.
2024-09-30 23:15:18 +01:00
Shilei Tian
0b7a18bd4a
[Attributor] Use more appropriate approach to check flat address space (#108713) 2024-09-27 18:26:55 -04:00
macurtis-amd
72fd35b85b
[Attributor] Report change when updating ReachesReturn (#108965) 2024-09-19 11:10:18 -05:00
Shilei Tian
4808842771
[NFC][Attributor] Use unsigned integer for address space tracking (#108447) 2024-09-12 13:56:21 -07:00
Johannes Doerfert
56a033462e
[Attributor] Keep track of reached returns in AAPointerInfo (#107479)
Instead of visiting call sites in Attribute::checkForAllUses, we now
keep track of returns in AAPointerInfo and use the call site return
information as required. This way, the user of
AAPointerInfo(CallSite)Argument can determine if the call return should
be visited. We do not collect them as "may accesses" in the
AAPointerInfo(CallSite)Argument itself in case a return user is found.
2024-09-10 08:13:21 -07:00
Shilei Tian
ce2e38653f
[Attributor] Add support for atomic operations in AAAddressSpace (#106927) 2024-09-06 12:45:16 -04:00
Shilei Tian
109cd11dc4
[Attributor] Skip AS specialization for volatile memory instructions (#107250) 2024-09-06 11:00:30 -04:00
Johannes Doerfert
84bf0da34d
[Attributor][FIX] Ensure to always translate call site arguments (#107323)
When we propagate call site arguments we always need to translate them,
this is important as we ended up picking the function argument for a
recurisve call not the call site argument. `@recBad` and `@recGood` in
`returned.ll` show the problem as they used to transform them the same
way. The restructuring cleans the code up and helps derive more
"returned" arguments and better information in the presence of recursive
calls. The "dropped" attributes are simply dropped because we do not
query them anymore, not because we cannot derive them.
2024-09-05 13:37:21 -07:00
Johannes Doerfert
e6dece9f69
[Attributor][FIX] Mark "may" accesses through call sites as such (#107439)
Before, we kept the call site access kind (may/must) when we translated
the access. However, the pointer we access it through (by passing it to
the callee) might not be the underlying object. We have similar logic
when we add store and load accesses.
2024-09-05 13:33:58 -07:00
Anshil Gandhi
ed2f90902c
[NFC][Attributor] Track the number of promoted indirect calls (#106214) 2024-08-27 13:28:33 -04:00
Kazu Hirata
820396c3a8
[Transforms] Construct SmallVector with iterator ranges (NFC) (#105607) 2024-08-21 23:32:13 -07:00
Johannes Doerfert
8266d47cd1
[Attributor] Improve AAUnderlyingObjects (#104835)
- Allocas and GlobalValues cannot be simplified, so we should not try.
- If we never used any assumed state, the AAUnderlyingObjects doesn't
require an additional update.
- If we have seen an object (or it's underlying object) before, we do
not need to inspect it anymore.

The original logic for "SeenObjects" was flawed and caused us to add
intermediate values to the underlying object list if a PHI or select
instruction referenced the same underlying object twice. The test
changes are all instances of this situation and we now correctly derive
`memory(none)` for the functions that only access stack memory.

---------

Co-authored-by: Shilei Tian <i@tianshilei.me>
2024-08-20 12:05:20 -07:00
Johannes Doerfert
7156bcf286
[Attributor][FIX] Ensure we do not use stale references (#104495)
When copying map entries, we might run into resizing and invalidate the
RHS of the assignment. We dealt with this before and now use the proper
helper to avoid the problem in another place.

Fixes: https://github.com/llvm/llvm-project/issues/104397
2024-08-15 18:45:36 -04:00
Shilei Tian
1ca9fe6db3 Reapply "[Attributor][AMDGPU] Enable AAIndirectCallInfo for AMDAttributor (#100952)"
This reverts commit 36467bfe89f231458eafda3edb916c028f1f0619.
2024-08-14 17:16:47 -04:00
Yingwei Zheng
f364b2ee22
[LLVM] Don't peek through bitcast on pointers and gep with zero indices. NFC. (#102889)
Since we are using opaque pointers now, we don't need to peek through
bitcast on pointers and gep with zero indices.
2024-08-13 22:38:50 +08:00
Shilei Tian
36467bfe89 Revert "Reapply "[Attributor][AMDGPU] Enable AAIndirectCallInfo for AMDAttributor (#100952)""
This reverts commit 7a68449a82ab1c1ab005caa72c1d986ca5deca36.

https://lab.llvm.org/buildbot/#/builders/123/builds/3205
2024-08-07 09:22:48 -04:00
Shilei Tian
7a68449a82 Reapply "[Attributor][AMDGPU] Enable AAIndirectCallInfo for AMDAttributor (#100952)"
This reverts commit 874cd100a076f3b98aaae09f90ef224682501538.
2024-08-06 22:46:32 -04:00
Shilei Tian
53d33d3ba5
[Attributor] Fix an issue that an access is skipped by mistake (#101862)
When we check if an access can be skipped, there is a case that an
inter-procedural interference access exists after a dominant write.
Currently we
rely on `AAInterFnReachability` to tell if the access can be reachable.
If it is
not, we can safely skip the access. However, it is based on an
assumption that
the AA exists. It is possible that the AA doesn't exist. In this case,
we can't
safely assume the acess can be skipped because we have to assume the
access can
reach. This can happen when `AAInterFnReachability` is not in the
allowed AA
list when creating the attributor, such as AMDGPUAttributor.

Co-authored-by: Mark de Wever <koraq@xs4all.nl>
2024-08-06 21:29:39 -04:00
Shilei Tian
4b6e3e38c4
[Attributor] Improve debug string of AAUnderlyingObjects (#101861) 2024-08-06 12:31:35 -07:00
Shilei Tian
874cd100a0 Revert "[Attributor][AMDGPU] Enable AAIndirectCallInfo for AMDAttributor (#100952)"
This reverts commit ab819d7cf86932e4a47b5bf6aadea9d714a313a9.
2024-08-02 18:31:21 -04:00
Shilei Tian
ab819d7cf8
[Attributor][AMDGPU] Enable AAIndirectCallInfo for AMDAttributor (#100952) 2024-08-02 17:23:18 -04:00
Shilei Tian
e7f73c03df [Attributor] Use getPointerAddressSpace to replace a cast followed by a getAddressSpace 2024-08-01 22:57:43 -04:00
Shilei Tian
9373a43218
[Attributor] Indicate optimistic fixed point if an instruction already has non-zero address space (#101589) 2024-08-01 22:55:09 -04:00
Vidush Singhal
c7633ddb28
[Attributor]: Ensure cycle info is not null when handling PHI in AAPointerInfo (#97321)
Ensure cycle info object is not null for simple PHI case

for the test:
`llvm/test/Transforms/Attributor/phi_bug_pointer_info.ll`

Debug info Before the change: 

```
Accesses by bin after update:
[8-12] : 1
     - 9 -   store i32 %0, ptr %field2, align 4
       - c:   %0 = load i32, ptr %val, align 4
[32-36] : 1
     - 9 -   store i32 %1, ptr %field8, align 4
       - c:   %1 = load i32, ptr %val2, align 4
[2147483647-4294967294] : 1
     - 6 -   %ret = load i32, ptr %x, align 4
       - c: <unknown>
```

Debug info After the change: 

```
Accesses by bin after update:
[8-12] : 2
     - 9 -   store i32 %0, ptr %field2, align 4
       - c:   %0 = load i32, ptr %val, align 4
     - 6 -   %ret = load i32, ptr %x, align 4
       - c: <unknown>
[32-36] : 2
     - 9 -   store i32 %1, ptr %field8, align 4
       - c:   %1 = load i32, ptr %val2, align 4
     - 6 -   %ret = load i32, ptr %x, align 4
       - c: <unknown>
```

Co-authored-by: Vidush Singhal <singhal2@ruby964.llnl.gov>
2024-07-01 17:20:34 -07:00
Youngsuk Kim
2051736f7b [llvm][Transforms] Avoid 'raw_string_ostream::str' (NFC)
Since `raw_string_ostream` doesn't own the string buffer, it is
desirable (in terms of memory safety) for users to directly reference
the string buffer rather than use `raw_string_ostream::str()`.

Work towards TODO comment to remove `raw_string_ostream::str()`.
2024-06-30 09:03:29 -05:00
Nikita Popov
9df71d7673
[IR] Add getDataLayout() helpers to Function and GlobalValue (#96919)
Similar to https://github.com/llvm/llvm-project/pull/96902, this adds
`getDataLayout()` helpers to Function and GlobalValue, replacing the
current `getParent()->getDataLayout()` pattern.
2024-06-28 08:36:49 +02:00
Nikita Popov
2d209d964a
[IR] Add getDataLayout() helpers to BasicBlock and Instruction (#96902)
This is a helper to avoid writing `getModule()->getDataLayout()`. I
regularly try to use this method only to remember it doesn't exist...

`getModule()->getDataLayout()` is also a common (the most common?)
reason why code has to include the Module.h header.
2024-06-27 16:38:15 +02:00
Stephen Tozer
d75f9dd1d2 Revert "[IR][NFC] Update IRBuilder to use InsertPosition (#96497)"
Reverts the above commit, as it updates a common header function and
did not update all callsites:

  https://lab.llvm.org/buildbot/#/builders/29/builds/382

This reverts commit 6481dc57612671ebe77fe9c34214fba94e1b3b27.
2024-06-24 18:00:22 +01:00
Stephen Tozer
6481dc5761
[IR][NFC] Update IRBuilder to use InsertPosition (#96497)
Uses the new InsertPosition class (added in #94226) to simplify some of
the IRBuilder interface, and removes the need to pass a BasicBlock
alongside a BasicBlock::iterator, using the fact that we can now get the
parent basic block from the iterator even if it points to the sentinel.
This patch removes the BasicBlock argument from each constructor or call
to setInsertPoint.

This has no functional effect, but later on as we look to remove the
`Instruction *InsertBefore` argument from instruction-creation
(discussed
[here](https://discourse.llvm.org/t/psa-instruction-constructors-changing-to-iterator-only-insertion/77845)),
this will simplify the process by allowing us to deprecate the
InsertPosition constructor directly and catch all the cases where we use
instructions rather than iterators.
2024-06-24 17:27:43 +01:00
Fangrui Song
89e8e63f47 [Attributor] Stabilize llvm.assume output
Don't rely on the iteration order of DenseSet<StringRef>, which is not
guaranteed to be deterministic.
2024-06-19 15:36:46 -07:00
Vidush Singhal
bea329ecb0
[Attributor]: allow more than one offset for a pass through user in AAPointerInfo (#94416)
Co-authored-by: Vidush Singhal <singhal2@ruby964.llnl.gov>
2024-06-17 16:31:39 -07:00
Kazu Hirata
7c6d0d26b1
[llvm] Use llvm::unique (NFC) (#95628) 2024-06-14 22:49:36 -07:00