Skip to content

Commit 91cacb3

Browse files
committed
Auto merge of rust-lang#97512 - scottmcm:add-coldcc, r=nagisa,lcnr
Add support for emitting functions with `coldcc` to LLVM The eventual goal is to try using this for things like the internal panicking stuff, to see whether it helps.
2 parents bb55bd4 + be4e089 commit 91cacb3

File tree

14 files changed

+132
-4
lines changed

14 files changed

+132
-4
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

+8
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ impl<'a> PostExpansionVisitor<'a> {
113113
"rust-call ABI is subject to change"
114114
);
115115
}
116+
"rust-cold" => {
117+
gate_feature_post!(
118+
&self,
119+
rust_cold_cc,
120+
span,
121+
"rust-cold is experimental and subject to change"
122+
);
123+
}
116124
"ptx-kernel" => {
117125
gate_feature_post!(
118126
&self,

compiler/rustc_codegen_cranelift/src/abi/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ fn clif_sig_from_fn_abi<'tcx>(
2323
) -> Signature {
2424
let call_conv = match fn_abi.conv {
2525
Conv::Rust | Conv::C => default_call_conv,
26+
Conv::RustCold => CallConv::Cold,
2627
Conv::X86_64SysV => CallConv::SystemV,
2728
Conv::X86_64Win64 => CallConv::WindowsFastcall,
2829
Conv::ArmAapcs

compiler/rustc_codegen_llvm/src/abi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
393393
fn llvm_cconv(&self) -> llvm::CallConv {
394394
match self.conv {
395395
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
396+
Conv::RustCold => llvm::ColdCallConv,
396397
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
397398
Conv::AvrInterrupt => llvm::AvrInterrupt,
398399
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,

compiler/rustc_feature/src/active.rs

+2
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ declare_features! (
496496
(incomplete, repr128, "1.16.0", Some(56071), None),
497497
/// Allows `repr(simd)` and importing the various simd intrinsics.
498498
(active, repr_simd, "1.4.0", Some(27731), None),
499+
/// Allows `extern "rust-cold"`.
500+
(active, rust_cold_cc, "1.63.0", Some(97544), None),
499501
/// Allows the use of SIMD types in functions declared in `extern` blocks.
500502
(active, simd_ffi, "1.0.0", Some(27731), None),
501503
/// Allows specialization of implementations (RFC 1210).

compiler/rustc_middle/src/ty/layout.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2971,7 +2971,7 @@ pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: Spe
29712971
| RustIntrinsic
29722972
| PlatformIntrinsic
29732973
| Unadjusted => false,
2974-
Rust | RustCall => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
2974+
Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
29752975
}
29762976
}
29772977

@@ -2980,6 +2980,7 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv {
29802980
use rustc_target::spec::abi::Abi::*;
29812981
match tcx.sess.target.adjust_abi(abi) {
29822982
RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
2983+
RustCold => Conv::RustCold,
29832984

29842985
// It's the ABI's job to select this, not ours.
29852986
System { .. } => bug!("system abi should be selected elsewhere"),

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,7 @@ symbols! {
11631163
rust_2024,
11641164
rust_2024_preview,
11651165
rust_begin_unwind,
1166+
rust_cold_cc,
11661167
rust_eh_catch_typeinfo,
11671168
rust_eh_personality,
11681169
rust_eh_register_frames,

compiler/rustc_target/src/abi/call/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,11 @@ pub enum Conv {
580580
C,
581581
Rust,
582582

583+
/// For things unlikely to be called, where smaller caller codegen is
584+
/// preferred over raw speed.
585+
/// Stronger than just `#[cold]` because `fn` pointers might be incompatible.
586+
RustCold,
587+
583588
// Target-specific calling conventions.
584589
ArmAapcs,
585590
CCmseNonSecureCall,

compiler/rustc_target/src/spec/abi.rs

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub enum Abi {
3535
RustCall,
3636
PlatformIntrinsic,
3737
Unadjusted,
38+
RustCold,
3839
}
3940

4041
#[derive(Copy, Clone)]
@@ -81,6 +82,7 @@ const AbiDatas: &[AbiData] = &[
8182
AbiData { abi: Abi::RustCall, name: "rust-call" },
8283
AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" },
8384
AbiData { abi: Abi::Unadjusted, name: "unadjusted" },
85+
AbiData { abi: Abi::RustCold, name: "rust-cold" },
8486
];
8587

8688
/// Returns the ABI with the given name (if any).
@@ -139,6 +141,7 @@ impl Abi {
139141
RustCall => 31,
140142
PlatformIntrinsic => 32,
141143
Unadjusted => 33,
144+
RustCold => 34,
142145
};
143146
debug_assert!(
144147
AbiDatas

compiler/rustc_target/src/spec/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1620,7 +1620,8 @@ impl Target {
16201620
| PlatformIntrinsic
16211621
| Unadjusted
16221622
| Cdecl { .. }
1623-
| EfiApi => true,
1623+
| EfiApi
1624+
| RustCold => true,
16241625
X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]),
16251626
Aapcs { .. } => "arm" == self.arch,
16261627
CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// compile-flags: -C no-prepopulate-passes
2+
3+
#![crate_type = "lib"]
4+
#![feature(rust_cold_cc)]
5+
6+
// wasm marks the definition as `dso_local`, so allow that as optional.
7+
8+
// CHECK: define{{( dso_local)?}} coldcc void @this_should_never_happen(i16
9+
// CHECK: call coldcc void @this_should_never_happen(i16
10+
11+
#[no_mangle]
12+
pub extern "rust-cold" fn this_should_never_happen(x: u16) {}
13+
14+
pub fn do_things(x: u16) {
15+
if x == 12345 {
16+
this_should_never_happen(54321);
17+
}
18+
}

src/test/ui/codemap_tests/unicode.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
44
LL | extern "路濫狼á́́" fn foo() {}
55
| ^^^^^^^^^ invalid ABI
66
|
7-
= help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
7+
= help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted, rust-cold
88

99
error: aborting due to previous error
1010

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![crate_type = "lib"]
2+
3+
extern "rust-cold" fn fu() {} //~ ERROR rust-cold is experimental
4+
5+
trait T {
6+
extern "rust-cold" fn mu(); //~ ERROR rust-cold is experimental
7+
extern "rust-cold" fn dmu() {} //~ ERROR rust-cold is experimental
8+
}
9+
10+
struct S;
11+
impl T for S {
12+
extern "rust-cold" fn mu() {} //~ ERROR rust-cold is experimental
13+
}
14+
15+
impl S {
16+
extern "rust-cold" fn imu() {} //~ ERROR rust-cold is experimental
17+
}
18+
19+
type TAU = extern "rust-cold" fn(); //~ ERROR rust-cold is experimental
20+
21+
extern "rust-cold" {} //~ ERROR rust-cold is experimental
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
error[E0658]: rust-cold is experimental and subject to change
2+
--> $DIR/feature-gate-rust_cold_cc.rs:3:8
3+
|
4+
LL | extern "rust-cold" fn fu() {}
5+
| ^^^^^^^^^^^
6+
|
7+
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
8+
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable
9+
10+
error[E0658]: rust-cold is experimental and subject to change
11+
--> $DIR/feature-gate-rust_cold_cc.rs:6:12
12+
|
13+
LL | extern "rust-cold" fn mu();
14+
| ^^^^^^^^^^^
15+
|
16+
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
17+
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable
18+
19+
error[E0658]: rust-cold is experimental and subject to change
20+
--> $DIR/feature-gate-rust_cold_cc.rs:7:12
21+
|
22+
LL | extern "rust-cold" fn dmu() {}
23+
| ^^^^^^^^^^^
24+
|
25+
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
26+
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable
27+
28+
error[E0658]: rust-cold is experimental and subject to change
29+
--> $DIR/feature-gate-rust_cold_cc.rs:12:12
30+
|
31+
LL | extern "rust-cold" fn mu() {}
32+
| ^^^^^^^^^^^
33+
|
34+
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
35+
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable
36+
37+
error[E0658]: rust-cold is experimental and subject to change
38+
--> $DIR/feature-gate-rust_cold_cc.rs:16:12
39+
|
40+
LL | extern "rust-cold" fn imu() {}
41+
| ^^^^^^^^^^^
42+
|
43+
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
44+
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable
45+
46+
error[E0658]: rust-cold is experimental and subject to change
47+
--> $DIR/feature-gate-rust_cold_cc.rs:19:19
48+
|
49+
LL | type TAU = extern "rust-cold" fn();
50+
| ^^^^^^^^^^^
51+
|
52+
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
53+
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable
54+
55+
error[E0658]: rust-cold is experimental and subject to change
56+
--> $DIR/feature-gate-rust_cold_cc.rs:21:8
57+
|
58+
LL | extern "rust-cold" {}
59+
| ^^^^^^^^^^^
60+
|
61+
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
62+
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable
63+
64+
error: aborting due to 7 previous errors
65+
66+
For more information about this error, try `rustc --explain E0658`.

src/test/ui/parser/issues/issue-8537.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize`
44
LL | "invalid-ab_isize"
55
| ^^^^^^^^^^^^^^^^^^ invalid ABI
66
|
7-
= help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted
7+
= help: valid ABIs: Rust, C, C-unwind, cdecl, cdecl-unwind, stdcall, stdcall-unwind, fastcall, fastcall-unwind, vectorcall, vectorcall-unwind, thiscall, thiscall-unwind, aapcs, aapcs-unwind, win64, win64-unwind, sysv64, sysv64-unwind, ptx-kernel, msp430-interrupt, x86-interrupt, amdgpu-kernel, efiapi, avr-interrupt, avr-non-blocking-interrupt, C-cmse-nonsecure-call, wasm, system, system-unwind, rust-intrinsic, rust-call, platform-intrinsic, unadjusted, rust-cold
88

99
error: aborting due to previous error
1010

0 commit comments

Comments
 (0)