Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d77a1364
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,发现更多精彩内容 >>
提交
d77a1364
编写于
8月 04, 2016
作者:
S
Scott A Carr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add SetDiscriminant StatementKind to enable deaggregation of enums
上级
42001edc
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
156 addition
and
18 deletion
+156
-18
src/librustc/mir/repr.rs
src/librustc/mir/repr.rs
+5
-1
src/librustc/mir/visit.rs
src/librustc/mir/visit.rs
+3
-0
src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
+3
-0
src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
+3
-0
src/librustc_borrowck/borrowck/mir/gather_moves.rs
src/librustc_borrowck/borrowck/mir/gather_moves.rs
+4
-0
src/librustc_borrowck/borrowck/mir/mod.rs
src/librustc_borrowck/borrowck/mir/mod.rs
+3
-0
src/librustc_mir/transform/deaggregator.rs
src/librustc_mir/transform/deaggregator.rs
+34
-11
src/librustc_mir/transform/promote_consts.rs
src/librustc_mir/transform/promote_consts.rs
+19
-3
src/librustc_mir/transform/type_check.rs
src/librustc_mir/transform/type_check.rs
+20
-3
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/constant.rs
+3
-0
src/librustc_trans/mir/statement.rs
src/librustc_trans/mir/statement.rs
+14
-0
src/test/mir-opt/deaggregator_test_enum.rs
src/test/mir-opt/deaggregator_test_enum.rs
+45
-0
未找到文件。
src/librustc/mir/repr.rs
浏览文件 @
d77a1364
...
...
@@ -689,13 +689,17 @@ pub struct Statement<'tcx> {
#[derive(Clone,
Debug,
RustcEncodable,
RustcDecodable)]
pub
enum
StatementKind
<
'tcx
>
{
Assign
(
Lvalue
<
'tcx
>
,
Rvalue
<
'tcx
>
),
SetDiscriminant
{
lvalue
:
Lvalue
<
'tcx
>
,
variant_index
:
usize
},
}
impl
<
'tcx
>
Debug
for
Statement
<
'tcx
>
{
fn
fmt
(
&
self
,
fmt
:
&
mut
Formatter
)
->
fmt
::
Result
{
use
self
::
StatementKind
::
*
;
match
self
.kind
{
Assign
(
ref
lv
,
ref
rv
)
=>
write!
(
fmt
,
"{:?} = {:?}"
,
lv
,
rv
)
Assign
(
ref
lv
,
ref
rv
)
=>
write!
(
fmt
,
"{:?} = {:?}"
,
lv
,
rv
),
SetDiscriminant
{
lvalue
:
ref
lv
,
variant_index
:
index
}
=>
{
write!
(
fmt
,
"discriminant({:?}) = {:?}"
,
lv
,
index
)
}
}
}
}
...
...
src/librustc/mir/visit.rs
浏览文件 @
d77a1364
...
...
@@ -323,6 +323,9 @@ fn super_statement(&mut self,
ref
$
(
$mutability
)
*
rvalue
)
=>
{
self
.visit_assign
(
block
,
lvalue
,
rvalue
);
}
StatementKind
::
SetDiscriminant
{
ref
$
(
$mutability
)
*
lvalue
,
..
}
=>
{
self
.visit_lvalue
(
lvalue
,
LvalueContext
::
Store
);
}
}
}
...
...
src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
浏览文件 @
d77a1364
...
...
@@ -442,6 +442,9 @@ fn statement_effect(&self,
}
let
bits_per_block
=
self
.bits_per_block
(
ctxt
);
match
stmt
.kind
{
repr
::
StatementKind
::
SetDiscriminant
{
..
}
=>
{
span_bug!
(
stmt
.source_info.span
,
"SetDiscriminant should not exist in borrowck"
);
}
repr
::
StatementKind
::
Assign
(
ref
lvalue
,
_
)
=>
{
// assigning into this `lvalue` kills all
// MoveOuts from it, and *also* all MoveOuts
...
...
src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
浏览文件 @
d77a1364
...
...
@@ -104,6 +104,9 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
repr
::
StatementKind
::
Assign
(
ref
lvalue
,
ref
rvalue
)
=>
{
(
lvalue
,
rvalue
)
}
repr
::
StatementKind
::
SetDiscriminant
{
..
}
=>
span_bug!
(
stmt
.source_info.span
,
"sanity_check should run before Deaggregator inserts SetDiscriminant"
),
};
if
lvalue
==
peek_arg_lval
{
...
...
src/librustc_borrowck/borrowck/mir/gather_moves.rs
浏览文件 @
d77a1364
...
...
@@ -616,6 +616,10 @@ fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MoveD
Rvalue
::
InlineAsm
{
..
}
=>
{}
}
}
StatementKind
::
SetDiscriminant
{
..
}
=>
{
span_bug!
(
stmt
.source_info.span
,
"SetDiscriminant should not exist during borrowck"
);
}
}
}
...
...
src/librustc_borrowck/borrowck/mir/mod.rs
浏览文件 @
d77a1364
...
...
@@ -369,6 +369,9 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
let
block
=
&
mir
[
loc
.block
];
match
block
.statements
.get
(
loc
.index
)
{
Some
(
stmt
)
=>
match
stmt
.kind
{
repr
::
StatementKind
::
SetDiscriminant
{
..
}
=>
{
span_bug!
(
stmt
.source_info.span
,
"SetDiscrimant should not exist during borrowck"
);
}
repr
::
StatementKind
::
Assign
(
ref
lvalue
,
_
)
=>
{
debug!
(
"drop_flag_effects: assignment {:?}"
,
stmt
);
on_all_children_bits
(
tcx
,
mir
,
move_data
,
...
...
src/librustc_mir/transform/deaggregator.rs
浏览文件 @
d77a1364
...
...
@@ -39,7 +39,7 @@ fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
mut
curr
:
usize
=
0
;
for
bb
in
mir
.basic_blocks_mut
()
{
let
idx
=
match
get_aggregate_statement
(
curr
,
&
bb
.statements
)
{
let
idx
=
match
get_aggregate_statement
_index
(
curr
,
&
bb
.statements
)
{
Some
(
idx
)
=>
idx
,
None
=>
continue
,
};
...
...
@@ -48,7 +48,11 @@ fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
src_info
=
bb
.statements
[
idx
]
.source_info
;
let
suffix_stmts
=
bb
.statements
.split_off
(
idx
+
1
);
let
orig_stmt
=
bb
.statements
.pop
()
.unwrap
();
let
StatementKind
::
Assign
(
ref
lhs
,
ref
rhs
)
=
orig_stmt
.kind
;
let
(
lhs
,
rhs
)
=
match
orig_stmt
.kind
{
StatementKind
::
Assign
(
ref
lhs
,
ref
rhs
)
=>
(
lhs
,
rhs
),
StatementKind
::
SetDiscriminant
{
..
}
=>
span_bug!
(
src_info
.span
,
"expected aggregate, not {:?}"
,
orig_stmt
.kind
),
};
let
(
agg_kind
,
operands
)
=
match
rhs
{
&
Rvalue
::
Aggregate
(
ref
agg_kind
,
ref
operands
)
=>
(
agg_kind
,
operands
),
_
=>
span_bug!
(
src_info
.span
,
"expected aggregate, not {:?}"
,
rhs
),
...
...
@@ -64,10 +68,14 @@ fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
ty
=
variant_def
.fields
[
i
]
.ty
(
tcx
,
substs
);
let
rhs
=
Rvalue
::
Use
(
op
.clone
());
// since we don't handle enums, we don't need a cast
let
lhs_cast
=
lhs
.clone
();
// FIXME we cannot deaggregate enums issue: #35186
let
lhs_cast
=
if
adt_def
.variants
.len
()
>
1
{
Lvalue
::
Projection
(
Box
::
new
(
LvalueProjection
{
base
:
lhs
.clone
(),
elem
:
ProjectionElem
::
Downcast
(
adt_def
,
variant
),
}))
}
else
{
lhs
.clone
()
};
let
lhs_proj
=
Lvalue
::
Projection
(
Box
::
new
(
LvalueProjection
{
base
:
lhs_cast
,
...
...
@@ -80,18 +88,34 @@ fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!
(
"inserting: {:?} @ {:?}"
,
new_statement
,
idx
+
i
);
bb
.statements
.push
(
new_statement
);
}
// if the aggregate was an enum, we need to set the discriminant
if
adt_def
.variants
.len
()
>
1
{
let
set_discriminant
=
Statement
{
kind
:
StatementKind
::
SetDiscriminant
{
lvalue
:
lhs
.clone
(),
variant_index
:
variant
,
},
source_info
:
src_info
,
};
bb
.statements
.push
(
set_discriminant
);
};
curr
=
bb
.statements
.len
();
bb
.statements
.extend
(
suffix_stmts
);
}
}
}
fn
get_aggregate_statement
<
'a
,
'tcx
,
'b
>
(
curr
:
usize
,
fn
get_aggregate_statement
_index
<
'a
,
'tcx
,
'b
>
(
start
:
usize
,
statements
:
&
Vec
<
Statement
<
'tcx
>>
)
->
Option
<
usize
>
{
for
i
in
curr
..
statements
.len
()
{
for
i
in
start
..
statements
.len
()
{
let
ref
statement
=
statements
[
i
];
let
StatementKind
::
Assign
(
_
,
ref
rhs
)
=
statement
.kind
;
let
rhs
=
match
statement
.kind
{
StatementKind
::
Assign
(
_
,
ref
rhs
)
=>
rhs
,
StatementKind
::
SetDiscriminant
{
..
}
=>
continue
,
};
let
(
kind
,
operands
)
=
match
rhs
{
&
Rvalue
::
Aggregate
(
ref
kind
,
ref
operands
)
=>
(
kind
,
operands
),
_
=>
continue
,
...
...
@@ -100,9 +124,8 @@ fn get_aggregate_statement<'a, 'tcx, 'b>(curr: usize,
&
AggregateKind
::
Adt
(
adt_def
,
variant
,
_
)
=>
(
adt_def
,
variant
),
_
=>
continue
,
};
if
operands
.len
()
==
0
||
adt_def
.variants
.len
()
>
1
{
if
operands
.len
()
==
0
{
// don't deaggregate ()
// don't deaggregate enums ... for now
continue
;
}
debug!
(
"getting variant {:?}"
,
variant
);
...
...
src/librustc_mir/transform/promote_consts.rs
浏览文件 @
d77a1364
...
...
@@ -219,7 +219,13 @@ fn promote_temp(&mut self, temp: Temp) -> Temp {
let
(
mut
rvalue
,
mut
call
)
=
(
None
,
None
);
let
source_info
=
if
stmt_idx
<
no_stmts
{
let
statement
=
&
mut
self
.source
[
bb
]
.statements
[
stmt_idx
];
let
StatementKind
::
Assign
(
_
,
ref
mut
rhs
)
=
statement
.kind
;
let
mut
rhs
=
match
statement
.kind
{
StatementKind
::
Assign
(
_
,
ref
mut
rhs
)
=>
rhs
,
StatementKind
::
SetDiscriminant
{
..
}
=>
span_bug!
(
statement
.source_info.span
,
"cannot promote SetDiscriminant {:?}"
,
statement
),
};
if
self
.keep_original
{
rvalue
=
Some
(
rhs
.clone
());
}
else
{
...
...
@@ -300,10 +306,16 @@ fn promote_candidate(mut self, candidate: Candidate) {
});
let
mut
rvalue
=
match
candidate
{
Candidate
::
Ref
(
Location
{
block
:
bb
,
statement_index
:
stmt_idx
})
=>
{
match
self
.source
[
bb
]
.statements
[
stmt_idx
]
.kind
{
let
ref
mut
statement
=
self
.source
[
bb
]
.statements
[
stmt_idx
];
match
statement
.kind
{
StatementKind
::
Assign
(
_
,
ref
mut
rvalue
)
=>
{
mem
::
replace
(
rvalue
,
Rvalue
::
Use
(
new_operand
))
}
StatementKind
::
SetDiscriminant
{
..
}
=>
{
span_bug!
(
statement
.source_info.span
,
"cannot promote SetDiscriminant {:?}"
,
statement
);
}
}
}
Candidate
::
ShuffleIndices
(
bb
)
=>
{
...
...
@@ -340,7 +352,11 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>,
let
(
span
,
ty
)
=
match
candidate
{
Candidate
::
Ref
(
Location
{
block
:
bb
,
statement_index
:
stmt_idx
})
=>
{
let
statement
=
&
mir
[
bb
]
.statements
[
stmt_idx
];
let
StatementKind
::
Assign
(
ref
dest
,
_
)
=
statement
.kind
;
let
dest
=
match
statement
.kind
{
StatementKind
::
Assign
(
ref
dest
,
_
)
=>
dest
,
StatementKind
::
SetDiscriminant
{
..
}
=>
panic!
(
"cannot promote SetDiscriminant"
),
};
if
let
Lvalue
::
Temp
(
index
)
=
*
dest
{
if
temps
[
index
]
==
TempState
::
PromotedOut
{
// Already promoted.
...
...
src/librustc_mir/transform/type_check.rs
浏览文件 @
d77a1364
...
...
@@ -14,7 +14,7 @@
use
rustc
::
infer
::{
self
,
InferCtxt
,
InferOk
};
use
rustc
::
traits
::{
self
,
ProjectionMode
};
use
rustc
::
ty
::
fold
::
TypeFoldable
;
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
,
TypeVariants
};
use
rustc
::
mir
::
repr
::
*
;
use
rustc
::
mir
::
tcx
::
LvalueTy
;
use
rustc
::
mir
::
transform
::{
MirPass
,
MirSource
,
Pass
};
...
...
@@ -360,10 +360,27 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>) {
span_mirbug!
(
self
,
stmt
,
"bad assignment ({:?} = {:?}): {:?}"
,
lv_ty
,
rv_ty
,
terr
);
}
}
// FIXME: rvalue with undeterminable type - e.g. inline
// asm.
}
}
StatementKind
::
SetDiscriminant
{
ref
lvalue
,
variant_index
}
=>
{
let
lvalue_type
=
lvalue
.ty
(
mir
,
tcx
)
.to_ty
(
tcx
);
let
adt
=
match
lvalue_type
.sty
{
TypeVariants
::
TyEnum
(
adt
,
_
)
=>
adt
,
_
=>
{
span_bug!
(
stmt
.source_info.span
,
"bad set discriminant ({:?} = {:?}): lhs is not an enum"
,
lvalue
,
variant_index
);
}
};
if
variant_index
>=
adt
.variants
.len
()
{
span_bug!
(
stmt
.source_info.span
,
"bad set discriminant ({:?} = {:?}): value of of range"
,
lvalue
,
variant_index
);
};
}
}
}
...
...
src/librustc_trans/mir/constant.rs
浏览文件 @
d77a1364
...
...
@@ -285,6 +285,9 @@ fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalFailure> {
Err
(
err
)
=>
if
failure
.is_ok
()
{
failure
=
Err
(
err
);
}
}
}
mir
::
StatementKind
::
SetDiscriminant
{
..
}
=>
{
span_bug!
(
span
,
"SetDiscriminant should not appear in constants?"
);
}
}
}
...
...
src/librustc_trans/mir/statement.rs
浏览文件 @
d77a1364
...
...
@@ -14,6 +14,8 @@
use
super
::
MirContext
;
use
super
::
LocalRef
;
use
super
::
super
::
adt
;
use
super
::
super
::
disr
::
Disr
;
impl
<
'bcx
,
'tcx
>
MirContext
<
'bcx
,
'tcx
>
{
pub
fn
trans_statement
(
&
mut
self
,
...
...
@@ -57,6 +59,18 @@ pub fn trans_statement(&mut self,
self
.trans_rvalue
(
bcx
,
tr_dest
,
rvalue
,
debug_loc
)
}
}
mir
::
StatementKind
::
SetDiscriminant
{
ref
lvalue
,
variant_index
}
=>
{
let
ty
=
self
.monomorphized_lvalue_ty
(
lvalue
);
let
repr
=
adt
::
represent_type
(
bcx
.ccx
(),
ty
);
let
lvalue_transed
=
self
.trans_lvalue
(
&
bcx
,
lvalue
);
bcx
.with_block
(|
bcx
|
adt
::
trans_set_discr
(
bcx
,
&
repr
,
lvalue_transed
.llval
,
Disr
::
from
(
variant_index
))
);
bcx
}
}
}
}
src/test/mir-opt/deaggregator_test_enum.rs
0 → 100644
浏览文件 @
d77a1364
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
enum
Baz
{
Empty
,
Foo
{
x
:
usize
},
}
fn
bar
(
a
:
usize
)
->
Baz
{
Baz
::
Foo
{
x
:
a
}
}
fn
main
()
{
let
x
=
bar
(
10
);
match
x
{
Baz
::
Empty
=>
println!
(
"empty"
),
Baz
::
Foo
{
x
}
=>
println!
(
"{}"
,
x
),
};
}
// END RUST SOURCE
// START rustc.node10.Deaggregator.before.mir
// bb0: {
// var0 = arg0; // scope 0 at main.rs:7:8: 7:9
// tmp0 = var0; // scope 1 at main.rs:8:19: 8:20
// return = Baz::Foo { x: tmp0 }; // scope 1 at main.rs:8:5: 8:21
// goto -> bb1; // scope 1 at main.rs:7:1: 9:2
// }
// END rustc.node10.Deaggregator.before.mir
// START rustc.node10.Deaggregator.after.mir
// bb0: {
// var0 = arg0; // scope 0 at main.rs:7:8: 7:9
// tmp0 = var0; // scope 1 at main.rs:8:19: 8:20
// ((return as Foo).0: usize) = tmp0; // scope 1 at main.rs:8:5: 8:21
// discriminant(return) = 1; // scope 1 at main.rs:8:5: 8:21
// goto -> bb1; // scope 1 at main.rs:7:1: 9:2
// }
// END rustc.node10.Deaggregator.after.mir
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录