Skip to content

Commit 359bf16

Browse files
committed
Unrolled build for #164929 in rollup 164931
Rollup merge of #164929 - JonathanBrouwer:revert-gcc, r=Kobzol Revert "rustc_codegen_gcc subtree update" Reverts #164869 because it broke main again See #164921 (comment) See discussion in [#t-infra > Tree ops @ 💬](https://rust-lang.zulipchat.com/#narrow/channel/242791-t-infra/topic/Tree.20ops/near/634790354)
2 parents 7d0f9b4 + ceeb0e0 commit 359bf16

19 files changed

Lines changed: 194 additions & 242 deletions

File tree

‎compiler/rustc_codegen_gcc/.github/workflows/ci.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ jobs:
116116
- name: Set env
117117
run: |
118118
echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV
119+
# /tmp is a small tmpfs, and rustdoc keeps every compiled doctest there until the run ends.
120+
echo "TMPDIR=$RUNNER_TEMP" >> $GITHUB_ENV
119121
120122
#- name: Cache rust repository
121123
## We only clone the rust repository for rustc tests

‎compiler/rustc_codegen_gcc/.github/workflows/rustup.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ jobs:
7777
- name: Set env
7878
run: |
7979
echo "workspace="$GITHUB_WORKSPACE >> $GITHUB_ENV
80+
# /tmp is a small tmpfs, and rustdoc keeps every compiled doctest there until the run ends.
81+
echo "TMPDIR=$RUNNER_TEMP" >> $GITHUB_ENV
8082
8183
- name: Prepare
8284
if: ${{ matrix.run_cargo_tests }}

