Skip to content

Commit e90be84

Browse files
committed
Add support for emitting functions with coldcc in LLVM
The eventual goal is to try using this for things like the internal panicking stuff, to see whether it helps.
1 parent 0acc4a3 commit e90be84

File tree

12 files changed

+128
-3
lines changed

12 files changed

+128
-3
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 8 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn clif_sig_from_fn_abi<'tcx>(
2222
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
2323
) -> Signature {
2424
let call_conv = match fn_abi.conv {
25-
Conv::Rust | Conv::C => default_call_conv,
25+
Conv::Rust | Conv::C | Conv::RustCold => default_call_conv,
2626
Conv::X86_64SysV => CallConv::SystemV,
2727
Conv::X86_64Win64 => CallConv::WindowsFastcall,
2828
Conv::ArmAapcs

compiler/rustc_codegen_llvm/src/abi.rs

Lines changed: 1 addition & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,7 @@ symbols! {
11601160
rust_2024,
11611161
rust_2024_preview,
11621162
rust_begin_unwind,
1163+
rust_cold_cc,
11631164
rust_eh_catch_typeinfo,
11641165
rust_eh_personality,
11651166
rust_eh_register_frames,

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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,8 @@ impl Target {
16181618
| PlatformIntrinsic
16191619
| Unadjusted
16201620
| Cdecl { .. }
1621-
| EfiApi => true,
1621+
| EfiApi
1622+
| RustCold => true,
16221623
X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]),
16231624
Aapcs { .. } => "arm" == self.arch,
16241625
CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]),
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// compile-flags: -C no-prepopulate-passes
2+
3+
#![crate_type = "lib"]
4+
#![feature(rust_cold_cc)]
5+
6+
// CHECK: define coldcc void @this_should_never_happen(i16
7+
// CHECK: call coldcc void @this_should_never_happen(i16
8+
9+
#[no_mangle]
10+
pub extern "rust-cold" fn this_should_never_happen(x: u16) {}
11+
12+
pub fn do_things(x: u16) {
13+
if x == 12345 {
14+
this_should_never_happen(54321);
15+
}
16+
}
Lines changed: 21 additions & 0 deletions
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
Lines changed: 66 additions & 0 deletions
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`.

0 commit comments

Comments
 (0)