Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d371ebe1
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d371ebe1
编写于
5月 04, 2022
作者:
L
lcnr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
only compute `codegen_fn_attrs` where needed
上级
66ff6c32
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
154 addition
and
51 deletion
+154
-51
compiler/rustc_metadata/src/rmeta/encoder.rs
compiler/rustc_metadata/src/rmeta/encoder.rs
+3
-1
compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+3
-1
compiler/rustc_middle/src/ty/instance.rs
compiler/rustc_middle/src/ty/instance.rs
+2
-1
compiler/rustc_middle/src/ty/util.rs
compiler/rustc_middle/src/ty/util.rs
+36
-0
compiler/rustc_mir_build/src/check_unsafety.rs
compiler/rustc_mir_build/src/check_unsafety.rs
+6
-2
compiler/rustc_mir_transform/src/check_unsafety.rs
compiler/rustc_mir_transform/src/check_unsafety.rs
+6
-1
compiler/rustc_passes/src/check_attr.rs
compiler/rustc_passes/src/check_attr.rs
+24
-1
compiler/rustc_passes/src/dead.rs
compiler/rustc_passes/src/dead.rs
+11
-9
compiler/rustc_passes/src/reachable.rs
compiler/rustc_passes/src/reachable.rs
+17
-11
compiler/rustc_symbol_mangling/src/lib.rs
compiler/rustc_symbol_mangling/src/lib.rs
+25
-14
compiler/rustc_typeck/src/collect.rs
compiler/rustc_typeck/src/collect.rs
+21
-10
未找到文件。
compiler/rustc_metadata/src/rmeta/encoder.rs
浏览文件 @
d371ebe1
...
...
@@ -1007,7 +1007,9 @@ fn encode_def_ids(&mut self) {
record!
(
self
.tables.def_span
[
def_id
]
<-
tcx
.def_span
(
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.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
)
{
record!
(
self
.tables.visibility
[
def_id
]
<-
self
.tcx
.visibility
(
def_id
));
}
...
...
compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
浏览文件 @
d371ebe1
...
...
@@ -95,7 +95,9 @@ pub struct CodegenFnAttrFlags: u32 {
}
impl
CodegenFnAttrs
{
pub
fn
new
()
->
CodegenFnAttrs
{
pub
const
EMPTY
:
&
'static
Self
=
&
Self
::
new
();
pub
const
fn
new
()
->
CodegenFnAttrs
{
CodegenFnAttrs
{
flags
:
CodegenFnAttrFlags
::
empty
(),
inline
:
InlineAttr
::
None
,
...
...
compiler/rustc_middle/src/ty/instance.rs
浏览文件 @
d371ebe1
...
...
@@ -246,7 +246,8 @@ pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool {
match
*
self
{
InstanceDef
::
Item
(
ty
::
WithOptConstParam
{
did
:
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
,
_
=>
false
,
...
...
compiler/rustc_middle/src/ty/util.rs
浏览文件 @
d371ebe1
...
...
@@ -139,6 +139,42 @@ pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
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
>
{
match
res
{
Res
::
Def
(
DefKind
::
Ctor
(
CtorOf
::
Variant
,
_
),
def_id
)
=>
{
...
...
compiler/rustc_mir_build/src/check_unsafety.rs
浏览文件 @
d371ebe1
...
...
@@ -27,7 +27,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
body_unsafety
:
BodyUnsafety
,
/// The `#[target_feature]` attributes of the body. Used for checking
/// 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
/// of the LHS and the span of the assignment expression.
assignment_info
:
Option
<
(
Ty
<
'tcx
>
,
Span
)
>
,
...
...
@@ -661,7 +661,11 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
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
=
if
body_unsafety
.is_unsafe
()
{
SafetyContext
::
UnsafeFn
}
else
{
SafetyContext
::
Safe
};
let
mut
visitor
=
UnsafetyVisitor
{
...
...
compiler/rustc_mir_transform/src/check_unsafety.rs
浏览文件 @
d371ebe1
...
...
@@ -375,7 +375,12 @@ fn check_target_features(&mut self, func_did: DefId) {
}
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`?
if
!
callee_features
.iter
()
.all
(|
feature
|
self_features
.contains
(
feature
))
{
...
...
compiler/rustc_passes/src/check_attr.rs
浏览文件 @
d371ebe1
...
...
@@ -104,6 +104,9 @@ fn check_attributes(
sym
::
rustc_allow_const_fn_unstable
=>
{
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
::
rustc_legacy_const_generics
=>
{
self
.check_rustc_legacy_const_generics
(
&
attr
,
span
,
target
,
item
)
...
...
@@ -193,6 +196,7 @@ fn check_attributes(
return
;
}
// FIXME(@lcnr): this doesn't belong here.
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
));
}
...
...
@@ -1659,7 +1663,7 @@ fn check_repr(
}
}
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
(
&
self
.tcx.sess.parse_sess
,
sym
::
fn_align
,
...
...
@@ -1980,6 +1984,25 @@ fn check_rustc_allow_const_fn_unstable(
}
}
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.
fn
check_default_method_body_is_const
(
&
self
,
...
...
compiler/rustc_passes/src/dead.rs
浏览文件 @
d371ebe1
...
...
@@ -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
cg_attrs
=
tcx
.codegen_fn_attrs
(
def_id
);
// #[used], #[no_mangle], #[export_name], etc also keeps the item alive
// forcefully, e.g., for placing it in a specific section.
if
cg_attrs
.contains_extern_indicator
()
||
cg_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
USED
)
||
cg_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
USED_LINKER
)
{
return
true
;
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
// forcefully, e.g., for placing it in a specific section.
if
cg_attrs
.contains_extern_indicator
()
||
cg_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
USED
)
||
cg_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
USED_LINKER
)
{
return
true
;
}
}
tcx
.lint_level_at_node
(
lint
::
builtin
::
DEAD_CODE
,
id
)
.0
==
lint
::
Allow
...
...
compiler/rustc_passes/src/reachable.rs
浏览文件 @
d371ebe1
...
...
@@ -208,7 +208,11 @@ fn propagate_node(&mut self, node: &Node<'tcx>, search_item: LocalDefId) {
}
else
{
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
std_internal
=
codegen_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
RUSTC_STD_INTERNAL_SYMBOL
);
...
...
@@ -329,16 +333,18 @@ fn push_to_worklist_if_has_custom_linkage(&mut self, def_id: LocalDefId) {
// Anything which has custom linkage gets thrown on the worklist no
// matter where it is in the crate, along with "special std symbols"
// which are currently akin to allocator symbols.
let
codegen_attrs
=
self
.tcx
.codegen_fn_attrs
(
def_id
);
if
codegen_attrs
.contains_extern_indicator
()
||
codegen_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
RUSTC_STD_INTERNAL_SYMBOL
)
// FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by
// `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their
// `SymbolExportLevel::Rust` export level but may end up being exported in dylibs.
||
codegen_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
USED
)
||
codegen_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
USED_LINKER
)
{
self
.worklist
.push
(
def_id
);
if
self
.tcx
.has_codegen_attrs
(
self
.tcx
.def_kind
(
def_id
))
{
let
codegen_attrs
=
self
.tcx
.codegen_fn_attrs
(
def_id
);
if
codegen_attrs
.contains_extern_indicator
()
||
codegen_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
RUSTC_STD_INTERNAL_SYMBOL
)
// FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by
// `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their
// `SymbolExportLevel::Rust` export level but may end up being exported in dylibs.
||
codegen_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
USED
)
||
codegen_attrs
.flags
.contains
(
CodegenFnAttrFlags
::
USED_LINKER
)
{
self
.worklist
.push
(
def_id
);
}
}
}
}
...
...
compiler/rustc_symbol_mangling/src/lib.rs
浏览文件 @
d371ebe1
...
...
@@ -96,8 +96,10 @@
#[macro_use]
extern
crate
rustc_middle
;
use
rustc_hir
::
def
::
DefKind
;
use
rustc_hir
::
def_id
::{
CrateNum
,
LOCAL_CRATE
};
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
::
ty
::
query
::
Providers
;
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.
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
// few exceptions to this rule though:
...
...
@@ -213,20 +219,25 @@ fn compute_symbol_name<'tcx>(
return
tcx
.item_name
(
def_id
)
.to_string
();
}
let
avoid_cross_crate_conflicts
=
// If this is an instance of a generic function, we also hash in
// the ID of the instantiating crate. This avoids symbol conflicts
// in case the same instances is emitted in two crates of the same
// project.
is_generic
(
substs
)
||
// If we're dealing with an instance of a function that's inlined from
// another crate but we're marking it as globally shared to our
// compilation (aka we're not making an internal copy in each of our
// codegen units) then this symbol may become an exported (but hidden
// visibility) symbol. This means that multiple crates may do the same
// 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
// another crate but we're marking it as globally shared to our
// compilation (aka we're not making an internal copy in each of our
// codegen units) then this symbol may become an exported (but hidden
// visibility) symbol. This means that multiple crates may do the same
// and we want to be sure to avoid any symbol conflicts here.
matches!
(
MonoItem
::
Fn
(
instance
)
.instantiation_mode
(
tcx
),
InstantiationMode
::
GloballyShared
{
may_conflict
:
true
});
// If this is an instance of a generic function, we also hash in
// the ID of the instantiating crate. This avoids symbol conflicts
// in case the same instances is emitted in two crates of the same
// project.
let
avoid_cross_crate_conflicts
=
is_generic
(
substs
)
||
is_globally_shared_function
;
let
instantiating_crate
=
if
avoid_cross_crate_conflicts
{
Some
(
compute_instantiating_crate
())
}
else
{
None
};
...
...
compiler/rustc_typeck/src/collect.rs
浏览文件 @
d371ebe1
...
...
@@ -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
{
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
attrs
=
tcx
.hir
()
.attrs
(
tcx
.hir
()
.local_def_id_to_hir_id
(
did
));
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
/// inline assembly.
fn
asm_target_features
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
id
:
DefId
)
->
&
'tcx
FxHashSet
<
Symbol
>
{
fn
asm_target_features
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
d
id
:
DefId
)
->
&
'tcx
FxHashSet
<
Symbol
>
{
let
mut
target_features
=
tcx
.sess.target_features
.clone
();
let
attrs
=
tcx
.codegen_fn_attrs
(
id
);
target_features
.extend
(
&
attrs
.target_features
);
match
attrs
.instruction_set
{
None
=>
{}
Some
(
InstructionSetAttr
::
ArmA32
)
=>
{
target_features
.remove
(
&
sym
::
thumb_mode
);
}
Some
(
InstructionSetAttr
::
ArmT32
)
=>
{
target_features
.insert
(
sym
::
thumb_mode
);
if
tcx
.has_codegen_attrs
(
tcx
.def_kind
(
did
))
{
let
attrs
=
tcx
.codegen_fn_attrs
(
did
);
target_features
.extend
(
&
attrs
.target_features
);
match
attrs
.instruction_set
{
None
=>
{}
Some
(
InstructionSetAttr
::
ArmA32
)
=>
{
target_features
.remove
(
&
sym
::
thumb_mode
);
}
Some
(
InstructionSetAttr
::
ArmT32
)
=>
{
target_features
.insert
(
sym
::
thumb_mode
);
}
}
}
tcx
.arena
.alloc
(
target_features
)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录