From 042aa379a5cf6f6148664b74c9ebdf88ad8a5c1d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 10 Jan 2022 15:48:05 +0100 Subject: [PATCH] Pass target_features set instead of has_feature closure This avoids unnecessary monomorphizations in codegen backends --- compiler/rustc_ast_lowering/src/asm.rs | 4 +- .../rustc_codegen_cranelift/src/inline_asm.rs | 8 +-- compiler/rustc_target/src/asm/aarch64.rs | 3 +- compiler/rustc_target/src/asm/arm.rs | 23 ++++--- compiler/rustc_target/src/asm/bpf.rs | 5 +- compiler/rustc_target/src/asm/mod.rs | 68 +++++++++---------- compiler/rustc_target/src/asm/riscv.rs | 5 +- compiler/rustc_target/src/asm/x86.rs | 9 +-- 8 files changed, 63 insertions(+), 62 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 16a9631f846..89d411d4b36 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -66,7 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { for (abi_name, abi_span) in &asm.clobber_abis { match asm::InlineAsmClobberAbi::parse( asm_arch, - |feature| self.sess.target_features.contains(&feature), + &self.sess.target_features, &self.sess.target, *abi_name, ) { @@ -134,7 +134,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch { asm::InlineAsmReg::parse( asm_arch, - |feature| sess.target_features.contains(&feature), + &sess.target_features, &sess.target, s, ) diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index be39dbd2e2a..c242c75ed18 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -182,11 +182,7 @@ struct InlineAssemblyGenerator<'a, 'tcx> { impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { fn allocate_registers(&mut self) { let sess = self.tcx.sess; - let map = allocatable_registers( - self.arch, - |feature| sess.target_features.contains(&feature), - &sess.target, - ); + let map = allocatable_registers(self.arch, &sess.target_features, &sess.target); let mut allocated = FxHashMap::<_, (bool, bool)>::default(); let mut regs = vec![None; self.operands.len()]; @@ -319,7 +315,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Allocate stack slots for saving clobbered registers let abi_clobber = InlineAsmClobberAbi::parse( self.arch, - |feature| self.tcx.sess.target_features.contains(&feature), + &self.tcx.sess.target_features, &self.tcx.sess.target, sym::C, ) diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index 2415b16d782..da875508676 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -1,5 +1,6 @@ use super::{InlineAsmArch, InlineAsmType}; use crate::spec::Target; +use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; @@ -74,7 +75,7 @@ impl AArch64InlineAsmRegClass { pub fn reserved_x18( _arch: InlineAsmArch, - _has_feature: impl FnMut(Symbol) -> bool, + _target_features: &FxHashSet, target: &Target, ) -> Result<(), &'static str> { if target.os == "android" diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 83782206735..e3615b43c70 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -1,5 +1,6 @@ use super::{InlineAsmArch, InlineAsmType}; use crate::spec::Target; +use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; use std::fmt; @@ -60,16 +61,16 @@ impl ArmInlineAsmRegClass { } // This uses the same logic as useR7AsFramePointer in LLVM -fn frame_pointer_is_r7(mut has_feature: impl FnMut(Symbol) -> bool, target: &Target) -> bool { - target.is_like_osx || (!target.is_like_windows && has_feature(sym::thumb_mode)) +fn frame_pointer_is_r7(target_features: &FxHashSet, target: &Target) -> bool { + target.is_like_osx || (!target.is_like_windows && target_features.contains(&sym::thumb_mode)) } fn frame_pointer_r11( _arch: InlineAsmArch, - has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, target: &Target, ) -> Result<(), &'static str> { - if !frame_pointer_is_r7(has_feature, target) { + if !frame_pointer_is_r7(target_features, target) { Err("the frame pointer (r11) cannot be used as an operand for inline asm") } else { Ok(()) @@ -78,10 +79,10 @@ fn frame_pointer_r11( fn frame_pointer_r7( _arch: InlineAsmArch, - has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, target: &Target, ) -> Result<(), &'static str> { - if frame_pointer_is_r7(has_feature, target) { + if frame_pointer_is_r7(target_features, target) { Err("the frame pointer (r7) cannot be used as an operand for inline asm") } else { Ok(()) @@ -90,10 +91,10 @@ fn frame_pointer_r7( fn not_thumb1( _arch: InlineAsmArch, - mut has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, _target: &Target, ) -> Result<(), &'static str> { - if has_feature(sym::thumb_mode) && !has_feature(sym::thumb2) { + if target_features.contains(&sym::thumb_mode) && !target_features.contains(&sym::thumb2) { Err("high registers (r8+) cannot be used in Thumb-1 code") } else { Ok(()) @@ -102,14 +103,14 @@ fn not_thumb1( fn reserved_r9( arch: InlineAsmArch, - mut has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, target: &Target, ) -> Result<(), &'static str> { - not_thumb1(arch, &mut has_feature, target)?; + not_thumb1(arch, target_features, target)?; // We detect this using the reserved-r9 feature instead of using the target // because the relocation model can be changed with compiler options. - if has_feature(sym::reserved_r9) { + if target_features.contains(&sym::reserved_r9) { Err("the RWPI static base register (r9) cannot be used as an operand for inline asm") } else { Ok(()) diff --git a/compiler/rustc_target/src/asm/bpf.rs b/compiler/rustc_target/src/asm/bpf.rs index f9a68731282..d94fcb53e24 100644 --- a/compiler/rustc_target/src/asm/bpf.rs +++ b/compiler/rustc_target/src/asm/bpf.rs @@ -1,4 +1,5 @@ use super::{InlineAsmArch, InlineAsmType, Target}; +use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; use std::fmt; @@ -44,10 +45,10 @@ impl BpfInlineAsmRegClass { fn only_alu32( _arch: InlineAsmArch, - mut has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, _target: &Target, ) -> Result<(), &'static str> { - if !has_feature(sym::alu32) { + if !target_features.contains(&sym::alu32) { Err("register can't be used without the `alu32` target feature") } else { Ok(()) diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 33053089aa8..6b82bb337e6 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -81,14 +81,14 @@ macro_rules! def_regs { pub fn parse( _arch: super::InlineAsmArch, - mut _has_feature: impl FnMut(rustc_span::Symbol) -> bool, + _target_features: &rustc_data_structures::fx::FxHashSet, _target: &crate::spec::Target, name: &str, ) -> Result { match name { $( $($alias)|* | $reg_name => { - $($filter(_arch, &mut _has_feature, _target)?;)? + $($filter(_arch, _target_features, _target)?;)? Ok(Self::$reg) } )* @@ -102,7 +102,7 @@ macro_rules! def_regs { pub(super) fn fill_reg_map( _arch: super::InlineAsmArch, - mut _has_feature: impl FnMut(rustc_span::Symbol) -> bool, + _target_features: &rustc_data_structures::fx::FxHashSet, _target: &crate::spec::Target, _map: &mut rustc_data_structures::fx::FxHashMap< super::InlineAsmRegClass, @@ -112,7 +112,7 @@ macro_rules! def_regs { #[allow(unused_imports)] use super::{InlineAsmReg, InlineAsmRegClass}; $( - if $($filter(_arch, &mut _has_feature, _target).is_ok() &&)? true { + if $($filter(_arch, _target_features, _target).is_ok() &&)? true { if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) { set.insert(InlineAsmReg::$arch($arch_reg::$reg)); } @@ -289,7 +289,7 @@ impl InlineAsmReg { pub fn parse( arch: InlineAsmArch, - has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, target: &Target, name: Symbol, ) -> Result { @@ -298,43 +298,43 @@ impl InlineAsmReg { let name = name.as_str(); Ok(match arch { InlineAsmArch::X86 | InlineAsmArch::X86_64 => { - Self::X86(X86InlineAsmReg::parse(arch, has_feature, target, name)?) + Self::X86(X86InlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::Arm => { - Self::Arm(ArmInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::Arm(ArmInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::AArch64 => { - Self::AArch64(AArch64InlineAsmReg::parse(arch, has_feature, target, name)?) + Self::AArch64(AArch64InlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { - Self::RiscV(RiscVInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::RiscV(RiscVInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::Nvptx64 => { - Self::Nvptx(NvptxInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::Nvptx(NvptxInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => { - Self::PowerPC(PowerPCInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::PowerPC(PowerPCInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::Hexagon => { - Self::Hexagon(HexagonInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::Hexagon(HexagonInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::Mips | InlineAsmArch::Mips64 => { - Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::Mips(MipsInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::S390x => { - Self::S390x(S390xInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::S390x(S390xInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::SpirV => { - Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::SpirV(SpirVInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => { - Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::Wasm(WasmInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::Bpf => { - Self::Bpf(BpfInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::Bpf(BpfInlineAsmReg::parse(arch, target_features, target, name)?) } InlineAsmArch::Avr => { - Self::Avr(AvrInlineAsmReg::parse(arch, has_feature, target, name)?) + Self::Avr(AvrInlineAsmReg::parse(arch, target_features, target, name)?) } }) } @@ -695,73 +695,73 @@ impl fmt::Display for InlineAsmType { // falling back to an external assembler. pub fn allocatable_registers( arch: InlineAsmArch, - has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, target: &crate::spec::Target, ) -> FxHashMap> { match arch { InlineAsmArch::X86 | InlineAsmArch::X86_64 => { let mut map = x86::regclass_map(); - x86::fill_reg_map(arch, has_feature, target, &mut map); + x86::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::Arm => { let mut map = arm::regclass_map(); - arm::fill_reg_map(arch, has_feature, target, &mut map); + arm::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::AArch64 => { let mut map = aarch64::regclass_map(); - aarch64::fill_reg_map(arch, has_feature, target, &mut map); + aarch64::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { let mut map = riscv::regclass_map(); - riscv::fill_reg_map(arch, has_feature, target, &mut map); + riscv::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::Nvptx64 => { let mut map = nvptx::regclass_map(); - nvptx::fill_reg_map(arch, has_feature, target, &mut map); + nvptx::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => { let mut map = powerpc::regclass_map(); - powerpc::fill_reg_map(arch, has_feature, target, &mut map); + powerpc::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::Hexagon => { let mut map = hexagon::regclass_map(); - hexagon::fill_reg_map(arch, has_feature, target, &mut map); + hexagon::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::Mips | InlineAsmArch::Mips64 => { let mut map = mips::regclass_map(); - mips::fill_reg_map(arch, has_feature, target, &mut map); + mips::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::S390x => { let mut map = s390x::regclass_map(); - s390x::fill_reg_map(arch, has_feature, target, &mut map); + s390x::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::SpirV => { let mut map = spirv::regclass_map(); - spirv::fill_reg_map(arch, has_feature, target, &mut map); + spirv::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => { let mut map = wasm::regclass_map(); - wasm::fill_reg_map(arch, has_feature, target, &mut map); + wasm::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::Bpf => { let mut map = bpf::regclass_map(); - bpf::fill_reg_map(arch, has_feature, target, &mut map); + bpf::fill_reg_map(arch, target_features, target, &mut map); map } InlineAsmArch::Avr => { let mut map = avr::regclass_map(); - avr::fill_reg_map(arch, has_feature, target, &mut map); + avr::fill_reg_map(arch, target_features, target, &mut map); map } } @@ -794,7 +794,7 @@ impl InlineAsmClobberAbi { /// clobber ABIs for the target. pub fn parse( arch: InlineAsmArch, - has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, target: &Target, name: Symbol, ) -> Result { @@ -819,7 +819,7 @@ impl InlineAsmClobberAbi { }, InlineAsmArch::AArch64 => match name { "C" | "system" | "efiapi" => { - Ok(if aarch64::reserved_x18(arch, has_feature, target).is_err() { + Ok(if aarch64::reserved_x18(arch, target_features, target).is_err() { InlineAsmClobberAbi::AArch64NoX18 } else { InlineAsmClobberAbi::AArch64 diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index 391b34aa05c..39644d232ba 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -1,5 +1,6 @@ use super::{InlineAsmArch, InlineAsmType}; use crate::spec::Target; +use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; use std::fmt; @@ -53,10 +54,10 @@ impl RiscVInlineAsmRegClass { fn not_e( _arch: InlineAsmArch, - mut has_feature: impl FnMut(Symbol) -> bool, + target_features: &FxHashSet, _target: &Target, ) -> Result<(), &'static str> { - if has_feature(sym::e) { + if target_features.contains(&sym::e) { Err("register can't be used with the `e` target feature") } else { Ok(()) diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index e77eb71e670..01d32570f78 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -1,5 +1,6 @@ use super::{InlineAsmArch, InlineAsmType}; use crate::spec::Target; +use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::Symbol; use std::fmt; @@ -138,7 +139,7 @@ impl X86InlineAsmRegClass { fn x86_64_only( arch: InlineAsmArch, - _has_feature: impl FnMut(Symbol) -> bool, + _target_features: &FxHashSet, _target: &Target, ) -> Result<(), &'static str> { match arch { @@ -150,7 +151,7 @@ fn x86_64_only( fn high_byte( arch: InlineAsmArch, - _has_feature: impl FnMut(Symbol) -> bool, + _target_features: &FxHashSet, _target: &Target, ) -> Result<(), &'static str> { match arch { @@ -161,7 +162,7 @@ fn high_byte( fn rbx_reserved( arch: InlineAsmArch, - _has_feature: impl FnMut(Symbol) -> bool, + _target_features: &FxHashSet, _target: &Target, ) -> Result<(), &'static str> { match arch { @@ -175,7 +176,7 @@ fn rbx_reserved( fn esi_reserved( arch: InlineAsmArch, - _has_feature: impl FnMut(Symbol) -> bool, + _target_features: &FxHashSet, _target: &Target, ) -> Result<(), &'static str> { match arch {