Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
0b958790
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,发现更多精彩内容 >>
提交
0b958790
编写于
4月 24, 2020
作者:
B
bors
浏览文件
操作
浏览文件
下载
差异文件
Auto merge of #70820 - spastorino:replace-fragile-erroneous-const-sys, r=oli-obk
Replace fragile erroneous const sys Closes #67191 r? @oli-obk
上级
5a595275
7bc45f6b
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
133 addition
and
82 deletion
+133
-82
src/librustc_codegen_ssa/mir/mod.rs
src/librustc_codegen_ssa/mir/mod.rs
+14
-0
src/librustc_middle/mir/mod.rs
src/librustc_middle/mir/mod.rs
+7
-1
src/librustc_middle/mir/visit.rs
src/librustc_middle/mir/visit.rs
+5
-0
src/librustc_mir/transform/const_prop.rs
src/librustc_mir/transform/const_prop.rs
+6
-0
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/inline.rs
+11
-1
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/mod.rs
+12
-1
src/librustc_mir/transform/required_consts.rs
src/librustc_mir/transform/required_consts.rs
+23
-0
src/librustc_mir/transform/simplify.rs
src/librustc_mir/transform/simplify.rs
+10
-25
src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir
...pt/const_allocation2/32bit/rustc.main.ConstProp.after.mir
+15
-15
src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir
...pt/const_allocation2/64bit/rustc.main.ConstProp.after.mir
+16
-16
src/test/mir-opt/remove-never-const.rs
src/test/mir-opt/remove-never-const.rs
+3
-2
src/test/mir-opt/remove-never-const/rustc.no_codegen.PreCodegen.after.mir
.../remove-never-const/rustc.no_codegen.PreCodegen.after.mir
+11
-0
src/test/mir-opt/retain-never-const/rustc.no_codegen.PreCodegen.after.mir
.../retain-never-const/rustc.no_codegen.PreCodegen.after.mir
+0
-21
未找到文件。
src/librustc_codegen_ssa/mir/mod.rs
浏览文件 @
0b958790
use
crate
::
base
;
use
crate
::
traits
::
*
;
use
rustc_errors
::
ErrorReported
;
use
rustc_middle
::
mir
;
use
rustc_middle
::
mir
::
interpret
::
ErrorHandled
;
use
rustc_middle
::
ty
::
layout
::{
FnAbiExt
,
HasTyCtxt
,
TyAndLayout
};
use
rustc_middle
::
ty
::{
self
,
Instance
,
Ty
,
TypeFoldable
};
use
rustc_target
::
abi
::
call
::{
FnAbi
,
PassMode
};
...
...
@@ -189,6 +191,18 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx
.per_local_var_debug_info
=
fx
.compute_per_local_var_debug_info
();
for
const_
in
&
mir
.required_consts
{
if
let
Err
(
err
)
=
fx
.eval_mir_constant
(
const_
)
{
match
err
{
// errored or at least linted
ErrorHandled
::
Reported
(
ErrorReported
)
|
ErrorHandled
::
Linted
=>
{}
ErrorHandled
::
TooGeneric
=>
{
span_bug!
(
const_
.span
,
"codgen encountered polymorphic constant: {:?}"
,
err
)
}
}
}
}
let
memory_locals
=
analyze
::
non_ssa_locals
(
&
fx
);
// Allocate variable and temp allocas
...
...
src/librustc_middle/mir/mod.rs
浏览文件 @
0b958790
...
...
@@ -156,6 +156,10 @@ pub struct Body<'tcx> {
/// A span representing this MIR, for error reporting.
pub
span
:
Span
,
/// Constants that are required to evaluate successfully for this MIR to be well-formed.
/// We hold in this field all the constants we are not able to evaluate yet.
pub
required_consts
:
Vec
<
Constant
<
'tcx
>>
,
/// The user may be writing e.g. &[(SOME_CELL, 42)][i].1 and this would get promoted, because
/// we'd statically know that no thing with interior mutability will ever be available to the
/// user without some serious unsafe code. Now this means that our promoted is actually
...
...
@@ -203,6 +207,7 @@ pub fn new(
spread_arg
:
None
,
var_debug_info
,
span
,
required_consts
:
Vec
::
new
(),
ignore_interior_mut_in_const_validation
:
false
,
control_flow_destroyed
,
predecessor_cache
:
PredecessorCache
::
new
(),
...
...
@@ -227,6 +232,7 @@ pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) ->
arg_count
:
0
,
spread_arg
:
None
,
span
:
DUMMY_SP
,
required_consts
:
Vec
::
new
(),
control_flow_destroyed
:
Vec
::
new
(),
generator_kind
:
None
,
var_debug_info
:
Vec
::
new
(),
...
...
@@ -2395,7 +2401,7 @@ fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
/// this does not necessarily mean that they are "==" in Rust -- in
/// particular one must be wary of `NaN`!
#[derive(Clone,
PartialEq,
RustcEncodable,
RustcDecodable,
HashStable)]
#[derive(Clone,
Copy,
PartialEq,
RustcEncodable,
RustcDecodable,
HashStable)]
pub
struct
Constant
<
'tcx
>
{
pub
span
:
Span
,
...
...
src/librustc_middle/mir/visit.rs
浏览文件 @
0b958790
...
...
@@ -288,6 +288,11 @@ fn super_body(
}
self
.visit_span
(
&
$
(
$mutability
)
?
body
.span
);
for
const_
in
&
$
(
$mutability
)
?
body
.required_consts
{
let
location
=
START_BLOCK
.start_location
();
self
.visit_constant
(
const_
,
location
);
}
}
fn
super_basic_block_data
(
&
mut
self
,
...
...
src/librustc_mir/transform/const_prop.rs
浏览文件 @
0b958790
...
...
@@ -830,6 +830,12 @@ fn tcx(&self) -> TyCtxt<'tcx> {
self
.tcx
}
fn
visit_body
(
&
mut
self
,
body
:
&
mut
Body
<
'tcx
>
)
{
for
(
bb
,
data
)
in
body
.basic_blocks_mut
()
.iter_enumerated_mut
()
{
self
.visit_basic_block_data
(
bb
,
data
);
}
}
fn
visit_constant
(
&
mut
self
,
constant
:
&
mut
Constant
<
'tcx
>
,
location
:
Location
)
{
trace!
(
"visit_constant: {:?}"
,
constant
);
self
.super_constant
(
constant
,
location
);
...
...
src/librustc_mir/transform/inline.rs
浏览文件 @
0b958790
...
...
@@ -8,7 +8,7 @@
use
rustc_middle
::
mir
::
visit
::
*
;
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
ty
::
subst
::{
Subst
,
SubstsRef
};
use
rustc_middle
::
ty
::{
self
,
Instance
,
InstanceDef
,
ParamEnv
,
Ty
,
TyCtxt
};
use
rustc_middle
::
ty
::{
self
,
ConstKind
,
Instance
,
InstanceDef
,
ParamEnv
,
Ty
,
TyCtxt
};
use
rustc_session
::
config
::
Sanitizer
;
use
rustc_target
::
spec
::
abi
::
Abi
;
...
...
@@ -123,6 +123,16 @@ fn run_pass(&self, caller_body: &mut Body<'tcx>) {
continue
;
};
// Copy only unevaluated constants from the callee_body into the caller_body.
// Although we are only pushing `ConstKind::Unevaluated` consts to
// `required_consts`, here we may not only have `ConstKind::Unevaluated`
// because we are calling `subst_and_normalize_erasing_regions`.
caller_body
.required_consts
.extend
(
callee_body
.required_consts
.iter
()
.copied
()
.filter
(|
&
constant
|
{
matches!
(
constant
.literal.val
,
ConstKind
::
Unevaluated
(
_
,
_
,
_
))
}),
);
let
start
=
caller_body
.basic_blocks
()
.len
();
debug!
(
"attempting to inline callsite {:?} - body={:?}"
,
callsite
,
callee_body
);
if
!
self
.inline_call
(
callsite
,
caller_body
,
callee_body
)
{
...
...
src/librustc_mir/transform/mod.rs
浏览文件 @
0b958790
use
crate
::{
shim
,
util
};
use
required_consts
::
RequiredConstsVisitor
;
use
rustc_ast
::
ast
;
use
rustc_hir
as
hir
;
use
rustc_hir
::
def_id
::{
CrateNum
,
DefId
,
DefIdSet
,
LocalDefId
,
LOCAL_CRATE
};
use
rustc_hir
::
intravisit
::{
self
,
NestedVisitorMap
,
Visitor
};
use
rustc_index
::
vec
::
IndexVec
;
use
rustc_middle
::
mir
::{
Body
,
ConstQualifs
,
MirPhase
,
Promoted
};
use
rustc_middle
::
mir
::
visit
::
Visitor
as
_
;
use
rustc_middle
::
mir
::{
traversal
,
Body
,
ConstQualifs
,
MirPhase
,
Promoted
};
use
rustc_middle
::
ty
::
query
::
Providers
;
use
rustc_middle
::
ty
::
steal
::
Steal
;
use
rustc_middle
::
ty
::{
InstanceDef
,
TyCtxt
,
TypeFoldable
};
...
...
@@ -29,6 +31,7 @@
pub
mod
promote_consts
;
pub
mod
qualify_min_const_fn
;
pub
mod
remove_noop_landing_pads
;
pub
mod
required_consts
;
pub
mod
rustc_peek
;
pub
mod
simplify
;
pub
mod
simplify_branches
;
...
...
@@ -237,6 +240,14 @@ fn mir_validated(
let
_
=
tcx
.mir_const_qualif
(
def_id
);
let
mut
body
=
tcx
.mir_const
(
def_id
)
.steal
();
let
mut
required_consts
=
Vec
::
new
();
let
mut
required_consts_visitor
=
RequiredConstsVisitor
::
new
(
&
mut
required_consts
);
for
(
bb
,
bb_data
)
in
traversal
::
reverse_postorder
(
&
body
)
{
required_consts_visitor
.visit_basic_block_data
(
bb
,
bb_data
);
}
body
.required_consts
=
required_consts
;
let
promote_pass
=
promote_consts
::
PromoteTemps
::
default
();
run_passes
(
tcx
,
...
...
src/librustc_mir/transform/required_consts.rs
0 → 100644
浏览文件 @
0b958790
use
rustc_middle
::
mir
::
visit
::
Visitor
;
use
rustc_middle
::
mir
::{
Constant
,
Location
};
use
rustc_middle
::
ty
::
ConstKind
;
pub
struct
RequiredConstsVisitor
<
'a
,
'tcx
>
{
required_consts
:
&
'a
mut
Vec
<
Constant
<
'tcx
>>
,
}
impl
<
'a
,
'tcx
>
RequiredConstsVisitor
<
'a
,
'tcx
>
{
pub
fn
new
(
required_consts
:
&
'a
mut
Vec
<
Constant
<
'tcx
>>
)
->
Self
{
RequiredConstsVisitor
{
required_consts
}
}
}
impl
<
'a
,
'tcx
>
Visitor
<
'tcx
>
for
RequiredConstsVisitor
<
'a
,
'tcx
>
{
fn
visit_constant
(
&
mut
self
,
constant
:
&
Constant
<
'tcx
>
,
_
:
Location
)
{
let
const_kind
=
constant
.literal.val
;
if
let
ConstKind
::
Unevaluated
(
_
,
_
,
_
)
=
const_kind
{
self
.required_consts
.push
(
*
constant
);
}
}
}
src/librustc_mir/transform/simplify.rs
浏览文件 @
0b958790
...
...
@@ -32,7 +32,7 @@
use
rustc_index
::
vec
::{
Idx
,
IndexVec
};
use
rustc_middle
::
mir
::
visit
::{
MutVisitor
,
MutatingUseContext
,
PlaceContext
,
Visitor
};
use
rustc_middle
::
mir
::
*
;
use
rustc_middle
::
ty
::
{
self
,
TyCtxt
}
;
use
rustc_middle
::
ty
::
TyCtxt
;
use
std
::
borrow
::
Cow
;
pub
struct
SimplifyCfg
{
...
...
@@ -400,33 +400,18 @@ fn visit_local(&mut self, local: &Local, ctx: PlaceContext, location: Location)
if
location
.statement_index
!=
block
.statements
.len
()
{
let
stmt
=
&
block
.statements
[
location
.statement_index
];
fn
can_skip_constant
(
c
:
&
ty
::
Const
<
'tcx
>
)
->
bool
{
// Keep assignments from unevaluated constants around, since the
// evaluation may report errors, even if the use of the constant
// is dead code.
!
matches!
(
c
.val
,
ty
::
ConstKind
::
Unevaluated
(
..
))
}
fn
can_skip_operand
(
o
:
&
Operand
<
'_
>
)
->
bool
{
match
o
{
Operand
::
Copy
(
_
)
|
Operand
::
Move
(
_
)
=>
true
,
Operand
::
Constant
(
c
)
=>
can_skip_constant
(
c
.literal
),
}
}
if
let
StatementKind
::
Assign
(
box
(
dest
,
rvalue
))
=
&
stmt
.kind
{
if
!
dest
.is_indirect
()
&&
dest
.local
==
*
local
{
let
can_skip
=
match
rvalue
{
Rvalue
::
Use
(
op
)
=>
can_skip_operand
(
op
),
Rvalue
::
Discriminant
(
_
)
=>
true
,
Rvalue
::
BinaryOp
(
_
,
l
,
r
)
|
Rvalue
::
CheckedBinaryOp
(
_
,
l
,
r
)
=>
{
can_skip_operand
(
l
)
&&
can_skip_operand
(
r
)
}
Rvalue
::
Repeat
(
op
,
c
)
=>
can_skip_operand
(
op
)
&&
can_skip_constant
(
c
),
Rvalue
::
AddressOf
(
_
,
_
)
=>
true
,
Rvalue
::
Len
(
_
)
=>
true
,
Rvalue
::
UnaryOp
(
_
,
op
)
=>
can_skip_operand
(
op
),
Rvalue
::
Aggregate
(
_
,
operands
)
=>
operands
.iter
()
.all
(
can_skip_operand
),
Rvalue
::
Use
(
_
)
|
Rvalue
::
Discriminant
(
_
)
|
Rvalue
::
BinaryOp
(
_
,
_
,
_
)
|
Rvalue
::
CheckedBinaryOp
(
_
,
_
,
_
)
|
Rvalue
::
Repeat
(
_
,
_
)
|
Rvalue
::
AddressOf
(
_
,
_
)
|
Rvalue
::
Len
(
_
)
|
Rvalue
::
UnaryOp
(
_
,
_
)
|
Rvalue
::
Aggregate
(
_
,
_
)
=>
true
,
_
=>
false
,
};
...
...
src/test/mir-opt/const_allocation2/32bit/rustc.main.ConstProp.after.mir
浏览文件 @
0b958790
...
...
@@ -30,41 +30,41 @@ fn main() -> () {
}
alloc0 (static: FOO, size: 8, align: 4) {
╾alloc2
5
+0╼ 03 00 00 00 │ ╾──╼....
╾alloc2
1
+0╼ 03 00 00 00 │ ╾──╼....
}
alloc2
5
(size: 48, align: 4) {
0x00 │ 00 00 00 00 __ __ __ __ ╾alloc
10+0
╼ 00 00 00 00 │ ....░░░░╾──╼....
0x10 │ 00 00 00 00 __ __ __ __ ╾alloc
15+0
╼ 02 00 00 00 │ ....░░░░╾──╼....
0x20 │ 01 00 00 00 2a 00 00 00 ╾alloc
23
+0╼ 03 00 00 00 │ ....*...╾──╼....
alloc2
1
(size: 48, align: 4) {
0x00 │ 00 00 00 00 __ __ __ __ ╾alloc
4+0─
╼ 00 00 00 00 │ ....░░░░╾──╼....
0x10 │ 00 00 00 00 __ __ __ __ ╾alloc
9+0─
╼ 02 00 00 00 │ ....░░░░╾──╼....
0x20 │ 01 00 00 00 2a 00 00 00 ╾alloc
19
+0╼ 03 00 00 00 │ ....*...╾──╼....
}
alloc
10
(size: 0, align: 4) {}
alloc
4
(size: 0, align: 4) {}
alloc
15
(size: 8, align: 4) {
╾alloc
13+0╼ ╾alloc14+0
╼ │ ╾──╼╾──╼
alloc
9
(size: 8, align: 4) {
╾alloc
7+0─╼ ╾alloc8+0─
╼ │ ╾──╼╾──╼
}
alloc
13
(size: 1, align: 1) {
alloc
7
(size: 1, align: 1) {
05 │ .
}
alloc
14
(size: 1, align: 1) {
alloc
8
(size: 1, align: 1) {
06 │ .
}
alloc
23
(size: 12, align: 4) {
╾alloc1
9+3╼ ╾alloc20+0╼ ╾alloc22
+2╼ │ ╾──╼╾──╼╾──╼
alloc
19
(size: 12, align: 4) {
╾alloc1
5+3╼ ╾alloc16+0╼ ╾alloc18
+2╼ │ ╾──╼╾──╼╾──╼
}
alloc1
9
(size: 4, align: 1) {
alloc1
5
(size: 4, align: 1) {
2a 45 15 6f │ *E.o
}
alloc
20
(size: 1, align: 1) {
alloc
16
(size: 1, align: 1) {
2a │ *
}
alloc
22
(size: 4, align: 1) {
alloc
18
(size: 4, align: 1) {
2a 45 15 6f │ *E.o
}
src/test/mir-opt/const_allocation2/64bit/rustc.main.ConstProp.after.mir
浏览文件 @
0b958790
...
...
@@ -30,44 +30,44 @@ fn main() -> () {
}
alloc0 (static: FOO, size: 16, align: 8) {
╾──────alloc2
5
+0──────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
╾──────alloc2
1
+0──────╼ 03 00 00 00 00 00 00 00 │ ╾──────╼........
}
alloc2
5
(size: 72, align: 8) {
0x00 │ 00 00 00 00 __ __ __ __ ╾──────alloc
10+0
──────╼ │ ....░░░░╾──────╼
alloc2
1
(size: 72, align: 8) {
0x00 │ 00 00 00 00 __ __ __ __ ╾──────alloc
4+0─
──────╼ │ ....░░░░╾──────╼
0x10 │ 00 00 00 00 00 00 00 00 00 00 00 00 __ __ __ __ │ ............░░░░
0x20 │ ╾──────alloc
15+0
──────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........
0x30 │ 01 00 00 00 2a 00 00 00 ╾──────alloc
23
+0──────╼ │ ....*...╾──────╼
0x20 │ ╾──────alloc
9+0─
──────╼ 02 00 00 00 00 00 00 00 │ ╾──────╼........
0x30 │ 01 00 00 00 2a 00 00 00 ╾──────alloc
19
+0──────╼ │ ....*...╾──────╼
0x40 │ 03 00 00 00 00 00 00 00 │ ........
}
alloc
10
(size: 0, align: 8) {}
alloc
4
(size: 0, align: 8) {}
alloc
15
(size: 16, align: 8) {
╾──────alloc
13+0──────╼ ╾──────alloc14+0
──────╼ │ ╾──────╼╾──────╼
alloc
9
(size: 16, align: 8) {
╾──────alloc
7+0───────╼ ╾──────alloc8+0─
──────╼ │ ╾──────╼╾──────╼
}
alloc
13
(size: 1, align: 1) {
alloc
7
(size: 1, align: 1) {
05 │ .
}
alloc
14
(size: 1, align: 1) {
alloc
8
(size: 1, align: 1) {
06 │ .
}
alloc
23
(size: 24, align: 8) {
0x00 │ ╾──────alloc1
9+3──────╼ ╾──────alloc20
+0──────╼ │ ╾──────╼╾──────╼
0x10 │ ╾──────alloc
22
+2──────╼ │ ╾──────╼
alloc
19
(size: 24, align: 8) {
0x00 │ ╾──────alloc1
5+3──────╼ ╾──────alloc16
+0──────╼ │ ╾──────╼╾──────╼
0x10 │ ╾──────alloc
18
+2──────╼ │ ╾──────╼
}
alloc1
9
(size: 4, align: 1) {
alloc1
5
(size: 4, align: 1) {
2a 45 15 6f │ *E.o
}
alloc
20
(size: 1, align: 1) {
alloc
16
(size: 1, align: 1) {
2a │ *
}
alloc
22
(size: 4, align: 1) {
alloc
18
(size: 4, align: 1) {
2a 45 15 6f │ *E.o
}
src/test/mir-opt/re
tain
-never-const.rs
→
src/test/mir-opt/re
move
-never-const.rs
浏览文件 @
0b958790
// Regression test for #66975 - ensure that we don't keep unevaluated
// `!`-typed constants until codegen.
// This was originally a regression test for #66975 - ensure that we do not generate never typed
// consts in codegen. We also have tests for this that catches the error, see
// src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs.
// Force generation of optimized mir for functions that do not reach codegen.
// compile-flags: --emit mir,link
...
...
src/test/mir-opt/remove-never-const/rustc.no_codegen.PreCodegen.after.mir
0 → 100644
浏览文件 @
0b958790
// MIR for `no_codegen` after PreCodegen
fn no_codegen() -> () {
let mut _0: (); // return place in scope 0 at $DIR/remove-never-const.rs:19:20: 19:20
scope 1 {
}
bb0: {
unreachable; // bb0[0]: scope 0 at $DIR/remove-never-const.rs:20:13: 20:33
}
}
src/test/mir-opt/retain-never-const/rustc.no_codegen.PreCodegen.after.mir
已删除
100644 → 0
浏览文件 @
5a595275
// MIR for `no_codegen` after PreCodegen
fn no_codegen() -> () {
let mut _0: (); // return place in scope 0 at $DIR/retain-never-const.rs:18:20: 18:20
let mut _1: !; // in scope 0 at $DIR/retain-never-const.rs:19:13: 19:33
scope 1 {
}
bb0: {
StorageLive(_1); // bb0[0]: scope 0 at $DIR/retain-never-const.rs:19:13: 19:33
_1 = const PrintName::<T>::VOID; // bb0[1]: scope 0 at $DIR/retain-never-const.rs:19:13: 19:33
// ty::Const
// + ty: !
// + val: Unevaluated(DefId(0:9 ~ retain_never_const[317d]::{{impl}}[0]::VOID[0]), [T], None)
// mir::Constant
// + span: $DIR/retain-never-const.rs:19:13: 19:33
// + user_ty: UserType(0)
// + literal: Const { ty: !, val: Unevaluated(DefId(0:9 ~ retain_never_const[317d]::{{impl}}[0]::VOID[0]), [T], None) }
unreachable; // bb0[2]: scope 0 at $DIR/retain-never-const.rs:19:13: 19:33
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录