Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
45fd7416
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,发现更多精彩内容 >>
提交
45fd7416
编写于
2月 17, 2018
作者:
E
Eduard-Mihai Burtescu
提交者:
Mike Hommey
4月 18, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_trans: also check dominators for SSA values in mir::analyze.
Fixes #50041
上级
23561c67
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
60 addition
and
27 deletion
+60
-27
src/librustc_trans/mir/analyze.rs
src/librustc_trans/mir/analyze.rs
+59
-26
src/librustc_trans/mir/mod.rs
src/librustc_trans/mir/mod.rs
+1
-1
未找到文件。
src/librustc_trans/mir/analyze.rs
浏览文件 @
45fd7416
...
...
@@ -12,6 +12,7 @@
//! which do not.
use
rustc_data_structures
::
bitvec
::
BitVector
;
use
rustc_data_structures
::
control_flow_graph
::
dominators
::
Dominators
;
use
rustc_data_structures
::
indexed_vec
::{
Idx
,
IndexVec
};
use
rustc
::
mir
::{
self
,
Location
,
TerminatorKind
};
use
rustc
::
mir
::
visit
::{
Visitor
,
PlaceContext
};
...
...
@@ -21,7 +22,7 @@
use
type_of
::
LayoutLlvmExt
;
use
super
::
FunctionCx
;
pub
fn
memory
_locals
<
'a
,
'tcx
>
(
fx
:
&
FunctionCx
<
'a
,
'tcx
>
)
->
BitVector
{
pub
fn
non_ssa
_locals
<
'a
,
'tcx
>
(
fx
:
&
FunctionCx
<
'a
,
'tcx
>
)
->
BitVector
{
let
mir
=
fx
.mir
;
let
mut
analyzer
=
LocalAnalyzer
::
new
(
fx
);
...
...
@@ -43,43 +44,60 @@ pub fn memory_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector {
// (e.g. structs) into an alloca unconditionally, just so
// that we don't have to deal with having two pathways
// (gep vs extractvalue etc).
analyzer
.
mark_as_memory
(
mir
::
Local
::
new
(
index
));
analyzer
.
not_ssa
(
mir
::
Local
::
new
(
index
));
}
}
analyzer
.
memory
_locals
analyzer
.
non_ssa
_locals
}
struct
LocalAnalyzer
<
'mir
,
'a
:
'mir
,
'tcx
:
'a
>
{
fx
:
&
'mir
FunctionCx
<
'a
,
'tcx
>
,
memory_locals
:
BitVector
,
seen_assigned
:
BitVector
dominators
:
Dominators
<
mir
::
BasicBlock
>
,
non_ssa_locals
:
BitVector
,
// The location of the first visited direct assignment to each
// local, or an invalid location (out of bounds `block` index).
first_assignment
:
IndexVec
<
mir
::
Local
,
Location
>
}
impl
<
'mir
,
'a
,
'tcx
>
LocalAnalyzer
<
'mir
,
'a
,
'tcx
>
{
fn
new
(
fx
:
&
'mir
FunctionCx
<
'a
,
'tcx
>
)
->
LocalAnalyzer
<
'mir
,
'a
,
'tcx
>
{
let
invalid_location
=
mir
::
BasicBlock
::
new
(
fx
.mir
.basic_blocks
()
.len
())
.start_location
();
let
mut
analyzer
=
LocalAnalyzer
{
fx
,
memory_locals
:
BitVector
::
new
(
fx
.mir.local_decls
.len
()),
seen_assigned
:
BitVector
::
new
(
fx
.mir.local_decls
.len
())
dominators
:
fx
.mir
.dominators
(),
non_ssa_locals
:
BitVector
::
new
(
fx
.mir.local_decls
.len
()),
first_assignment
:
IndexVec
::
from_elem
(
invalid_location
,
&
fx
.mir.local_decls
)
};
// Arguments get assigned to by means of the function being called
for
idx
in
0
..
fx
.mir.arg_count
{
analyzer
.
seen_assigned
.insert
(
idx
+
1
);
for
arg
in
fx
.mir
.args_iter
()
{
analyzer
.
first_assignment
[
arg
]
=
mir
::
START_BLOCK
.start_location
(
);
}
analyzer
}
fn
mark_as_memory
(
&
mut
self
,
local
:
mir
::
Local
)
{
debug!
(
"marking {:?} as memory"
,
local
);
self
.memory_locals
.insert
(
local
.index
());
fn
first_assignment
(
&
self
,
local
:
mir
::
Local
)
->
Option
<
Location
>
{
let
location
=
self
.first_assignment
[
local
];
if
location
.block
.index
()
<
self
.fx.mir
.basic_blocks
()
.len
()
{
Some
(
location
)
}
else
{
None
}
}
fn
mark_assigned
(
&
mut
self
,
local
:
mir
::
Local
)
{
if
!
self
.seen_assigned
.insert
(
local
.index
())
{
self
.mark_as_memory
(
local
);
fn
not_ssa
(
&
mut
self
,
local
:
mir
::
Local
)
{
debug!
(
"marking {:?} as non-SSA"
,
local
);
self
.non_ssa_locals
.insert
(
local
.index
());
}
fn
assign
(
&
mut
self
,
local
:
mir
::
Local
,
location
:
Location
)
{
if
self
.first_assignment
(
local
)
.is_some
()
{
self
.not_ssa
(
local
);
}
else
{
self
.first_assignment
[
local
]
=
location
;
}
}
}
...
...
@@ -93,9 +111,9 @@ fn visit_assign(&mut self,
debug!
(
"visit_assign(block={:?}, place={:?}, rvalue={:?})"
,
block
,
place
,
rvalue
);
if
let
mir
::
Place
::
Local
(
index
)
=
*
place
{
self
.
mark_assigned
(
index
);
self
.
assign
(
index
,
location
);
if
!
self
.fx
.rvalue_creates_operand
(
rvalue
)
{
self
.
mark_as_memory
(
index
);
self
.
not_ssa
(
index
);
}
}
else
{
self
.visit_place
(
place
,
PlaceContext
::
Store
,
location
);
...
...
@@ -161,7 +179,7 @@ fn visit_place(&mut self,
if
layout
.is_llvm_immediate
()
||
layout
.is_llvm_scalar_pair
()
{
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `
mark_as_memory
` on locals.
// which would trigger `
not_ssa
` on locals.
self
.visit_place
(
&
proj
.base
,
context
,
location
);
return
;
}
...
...
@@ -178,35 +196,50 @@ fn visit_place(&mut self,
}
fn
visit_local
(
&
mut
self
,
&
index
:
&
mir
::
Local
,
&
local
:
&
mir
::
Local
,
context
:
PlaceContext
<
'tcx
>
,
_
:
Location
)
{
location
:
Location
)
{
match
context
{
PlaceContext
::
Call
=>
{
self
.
mark_assigned
(
index
);
self
.
assign
(
local
,
location
);
}
PlaceContext
::
StorageLive
|
PlaceContext
::
StorageDead
|
PlaceContext
::
Validate
|
PlaceContext
::
Validate
=>
{}
PlaceContext
::
Copy
|
PlaceContext
::
Move
=>
{}
PlaceContext
::
Move
=>
{
// Reads from uninitialized variables (e.g. in dead code, after
// optimizations) require locals to be in (uninitialized) memory.
// NB: there can be uninitialized reads of a local visited after
// an assignment to that local, if they happen on disjoint paths.
let
ssa_read
=
match
self
.first_assignment
(
local
)
{
Some
(
assignment_location
)
=>
{
assignment_location
.dominates
(
location
,
&
self
.dominators
)
}
None
=>
false
};
if
!
ssa_read
{
self
.not_ssa
(
local
);
}
}
PlaceContext
::
Inspect
|
PlaceContext
::
Store
|
PlaceContext
::
AsmOutput
|
PlaceContext
::
Borrow
{
..
}
|
PlaceContext
::
Projection
(
..
)
=>
{
self
.
mark_as_memory
(
index
);
self
.
not_ssa
(
local
);
}
PlaceContext
::
Drop
=>
{
let
ty
=
mir
::
Place
::
Local
(
index
)
.ty
(
self
.fx.mir
,
self
.fx.cx.tcx
);
let
ty
=
mir
::
Place
::
Local
(
local
)
.ty
(
self
.fx.mir
,
self
.fx.cx.tcx
);
let
ty
=
self
.fx
.monomorphize
(
&
ty
.to_ty
(
self
.fx.cx.tcx
));
// Only need the place if we're actually dropping it.
if
self
.fx.cx
.type_needs_drop
(
ty
)
{
self
.
mark_as_memory
(
index
);
self
.
not_ssa
(
local
);
}
}
}
...
...
src/librustc_trans/mir/mod.rs
浏览文件 @
45fd7416
...
...
@@ -252,7 +252,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
},
};
let
memory_locals
=
analyze
::
memory
_locals
(
&
fx
);
let
memory_locals
=
analyze
::
non_ssa
_locals
(
&
fx
);
// Allocate variable and temp allocas
fx
.locals
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录