Skip to content

Commit

Permalink
Auto merge of #97512 - scottmcm:add-coldcc, r=nagisa,lcnr
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jun 7, 2022
2 parents bb55bd4 + be4e089 commit 91cacb3
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 4 deletions.
8 changes: 8 additions & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ impl<'a> PostExpansionVisitor<'a> {
"rust-call ABI is subject to change"
);
}
"rust-cold" => {
gate_feature_post!(
&self,
rust_cold_cc,
span,
"rust-cold is experimental and subject to change"
);
}
"ptx-kernel" => {
gate_feature_post!(
&self,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_cranelift/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ fn clif_sig_from_fn_abi<'tcx>(
) -> Signature {
let call_conv = match fn_abi.conv {
Conv::Rust | Conv::C => default_call_conv,
Conv::RustCold => CallConv::Cold,
Conv::X86_64SysV => CallConv::SystemV,
Conv::X86_64Win64 => CallConv::WindowsFastcall,
Conv::ArmAapcs
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
fn llvm_cconv(&self) -> llvm::CallConv {
match self.conv {
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
Conv::RustCold => llvm::ColdCallConv,
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
Conv::AvrInterrupt => llvm::AvrInterrupt,
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ declare_features! (
(incomplete, repr128, "1.16.0", Some(56071), None),
/// Allows `repr(simd)` and importing the various simd intrinsics.
(active, repr_simd, "1.4.0", Some(27731), None),
/// Allows `extern "rust-cold"`.
(active, rust_cold_cc, "1.63.0", Some(97544), None),
/// Allows the use of SIMD types in functions declared in `extern` blocks.
(active, simd_ffi, "1.0.0", Some(27731), None),
/// Allows specialization of implementations (RFC 1210).
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2971,7 +2971,7 @@ pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: Spe
| RustIntrinsic
| PlatformIntrinsic
| Unadjusted => false,
Rust | RustCall => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
}
}

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

// It's the ABI's job to select this, not ours.
System { .. } => bug!("system abi should be selected elsewhere"),
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,7 @@ symbols! {
rust_2024,
rust_2024_preview,
rust_begin_unwind,
rust_cold_cc,
rust_eh_catch_typeinfo,
rust_eh_personality,
rust_eh_register_frames,
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_target/src/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,11 @@ pub enum Conv {
C,
Rust,

/// For things unlikely to be called, where smaller caller codegen is
/// preferred over raw speed.
/// Stronger than just `#[cold]` because `fn` pointers might be incompatible.
RustCold,

// Target-specific calling conventions.
ArmAapcs,
CCmseNonSecureCall,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub enum Abi {
RustCall,
PlatformIntrinsic,
Unadjusted,
RustCold,
}

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -81,6 +82,7 @@ const AbiDatas: &[AbiData] = &[
AbiData { abi: Abi::RustCall, name: "rust-call" },
AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" },
AbiData { abi: Abi::Unadjusted, name: "unadjusted" },
AbiData { abi: Abi::RustCold, name: "rust-cold" },
];

/// Returns the ABI with the given name (if any).
Expand Down Expand Up @@ -139,6 +141,7 @@ impl Abi {
RustCall => 31,
PlatformIntrinsic => 32,
Unadjusted => 33,
RustCold => 34,
};
debug_assert!(
AbiDatas
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1620,7 +1620,8 @@ impl Target {
| PlatformIntrinsic
| Unadjusted
| Cdecl { .. }
| EfiApi => true,
| EfiApi
| RustCold => true,
X86Interrupt => ["x86", "x86_64"].contains(&&self.arch[..]),
Aapcs { .. } => "arm" == self.arch,
CCmseNonSecureCall => ["arm", "aarch64"].contains(&&self.arch[..]),
Expand Down
18 changes: 18 additions & 0 deletions src/test/codegen/cold-call-declare-and-call.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]
#![feature(rust_cold_cc)]

// wasm marks the definition as `dso_local`, so allow that as optional.

// CHECK: define{{( dso_local)?}} coldcc void @this_should_never_happen(i16
// CHECK: call coldcc void @this_should_never_happen(i16

#[no_mangle]
pub extern "rust-cold" fn this_should_never_happen(x: u16) {}

pub fn do_things(x: u16) {
if x == 12345 {
this_should_never_happen(54321);
}
}
2 changes: 1 addition & 1 deletion src/test/ui/codemap_tests/unicode.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
LL | extern "路濫狼á́́" fn foo() {}
| ^^^^^^^^^ invalid ABI
|
= 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
= 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

error: aborting due to previous error

Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/feature-gates/feature-gate-rust_cold_cc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#![crate_type = "lib"]

extern "rust-cold" fn fu() {} //~ ERROR rust-cold is experimental

trait T {
extern "rust-cold" fn mu(); //~ ERROR rust-cold is experimental
extern "rust-cold" fn dmu() {} //~ ERROR rust-cold is experimental
}

struct S;
impl T for S {
extern "rust-cold" fn mu() {} //~ ERROR rust-cold is experimental
}

impl S {
extern "rust-cold" fn imu() {} //~ ERROR rust-cold is experimental
}

type TAU = extern "rust-cold" fn(); //~ ERROR rust-cold is experimental

extern "rust-cold" {} //~ ERROR rust-cold is experimental
66 changes: 66 additions & 0 deletions src/test/ui/feature-gates/feature-gate-rust_cold_cc.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
error[E0658]: rust-cold is experimental and subject to change
--> $DIR/feature-gate-rust_cold_cc.rs:3:8
|
LL | extern "rust-cold" fn fu() {}
| ^^^^^^^^^^^
|
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable

error[E0658]: rust-cold is experimental and subject to change
--> $DIR/feature-gate-rust_cold_cc.rs:6:12
|
LL | extern "rust-cold" fn mu();
| ^^^^^^^^^^^
|
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable

error[E0658]: rust-cold is experimental and subject to change
--> $DIR/feature-gate-rust_cold_cc.rs:7:12
|
LL | extern "rust-cold" fn dmu() {}
| ^^^^^^^^^^^
|
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable

error[E0658]: rust-cold is experimental and subject to change
--> $DIR/feature-gate-rust_cold_cc.rs:12:12
|
LL | extern "rust-cold" fn mu() {}
| ^^^^^^^^^^^
|
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable

error[E0658]: rust-cold is experimental and subject to change
--> $DIR/feature-gate-rust_cold_cc.rs:16:12
|
LL | extern "rust-cold" fn imu() {}
| ^^^^^^^^^^^
|
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable

error[E0658]: rust-cold is experimental and subject to change
--> $DIR/feature-gate-rust_cold_cc.rs:19:19
|
LL | type TAU = extern "rust-cold" fn();
| ^^^^^^^^^^^
|
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable

error[E0658]: rust-cold is experimental and subject to change
--> $DIR/feature-gate-rust_cold_cc.rs:21:8
|
LL | extern "rust-cold" {}
| ^^^^^^^^^^^
|
= note: see issue #97544 <https://github.com/rust-lang/rust/issues/97544> for more information
= help: add `#![feature(rust_cold_cc)]` to the crate attributes to enable

error: aborting due to 7 previous errors

For more information about this error, try `rustc --explain E0658`.
2 changes: 1 addition & 1 deletion src/test/ui/parser/issues/issue-8537.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `invalid-ab_isize`
LL | "invalid-ab_isize"
| ^^^^^^^^^^^^^^^^^^ invalid ABI
|
= 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
= 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

error: aborting due to previous error

Expand Down

0 comments on commit 91cacb3

Please sign in to comment.