Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
98d23248
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,发现更多精彩内容 >>
提交
98d23248
编写于
7月 01, 2019
作者:
S
Santiago Pastorino
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Avoid cloning place in LocalAnalyzer visitor
上级
d0accade
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
91 addition
and
56 deletion
+91
-56
src/librustc/mir/mod.rs
src/librustc/mir/mod.rs
+6
-0
src/librustc_codegen_ssa/mir/analyze.rs
src/librustc_codegen_ssa/mir/analyze.rs
+85
-56
未找到文件。
src/librustc/mir/mod.rs
浏览文件 @
98d23248
...
...
@@ -1826,6 +1826,12 @@ pub struct Field {
}
}
#[derive(Debug)]
pub
struct
PlaceRef
<
'a
,
'tcx
>
{
pub
base
:
&
'a
PlaceBase
<
'tcx
>
,
pub
projection
:
&
'a
Option
<
Box
<
Projection
<
'tcx
>>>
,
}
impl
<
'tcx
>
Place
<
'tcx
>
{
pub
const
RETURN_PLACE
:
Place
<
'tcx
>
=
Place
{
base
:
PlaceBase
::
Local
(
RETURN_PLACE
),
...
...
src/librustc_codegen_ssa/mir/analyze.rs
浏览文件 @
98d23248
...
...
@@ -92,6 +92,86 @@ fn assign(&mut self, local: mir::Local, location: Location) {
self
.first_assignment
[
local
]
=
location
;
}
}
fn
process_place
(
&
mut
self
,
place_ref
:
&
mir
::
PlaceRef
<
'_
,
'tcx
>
,
context
:
PlaceContext
,
location
:
Location
)
{
let
cx
=
self
.fx.cx
;
if
let
Some
(
proj
)
=
place_ref
.projection
{
// Allow uses of projections that are ZSTs or from scalar fields.
let
is_consume
=
match
context
{
PlaceContext
::
NonMutatingUse
(
NonMutatingUseContext
::
Copy
)
|
PlaceContext
::
NonMutatingUse
(
NonMutatingUseContext
::
Move
)
=>
true
,
_
=>
false
};
if
is_consume
{
let
base_ty
=
mir
::
Place
::
ty_from
(
place_ref
.base
,
&
proj
.base
,
self
.fx.mir
,
cx
.tcx
());
let
base_ty
=
self
.fx
.monomorphize
(
&
base_ty
);
// ZSTs don't require any actual memory access.
let
elem_ty
=
base_ty
.projection_ty
(
cx
.tcx
(),
&
proj
.elem
)
.ty
;
let
elem_ty
=
self
.fx
.monomorphize
(
&
elem_ty
);
if
cx
.layout_of
(
elem_ty
)
.is_zst
()
{
return
;
}
if
let
mir
::
ProjectionElem
::
Field
(
..
)
=
proj
.elem
{
let
layout
=
cx
.layout_of
(
base_ty
.ty
);
if
cx
.is_backend_immediate
(
layout
)
||
cx
.is_backend_scalar_pair
(
layout
)
{
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `not_ssa` on locals.
self
.process_place
(
&
mir
::
PlaceRef
{
base
:
place_ref
.base
,
projection
:
&
proj
.base
,
},
context
,
location
,
);
return
;
}
}
}
// A deref projection only reads the pointer, never needs the place.
if
let
mir
::
ProjectionElem
::
Deref
=
proj
.elem
{
self
.process_place
(
&
mir
::
PlaceRef
{
base
:
place_ref
.base
,
projection
:
&
proj
.base
,
},
PlaceContext
::
NonMutatingUse
(
NonMutatingUseContext
::
Copy
),
location
);
return
;
}
}
// FIXME this is super_place code, is repeated here to avoid cloning place or changing
// visit_place API
let
mut
context
=
context
;
if
place_ref
.projection
.is_some
()
{
context
=
if
context
.is_mutating_use
()
{
PlaceContext
::
MutatingUse
(
MutatingUseContext
::
Projection
)
}
else
{
PlaceContext
::
NonMutatingUse
(
NonMutatingUseContext
::
Projection
)
};
}
self
.visit_place_base
(
place_ref
.base
,
context
,
location
);
if
let
Some
(
box
proj
)
=
place_ref
.projection
{
self
.visit_projection
(
place_ref
.base
,
proj
,
context
,
location
);
}
}
}
impl
<
'mir
,
'a
,
'tcx
,
Bx
:
BuilderMethods
<
'a
,
'tcx
>>
Visitor
<
'tcx
>
...
...
@@ -158,63 +238,12 @@ fn visit_place(&mut self,
context
:
PlaceContext
,
location
:
Location
)
{
debug!
(
"visit_place(place={:?}, context={:?})"
,
place
,
context
);
let
cx
=
self
.fx.cx
;
if
let
Some
(
proj
)
=
&
place
.projection
{
// Allow uses of projections that are ZSTs or from scalar fields.
let
is_consume
=
match
context
{
PlaceContext
::
NonMutatingUse
(
NonMutatingUseContext
::
Copy
)
|
PlaceContext
::
NonMutatingUse
(
NonMutatingUseContext
::
Move
)
=>
true
,
_
=>
false
};
if
is_consume
{
let
base_ty
=
mir
::
Place
::
ty_from
(
&
place
.base
,
&
proj
.base
,
self
.fx.mir
,
cx
.tcx
());
let
base_ty
=
self
.fx
.monomorphize
(
&
base_ty
);
// ZSTs don't require any actual memory access.
let
elem_ty
=
base_ty
.projection_ty
(
cx
.tcx
(),
&
proj
.elem
)
.ty
;
let
elem_ty
=
self
.fx
.monomorphize
(
&
elem_ty
);
if
cx
.layout_of
(
elem_ty
)
.is_zst
()
{
return
;
}
if
let
mir
::
ProjectionElem
::
Field
(
..
)
=
proj
.elem
{
let
layout
=
cx
.layout_of
(
base_ty
.ty
);
if
cx
.is_backend_immediate
(
layout
)
||
cx
.is_backend_scalar_pair
(
layout
)
{
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `not_ssa` on locals.
self
.visit_place
(
// FIXME do not clone
&
mir
::
Place
{
base
:
place
.base
.clone
(),
projection
:
proj
.base
.clone
(),
},
context
,
location
,
);
return
;
}
}
}
// A deref projection only reads the pointer, never needs the place.
if
let
mir
::
ProjectionElem
::
Deref
=
proj
.elem
{
return
self
.visit_place
(
// FIXME do not clone
&
mir
::
Place
{
base
:
place
.base
.clone
(),
projection
:
proj
.base
.clone
(),
},
PlaceContext
::
NonMutatingUse
(
NonMutatingUseContext
::
Copy
),
location
);
}
}
self
.super_place
(
place
,
context
,
location
);
let
place_ref
=
mir
::
PlaceRef
{
base
:
&
place
.base
,
projection
:
&
place
.projection
,
};
self
.process_place
(
&
place_ref
,
context
,
location
);
}
fn
visit_local
(
&
mut
self
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录