‎compiler/rustc_codegen_gcc/Cargo.lock‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,18 @@ dependencies = [
5656

5757
[[package]]
5858
name = "gccjit"
59-
version = "7.3.0"
59+
version = "7.2.0"
6060
source = "registry+https://github.com/rust-lang/crates.io-index"
61-
checksum = "ea1820165dfb376a3bbfe8b69628d9e5a851c423e0480a666f71f560e2d0a924"
61+
checksum = "27cd340f3c265988de3379689cbbd103c25b1f8a3d0cc73f91a49083e899d3e1"
6262
dependencies = [
6363
"gccjit_sys",
6464
]
6565

6666
[[package]]
6767
name = "gccjit_sys"
68-
version = "4.3.0"
68+
version = "4.2.0"
6969
source = "registry+https://github.com/rust-lang/crates.io-index"
70-
checksum = "a6091291fc118448b91df5b662d20564020198fee46d8445a6aa0c25b6b435be"
70+
checksum = "da2d9d74572f004908f17ec1bd0af071e5db63a12c3335c9651a6125593951c6"
7171
dependencies = [
7272
"libc",
7373
]

‎compiler/rustc_codegen_gcc/Cargo.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ default = ["master"]
2020
[dependencies]
2121
object = { version = "0.39.0", default-features = false, features = ["std", "read"] }
2222
tempfile = "3.20"
23-
gccjit = { version = "7.3.0", features = ["dlopen"] }
23+
gccjit = { version = "7.2.0", features = ["dlopen"] }
2424
#gccjit = { git = "https://github.com/rust-lang/gccjit.rs", branch = "error-dlopen", features = ["dlopen"] }
2525

2626
# Local copy.

‎compiler/rustc_codegen_gcc/build_system/src/build.rs‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use std::path::{Path, PathBuf};
66

77
use crate::config::{Channel, ConfigInfo};
88
use crate::utils::{
9-
create_dir, get_sysroot_dir, run_command, run_command_with_output_and_env, rustc_version_info,
10-
walk_dir,
9+
create_dir, get_sysroot_dir, run_command, run_command_with_output_and_env, walk_dir,
1110
};
1211

1312
#[derive(Default)]
@@ -138,16 +137,17 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
138137
// Builds libs
139138
let mut rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default();
140139

141-
// Remap both source spans and embedded panic locations to the standard virtual path.
142-
let sysroot_source_dir = start_dir.join("sysroot_src");
143-
let rustc_commit = rustc_version_info(env.get("RUSTC").map(String::as_str))?
144-
.commit_hash
145-
.ok_or_else(|| "Couldn't retrieve rustc commit hash".to_string())?;
146-
// Cargo passes workspace-relative filenames, including those used by panic locations.
147-
// Also: the `==` is intentional! The first `=` is "FROM" and the second `=` is for "TO".
148-
rustflags.push_str(&format!(" --remap-path-prefix==/rustc/{rustc_commit}/library"));
140+
// Record the sysroot sources under the path the `rust-src` component uses, which is where
141+
// rustc looks for them to turn a sysroot span into `/rustc/$hash`. Without this, ui tests
142+
// print the build path where they expect `$SRC_DIR`.
143+
let sysroot_source_dir = lib_path.join("rustlib/src/rust/library");
149144
rustflags.push_str(&format!(
150-
" --remap-path-prefix={sysroot_source_dir}=/rustc/{rustc_commit}",
145+
" --remap-path-prefix={library_dir}={sysroot_source_dir}",
146+
library_dir = std::path::absolute(&library_dir)
147+
.map_err(|error| format!(
148+
"Failed to get the absolute path of the sysroot sources: {error:?}"
149+
))?
150+
.display(),
151151
sysroot_source_dir = std::path::absolute(&sysroot_source_dir)
152152
.map_err(|error| format!(
153153
"Failed to get the absolute path of the sysroot sources: {error:?}"
Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,54 @@
1-
# Subtree sync procedure
1+
# git subtree sync
22

3-
`rustc_codegen_gcc` is using [Josh] to perform subtree synces with the `rust-lang/rust` repository.
3+
`rustc_codegen_gcc` is a subtree of the rust compiler. As such, it needs to be
4+
synced from time to time to ensure changes that happened on their side are also
5+
included on our side.
46

5-
[Josh]: https://josh-project.dev/docs/intro.html
7+
### How to install a forked git-subtree
68

7-
The procedure for performing subtree synchronizations is documented [here][rdg-josh].
9+
Using git-subtree with `rustc` requires a patched git to make it work.
10+
The PR that is needed is [here](https://github.com/gitgitgadget/git/pull/493).
11+
Use the following instructions to install it:
812

9-
[rdg-josh]: https://rustc-dev-guide.rust-lang.org/external-repos.html#synchronizing-a-josh-subtree
13+
```bash
14+
git clone git@github.com:tqc/git.git
15+
cd git
16+
git checkout tqc/subtree
17+
make
18+
make install
19+
cd contrib/subtree
20+
make
21+
cp git-subtree ~/bin
22+
```
1023

11-
## Pushing changes to `rust-lang/rust`
24+
### Syncing with rust compiler
1225

13-
If the used GCC commit (recorded in `libgccjit.version`) changed in `rustc_codegen_gcc`, then you will have to update the `gcc` submodule in the `rust-lang/rust` repository in the push sync PR. The CI in `rust-lang/rust` should ensure that these two commit references match. You can simply update the `gcc` submodule commit and push it to your push sync PR once it has been created.
26+
Do a sync with this command:
27+
28+
```bash
29+
PATH="$HOME/bin:$PATH" ~/bin/git-subtree push -P compiler/rustc_codegen_gcc/ ../rustc_codegen_gcc/ sync_branch_name
30+
cd ../rustc_codegen_gcc
31+
git checkout master
32+
git pull
33+
git checkout sync_branch_name
34+
git merge master
35+
```
36+
37+
To send the changes to the rust repo:
38+
39+
```bash
40+
cd ../rust
41+
git pull origin master
42+
git checkout -b subtree-update_cg_gcc_YYYY-MM-DD
43+
PATH="$HOME/bin:$PATH" ~/bin/git-subtree pull --prefix=compiler/rustc_codegen_gcc/ https://github.com/rust-lang/rustc_codegen_gcc.git master
44+
# Don't forget to update the `gcc` submodule to the same version as the
45+
# one in `rustc_codegen_gcc/libgccjit.version`.
46+
git push
47+
48+
# Immediately merge the merge commit into cg_gcc to prevent merge conflicts when syncing from rust-lang/rust later.
49+
PATH="$HOME/bin:$PATH" ~/bin/git-subtree push -P compiler/rustc_codegen_gcc/ ../rustc_codegen_gcc/ sync_branch_name
50+
```
51+
52+
FIXME: write a script that does the above.
53+
54+
https://rust-lang.zulipchat.com/#narrow/stream/301329-t-devtools/topic/subtree.20madness/near/258877725
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
e1c6e07b095d091177376a163da44039475e05e3
1+
37ea7cd851f04ee6a313c5067c9fde9328f876aa
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "nightly-2026-10-24"
2+
channel = "nightly-2026-10-19"
33
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

‎compiler/rustc_codegen_gcc/src/attributes.rs‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::base;
2020
use crate::context::CodegenCx;
2121
#[cfg(feature = "master")]
2222
use crate::gcc_util::to_gcc_aarch64_extension;
23-
use crate::gcc_util::{to_gcc_features, to_gcc_target_attribute_feature};
23+
use crate::gcc_util::to_gcc_features;
2424

2525
/// Checks if the function `instance` is recursively inline.
2626
/// Returns `false` if a functions is guaranteed to be non-recursive, and `true` if it *might* be recursive.
@@ -192,7 +192,20 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
192192
}
193193
let target_features = function_features
194194
.iter()
195-
.filter_map(|feature| to_gcc_target_attribute_feature(feature))
195+
.filter_map(|feature| {
196+
// FIXME(antoyo): support soft-float.
197+
if feature.contains("soft-float") {
198+
return None;
199+
}
200+
201+
if feature.starts_with('-') {
202+
Some(format!("no{}", feature))
203+
} else if let Some(stripped) = feature.strip_prefix('+') {
204+
Some(stripped.to_string())
205+
} else {
206+
Some(feature.to_string())
207+
}
208+
})
196209
.collect::<Vec<_>>()
197210
.join(",");
198211
if !target_features.is_empty() {

‎compiler/rustc_codegen_gcc/src/common.rs‎

Lines changed: 67 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,12 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
2828
self.const_uint(self.type_u16(), i as u64)
2929
}
3030

31-
fn global_const_string(&self, string: &str) -> LValue<'gcc> {
32-
// The bytes of a Rust string are not NUL-terminated and can contain NULs.
33-
let string = bytes_in_context(self, string.as_bytes());
31+
fn global_string(&self, string: &str) -> LValue<'gcc> {
32+
// FIXME(antoyo): handle non-null-terminated strings.
33+
let string = self.context.new_string_literal(string);
3434
let sym = self.generate_local_symbol_name("str");
3535
let global = self.declare_private_global(&sym, self.val_ty(string));
3636
global.global_set_initializer_rvalue(string);
37-
#[cfg(feature = "master")]
38-
global.global_set_readonly();
3937
global
4038
// FIXME(antoyo): set linkage.
4139
}
@@ -128,6 +126,18 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
128126
}
129127
}
130128

129+
/// The element type and element count of the array used to represent a run of `len` constant bytes.
130+
///
131+
/// Larger integers are used where possible: this reduces the number of rvalues, which is a
132+
/// significant memory saving on constant-heavy crates.
133+
fn byte_run_shape<'gcc>(cx: &CodegenCx<'gcc, '_>, len: usize) -> (Type<'gcc>, u64) {
134+
match len % 8 {
135+
0 => (cx.context.new_type::<u64>(), len as u64 / 8),
136+
4 => (cx.context.new_type::<u32>(), len as u64 / 4),
137+
_ => (cx.context.new_type::<u8>(), len as u64),
138+
}
139+
}
140+
131141
/// The type [`bytes_in_context`] gives a run of `len` constant bytes.
132142
///
133143
/// Exposed separately so that the type of a constant allocation can be computed before any of its
@@ -137,30 +147,65 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
137147
/// Two equal-but-distinct array types would key [`CodegenCx::type_struct`] differently and so
138148
/// produce two distinct anonymous structs, and libgccjit compares struct types by identity.
139149
pub fn bytes_type_in_context<'gcc>(cx: &CodegenCx<'gcc, '_>, len: usize) -> Type<'gcc> {
140-
if let Some(&typ) = cx.byte_array_types.borrow().get(&len) {
150+
let (element_type, count) = byte_run_shape(cx, len);
151+
if let Some(&typ) = cx.byte_array_types.borrow().get(&(element_type, count)) {
141152
return typ;
142153
}
143-
let typ = new_array_type(cx.context, None, cx.type_u8(), len as u64);
144-
cx.byte_array_types.borrow_mut().insert(len, typ);
154+
let typ = new_array_type(cx.context, None, element_type, count);
155+
cx.byte_array_types.borrow_mut().insert((element_type, count), typ);
145156
typ
146157
}
147158

159+
// FIXME(FractalFir): Consider using `global_set_initializer` instead. Before this is done, we need to confirm that
160+
// `global_set_initializer` is more memory efficient than the current solution.
161+
// `global_set_initializer` calls `global_set_initializer_rvalue` under the hood - does it generate an array of rvalues,
162+
// or is it using a more efficient representation?
148163
pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> {
149164
let typ = bytes_type_in_context(cx, bytes.len());
150-
// Raw bytes take far less RAM in libgccjit than one rvalue per array element.
151-
#[cfg(feature = "master")]
152-
{
153-
cx.context.new_array_from_bytes(None, typ, bytes)
154-
}
155-
#[cfg(not(feature = "master"))]
156-
{
157-
let byte_type = cx.type_u8();
158-
let elements: Vec<_> = bytes
165+
let (element_type, _) = byte_run_shape(cx, bytes.len());
166+
let context = &cx.context;
167+
// Since we are representing arbitrary byte runs as integers, we need to follow the target
168+
// endianness.
169+
let endian = cx.sess().target.options.endian;
170+
let elements: Vec<_> = match bytes.len() % 8 {
171+
0 => {
172+
let (arrays, remainder) = bytes.as_chunks::<8>();
173+
debug_assert!(remainder.is_empty());
174+
arrays
175+
.iter()
176+
.map(|&arr| {
177+
context.new_rvalue_from_long(
178+
element_type,
179+
match endian {
180+
rustc_abi::Endian::Little => u64::from_le_bytes(arr) as i64,
181+
rustc_abi::Endian::Big => u64::from_be_bytes(arr) as i64,
182+
},
183+
)
184+
})
185+
.collect()
186+
}
187+
4 => {
188+
let (arrays, remainder) = bytes.as_chunks::<4>();
189+
debug_assert!(remainder.is_empty());
190+
arrays
191+
.iter()
192+
.map(|&arr| {
193+
context.new_rvalue_from_int(
194+
element_type,
195+
match endian {
196+
rustc_abi::Endian::Little => u32::from_le_bytes(arr) as i32,
197+
rustc_abi::Endian::Big => u32::from_be_bytes(arr) as i32,
198+
},
199+
)
200+
})
201+
.collect()
202+
}
203+
_ => bytes
159204
.iter()
160-
.map(|&byte| cx.context.new_rvalue_from_int(byte_type, byte as i32))
161-
.collect();
162-
cx.context.new_array_constructor(None, typ, &elements)
163-
}
205+
.map(|&byte| context.new_rvalue_from_int(element_type, byte as i32))
206+
.collect(),
207+
};
208+
context.new_array_constructor(None, typ, &elements)
164209
}
165210

166211
pub fn type_is_pointer(typ: Type<'_>) -> bool {
@@ -247,7 +292,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> {
247292
fn const_str(&self, s: &str) -> (RValue<'gcc>, RValue<'gcc>) {
248293
let mut const_str_cache = self.const_str_cache.borrow_mut();
249294
let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| {
250-
let g = self.global_const_string(s);
295+
let g = self.global_string(s);
251296
const_str_cache.insert(s.to_owned(), g);
252297
g
253298
});

0 commit comments

Comments
 (0)