Skip to content

Commit 042aa37

Browse files
committed
Pass target_features set instead of has_feature closure
This avoids unnecessary monomorphizations in codegen backends
1 parent 991cbd1 commit 042aa37

File tree

8 files changed

+63
-62
lines changed

8 files changed

+63
-62
lines changed

Diff for: compiler/rustc_ast_lowering/src/asm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -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(&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(&feature),
137+
&sess.target_features,
138138
&sess.target,
139139
s,
140140
)

Diff for: compiler/rustc_codegen_cranelift/src/inline_asm.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -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(&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,7 +315,7 @@ 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(&feature),
318+
&self.tcx.sess.target_features,
323319
&self.tcx.sess.target,
324320
sym::C,
325321
)

Diff for: compiler/rustc_target/src/asm/aarch64.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{InlineAsmArch, InlineAsmType};
22
use crate::spec::Target;
3+
use rustc_data_structures::stable_set::FxHashSet;
34
use rustc_macros::HashStable_Generic;
45
use rustc_span::Symbol;
56
use std::fmt;
@@ -74,7 +75,7 @@ impl AArch64InlineAsmRegClass {
7475

7576
pub fn reserved_x18(
7677
_arch: InlineAsmArch,
77-
_has_feature: impl FnMut(Symbol) -> bool,
78+
_target_features: &FxHashSet<Symbol>,
7879
target: &Target,
7980
) -> Result<(), &'static str> {
8081
if target.os == "android"

Diff for: compiler/rustc_target/src/asm/arm.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{InlineAsmArch, InlineAsmType};
22
use crate::spec::Target;
3+
use rustc_data_structures::stable_set::FxHashSet;
34
use rustc_macros::HashStable_Generic;
45
use rustc_span::{sym, Symbol};
56
use std::fmt;
@@ -60,16 +61,16 @@ impl ArmInlineAsmRegClass {
6061
}
6162

6263
// This uses the same logic as useR7AsFramePointer in LLVM
63-
fn frame_pointer_is_r7(mut has_feature: impl FnMut(Symbol) -> bool, target: &Target) -> bool {
64-
target.is_like_osx || (!target.is_like_windows && has_feature(sym::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))
6566
}
6667

6768
fn frame_pointer_r11(
6869
_arch: InlineAsmArch,
69-
has_feature: impl FnMut(Symbol) -> bool,
70+
target_features: &FxHashSet<Symbol>,
7071
target: &Target,
7172
) -> Result<(), &'static str> {
72-
if !frame_pointer_is_r7(has_feature, target) {
73+
if !frame_pointer_is_r7(target_features, target) {
7374
Err("the frame pointer (r11) cannot be used as an operand for inline asm")
7475
} else {
7576
Ok(())
@@ -78,10 +79,10 @@ fn frame_pointer_r11(
7879

7980
fn frame_pointer_r7(
8081
_arch: InlineAsmArch,
81-
has_feature: impl FnMut(Symbol) -> bool,
82+
target_features: &FxHashSet<Symbol>,
8283
target: &Target,
8384
) -> Result<(), &'static str> {
84-
if frame_pointer_is_r7(has_feature, target) {
85+
if frame_pointer_is_r7(target_features, target) {
8586
Err("the frame pointer (r7) cannot be used as an operand for inline asm")
8687
} else {
8788
Ok(())
@@ -90,10 +91,10 @@ fn frame_pointer_r7(
9091

9192
fn not_thumb1(
9293
_arch: InlineAsmArch,
93-
mut has_feature: impl FnMut(Symbol) -> bool,
94+
target_features: &FxHashSet<Symbol>,
9495
_target: &Target,
9596
) -> Result<(), &'static str> {
96-
if has_feature(sym::thumb_mode) && !has_feature(sym::thumb2) {
97+
if target_features.contains(&sym::thumb_mode) && !target_features.contains(&sym::thumb2) {
9798
Err("high registers (r8+) cannot be used in Thumb-1 code")
9899
} else {
99100
Ok(())
@@ -102,14 +103,14 @@ fn not_thumb1(
102103

103104
fn reserved_r9(
104105
arch: InlineAsmArch,
105-
mut has_feature: impl FnMut(Symbol) -> bool,
106+
target_features: &FxHashSet<Symbol>,
106107
target: &Target,
107108
) -> Result<(), &'static str> {
108-
not_thumb1(arch, &mut has_feature, target)?;
109+
not_thumb1(arch, target_features, target)?;
109110

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

Diff for: compiler/rustc_target/src/asm/bpf.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::{InlineAsmArch, InlineAsmType, Target};
2+
use rustc_data_structures::stable_set::FxHashSet;
23
use rustc_macros::HashStable_Generic;
34
use rustc_span::{sym, Symbol};
45
use std::fmt;
@@ -44,10 +45,10 @@ impl BpfInlineAsmRegClass {
4445

4546
fn only_alu32(
4647
_arch: InlineAsmArch,
47-
mut has_feature: impl FnMut(Symbol) -> bool,
48+
target_features: &FxHashSet<Symbol>,
4849
_target: &Target,
4950
) -> Result<(), &'static str> {
50-
if !has_feature(sym::alu32) {
51+
if !target_features.contains(&sym::alu32) {
5152
Err("register can't be used without the `alu32` target feature")
5253
} else {
5354
Ok(())

Diff for: compiler/rustc_target/src/asm/mod.rs

+34-34
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,14 @@ macro_rules! def_regs {
8181

8282
pub fn parse(
8383
_arch: super::InlineAsmArch,
84-
mut _has_feature: impl FnMut(rustc_span::Symbol) -> bool,
84+
_target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
8585
_target: &crate::spec::Target,
8686
name: &str,
8787
) -> Result<Self, &'static str> {
8888
match name {
8989
$(
9090
$($alias)|* | $reg_name => {
91-
$($filter(_arch, &mut _has_feature, _target)?;)?
91+
$($filter(_arch, _target_features, _target)?;)?
9292
Ok(Self::$reg)
9393
}
9494
)*
@@ -102,7 +102,7 @@ macro_rules! def_regs {
102102

103103
pub(super) fn fill_reg_map(
104104
_arch: super::InlineAsmArch,
105-
mut _has_feature: impl FnMut(rustc_span::Symbol) -> bool,
105+
_target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
106106
_target: &crate::spec::Target,
107107
_map: &mut rustc_data_structures::fx::FxHashMap<
108108
super::InlineAsmRegClass,
@@ -112,7 +112,7 @@ macro_rules! def_regs {
112112
#[allow(unused_imports)]
113113
use super::{InlineAsmReg, InlineAsmRegClass};
114114
$(
115-
if $($filter(_arch, &mut _has_feature, _target).is_ok() &&)? true {
115+
if $($filter(_arch, _target_features, _target).is_ok() &&)? true {
116116
if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
117117
set.insert(InlineAsmReg::$arch($arch_reg::$reg));
118118
}
@@ -289,7 +289,7 @@ impl InlineAsmReg {
289289

290290
pub fn parse(
291291
arch: InlineAsmArch,
292-
has_feature: impl FnMut(Symbol) -> bool,
292+
target_features: &FxHashSet<Symbol>,
293293
target: &Target,
294294
name: Symbol,
295295
) -> Result<Self, &'static str> {
@@ -298,43 +298,43 @@ impl InlineAsmReg {
298298
let name = name.as_str();
299299
Ok(match arch {
300300
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
301-
Self::X86(X86InlineAsmReg::parse(arch, has_feature, target, name)?)
301+
Self::X86(X86InlineAsmReg::parse(arch, target_features, target, name)?)
302302
}
303303
InlineAsmArch::Arm => {
304-
Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, target, name)?)
304+
Self::Arm(ArmInlineAsmReg::parse(arch, target_features, target, name)?)
305305
}
306306
InlineAsmArch::AArch64 => {
307-
Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, target, name)?)
307+
Self::AArch64(AArch64InlineAsmReg::parse(arch, target_features, target, name)?)
308308
}
309309
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
310-
Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, target, name)?)
310+
Self::RiscV(RiscVInlineAsmReg::parse(arch, target_features, target, name)?)
311311
}
312312
InlineAsmArch::Nvptx64 => {
313-
Self::Nvptx(NvptxInlineAsmReg::parse(arch, has_feature, target, name)?)
313+
Self::Nvptx(NvptxInlineAsmReg::parse(arch, target_features, target, name)?)
314314
}
315315
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
316-
Self::PowerPC(PowerPCInlineAsmReg::parse(arch, has_feature, target, name)?)
316+
Self::PowerPC(PowerPCInlineAsmReg::parse(arch, target_features, target, name)?)
317317
}
318318
InlineAsmArch::Hexagon => {
319-
Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, target, name)?)
319+
Self::Hexagon(HexagonInlineAsmReg::parse(arch, target_features, target, name)?)
320320
}
321321
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
322-
Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, name)?)
322+
Self::Mips(MipsInlineAsmReg::parse(arch, target_features, target, name)?)
323323
}
324324
InlineAsmArch::S390x => {
325-
Self::S390x(S390xInlineAsmReg::parse(arch, has_feature, target, name)?)
325+
Self::S390x(S390xInlineAsmReg::parse(arch, target_features, target, name)?)
326326
}
327327
InlineAsmArch::SpirV => {
328-
Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, name)?)
328+
Self::SpirV(SpirVInlineAsmReg::parse(arch, target_features, target, name)?)
329329
}
330330
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
331-
Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, name)?)
331+
Self::Wasm(WasmInlineAsmReg::parse(arch, target_features, target, name)?)
332332
}
333333
InlineAsmArch::Bpf => {
334-
Self::Bpf(BpfInlineAsmReg::parse(arch, has_feature, target, name)?)
334+
Self::Bpf(BpfInlineAsmReg::parse(arch, target_features, target, name)?)
335335
}
336336
InlineAsmArch::Avr => {
337-
Self::Avr(AvrInlineAsmReg::parse(arch, has_feature, target, name)?)
337+
Self::Avr(AvrInlineAsmReg::parse(arch, target_features, target, name)?)
338338
}
339339
})
340340
}
@@ -695,73 +695,73 @@ impl fmt::Display for InlineAsmType {
695695
// falling back to an external assembler.
696696
pub fn allocatable_registers(
697697
arch: InlineAsmArch,
698-
has_feature: impl FnMut(Symbol) -> bool,
698+
target_features: &FxHashSet<Symbol>,
699699
target: &crate::spec::Target,
700700
) -> FxHashMap<InlineAsmRegClass, FxHashSet<InlineAsmReg>> {
701701
match arch {
702702
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
703703
let mut map = x86::regclass_map();
704-
x86::fill_reg_map(arch, has_feature, target, &mut map);
704+
x86::fill_reg_map(arch, target_features, target, &mut map);
705705
map
706706
}
707707
InlineAsmArch::Arm => {
708708
let mut map = arm::regclass_map();
709-
arm::fill_reg_map(arch, has_feature, target, &mut map);
709+
arm::fill_reg_map(arch, target_features, target, &mut map);
710710
map
711711
}
712712
InlineAsmArch::AArch64 => {
713713
let mut map = aarch64::regclass_map();
714-
aarch64::fill_reg_map(arch, has_feature, target, &mut map);
714+
aarch64::fill_reg_map(arch, target_features, target, &mut map);
715715
map
716716
}
717717
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
718718
let mut map = riscv::regclass_map();
719-
riscv::fill_reg_map(arch, has_feature, target, &mut map);
719+
riscv::fill_reg_map(arch, target_features, target, &mut map);
720720
map
721721
}
722722
InlineAsmArch::Nvptx64 => {
723723
let mut map = nvptx::regclass_map();
724-
nvptx::fill_reg_map(arch, has_feature, target, &mut map);
724+
nvptx::fill_reg_map(arch, target_features, target, &mut map);
725725
map
726726
}
727727
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
728728
let mut map = powerpc::regclass_map();
729-
powerpc::fill_reg_map(arch, has_feature, target, &mut map);
729+
powerpc::fill_reg_map(arch, target_features, target, &mut map);
730730
map
731731
}
732732
InlineAsmArch::Hexagon => {
733733
let mut map = hexagon::regclass_map();
734-
hexagon::fill_reg_map(arch, has_feature, target, &mut map);
734+
hexagon::fill_reg_map(arch, target_features, target, &mut map);
735735
map
736736
}
737737
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
738738
let mut map = mips::regclass_map();
739-
mips::fill_reg_map(arch, has_feature, target, &mut map);
739+
mips::fill_reg_map(arch, target_features, target, &mut map);
740740
map
741741
}
742742
InlineAsmArch::S390x => {
743743
let mut map = s390x::regclass_map();
744-
s390x::fill_reg_map(arch, has_feature, target, &mut map);
744+
s390x::fill_reg_map(arch, target_features, target, &mut map);
745745
map
746746
}
747747
InlineAsmArch::SpirV => {
748748
let mut map = spirv::regclass_map();
749-
spirv::fill_reg_map(arch, has_feature, target, &mut map);
749+
spirv::fill_reg_map(arch, target_features, target, &mut map);
750750
map
751751
}
752752
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
753753
let mut map = wasm::regclass_map();
754-
wasm::fill_reg_map(arch, has_feature, target, &mut map);
754+
wasm::fill_reg_map(arch, target_features, target, &mut map);
755755
map
756756
}
757757
InlineAsmArch::Bpf => {
758758
let mut map = bpf::regclass_map();
759-
bpf::fill_reg_map(arch, has_feature, target, &mut map);
759+
bpf::fill_reg_map(arch, target_features, target, &mut map);
760760
map
761761
}
762762
InlineAsmArch::Avr => {
763763
let mut map = avr::regclass_map();
764-
avr::fill_reg_map(arch, has_feature, target, &mut map);
764+
avr::fill_reg_map(arch, target_features, target, &mut map);
765765
map
766766
}
767767
}
@@ -794,7 +794,7 @@ impl InlineAsmClobberAbi {
794794
/// clobber ABIs for the target.
795795
pub fn parse(
796796
arch: InlineAsmArch,
797-
has_feature: impl FnMut(Symbol) -> bool,
797+
target_features: &FxHashSet<Symbol>,
798798
target: &Target,
799799
name: Symbol,
800800
) -> Result<Self, &'static [&'static str]> {
@@ -819,7 +819,7 @@ impl InlineAsmClobberAbi {
819819
},
820820
InlineAsmArch::AArch64 => match name {
821821
"C" | "system" | "efiapi" => {
822-
Ok(if aarch64::reserved_x18(arch, has_feature, target).is_err() {
822+
Ok(if aarch64::reserved_x18(arch, target_features, target).is_err() {
823823
InlineAsmClobberAbi::AArch64NoX18
824824
} else {
825825
InlineAsmClobberAbi::AArch64

Diff for: compiler/rustc_target/src/asm/riscv.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::{InlineAsmArch, InlineAsmType};
22
use crate::spec::Target;
3+
use rustc_data_structures::stable_set::FxHashSet;
34
use rustc_macros::HashStable_Generic;
45
use rustc_span::{sym, Symbol};
56
use std::fmt;
@@ -53,10 +54,10 @@ impl RiscVInlineAsmRegClass {
5354

5455
fn not_e(
5556
_arch: InlineAsmArch,
56-
mut has_feature: impl FnMut(Symbol) -> bool,
57+
target_features: &FxHashSet<Symbol>,
5758
_target: &Target,
5859
) -> Result<(), &'static str> {
59-
if has_feature(sym::e) {
60+
if target_features.contains(&sym::e) {
6061
Err("register can't be used with the `e` target feature")
6162
} else {
6263
Ok(())

0 commit comments

Comments
 (0)