mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
only compute codegen_fn_attrs
where needed
This commit is contained in:
parent
66ff6c32e5
commit
d371ebe117
@ -1007,7 +1007,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
|
record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
|
||||||
self.encode_attrs(def_id);
|
self.encode_attrs(def_id);
|
||||||
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
|
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
|
||||||
record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id));
|
if tcx.has_codegen_attrs(def_kind) {
|
||||||
|
record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id));
|
||||||
|
}
|
||||||
if should_encode_visibility(def_kind) {
|
if should_encode_visibility(def_kind) {
|
||||||
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
|
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,9 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CodegenFnAttrs {
|
impl CodegenFnAttrs {
|
||||||
pub fn new() -> CodegenFnAttrs {
|
pub const EMPTY: &'static Self = &Self::new();
|
||||||
|
|
||||||
|
pub const fn new() -> CodegenFnAttrs {
|
||||||
CodegenFnAttrs {
|
CodegenFnAttrs {
|
||||||
flags: CodegenFnAttrFlags::empty(),
|
flags: CodegenFnAttrFlags::empty(),
|
||||||
inline: InlineAttr::None,
|
inline: InlineAttr::None,
|
||||||
|
@ -246,7 +246,8 @@ impl<'tcx> InstanceDef<'tcx> {
|
|||||||
match *self {
|
match *self {
|
||||||
InstanceDef::Item(ty::WithOptConstParam { did: def_id, .. })
|
InstanceDef::Item(ty::WithOptConstParam { did: def_id, .. })
|
||||||
| InstanceDef::Virtual(def_id, _) => {
|
| InstanceDef::Virtual(def_id, _) => {
|
||||||
tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
|
tcx.has_codegen_attrs(tcx.def_kind(def_id))
|
||||||
|
&& tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
|
||||||
}
|
}
|
||||||
InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller,
|
InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller,
|
||||||
_ => false,
|
_ => false,
|
||||||
|
@ -139,6 +139,42 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
hasher.finish()
|
hasher.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_codegen_attrs(self, def_kind: DefKind) -> bool {
|
||||||
|
match def_kind {
|
||||||
|
DefKind::Fn
|
||||||
|
| DefKind::AssocFn
|
||||||
|
| DefKind::Ctor(..)
|
||||||
|
| DefKind::Closure
|
||||||
|
| DefKind::Generator
|
||||||
|
| DefKind::Static(_) => true,
|
||||||
|
DefKind::Mod
|
||||||
|
| DefKind::Struct
|
||||||
|
| DefKind::Union
|
||||||
|
| DefKind::Enum
|
||||||
|
| DefKind::Variant
|
||||||
|
| DefKind::Trait
|
||||||
|
| DefKind::TyAlias
|
||||||
|
| DefKind::ForeignTy
|
||||||
|
| DefKind::TraitAlias
|
||||||
|
| DefKind::AssocTy
|
||||||
|
| DefKind::Const
|
||||||
|
| DefKind::AssocConst
|
||||||
|
| DefKind::Macro(..)
|
||||||
|
| DefKind::Use
|
||||||
|
| DefKind::ForeignMod
|
||||||
|
| DefKind::OpaqueTy
|
||||||
|
| DefKind::Impl
|
||||||
|
| DefKind::Field
|
||||||
|
| DefKind::TyParam
|
||||||
|
| DefKind::ConstParam
|
||||||
|
| DefKind::LifetimeParam
|
||||||
|
| DefKind::AnonConst
|
||||||
|
| DefKind::InlineConst
|
||||||
|
| DefKind::GlobalAsm
|
||||||
|
| DefKind::ExternCrate => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn res_generics_def_id(self, res: Res) -> Option<DefId> {
|
pub fn res_generics_def_id(self, res: Res) -> Option<DefId> {
|
||||||
match res {
|
match res {
|
||||||
Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => {
|
Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => {
|
||||||
|
@ -27,7 +27,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
|
|||||||
body_unsafety: BodyUnsafety,
|
body_unsafety: BodyUnsafety,
|
||||||
/// The `#[target_feature]` attributes of the body. Used for checking
|
/// The `#[target_feature]` attributes of the body. Used for checking
|
||||||
/// calls to functions with `#[target_feature]` (RFC 2396).
|
/// calls to functions with `#[target_feature]` (RFC 2396).
|
||||||
body_target_features: &'tcx Vec<Symbol>,
|
body_target_features: &'tcx [Symbol],
|
||||||
/// When inside the LHS of an assignment to a field, this is the type
|
/// When inside the LHS of an assignment to a field, this is the type
|
||||||
/// of the LHS and the span of the assignment expression.
|
/// of the LHS and the span of the assignment expression.
|
||||||
assignment_info: Option<(Ty<'tcx>, Span)>,
|
assignment_info: Option<(Ty<'tcx>, Span)>,
|
||||||
@ -661,7 +661,11 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
|
|||||||
BodyUnsafety::Safe
|
BodyUnsafety::Safe
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let body_target_features = &tcx.codegen_fn_attrs(def.did).target_features;
|
let body_target_features: &[_] = if tcx.has_codegen_attrs(tcx.def_kind(def.did)) {
|
||||||
|
&tcx.codegen_fn_attrs(def.did).target_features
|
||||||
|
} else {
|
||||||
|
&[]
|
||||||
|
};
|
||||||
let safety_context =
|
let safety_context =
|
||||||
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
|
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
|
||||||
let mut visitor = UnsafetyVisitor {
|
let mut visitor = UnsafetyVisitor {
|
||||||
|
@ -375,7 +375,12 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
|
let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
|
||||||
let self_features = &self.tcx.codegen_fn_attrs(self.body_did).target_features;
|
// Constants don't have codegen attributes, so the body might not have codegen attributes.
|
||||||
|
let self_features: &[_] = if self.tcx.has_codegen_attrs(self.tcx.def_kind(self.body_did)) {
|
||||||
|
&self.tcx.codegen_fn_attrs(self.body_did).target_features
|
||||||
|
} else {
|
||||||
|
&[]
|
||||||
|
};
|
||||||
|
|
||||||
// Is `callee_features` a subset of `calling_features`?
|
// Is `callee_features` a subset of `calling_features`?
|
||||||
if !callee_features.iter().all(|feature| self_features.contains(feature)) {
|
if !callee_features.iter().all(|feature| self_features.contains(feature)) {
|
||||||
|
@ -104,6 +104,9 @@ impl CheckAttrVisitor<'_> {
|
|||||||
sym::rustc_allow_const_fn_unstable => {
|
sym::rustc_allow_const_fn_unstable => {
|
||||||
self.check_rustc_allow_const_fn_unstable(hir_id, &attr, span, target)
|
self.check_rustc_allow_const_fn_unstable(hir_id, &attr, span, target)
|
||||||
}
|
}
|
||||||
|
sym::rustc_std_internal_symbol => {
|
||||||
|
self.check_rustc_std_internal_symbol(&attr, span, target)
|
||||||
|
}
|
||||||
sym::naked => self.check_naked(hir_id, attr, span, target),
|
sym::naked => self.check_naked(hir_id, attr, span, target),
|
||||||
sym::rustc_legacy_const_generics => {
|
sym::rustc_legacy_const_generics => {
|
||||||
self.check_rustc_legacy_const_generics(&attr, span, target, item)
|
self.check_rustc_legacy_const_generics(&attr, span, target, item)
|
||||||
@ -193,6 +196,7 @@ impl CheckAttrVisitor<'_> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME(@lcnr): this doesn't belong here.
|
||||||
if matches!(target, Target::Closure | Target::Fn | Target::Method(_) | Target::ForeignFn) {
|
if matches!(target, Target::Closure | Target::Fn | Target::Method(_) | Target::ForeignFn) {
|
||||||
self.tcx.ensure().codegen_fn_attrs(self.tcx.hir().local_def_id(hir_id));
|
self.tcx.ensure().codegen_fn_attrs(self.tcx.hir().local_def_id(hir_id));
|
||||||
}
|
}
|
||||||
@ -1659,7 +1663,7 @@ impl CheckAttrVisitor<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sym::align => {
|
sym::align => {
|
||||||
if let (Target::Fn, true) = (target, !self.tcx.features().fn_align) {
|
if let (Target::Fn, false) = (target, self.tcx.features().fn_align) {
|
||||||
feature_err(
|
feature_err(
|
||||||
&self.tcx.sess.parse_sess,
|
&self.tcx.sess.parse_sess,
|
||||||
sym::fn_align,
|
sym::fn_align,
|
||||||
@ -1980,6 +1984,25 @@ impl CheckAttrVisitor<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_rustc_std_internal_symbol(
|
||||||
|
&self,
|
||||||
|
attr: &Attribute,
|
||||||
|
span: Span,
|
||||||
|
target: Target,
|
||||||
|
) -> bool {
|
||||||
|
match target {
|
||||||
|
Target::Fn | Target::Static => true,
|
||||||
|
_ => {
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.struct_span_err(attr.span, "attribute should be applied functions or statics")
|
||||||
|
.span_label(span, "not a function or static")
|
||||||
|
.emit();
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// default_method_body_is_const should only be applied to trait methods with default bodies.
|
/// default_method_body_is_const should only be applied to trait methods with default bodies.
|
||||||
fn check_default_method_body_is_const(
|
fn check_default_method_body_is_const(
|
||||||
&self,
|
&self,
|
||||||
|
@ -452,15 +452,17 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let def_id = tcx.hir().local_def_id(id);
|
let def_id = tcx.hir().local_def_id(id);
|
||||||
let cg_attrs = tcx.codegen_fn_attrs(def_id);
|
if tcx.has_codegen_attrs(tcx.def_kind(def_id)) {
|
||||||
|
let cg_attrs = tcx.codegen_fn_attrs(def_id);
|
||||||
|
|
||||||
// #[used], #[no_mangle], #[export_name], etc also keeps the item alive
|
// #[used], #[no_mangle], #[export_name], etc also keeps the item alive
|
||||||
// forcefully, e.g., for placing it in a specific section.
|
// forcefully, e.g., for placing it in a specific section.
|
||||||
if cg_attrs.contains_extern_indicator()
|
if cg_attrs.contains_extern_indicator()
|
||||||
|| cg_attrs.flags.contains(CodegenFnAttrFlags::USED)
|
|| cg_attrs.flags.contains(CodegenFnAttrFlags::USED)
|
||||||
|| cg_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
|
|| cg_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
|
tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
|
||||||
|
@ -208,7 +208,11 @@ impl<'tcx> ReachableContext<'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
let codegen_attrs = self.tcx.codegen_fn_attrs(search_item);
|
let codegen_attrs = if self.tcx.has_codegen_attrs(self.tcx.def_kind(search_item)) {
|
||||||
|
self.tcx.codegen_fn_attrs(search_item)
|
||||||
|
} else {
|
||||||
|
CodegenFnAttrs::EMPTY
|
||||||
|
};
|
||||||
let is_extern = codegen_attrs.contains_extern_indicator();
|
let is_extern = codegen_attrs.contains_extern_indicator();
|
||||||
let std_internal =
|
let std_internal =
|
||||||
codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
|
codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
|
||||||
@ -329,16 +333,18 @@ impl CollectPrivateImplItemsVisitor<'_, '_> {
|
|||||||
// Anything which has custom linkage gets thrown on the worklist no
|
// Anything which has custom linkage gets thrown on the worklist no
|
||||||
// matter where it is in the crate, along with "special std symbols"
|
// matter where it is in the crate, along with "special std symbols"
|
||||||
// which are currently akin to allocator symbols.
|
// which are currently akin to allocator symbols.
|
||||||
let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
|
if self.tcx.has_codegen_attrs(self.tcx.def_kind(def_id)) {
|
||||||
if codegen_attrs.contains_extern_indicator()
|
let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
|
||||||
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
if codegen_attrs.contains_extern_indicator()
|
||||||
// FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by
|
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
|
||||||
// `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their
|
// FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by
|
||||||
// `SymbolExportLevel::Rust` export level but may end up being exported in dylibs.
|
// `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their
|
||||||
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED)
|
// `SymbolExportLevel::Rust` export level but may end up being exported in dylibs.
|
||||||
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
|
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED)
|
||||||
{
|
|| codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
|
||||||
self.worklist.push(def_id);
|
{
|
||||||
|
self.worklist.push(def_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,8 +96,10 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc_middle;
|
extern crate rustc_middle;
|
||||||
|
|
||||||
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
|
||||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
|
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||||
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
|
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
@ -175,7 +177,11 @@ fn compute_symbol_name<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
|
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
|
||||||
let attrs = tcx.codegen_fn_attrs(def_id);
|
let attrs = if tcx.has_codegen_attrs(tcx.def_kind(def_id)) {
|
||||||
|
tcx.codegen_fn_attrs(def_id)
|
||||||
|
} else {
|
||||||
|
CodegenFnAttrs::EMPTY
|
||||||
|
};
|
||||||
|
|
||||||
// Foreign items by default use no mangling for their symbol name. There's a
|
// Foreign items by default use no mangling for their symbol name. There's a
|
||||||
// few exceptions to this rule though:
|
// few exceptions to this rule though:
|
||||||
@ -213,20 +219,25 @@ fn compute_symbol_name<'tcx>(
|
|||||||
return tcx.item_name(def_id).to_string();
|
return tcx.item_name(def_id).to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
let avoid_cross_crate_conflicts =
|
// If we're dealing with an instance of a function that's inlined from
|
||||||
// If this is an instance of a generic function, we also hash in
|
// another crate but we're marking it as globally shared to our
|
||||||
// the ID of the instantiating crate. This avoids symbol conflicts
|
// compilation (aka we're not making an internal copy in each of our
|
||||||
// in case the same instances is emitted in two crates of the same
|
// codegen units) then this symbol may become an exported (but hidden
|
||||||
// project.
|
// visibility) symbol. This means that multiple crates may do the same
|
||||||
is_generic(substs) ||
|
// and we want to be sure to avoid any symbol conflicts here.
|
||||||
|
let is_globally_shared_function = matches!(
|
||||||
|
tcx.def_kind(instance.def_id()),
|
||||||
|
DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator | DefKind::Ctor(..)
|
||||||
|
) && matches!(
|
||||||
|
MonoItem::Fn(instance).instantiation_mode(tcx),
|
||||||
|
InstantiationMode::GloballyShared { may_conflict: true }
|
||||||
|
);
|
||||||
|
|
||||||
// If we're dealing with an instance of a function that's inlined from
|
// If this is an instance of a generic function, we also hash in
|
||||||
// another crate but we're marking it as globally shared to our
|
// the ID of the instantiating crate. This avoids symbol conflicts
|
||||||
// compilation (aka we're not making an internal copy in each of our
|
// in case the same instances is emitted in two crates of the same
|
||||||
// codegen units) then this symbol may become an exported (but hidden
|
// project.
|
||||||
// visibility) symbol. This means that multiple crates may do the same
|
let avoid_cross_crate_conflicts = is_generic(substs) || is_globally_shared_function;
|
||||||
// and we want to be sure to avoid any symbol conflicts here.
|
|
||||||
matches!(MonoItem::Fn(instance).instantiation_mode(tcx), InstantiationMode::GloballyShared { may_conflict: true });
|
|
||||||
|
|
||||||
let instantiating_crate =
|
let instantiating_crate =
|
||||||
if avoid_cross_crate_conflicts { Some(compute_instantiating_crate()) } else { None };
|
if avoid_cross_crate_conflicts { Some(compute_instantiating_crate()) } else { None };
|
||||||
|
@ -2720,6 +2720,14 @@ fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
|
let def_kind = tcx.def_kind(did);
|
||||||
|
assert!(
|
||||||
|
tcx.has_codegen_attrs(def_kind),
|
||||||
|
"unexpected `def_kind` in `codegen_fn_attrs`: {def_kind:?}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let did = did.expect_local();
|
let did = did.expect_local();
|
||||||
let attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(did));
|
let attrs = tcx.hir().attrs(tcx.hir().local_def_id_to_hir_id(did));
|
||||||
let mut codegen_fn_attrs = CodegenFnAttrs::new();
|
let mut codegen_fn_attrs = CodegenFnAttrs::new();
|
||||||
@ -3223,19 +3231,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
|
|||||||
|
|
||||||
/// Computes the set of target features used in a function for the purposes of
|
/// Computes the set of target features used in a function for the purposes of
|
||||||
/// inline assembly.
|
/// inline assembly.
|
||||||
fn asm_target_features<'tcx>(tcx: TyCtxt<'tcx>, id: DefId) -> &'tcx FxHashSet<Symbol> {
|
fn asm_target_features<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx FxHashSet<Symbol> {
|
||||||
let mut target_features = tcx.sess.target_features.clone();
|
let mut target_features = tcx.sess.target_features.clone();
|
||||||
let attrs = tcx.codegen_fn_attrs(id);
|
if tcx.has_codegen_attrs(tcx.def_kind(did)) {
|
||||||
target_features.extend(&attrs.target_features);
|
let attrs = tcx.codegen_fn_attrs(did);
|
||||||
match attrs.instruction_set {
|
target_features.extend(&attrs.target_features);
|
||||||
None => {}
|
match attrs.instruction_set {
|
||||||
Some(InstructionSetAttr::ArmA32) => {
|
None => {}
|
||||||
target_features.remove(&sym::thumb_mode);
|
Some(InstructionSetAttr::ArmA32) => {
|
||||||
}
|
target_features.remove(&sym::thumb_mode);
|
||||||
Some(InstructionSetAttr::ArmT32) => {
|
}
|
||||||
target_features.insert(sym::thumb_mode);
|
Some(InstructionSetAttr::ArmT32) => {
|
||||||
|
target_features.insert(sym::thumb_mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tcx.arena.alloc(target_features)
|
tcx.arena.alloc(target_features)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user