Skip to content

Commit d49cb3e

Browse files
chandlercjonmeowzygoloid
authored
Start building Clang runtimes on-demand (#5338)
This is the first step to having Clang's runtime libraries fully available for the Carbon toolchain. This PR focuses on the lowest level runtimes, the CRT files and the builtins library. The goal is to intercept Clang runs where it needs these target-dependent pieces to be available, and build them on demand using our Clang-running infrastructure. This avoids most of the subprocess overhead, but there is still some due to missing features in Clang. This requires exporting the sources for these runtimes from the Bazel build, and installing them in our target-independent resource directory. We then build a simplified "build" of these sources within the `ClangRunner` itself to produce the specific artifacts and layout expected by Clang. It also required fixing our use of Clang on macOS to have a default system root in order to successfully compile or link. It also required cleaning up how the `ClangRunner` used target information more generally -- instead of taking the target as a constructor parameter, it manages its target internally and relies on the Clang target-specifying command line flags. I looked at whether we could split this into another layer separate from the `ClangRunner`, but that proved frustratingly difficult to manage. While we support building these on-demand as part of a detected link, that doesn't seem feasible as we don't have the necessary separation between compilation runs of Clang and link runs of Clang. However, I have tried to factor the internals to provide as clear of separation as I could across these. I have also created a stand-alone subcommand to directly build the runtimes which allows for easy testing. It also supports building them into a specific directory, and that directory can in turn be passed to a Clang invocation. This is designed to work both at the API level with `ClangRunner` and at the subcommand level. Currently, the only part of the commandline that is detected and forwarded to the runtimes build is the target. Eventually, the plan is to expand this so that we can build a maximally tailored set of runtimes for a given compilation. The other big TODO here is to actually implement caching storage of these runtimes so they aren't built on every execution. Right now, this uses a somewhat hack-y build of a temporary directory, but this isn't expected to be suitable long-term. Building these runtimes on *every* link makes those commands take approximately 15 seconds with an ASan build like our default development build, and just over 2 seconds in an optimized build. Because of this, I've kept all of this disabled by default for now. The goal is that once caching and some other improvements land, we can enable this by default. --------- Co-authored-by: Jon Ross-Perkins <[email protected]> Co-authored-by: Richard Smith <[email protected]>
1 parent 816d458 commit d49cb3e

24 files changed

+1316
-123
lines changed

.codespell_ignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Exceptions. See /LICENSE for license information.
33
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44

5+
ArchType
56
atleast
67
circularly
78
compiletime
@@ -14,6 +15,7 @@ forin
1415
groupt
1516
indext
1617
inout
18+
isELF
1719
parameteras
1820
pullrequest
1921
rightt

MODULE.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ http_archive(
116116
"@carbon//bazel/llvm_project:0001_Patch_for_mallinfo2_when_using_Bazel_build_system.patch",
117117
"@carbon//bazel/llvm_project:0002_Added_Bazel_build_for_compiler_rt_fuzzer.patch",
118118
"@carbon//bazel/llvm_project:0003_Comment_out_unloaded_proto_library_dependencies.patch",
119+
"@carbon//bazel/llvm_project:0004_Introduce_filegroups_for_compiler_rt_builtins_runtime.patch",
119120
],
120121
strip_prefix = "llvm-project-{0}".format(llvm_project_version),
121122
urls = ["https://github.com/llvm/llvm-project/archive/{0}.tar.gz".format(llvm_project_version)],
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
From 19d5d9913778ca95da272f41c5916907154a5e73 Mon Sep 17 00:00:00 2001
2+
From: Chandler Carruth <[email protected]>
3+
Date: Thu, 24 Apr 2025 05:03:43 +0000
4+
Subject: [PATCH] Introduce filegroups for compiler-rt builtins runtimes
5+
6+
These filegroups allow downstream projects to package and build
7+
customized runtime libraries.
8+
9+
The filegroups work hard to use globs and a careful structuring to
10+
create the structured breakdown of sources needed to target different
11+
architectures and platforms without having to maintain a complete
12+
parallel list of sources from CMake.
13+
---
14+
.../compiler-rt/BUILD.bazel | 167 ++++++++++++++++++
15+
1 file changed, 167 insertions(+)
16+
17+
diff --git a/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel b/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
18+
index 6a5a89fdee40..7d158f0c13f2 100644
19+
--- a/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
20+
+++ b/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
21+
@@ -128,3 +128,170 @@ cc_library(
22+
],
23+
includes = ["lib/fuzzer"],
24+
)
25+
+
26+
+BUILTINS_CRTBEGIN_SRCS = ["lib/builtins/crtbegin.c"]
27+
+
28+
+filegroup(
29+
+ name = "builtins_crtbegin_src",
30+
+ srcs = BUILTINS_CRTBEGIN_SRCS,
31+
+)
32+
+
33+
+BUILTINS_CRTEND_SRCS = ["lib/builtins/crtend.c"]
34+
+
35+
+filegroup(
36+
+ name = "builtins_crtend_src",
37+
+ srcs = BUILTINS_CRTEND_SRCS,
38+
+)
39+
+
40+
+# Note that while LLVM's CompilerRT provides a few hosted sources, we don't
41+
+# currently build them:
42+
+#
43+
+# - `emutls.c`: Unclear we need to support targets with software emulated
44+
+# TLS rather than hardware support.
45+
+# - `enable_execute_stack.c`: Used to implement support for a builtin that
46+
+# marks part of the stack as *executable* to support the GCC extension of
47+
+# nested functions. This extension was never implemented in Clang, and is
48+
+# generally considered a security issue to include. We expect to be able
49+
+# to avoid even linking the support code for this into binaries at this
50+
+# point.
51+
+# - `eprintf.c`: This provided a legacy `__eprintf` builtin used by old
52+
+# versions of `assert.h` in its macros, but does not appear to be needed
53+
+# when building with modern versions of this header.
54+
+BUILTINS_HOSTED_SRCS = [
55+
+ "lib/builtins/emutls.c",
56+
+ "lib/builtins/enable_execute_stack.c",
57+
+ "lib/builtins/eprintf.c",
58+
+]
59+
+
60+
+filegroup(
61+
+ name = "builtins_hosted_srcs",
62+
+ srcs = BUILTINS_HOSTED_SRCS,
63+
+)
64+
+
65+
+BUILTINS_BF16_SRCS_PATTERNS = [
66+
+ # `bf` marks 16-bit Brain floating-point number builtins.
67+
+ "lib/builtins/*bf*.c",
68+
+]
69+
+
70+
+filegroup(
71+
+ name = "builtins_bf16_srcs",
72+
+ srcs = glob(BUILTINS_BF16_SRCS_PATTERNS),
73+
+)
74+
+
75+
+BUILTINS_X86_FP80_SRCS_PATTERNS = [
76+
+ # `xc` marks 80-bit complex number builtins.
77+
+ "lib/builtins/*xc*.c",
78+
+
79+
+ # `xf` marks 80-bit floating-point builtins.
80+
+ "lib/builtins/*xf*.c",
81+
+]
82+
+
83+
+filegroup(
84+
+ name = "builtins_x86_fp80_srcs",
85+
+ srcs = glob(
86+
+ BUILTINS_X86_FP80_SRCS_PATTERNS,
87+
+ exclude = BUILTINS_BF16_SRCS_PATTERNS,
88+
+ ),
89+
+)
90+
+
91+
+BUILTINS_TF_SRCS_PATTERNS = [
92+
+ # `tc` marks 128-bit complex number builtins.
93+
+ "lib/builtins/*tc*.c",
94+
+
95+
+ # `tf` marks 128-bit floating-point builtins.
96+
+ "lib/builtins/*tf*.c",
97+
+]
98+
+
99+
+BUILTINS_TF_EXCLUDES = (
100+
+ BUILTINS_HOSTED_SRCS +
101+
+ BUILTINS_BF16_SRCS_PATTERNS +
102+
+ BUILTINS_X86_FP80_SRCS_PATTERNS
103+
+)
104+
+
105+
+filegroup(
106+
+ name = "builtins_tf_srcs",
107+
+ srcs = glob(
108+
+ BUILTINS_TF_SRCS_PATTERNS,
109+
+ exclude = BUILTINS_TF_EXCLUDES,
110+
+ ),
111+
+)
112+
+
113+
+BUILTINS_MACOS_ATOMIC_SRCS_PATTERNS = [
114+
+ "lib/builtins/atomic_*.c",
115+
+]
116+
+
117+
+filegroup(
118+
+ name = "builtins_macos_atomic_srcs",
119+
+ srcs = glob(BUILTINS_MACOS_ATOMIC_SRCS_PATTERNS),
120+
+)
121+
+
122+
+filegroup(
123+
+ name = "builtins_aarch64_srcs",
124+
+ srcs = [
125+
+ "lib/builtins/cpu_model/aarch64.c",
126+
+ "lib/builtins/cpu_model/aarch64.h",
127+
+ ] + glob(
128+
+ [
129+
+ "lib/builtins/cpu_model/AArch64*.inc",
130+
+ "lib/builtins/cpu_model/aarch64/**/*.inc",
131+
+ "lib/builtins/aarch64/*.S",
132+
+ "lib/builtins/aarch64/*.c",
133+
+ ],
134+
+ exclude = [
135+
+ # This file isn't intended to directly compile, but to be used to
136+
+ # generate a collection of outline atomic helpers.
137+
+ # TODO: Add support for generating the sources for these helpers if
138+
+ # there are users that need this functionality from the builtins
139+
+ # library.
140+
+ "lib/builtins/aarch64/lse.S",
141+
+ ],
142+
+ ),
143+
+)
144+
+
145+
+filegroup(
146+
+ name = "builtins_x86_arch_srcs",
147+
+ srcs = [
148+
+ "lib/builtins/cpu_model/x86.c",
149+
+ "lib/builtins/i386/fp_mode.c",
150+
+ ],
151+
+)
152+
+
153+
+filegroup(
154+
+ name = "builtins_x86_64_srcs",
155+
+ srcs = glob([
156+
+ "lib/builtins/x86_64/*.c",
157+
+ "lib/builtins/x86_64/*.S",
158+
+ ]),
159+
+)
160+
+
161+
+filegroup(
162+
+ name = "builtins_i386_srcs",
163+
+ srcs = glob(
164+
+ [
165+
+ "lib/builtins/i386/*.c",
166+
+ "lib/builtins/i386/*.S",
167+
+ ],
168+
+ exclude = [
169+
+ # This file is used for both i386 and x86_64.
170+
+ "lib/builtins/i386/fp_mode.c",
171+
+ ],
172+
+ ),
173+
+)
174+
+
175+
+filegroup(
176+
+ name = "builtins_generic_srcs",
177+
+ srcs = ["lib/builtins/cpu_model/cpu_model.h"] + glob(
178+
+ [
179+
+ "lib/builtins/*.c",
180+
+ "lib/builtins/*.h",
181+
+ "lib/builtins/*.inc",
182+
+ ],
183+
+ exclude = (
184+
+ BUILTINS_CRTBEGIN_SRCS +
185+
+ BUILTINS_CRTEND_SRCS +
186+
+ BUILTINS_TF_EXCLUDES +
187+
+ BUILTINS_TF_SRCS_PATTERNS +
188+
+ BUILTINS_MACOS_ATOMIC_SRCS_PATTERNS
189+
+ ),
190+
+ ),
191+
+)
192+
--
193+
2.49.0.850.g28803427d3-goog
194+

scripts/fix_cc_deps.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ class RuleChoice(NamedTuple):
7070
IGNORE_SOURCE_FILE_REGEX = re.compile(
7171
r"^(third_party/clangd.*|common/version.*\.cpp"
7272
r"|.*_autogen_manifest\.cpp"
73-
r"|toolchain/base/llvm_tools.def)$"
73+
r"|toolchain/base/llvm_tools.def"
74+
r"|toolchain/base/runtime_sources.h)$"
7475
)
7576

7677

toolchain/base/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
load("//bazel/cc_rules:defs.bzl", "cc_library", "cc_test")
66
load("llvm_tools.bzl", "LLVM_MAIN_TOOLS", "generate_llvm_tools_def")
7+
load("runtime_sources.bzl", "generate_runtime_sources_cc_library")
78

89
package(default_visibility = ["//visibility:public"])
910

@@ -248,6 +249,8 @@ cc_library(
248249
] + [info.lib for info in LLVM_MAIN_TOOLS.values()],
249250
)
250251

252+
generate_runtime_sources_cc_library(name = "runtime_sources")
253+
251254
cc_library(
252255
name = "shared_value_stores",
253256
hdrs = ["shared_value_stores.h"],

0 commit comments

Comments
 (0)