Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
464c02e3
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
464c02e3
编写于
3月 09, 2016
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
integrate scopes into MIR
上级
b76f818c
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
168 addition
and
21 deletion
+168
-21
src/librustc/mir/repr.rs
src/librustc/mir/repr.rs
+54
-2
src/librustc_mir/build/block.rs
src/librustc_mir/build/block.rs
+1
-1
src/librustc_mir/build/cfg.rs
src/librustc_mir/build/cfg.rs
+6
-1
src/librustc_mir/build/mod.rs
src/librustc_mir/build/mod.rs
+68
-8
src/librustc_mir/build/scope.rs
src/librustc_mir/build/scope.rs
+30
-6
src/librustc_mir/mir_map.rs
src/librustc_mir/mir_map.rs
+9
-3
未找到文件。
src/librustc/mir/repr.rs
浏览文件 @
464c02e3
...
...
@@ -32,6 +32,10 @@ pub struct Mir<'tcx> {
/// that indexes into this vector.
pub
basic_blocks
:
Vec
<
BasicBlockData
<
'tcx
>>
,
/// List of lexical scopes; these are referenced by statements and
/// used (eventually) for debuginfo. Indexed by a `ScopeId`.
pub
scopes
:
ScopeDataVec
,
/// Return type of the function.
pub
return_ty
:
FnOutput
<
'tcx
>
,
...
...
@@ -613,13 +617,61 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
}
}
///////////////////////////////////////////////////////////////////////////
// Scopes
#[derive(Clone,
Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
ScopeDataVec
{
pub
vec
:
Vec
<
ScopeData
>
}
impl
ScopeDataVec
{
pub
fn
new
()
->
Self
{
ScopeDataVec
{
vec
:
Vec
::
new
()
}
}
}
impl
Index
<
ScopeId
>
for
ScopeDataVec
{
type
Output
=
ScopeData
;
#[inline]
fn
index
(
&
self
,
index
:
ScopeId
)
->
&
ScopeData
{
&
self
.vec
[
index
.index
()]
}
}
impl
IndexMut
<
ScopeId
>
for
ScopeDataVec
{
#[inline]
fn
index_mut
(
&
mut
self
,
index
:
ScopeId
)
->
&
mut
ScopeData
{
&
mut
self
.vec
[
index
.index
()]
}
}
#[derive(Copy,
Clone,
Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
ScopeId
(
u32
);
impl
ScopeId
{
pub
fn
new
(
index
:
usize
)
->
ScopeId
{
assert
!
(
index
<
(
u32
::
MAX
as
usize
));
ScopeId
(
index
as
u32
)
}
pub
fn
index
(
self
)
->
usize
{
self
.0
as
usize
}
}
#[derive(Clone,
Debug,
RustcEncodable,
RustcDecodable)]
pub
struct
ScopeData
{
pub
parent_scope
:
Option
<
ScopeId
>
,
}
///////////////////////////////////////////////////////////////////////////
// Operands
//
/// These are values that can appear inside an rvalue (or an index
/// lvalue). They are intentionally limited to prevent rvalues from
/// being nested in one another.
#[derive(Clone,
PartialEq,
RustcEncodable,
RustcDecodable)]
pub
enum
Operand
<
'tcx
>
{
Consume
(
Lvalue
<
'tcx
>
),
...
...
src/librustc_mir/build/block.rs
浏览文件 @
464c02e3
...
...
@@ -51,7 +51,7 @@ pub fn ast_block(&mut self,
}));
}
StmtKind
::
Let
{
remainder_scope
,
init_scope
,
pattern
,
initializer
}
=>
{
this
.push_scope
(
remainder_scope
);
this
.push_scope
(
remainder_scope
,
block
);
let_extent_stack
.push
(
remainder_scope
);
unpack!
(
block
=
this
.in_scope
(
init_scope
,
block
,
move
|
this
|
{
// FIXME #30046 ^~~~
...
...
src/librustc_mir/build/cfg.rs
浏览文件 @
464c02e3
...
...
@@ -13,7 +13,7 @@
//! Routines for manipulating the control-flow graph.
use
build
::
CFG
;
use
build
::
{
CFG
,
Location
}
;
use
rustc
::
mir
::
repr
::
*
;
use
syntax
::
codemap
::
Span
;
...
...
@@ -43,6 +43,11 @@ pub fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) {
self
.block_data_mut
(
block
)
.statements
.push
(
statement
);
}
pub
fn
current_location
(
&
mut
self
,
block
:
BasicBlock
)
->
Location
{
let
index
=
self
.block_data
(
block
)
.statements
.len
();
Location
{
block
:
block
,
statement_index
:
index
}
}
pub
fn
push_assign
(
&
mut
self
,
block
:
BasicBlock
,
span
:
Span
,
...
...
src/librustc_mir/build/mod.rs
浏览文件 @
464c02e3
...
...
@@ -21,8 +21,26 @@
pub
struct
Builder
<
'a
,
'tcx
:
'a
>
{
hir
:
Cx
<
'a
,
'tcx
>
,
cfg
:
CFG
<
'tcx
>
,
// the current set of scopes, updated as we traverse;
// see the `scope` module for more details
scopes
:
Vec
<
scope
::
Scope
<
'tcx
>>
,
// for each scope, a span of blocks that defines it;
// we track these for use in region and borrow checking,
// but these are liable to get out of date once optimization
// begins. They are also hopefully temporary, and will be
// no longer needed when we adopt graph-based regions.
scope_auxiliary
:
Vec
<
ScopeAuxiliary
>
,
// the current set of loops; see the `scope` module for more
// details
loop_scopes
:
Vec
<
scope
::
LoopScope
>
,
// the vector of all scopes that we have created thus far;
// we track this for debuginfo later
scope_data_vec
:
ScopeDataVec
,
var_decls
:
Vec
<
VarDecl
<
'tcx
>>
,
var_indices
:
FnvHashMap
<
ast
::
NodeId
,
u32
>
,
temp_decls
:
Vec
<
TempDecl
<
'tcx
>>
,
...
...
@@ -33,6 +51,42 @@ struct CFG<'tcx> {
basic_blocks
:
Vec
<
BasicBlockData
<
'tcx
>>
,
}
/// For each scope, we track the extent (from the HIR) and a
/// single-entry-multiple-exit subgraph that contains all the
/// statements/terminators within it.
///
/// This information is separated out from the main `ScopeData`
/// because it is short-lived. First, the extent contains node-ids,
/// so it cannot be saved and re-loaded. Second, any optimization will mess up
/// the dominator/postdominator information.
///
/// The intention is basically to use this information to do
/// regionck/borrowck and then throw it away once we are done.
pub
struct
ScopeAuxiliary
{
/// extent of this scope from the MIR.
pub
extent
:
CodeExtent
,
/// "entry point": dominator of all nodes in the scope
pub
dom
:
Location
,
/// "exit points": mutual postdominators of all nodes in the scope
pub
postdoms
:
Vec
<
Location
>
,
}
pub
struct
Location
{
/// the location is within this block
pub
block
:
BasicBlock
,
/// the location is the start of the this statement; or, if `statement_index`
/// == num-statements, then the start of the terminator.
pub
statement_index
:
usize
,
}
pub
struct
MirPlusPlus
<
'tcx
>
{
pub
mir
:
Mir
<
'tcx
>
,
pub
scope_auxiliary
:
Vec
<
ScopeAuxiliary
>
,
}
///////////////////////////////////////////////////////////////////////////
/// The `BlockAnd` "monad" packages up the new basic block along with a
/// produced value (sometimes just unit, of course). The `unpack!`
...
...
@@ -86,13 +140,15 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
argument_extent
:
CodeExtent
,
return_ty
:
FnOutput
<
'tcx
>
,
ast_block
:
&
'tcx
hir
::
Block
)
->
Mir
<
'tcx
>
{
->
Mir
PlusPlus
<
'tcx
>
{
let
cfg
=
CFG
{
basic_blocks
:
vec!
[]
};
let
mut
builder
=
Builder
{
hir
:
hir
,
cfg
:
cfg
,
scopes
:
vec!
[],
scope_data_vec
:
ScopeDataVec
::
new
(),
scope_auxiliary
:
vec!
[],
loop_scopes
:
vec!
[],
temp_decls
:
vec!
[],
var_decls
:
vec!
[],
...
...
@@ -113,13 +169,17 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>,
builder
.cfg
.terminate
(
block
,
Terminator
::
Goto
{
target
:
END_BLOCK
});
builder
.cfg
.terminate
(
END_BLOCK
,
Terminator
::
Return
);
Mir
{
basic_blocks
:
builder
.cfg.basic_blocks
,
var_decls
:
builder
.var_decls
,
arg_decls
:
arg_decls
,
temp_decls
:
builder
.temp_decls
,
return_ty
:
return_ty
,
span
:
span
MirPlusPlus
{
mir
:
Mir
{
basic_blocks
:
builder
.cfg.basic_blocks
,
scopes
:
builder
.scope_data_vec
,
var_decls
:
builder
.var_decls
,
arg_decls
:
arg_decls
,
temp_decls
:
builder
.temp_decls
,
return_ty
:
return_ty
,
span
:
span
},
scope_auxiliary
:
builder
.scope_auxiliary
,
}
}
...
...
src/librustc_mir/build/scope.rs
浏览文件 @
464c02e3
...
...
@@ -86,7 +86,7 @@
*/
use
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
,
CFG
};
use
build
::{
BlockAnd
,
BlockAndExtension
,
Builder
,
CFG
,
ScopeAuxiliary
};
use
rustc
::
middle
::
region
::
CodeExtent
;
use
rustc
::
middle
::
lang_items
;
use
rustc
::
middle
::
subst
::{
Substs
,
Subst
,
VecPerParamSpace
};
...
...
@@ -98,8 +98,11 @@
use
rustc_const_eval
::
ConstInt
;
pub
struct
Scope
<
'tcx
>
{
// the scope-id within the scope_data_vec
id
:
ScopeId
,
extent
:
CodeExtent
,
drops
:
Vec
<
DropData
<
'tcx
>>
,
// A scope may only have one associated free, because:
// 1. We require a `free` to only be scheduled in the scope of `EXPR` in `box EXPR`;
// 2. It only makes sense to have it translated into the diverge-path.
...
...
@@ -208,7 +211,7 @@ pub fn in_scope<F, R>(&mut self, extent: CodeExtent, mut block: BasicBlock, f: F
where
F
:
FnOnce
(
&
mut
Builder
<
'a
,
'tcx
>
)
->
BlockAnd
<
R
>
{
debug!
(
"in_scope(extent={:?}, block={:?})"
,
extent
,
block
);
self
.push_scope
(
extent
);
self
.push_scope
(
extent
,
block
);
let
rv
=
unpack!
(
block
=
f
(
self
));
unpack!
(
block
=
self
.pop_scope
(
extent
,
block
));
debug!
(
"in_scope: exiting extent={:?} block={:?}"
,
extent
,
block
);
...
...
@@ -219,26 +222,44 @@ pub fn in_scope<F, R>(&mut self, extent: CodeExtent, mut block: BasicBlock, f: F
/// scope and call `pop_scope` afterwards. Note that these two
/// calls must be paired; using `in_scope` as a convenience
/// wrapper maybe preferable.
pub
fn
push_scope
(
&
mut
self
,
extent
:
CodeExtent
)
{
pub
fn
push_scope
(
&
mut
self
,
extent
:
CodeExtent
,
entry
:
BasicBlock
)
{
debug!
(
"push_scope({:?})"
,
extent
);
let
parent_id
=
self
.scopes
.last
()
.map
(|
s
|
s
.id
);
let
id
=
ScopeId
::
new
(
self
.scope_data_vec.vec
.len
());
self
.scope_data_vec.vec
.push
(
ScopeData
{
parent_scope
:
parent_id
,
});
self
.scopes
.push
(
Scope
{
extent
:
extent
.clone
(),
id
:
id
,
extent
:
extent
,
drops
:
vec!
[],
free
:
None
});
self
.scope_auxiliary
.push
(
ScopeAuxiliary
{
extent
:
extent
,
dom
:
self
.cfg
.current_location
(
entry
),
postdoms
:
vec!
[]
});
}
/// Pops a scope, which should have extent `extent`, adding any
/// drops onto the end of `block` that are needed. This must
/// match 1-to-1 with `push_scope`.
pub
fn
pop_scope
(
&
mut
self
,
extent
:
CodeExtent
,
block
:
BasicBlock
)
->
BlockAnd
<
()
>
{
pub
fn
pop_scope
(
&
mut
self
,
extent
:
CodeExtent
,
mut
block
:
BasicBlock
)
->
BlockAnd
<
()
>
{
debug!
(
"pop_scope({:?}, {:?})"
,
extent
,
block
);
// We need to have `cached_block`s available for all the drops, so we call diverge_cleanup
// to make sure all the `cached_block`s are filled in.
self
.diverge_cleanup
();
let
scope
=
self
.scopes
.pop
()
.unwrap
();
assert_eq!
(
scope
.extent
,
extent
);
build_scope_drops
(
&
mut
self
.cfg
,
&
scope
,
&
self
.scopes
[
..
],
block
)
unpack!
(
block
=
build_scope_drops
(
&
mut
self
.cfg
,
&
scope
,
&
self
.scopes
,
block
));
self
.scope_auxiliary
[
scope
.id
.index
()]
.postdoms
.push
(
self
.cfg
.current_location
(
block
));
block
.and
(())
}
...
...
@@ -269,6 +290,9 @@ pub fn exit_scope(&mut self,
self
.cfg
.terminate
(
block
,
free
);
block
=
next
;
}
self
.scope_auxiliary
[
scope
.id
.index
()]
.postdoms
.push
(
self
.cfg
.current_location
(
block
));
}
self
.cfg
.terminate
(
block
,
Terminator
::
Goto
{
target
:
target
});
}
...
...
src/librustc_mir/mir_map.rs
浏览文件 @
464c02e3
...
...
@@ -19,7 +19,7 @@
extern
crate
syntax
;
extern
crate
rustc_front
;
use
build
;
use
build
::{
self
,
MirPlusPlus
}
;
use
rustc
::
dep_graph
::
DepNode
;
use
rustc
::
mir
::
repr
::
Mir
;
use
hair
::
cx
::
Cx
;
...
...
@@ -182,8 +182,14 @@ fn build_mir<'a,'tcx:'a>(cx: Cx<'a,'tcx>,
let
parameter_scope
=
cx
.tcx
()
.region_maps
.lookup_code_extent
(
CodeExtentData
::
ParameterScope
{
fn_id
:
fn_id
,
body_id
:
body
.id
});
let
mut
mir
=
build
::
construct
(
cx
,
span
,
implicit_arg_tys
,
arguments
,
parameter_scope
,
fn_sig
.output
,
body
);
let
MirPlusPlus
{
mut
mir
,
scope_auxiliary
:
_
}
=
build
::
construct
(
cx
,
span
,
implicit_arg_tys
,
arguments
,
parameter_scope
,
fn_sig
.output
,
body
);
match
cx
.tcx
()
.node_id_to_type
(
fn_id
)
.sty
{
ty
::
TyFnDef
(
_
,
_
,
f
)
if
f
.abi
==
Abi
::
RustCall
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录