31 Commits

Author SHA1 Message Date
Joseph Huber
9da4d74a88
[Clang] Always pass detected CUDA path to 'clang-nvlink-wrapper' (#152789)
Summary:
We always want to use the detected path. The clang driver's detection is
far more sophisticated so we should use that whenever possible. Also
update the usage so we properly fall back to path instead of incorrectly
using the `/bin` if not provided.
2025-08-11 07:22:11 -05:00
Miguel Cárdenas
e80acd4fae
[clang][nvlink-wrapper] Add support for opt-remarks command line options (#145365)
## Problem
When using `-fsave-optimization-record` with offloading, the Clang
driver passes optimization record options like
`-plugin-opt=opt-remarks-format=yaml` to `clang-nvlink-wrapper`.
However, the wrapper doesn't recognize these options, causing
compilation to fail.


## Solution
This patch adds support for the standard optimization record command
line options to `clang-nvlink-wrapper`, matching the interface provided
by LLD and gold-plugin as documented in the [LLVM Remarks
documentation](https://llvm.org/docs/Remarks.html).

## Changes
- **NVLinkOpts.td**: Added definitions for `opt-remarks-filename`,
`opt-remarks-format`, `opt-remarks-filter`, and
`opt-remarks-with-hotness` options
- **NVLinkOpts.td**: Added `plugin-opt=` aliases for these options to
match what the Clang driver sends
- **ClangNVLinkWrapper.cpp**: Updated `createLTO()` to use command line
arguments when available, falling back to existing global variables

## Testing
The fix allows `-fsave-optimization-record` to work correctly with
offloading, generating optimization records during the LTO phase without
throwing unknown argument errors.

This change maintains backward compatibility and follows the existing
pattern used by other LLVM linkers.
2025-06-23 13:15:04 -05:00
Chandler Carruth
dd647e3e60
Rework the Option library to reduce dynamic relocations (#119198)
Apologies for the large change, I looked for ways to break this up and
all of the ones I saw added real complexity. This change focuses on the
option's prefixed names and the array of prefixes. These are present in
every option and the dominant source of dynamic relocations for PIE or
PIC users of LLVM and Clang tooling. In some cases, 100s or 1000s of
them for the Clang driver which has a huge number of options.

This PR addresses this by building a string table and a prefixes table
that can be referenced with indices rather than pointers that require
dynamic relocations. This removes almost 7k dynmaic relocations from the
`clang` binary, roughly 8% of the remaining dynmaic relocations outside
of vtables. For busy-boxing use cases where many different option tables
are linked into the same binary, the savings add up a bit more.

The string table is a straightforward mechanism, but the prefixes
required some subtlety. They are encoded in a Pascal-string fashion with
a size followed by a sequence of offsets. This works relatively well for
the small realistic prefixes arrays in use.

Lots of code has to change in order to land this though: both all the
option library code has to be updated to use the string table and
prefixes table, and all the users of the options library have to be
updated to correctly instantiate the objects.

Some follow-up patches in the works to provide an abstraction for this
style of code, and to start using the same technique for some of the
other strings here now that the infrastructure is in place.
2024-12-11 15:44:44 -08:00
Joseph Huber
a78861fc55
[NvlinkWrapper] Add support for --undefined (#113934)
Summary:
This flag is pretty canonical in ELF linkers, it allows us to force the
link job to extract a library if it defines a specific symbol. This is
mostly useful for letting us forcibly extract things that don't fit the
normal model (i.e. kernels) from static libraries.
2024-10-29 15:34:28 -05:00
Joseph Huber
416731bf7f
[NvlinkWrapper] Use -plugin-opt=mattr= instead of a custom feature (#111712)
Summary:
We don't need a custom flag for this, LLVM had a way to get the features
which are forwarded via `plugin-opt`.
2024-10-18 17:32:23 -05:00
Joseph Huber
787a6d57f9 [nvlink-wrapper] Remove use of symlinks
Summary:
This was intended to be a neat optimization, but some objects come from
archives so this won't work. I could write some code to detect if it
came from an archive but I don't think it's wroth the complexity when
this already doesn't work on Windows.
2024-09-27 12:05:56 -05:00
Joseph Huber
44950de5b1
[nvlink-wrapper] Use a symbolic link instead of copying the file (#110139)
Summary:
We need all inputs to `nvlink` to end in `.cubin` while the rest of the
compiler toolchain wants `.o`. Previously we copied `.o` file to
`.cubin` files, but this is wasteful. Instead, we can just create a link
against it. This saves some disk space during link time.
2024-09-26 18:48:01 -07:00
Joseph Huber
68e2b695ea [NvlinkWrapper] Fix -pluing not consuming its argument
Summary:
Sometimes `clang` will pass `-plugin` when doing LTO, which should be
correctly consumed by the nvlink wrapper. Right now it was leaving the
`plugin.so` argument as a regular input, which would cause it to error
on the `.so` input.
2024-09-22 08:04:20 -05:00
Joseph Huber
394162f356
[Clang] Fix 'nvlink-wrapper' not ignoring -plugin like lld does (#104056)
Summary:
This caused issues with
https://gitlab.e4s.io/uo-public/llvm-openmp-offloading/-/jobs/301520
because adding `-flto` caused it to pass `-plugin` sometimes, which
isn't supported.
2024-08-14 13:39:13 -05:00
Joel E. Denny
3c639b83a6
[Clang] Simplify specifying passes via -Xoffload-linker (#102483)
Make it possible to do things like the following, regardless of whether
the offload target is nvptx or amdgpu:

```
$ clang -O1 -g -fopenmp --offload-arch=native test.c                       \
    -Xoffload-linker -mllvm=-pass-remarks=inline                           \
    -Xoffload-linker -mllvm=-force-remove-attribute=g.internalized:noinline\
    -Xoffload-linker --lto-newpm-passes='forceattrs,default<O1>'           \
    -Xoffload-linker --lto-debug-pass-manager                              \
    -foffload-lto
```

To accomplish that:

- In clang-linker-wrapper, do not forward options via `-Wl` if they
might have literal commas. Use `-Xlinker` instead.
- In clang-nvlink-wrapper, accept `--lto-debug-pass-manager` and
`--lto-newpm-passes`.
- In clang-nvlink-wrapper, drop `-passes` because it's inconsistent with
the interface of `lld`, which is used instead of clang-nvlink-wrapper
when the target is amdgpu. Without this patch, `-passes` is passed to
`nvlink`, producing an error anyway.

---------

Co-authored-by: Joseph Huber <huberjn@outlook.com>
2024-08-09 10:41:42 -04:00
Joseph Huber
2bf58f5d27
[Clang] Suppress missing architecture error when doing LTO (#100652)
Summary:
The `nvlink-wrapper` can do LTO now, which means we can still create
some LLVM-IR without needing an architecture. In the case that we try to
invoke `nvlink` internally, that will still fail. This patch simply
defers the error until later so we can use `--lto-emit-llvm` to get the
IR without specifying an architecture.
2024-07-31 14:41:55 -05:00
Joseph Huber
e603df083b [NvlinkWrapper] Add relocatable link support to LTO pass
Summary:
We need `-r` to work so we can preserve symbols.
2024-07-26 09:51:25 -05:00
Joseph Huber
adbe247701 Reapply "[Clang] Correctly forward --cuda-path to the nvlink wrapper (#100170)"
This reverts commit 7d388aeabb34cd954aa57e4321ad3aa9f382c557.
2024-07-23 14:52:30 -05:00
Joseph Huber
7d388aeabb Revert "[Clang] Correctly forward --cuda-path to the nvlink wrapper (#100170)"
This reverts commit 7e1fcf5dd657d465c3fc846f56c6f9d3a4560b43.
2024-07-23 14:51:40 -05:00
Joseph Huber
7e1fcf5dd6
[Clang] Correctly forward --cuda-path to the nvlink wrapper (#100170)
Summary:
This was not forwarded properly as it would try to pass it to `nvlink`.

Fixes https://github.com/llvm/llvm-project/issues/100168
2024-07-23 14:41:57 -05:00
Joseph Huber
d6905ea9b0 [Clang] Fix r-value binding that Windows doesn't like 2024-07-22 22:24:57 -05:00
Joseph Huber
f540160e9c [libc] Remove leftover debugging in clang-nvlink-wrapper
Summary:
This was accidentally left in.
2024-07-22 20:14:32 -05:00
Joseph Huber
624d3221d1 [Clang] Fix 'clang-nvlink-wrapper' not working w/o CUDA
Summary:
This would try to find `nvlink` and then fail even in `dry-run` mode.
We now just let it continue and pretend like we found it. Also add it to
the depends.
2024-07-22 18:57:54 -05:00
Joseph Huber
e391ba07fa [Clang] Fix incorrect value assignment in nvlink wrapper
Summary:
Gah, forgot to push this before I merged.
2024-07-22 18:23:02 -05:00
Joseph Huber
37d0568a65
[Clang] Introduce 'clang-nvlink-wrapper' to work around 'nvlink' (#96561)
Summary:
The `clang-nvlink-wrapper` is a utility that I removed awhile back
during the transition to the new driver. This patch adds back in a new,
upgraded version that does LTO + archive linking. It's not an easy
choice to reintroduce something I happily deleted, but this is the only
way to move forward with improving GPU support in LLVM.

While NVIDIA provides a linker called 'nvlink', its main interface is
very difficult to work with. It does not provide LTO, or static linking,
requires all files to be named a non-standard `.cubin`, and rejects link
jobs that other linkers would be fine with (i.e empty). I have spent a
great deal of time hacking around this in the GPU `libc` implementation,
where I deliberately avoid LTO and static linking and have about 100
lines of hacky CMake dedicated to storing these files in a format that
the clang-linker-wrapper accepts to avoid this limitation.

The main reason I want to re-intorudce this tool is because I am
planning on creating a more standard C/C++ toolchain for GPUs to use.
This will install files like the following.
```
<install>/lib/nvptx64-nvidia-cuda/libc.a
<install>/lib/nvptx64-nvidia-cuda/libc++.a
<install>/lib/nvptx64-nvidia-cuda/libomp.a
<install>/lib/clang/19/lib/nvptx64-nvidia-cuda/libclang_rt.builtins.a
```
Linking in these libraries will then simply require passing `-lc` like
is already done for non-GPU toolchains. However, this doesn't work with
the currently deficient `nvlink` linker, so I consider this a blocking
issue to massively improving the state of building GPU libraries.

In the future we may be able to convince NVIDIA to port their linker to
`ld.lld`, but for now this is the only workable solution that allows us
to hack around the weird behavior of their closed-source software.
This also copies some amount of logic from the clang-linker-wrapper,
but not enough for it to be worthwhile to merge them I feel. In the
future it may be possible to delete that handling from there entirely.
2024-07-22 18:20:14 -05:00
Joseph Huber
47166968db [OpenMP] Deprecate the old driver for OpenMP offloading
Recently OpenMP has transitioned to using the "new" driver which
primarily merges the device and host linking phases into a single
wrapper that handles both at the same time. This replaced a few tools
that were only used for OpenMP offloading, such as the
`clang-offload-wrapper` and `clang-nvlink-wrapper`. The new driver
carries some marked benefits compared to the old driver that is now
being deprecated. Things like device-side LTO, static library
support, and more compatible tooling. As such, we should be able to
completely deprecate the old driver, at least for OpenMP. The old driver
support will still exist for CUDA and HIP, although both of these can
currently be compiled on Linux with `--offload-new-driver` to use the new
method.

Note that this does not deprecate the `clang-offload-bundler`, although
it is unused by OpenMP now, it is still used by the HIP toolchain both
as their device binary format and object format.

When I proposed deprecating this code I heard some vendors voice
concernes about needing to update their code in their fork. They should
be able to just revert this commit if it lands.

Reviewed By: jdoerfert, MaskRay, ye-luo

Differential Revision: https://reviews.llvm.org/D130020
2022-08-26 13:47:09 -05:00
John Ericson
10d0d8c0c1 [clang][cmake] Use GNUInstallDirs to support custom installation dirs
I am breaking apart D99484 so the cause of build failures is easier to
understand.

Differential Revision: https://reviews.llvm.org/D117419
2022-01-21 23:58:08 +00:00
Joseph Huber
af5600420b [OpenMP] Don't pass empty files to nvlink
This patch adds and exception to the nvlink wrapper tool to not pass
empty cubin files to the nvlink job. If an empty file is passed to
nvlink it will cause an error indicating that the file could not be
opened. This would occur if the user tried to link object files that
contained offloading code with a file that didnt. This will act as a
workaround until the new OpenMP offloading driver becomes the default.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D117777
2022-01-20 13:12:02 -05:00
John Ericson
da77db58d7 Revert "[cmake] Use GNUInstallDirs to support custom installation dirs."
https://lab.llvm.org/buildbot/#/builders/46/builds/21146 Still have
this odd error, not sure how to reproduce, so I will just try breaking
up my patch.

This reverts commit 4a678f8072004eff9214c1a4e1836a14abb69535.
2022-01-16 05:48:30 +00:00
John Ericson
4a678f8072 [cmake] Use GNUInstallDirs to support custom installation dirs.
This is the original patch in my GNUInstallDirs series, now last to merge as the final piece!

It arose as a new draft of D28234. I initially did the unorthodox thing of pushing to that when I wasn't the original author, but since I ended up

 - Using `GNUInstallDirs`, rather than mimicking it, as the original author was hesitant to do but others requested.

 - Converting all the packages, not just LLVM, effecting many more projects than LLVM itself.

I figured it was time to make a new revision.

I have used this patch series (and many back-ports) as the basis of https://github.com/NixOS/nixpkgs/pull/111487 for my distro (NixOS), which was merged last spring (2021). It looked like people were generally on board in D28234, but I make note of this here in case extra motivation is useful.

---

As pointed out in the original issue, a central tension is that LLVM already has some partial support for these sorts of things. Variables like `COMPILER_RT_INSTALL_PATH` have already been dealt with. Variables like `LLVM_LIBDIR_SUFFIX` however, will require further work, so that we may use `CMAKE_INSTALL_LIBDIR`.

These remaining items will be addressed in further patches. What is here is now rote and so we should get it out of the way before dealing more intricately with the remainder.

Reviewed By: #libunwind, #libc, #libc_abi, compnerd

Differential Revision: https://reviews.llvm.org/D99484
2022-01-16 05:33:07 +00:00
John Ericson
6e52bfe09d Revert "[cmake] Use GNUInstallDirs to support custom installation dirs."
Sorry for the disruption, I will try again later.

This reverts commit efeb50197091b2ade24c00b9d55814bc433a7fd1.
2022-01-15 07:35:02 +00:00
John Ericson
efeb501970 [cmake] Use GNUInstallDirs to support custom installation dirs.
This is the original patch in my GNUInstallDirs series, now last to merge as the final piece!

It arose as a new draft of D28234. I initially did the unorthodox thing of pushing to that when I wasn't the original author, but since I ended up

 - Using `GNUInstallDirs`, rather than mimicking it, as the original author was hesitant to do but others requested.

 - Converting all the packages, not just LLVM, effecting many more projects than LLVM itself.

I figured it was time to make a new revision.

I have used this patch series (and many back-ports) as the basis of https://github.com/NixOS/nixpkgs/pull/111487 for my distro (NixOS), which was merged last spring (2021). It looked like people were generally on board in D28234, but I make note of this here in case extra motivation is useful.

---

As pointed out in the original issue, a central tension is that LLVM already has some partial support for these sorts of things. Variables like `COMPILER_RT_INSTALL_PATH` have already been dealt with. Variables like `LLVM_LIBDIR_SUFFIX` however, will require further work, so that we may use `CMAKE_INSTALL_LIBDIR`.

These remaining items will be addressed in further patches. What is here is now rote and so we should get it out of the way before dealing more intricately with the remainder.

Reviewed By: #libunwind, #libc, #libc_abi, compnerd

Differential Revision: https://reviews.llvm.org/D99484
2022-01-15 01:08:35 +00:00
Kazu Hirata
31cfb3f4f6 [clang] Remove redundant calls to c_str() (NFC)
Identified with readability-redundant-string-cstr.
2021-12-26 13:31:40 -08:00
Saiyedul Islam
f56548829c [Clang][clang-nvlink-wrapper] Pass nvlink path to the wrapper
Added support of a "--nvlink-path" option in clang-nvlink-wrapper which
takes the path of nvlink binary.

Static Device Library support for OpenMP (D105191) now searches for
nvlink binary and passes its location via this option. In absence
of this option, nvlink binary is searched in locations in PATH.

Differential Revision: https://reviews.llvm.org/D111488
2021-10-12 16:15:52 +00:00
Saiyedul Islam
e15836361c [clang-nvlink-wrapper] Add documentation in clang docs
Add documentation of clang-nvlink-wrapper tool in clang.
Add it to the release notes of clang. Fix a small MSVC
warning.

Differential Revision: https://reviews.llvm.org/D109225
2021-09-06 11:43:58 +05:30
Saiyedul Islam
83f3782c61 [clang-nvlink-wrapper] Wrapper around nvlink for archive files
nvlink does not support linking of cubin files archived in an archive.
 This tool extracts all the cubin files in the given device specific archive
 and pass them to nvlink. It is required for linking static device libraries
 for nvptx.

 Reviewed By: ye-luo

 Differential Revision: https://reviews.llvm.org/D108291
2021-09-01 16:00:29 +05:30