Skip to content

Commit 9ad5d82

Browse files
committed
Auto merge of #92731 - bjorn3:asm_support_changes, r=nagisa
Avoid unnecessary monomorphization of inline asm related functions This should reduce build time for codegen backends by avoiding duplicated monomorphization of certain inline asm related functions for each passed in closure type.
2 parents 7bc7be8 + 9336fe3 commit 9ad5d82

File tree

21 files changed

+133
-105
lines changed

21 files changed

+133
-105
lines changed

compiler/rustc_ast_lowering/src/asm.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_data_structures::stable_set::FxHashSet;
66
use rustc_errors::struct_span_err;
77
use rustc_hir as hir;
88
use rustc_session::parse::feature_err;
9-
use rustc_span::{sym, Span, Symbol};
9+
use rustc_span::{sym, Span};
1010
use rustc_target::asm;
1111
use std::collections::hash_map::Entry;
1212
use std::fmt::Write;
@@ -66,7 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6666
for (abi_name, abi_span) in &asm.clobber_abis {
6767
match asm::InlineAsmClobberAbi::parse(
6868
asm_arch,
69-
|feature| self.sess.target_features.contains(&Symbol::intern(feature)),
69+
&self.sess.target_features,
7070
&self.sess.target,
7171
*abi_name,
7272
) {
@@ -134,7 +134,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
134134
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
135135
asm::InlineAsmReg::parse(
136136
asm_arch,
137-
|feature| sess.target_features.contains(&Symbol::intern(feature)),
137+
&sess.target_features,
138138
&sess.target,
139139
s,
140140
)

compiler/rustc_codegen_cranelift/src/inline_asm.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::fmt::Write;
66

77
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
88
use rustc_middle::mir::InlineAsmOperand;
9-
use rustc_span::Symbol;
9+
use rustc_span::sym;
1010
use rustc_target::asm::*;
1111

1212
pub(crate) fn codegen_inline_asm<'tcx>(
@@ -182,11 +182,7 @@ struct InlineAssemblyGenerator<'a, 'tcx> {
182182
impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
183183
fn allocate_registers(&mut self) {
184184
let sess = self.tcx.sess;
185-
let map = allocatable_registers(
186-
self.arch,
187-
|feature| sess.target_features.contains(&Symbol::intern(feature)),
188-
&sess.target,
189-
);
185+
let map = allocatable_registers(self.arch, &sess.target_features, &sess.target);
190186
let mut allocated = FxHashMap::<_, (bool, bool)>::default();
191187
let mut regs = vec![None; self.operands.len()];
192188

@@ -319,9 +315,9 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
319315
// Allocate stack slots for saving clobbered registers
320316
let abi_clobber = InlineAsmClobberAbi::parse(
321317
self.arch,
322-
|feature| self.tcx.sess.target_features.contains(&Symbol::intern(feature)),
318+
&self.tcx.sess.target_features,
323319
&self.tcx.sess.target,
324-
Symbol::intern("C"),
320+
sym::C,
325321
)
326322
.unwrap()
327323
.clobbered_regs();

compiler/rustc_codegen_gcc/src/asm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
55
use rustc_codegen_ssa::traits::{AsmBuilderMethods, AsmMethods, BaseTypeMethods, BuilderMethods, GlobalAsmOperandRef, InlineAsmOperandRef};
66

77
use rustc_middle::{bug, ty::Instance};
8-
use rustc_span::{Span, Symbol};
8+
use rustc_span::Span;
99
use rustc_target::asm::*;
1010

1111
use std::borrow::Cow;
@@ -172,7 +172,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
172172
let is_target_supported = reg.reg_class().supported_types(asm_arch).iter()
173173
.any(|&(_, feature)| {
174174
if let Some(feature) = feature {
175-
self.tcx.sess.target_features.contains(&Symbol::intern(feature))
175+
self.tcx.sess.target_features.contains(&feature)
176176
} else {
177177
true // Register class is unconditionally supported
178178
}

compiler/rustc_codegen_llvm/src/asm.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_codegen_ssa::traits::*;
1313
use rustc_data_structures::fx::FxHashMap;
1414
use rustc_middle::ty::layout::TyAndLayout;
1515
use rustc_middle::{bug, span_bug, ty::Instance};
16-
use rustc_span::{Pos, Span, Symbol};
16+
use rustc_span::{Pos, Span};
1717
use rustc_target::abi::*;
1818
use rustc_target::asm::*;
1919

@@ -45,9 +45,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
4545
for &(_, feature) in reg_class.supported_types(asm_arch) {
4646
if let Some(feature) = feature {
4747
let codegen_fn_attrs = self.tcx.codegen_fn_attrs(instance.def_id());
48-
let feature_name = Symbol::intern(feature);
49-
if self.tcx.sess.target_features.contains(&feature_name)
50-
|| codegen_fn_attrs.target_features.contains(&feature_name)
48+
if self.tcx.sess.target_features.contains(&feature)
49+
|| codegen_fn_attrs.target_features.contains(&feature)
5150
{
5251
return true;
5352
}

compiler/rustc_passes/src/intrinsicck.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,8 @@ impl<'tcx> ExprVisitor<'tcx> {
294294
// (!). In that case we still need the earlier check to verify that the
295295
// register class is usable at all.
296296
if let Some(feature) = feature {
297-
let feat_sym = Symbol::intern(feature);
298-
if !self.tcx.sess.target_features.contains(&feat_sym)
299-
&& !target_features.contains(&feat_sym)
297+
if !self.tcx.sess.target_features.contains(&feature)
298+
&& !target_features.contains(&feature)
300299
{
301300
let msg = &format!("`{}` target feature is not enabled", feature);
302301
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
@@ -377,9 +376,8 @@ impl<'tcx> ExprVisitor<'tcx> {
377376
{
378377
match feature {
379378
Some(feature) => {
380-
let feat_sym = Symbol::intern(feature);
381-
if self.tcx.sess.target_features.contains(&feat_sym)
382-
|| attrs.target_features.contains(&feat_sym)
379+
if self.tcx.sess.target_features.contains(&feature)
380+
|| attrs.target_features.contains(&feature)
383381
{
384382
missing_required_features.clear();
385383
break;
@@ -413,7 +411,11 @@ impl<'tcx> ExprVisitor<'tcx> {
413411
let msg = format!(
414412
"register class `{}` requires at least one of the following target features: {}",
415413
reg_class.name(),
416-
features.join(", ")
414+
features
415+
.iter()
416+
.map(|f| f.as_str())
417+
.intersperse(", ")
418+
.collect::<String>(),
417419
);
418420
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
419421
// register isn't enabled, don't do more checks

compiler/rustc_passes/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
88
#![feature(crate_visibility_modifier)]
9+
#![feature(iter_intersperse)]
910
#![feature(let_else)]
1011
#![feature(map_try_insert)]
1112
#![feature(min_specialization)]

compiler/rustc_span/src/symbol.rs

+12
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ symbols! {
316316
allow_internal_unsafe,
317317
allow_internal_unstable,
318318
allowed,
319+
alu32,
319320
always,
320321
and,
321322
and_then,
@@ -362,7 +363,10 @@ symbols! {
362363
augmented_assignments,
363364
auto_traits,
364365
automatically_derived,
366+
avx,
365367
avx512_target_feature,
368+
avx512bw,
369+
avx512f,
366370
await_macro,
367371
bang,
368372
begin_panic,
@@ -593,6 +597,7 @@ symbols! {
593597
dylib,
594598
dyn_metadata,
595599
dyn_trait,
600+
e,
596601
edition_macro_pats,
597602
edition_panic,
598603
eh_catch_typeinfo,
@@ -683,6 +688,7 @@ symbols! {
683688
format_args_macro,
684689
format_args_nl,
685690
format_macro,
691+
fp,
686692
freeze,
687693
freg,
688694
frem_fast,
@@ -908,6 +914,7 @@ symbols! {
908914
neg,
909915
negate_unsigned,
910916
negative_impls,
917+
neon,
911918
never,
912919
never_type,
913920
never_type_fallback,
@@ -1102,6 +1109,7 @@ symbols! {
11021109
repr_packed,
11031110
repr_simd,
11041111
repr_transparent,
1112+
reserved_r9: "reserved-r9",
11051113
residual,
11061114
result,
11071115
rhs,
@@ -1296,6 +1304,7 @@ symbols! {
12961304
sqrtf64,
12971305
sreg,
12981306
sreg_low16,
1307+
sse,
12991308
sse4a_target_feature,
13001309
stable,
13011310
staged_api,
@@ -1362,6 +1371,8 @@ symbols! {
13621371
thread,
13631372
thread_local,
13641373
thread_local_macro,
1374+
thumb2,
1375+
thumb_mode: "thumb-mode",
13651376
todo_macro,
13661377
tool_attributes,
13671378
tool_lints,
@@ -1455,6 +1466,7 @@ symbols! {
14551466
vec,
14561467
vec_macro,
14571468
version,
1469+
vfp2,
14581470
vis,
14591471
visible_private_types,
14601472
volatile,

compiler/rustc_target/src/asm/aarch64.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use super::{InlineAsmArch, InlineAsmType};
22
use crate::spec::Target;
3+
use rustc_data_structures::stable_set::FxHashSet;
34
use rustc_macros::HashStable_Generic;
5+
use rustc_span::Symbol;
46
use std::fmt;
57

68
def_reg_class! {
@@ -58,11 +60,11 @@ impl AArch64InlineAsmRegClass {
5860
pub fn supported_types(
5961
self,
6062
_arch: InlineAsmArch,
61-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
63+
) -> &'static [(InlineAsmType, Option<Symbol>)] {
6264
match self {
6365
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
6466
Self::vreg | Self::vreg_low16 => types! {
65-
"fp": I8, I16, I32, I64, F32, F64,
67+
fp: I8, I16, I32, I64, F32, F64,
6668
VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1),
6769
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
6870
},
@@ -73,7 +75,7 @@ impl AArch64InlineAsmRegClass {
7375

7476
pub fn reserved_x18(
7577
_arch: InlineAsmArch,
76-
_has_feature: impl FnMut(&str) -> bool,
78+
_target_features: &FxHashSet<Symbol>,
7779
target: &Target,
7880
) -> Result<(), &'static str> {
7981
if target.os == "android"

compiler/rustc_target/src/asm/arm.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use super::{InlineAsmArch, InlineAsmType};
22
use crate::spec::Target;
3+
use rustc_data_structures::stable_set::FxHashSet;
34
use rustc_macros::HashStable_Generic;
5+
use rustc_span::{sym, Symbol};
46
use std::fmt;
57

68
def_reg_class! {
@@ -44,31 +46,31 @@ impl ArmInlineAsmRegClass {
4446
pub fn supported_types(
4547
self,
4648
_arch: InlineAsmArch,
47-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
49+
) -> &'static [(InlineAsmType, Option<Symbol>)] {
4850
match self {
4951
Self::reg => types! { _: I8, I16, I32, F32; },
50-
Self::sreg | Self::sreg_low16 => types! { "vfp2": I32, F32; },
52+
Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F32; },
5153
Self::dreg | Self::dreg_low16 | Self::dreg_low8 => types! {
52-
"vfp2": I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
54+
vfp2: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2);
5355
},
5456
Self::qreg | Self::qreg_low8 | Self::qreg_low4 => types! {
55-
"neon": VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4);
57+
neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4);
5658
},
5759
}
5860
}
5961
}
6062

6163
// This uses the same logic as useR7AsFramePointer in LLVM
62-
fn frame_pointer_is_r7(mut has_feature: impl FnMut(&str) -> bool, target: &Target) -> bool {
63-
target.is_like_osx || (!target.is_like_windows && has_feature("thumb-mode"))
64+
fn frame_pointer_is_r7(target_features: &FxHashSet<Symbol>, target: &Target) -> bool {
65+
target.is_like_osx || (!target.is_like_windows && target_features.contains(&sym::thumb_mode))
6466
}
6567

6668
fn frame_pointer_r11(
6769
_arch: InlineAsmArch,
68-
has_feature: impl FnMut(&str) -> bool,
70+
target_features: &FxHashSet<Symbol>,
6971
target: &Target,
7072
) -> Result<(), &'static str> {
71-
if !frame_pointer_is_r7(has_feature, target) {
73+
if !frame_pointer_is_r7(target_features, target) {
7274
Err("the frame pointer (r11) cannot be used as an operand for inline asm")
7375
} else {
7476
Ok(())
@@ -77,10 +79,10 @@ fn frame_pointer_r11(
7779

7880
fn frame_pointer_r7(
7981
_arch: InlineAsmArch,
80-
has_feature: impl FnMut(&str) -> bool,
82+
target_features: &FxHashSet<Symbol>,
8183
target: &Target,
8284
) -> Result<(), &'static str> {
83-
if frame_pointer_is_r7(has_feature, target) {
85+
if frame_pointer_is_r7(target_features, target) {
8486
Err("the frame pointer (r7) cannot be used as an operand for inline asm")
8587
} else {
8688
Ok(())
@@ -89,10 +91,10 @@ fn frame_pointer_r7(
8991

9092
fn not_thumb1(
9193
_arch: InlineAsmArch,
92-
mut has_feature: impl FnMut(&str) -> bool,
94+
target_features: &FxHashSet<Symbol>,
9395
_target: &Target,
9496
) -> Result<(), &'static str> {
95-
if has_feature("thumb-mode") && !has_feature("thumb2") {
97+
if target_features.contains(&sym::thumb_mode) && !target_features.contains(&sym::thumb2) {
9698
Err("high registers (r8+) cannot be used in Thumb-1 code")
9799
} else {
98100
Ok(())
@@ -101,14 +103,14 @@ fn not_thumb1(
101103

102104
fn reserved_r9(
103105
arch: InlineAsmArch,
104-
mut has_feature: impl FnMut(&str) -> bool,
106+
target_features: &FxHashSet<Symbol>,
105107
target: &Target,
106108
) -> Result<(), &'static str> {
107-
not_thumb1(arch, &mut has_feature, target)?;
109+
not_thumb1(arch, target_features, target)?;
108110

109111
// We detect this using the reserved-r9 feature instead of using the target
110112
// because the relocation model can be changed with compiler options.
111-
if has_feature("reserved-r9") {
113+
if target_features.contains(&sym::reserved_r9) {
112114
Err("the RWPI static base register (r9) cannot be used as an operand for inline asm")
113115
} else {
114116
Ok(())

compiler/rustc_target/src/asm/avr.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{InlineAsmArch, InlineAsmType};
22
use rustc_macros::HashStable_Generic;
3+
use rustc_span::Symbol;
34
use std::fmt;
45

56
def_reg_class! {
@@ -39,7 +40,7 @@ impl AvrInlineAsmRegClass {
3940
pub fn supported_types(
4041
self,
4142
_arch: InlineAsmArch,
42-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
43+
) -> &'static [(InlineAsmType, Option<Symbol>)] {
4344
match self {
4445
Self::reg => types! { _: I8; },
4546
Self::reg_upper => types! { _: I8; },

compiler/rustc_target/src/asm/bpf.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use super::{InlineAsmArch, InlineAsmType, Target};
2+
use rustc_data_structures::stable_set::FxHashSet;
23
use rustc_macros::HashStable_Generic;
4+
use rustc_span::{sym, Symbol};
35
use std::fmt;
46

57
def_reg_class! {
@@ -33,20 +35,20 @@ impl BpfInlineAsmRegClass {
3335
pub fn supported_types(
3436
self,
3537
_arch: InlineAsmArch,
36-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
38+
) -> &'static [(InlineAsmType, Option<Symbol>)] {
3739
match self {
3840
Self::reg => types! { _: I8, I16, I32, I64; },
39-
Self::wreg => types! { "alu32": I8, I16, I32; },
41+
Self::wreg => types! { alu32: I8, I16, I32; },
4042
}
4143
}
4244
}
4345

4446
fn only_alu32(
4547
_arch: InlineAsmArch,
46-
mut has_feature: impl FnMut(&str) -> bool,
48+
target_features: &FxHashSet<Symbol>,
4749
_target: &Target,
4850
) -> Result<(), &'static str> {
49-
if !has_feature("alu32") {
51+
if !target_features.contains(&sym::alu32) {
5052
Err("register can't be used without the `alu32` target feature")
5153
} else {
5254
Ok(())

0 commit comments

Comments
 (0)