Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
0b869724
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,发现更多精彩内容 >>
提交
0b869724
编写于
10月 09, 2017
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_trans: be more relaxed with non-lvalue consumes, especially ZSTs.
上级
c4d9ada7
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
59 addition
and
24 deletion
+59
-24
src/librustc_trans/mir/analyze.rs
src/librustc_trans/mir/analyze.rs
+20
-10
src/librustc_trans/mir/operand.rs
src/librustc_trans/mir/operand.rs
+39
-14
未找到文件。
src/librustc_trans/mir/analyze.rs
浏览文件 @
0b869724
...
@@ -136,19 +136,29 @@ fn visit_lvalue(&mut self,
...
@@ -136,19 +136,29 @@ fn visit_lvalue(&mut self,
context
:
LvalueContext
<
'tcx
>
,
context
:
LvalueContext
<
'tcx
>
,
location
:
Location
)
{
location
:
Location
)
{
debug!
(
"visit_lvalue(lvalue={:?}, context={:?})"
,
lvalue
,
context
);
debug!
(
"visit_lvalue(lvalue={:?}, context={:?})"
,
lvalue
,
context
);
let
ccx
=
self
.cx.ccx
;
if
let
mir
::
Lvalue
::
Projection
(
ref
proj
)
=
*
lvalue
{
if
let
mir
::
Lvalue
::
Projection
(
ref
proj
)
=
*
lvalue
{
// Allow uses of projections
of immediate pai
r fields.
// Allow uses of projections
that are ZSTs or from immediate scala
r fields.
if
let
LvalueContext
::
Consume
=
context
{
if
let
LvalueContext
::
Consume
=
context
{
if
let
mir
::
Lvalue
::
Local
(
_
)
=
proj
.base
{
let
base_ty
=
proj
.base
.ty
(
self
.cx.mir
,
ccx
.tcx
());
if
let
mir
::
ProjectionElem
::
Field
(
..
)
=
proj
.elem
{
let
base_ty
=
self
.cx
.monomorphize
(
&
base_ty
);
let
ty
=
proj
.base
.ty
(
self
.cx.mir
,
self
.cx.ccx
.tcx
());
let
ty
=
self
.cx
.monomorphize
(
&
ty
.to_ty
(
self
.cx.ccx
.tcx
()));
// ZSTs don't require any actual memory access.
let
layout
=
self
.cx.ccx
.layout_of
(
ty
);
let
elem_ty
=
base_ty
.projection_ty
(
ccx
.tcx
(),
&
proj
.elem
)
.to_ty
(
ccx
.tcx
());
if
layout
.is_llvm_scalar_pair
()
{
let
elem_ty
=
self
.cx
.monomorphize
(
&
elem_ty
);
if
ccx
.layout_of
(
elem_ty
)
.is_zst
()
{
return
;
return
;
}
}
if
let
mir
::
ProjectionElem
::
Field
(
..
)
=
proj
.elem
{
let
layout
=
ccx
.layout_of
(
base_ty
.to_ty
(
ccx
.tcx
()));
if
layout
.is_llvm_scalar_pair
()
{
// Recurse as a `Consume` instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `mark_as_lvalue` on locals.
self
.visit_lvalue
(
&
proj
.base
,
LvalueContext
::
Consume
,
location
);
return
;
}
}
}
}
}
}
...
...
src/librustc_trans/mir/operand.rs
浏览文件 @
0b869724
...
@@ -179,19 +179,19 @@ pub fn store(self, bcx: &Builder<'a, 'tcx>, dest: LvalueRef<'tcx>) {
...
@@ -179,19 +179,19 @@ pub fn store(self, bcx: &Builder<'a, 'tcx>, dest: LvalueRef<'tcx>) {
}
}
impl
<
'a
,
'tcx
>
MirContext
<
'a
,
'tcx
>
{
impl
<
'a
,
'tcx
>
MirContext
<
'a
,
'tcx
>
{
pub
fn
trans_consume
(
&
mut
self
,
fn
maybe_trans_consume_direct
(
&
mut
self
,
bcx
:
&
Builder
<
'a
,
'tcx
>
,
bcx
:
&
Builder
<
'a
,
'tcx
>
,
lvalue
:
&
mir
::
Lvalue
<
'tcx
>
)
lvalue
:
&
mir
::
Lvalue
<
'tcx
>
)
->
OperandRef
<
'tcx
>
->
Option
<
OperandRef
<
'tcx
>
>
{
{
debug!
(
"
trans_consume
(lvalue={:?})"
,
lvalue
);
debug!
(
"
maybe_trans_consume_direct
(lvalue={:?})"
,
lvalue
);
// watch out for locals that do not have an
// watch out for locals that do not have an
// alloca; they are handled somewhat differently
// alloca; they are handled somewhat differently
if
let
mir
::
Lvalue
::
Local
(
index
)
=
*
lvalue
{
if
let
mir
::
Lvalue
::
Local
(
index
)
=
*
lvalue
{
match
self
.locals
[
index
]
{
match
self
.locals
[
index
]
{
LocalRef
::
Operand
(
Some
(
o
))
=>
{
LocalRef
::
Operand
(
Some
(
o
))
=>
{
return
o
;
return
Some
(
o
)
;
}
}
LocalRef
::
Operand
(
None
)
=>
{
LocalRef
::
Operand
(
None
)
=>
{
bug!
(
"use of {:?} before def"
,
lvalue
);
bug!
(
"use of {:?} before def"
,
lvalue
);
...
@@ -204,21 +204,24 @@ pub fn trans_consume(&mut self,
...
@@ -204,21 +204,24 @@ pub fn trans_consume(&mut self,
// Moves out of pair fields are trivial.
// Moves out of pair fields are trivial.
if
let
&
mir
::
Lvalue
::
Projection
(
ref
proj
)
=
lvalue
{
if
let
&
mir
::
Lvalue
::
Projection
(
ref
proj
)
=
lvalue
{
if
let
mir
::
Lvalue
::
Local
(
index
)
=
proj
.base
{
if
let
mir
::
ProjectionElem
::
Field
(
ref
f
,
_
)
=
proj
.elem
{
if
let
LocalRef
::
Operand
(
Some
(
o
))
=
self
.locals
[
index
]
{
if
let
Some
(
o
)
=
self
.maybe_trans_consume_direct
(
bcx
,
&
proj
.base
)
{
match
(
o
.val
,
&
proj
.elem
)
{
let
layout
=
o
.layout
.field
(
bcx
.ccx
,
f
.index
());
(
OperandValue
::
Pair
(
a
,
b
),
&
mir
::
ProjectionElem
::
Field
(
ref
f
,
ty
))
=>
{
// Handled in `trans_consume`.
let
layout
=
bcx
.ccx
.layout_of
(
self
.monomorphize
(
&
ty
));
assert
!
(
!
layout
.is_zst
());
match
o
.val
{
OperandValue
::
Pair
(
a
,
b
)
=>
{
let
llval
=
[
a
,
b
][
f
.index
()];
let
llval
=
[
a
,
b
][
f
.index
()];
// HACK(eddyb) have to bitcast pointers
// HACK(eddyb) have to bitcast pointers
// until LLVM removes pointee types.
// until LLVM removes pointee types.
let
llval
=
bcx
.bitcast
(
llval
,
let
llval
=
bcx
.bitcast
(
llval
,
layout
.immediate_llvm_type
(
bcx
.ccx
));
layout
.immediate_llvm_type
(
bcx
.ccx
));
return
OperandRef
{
return
Some
(
OperandRef
{
val
:
OperandValue
::
Immediate
(
llval
),
val
:
OperandValue
::
Immediate
(
llval
),
layout
layout
};
}
)
;
}
}
_
=>
{}
_
=>
{}
}
}
...
@@ -226,6 +229,28 @@ pub fn trans_consume(&mut self,
...
@@ -226,6 +229,28 @@ pub fn trans_consume(&mut self,
}
}
}
}
None
}
pub
fn
trans_consume
(
&
mut
self
,
bcx
:
&
Builder
<
'a
,
'tcx
>
,
lvalue
:
&
mir
::
Lvalue
<
'tcx
>
)
->
OperandRef
<
'tcx
>
{
debug!
(
"trans_consume(lvalue={:?})"
,
lvalue
);
let
ty
=
self
.monomorphized_lvalue_ty
(
lvalue
);
let
layout
=
bcx
.ccx
.layout_of
(
ty
);
// ZSTs don't require any actual memory access.
if
layout
.is_zst
()
{
return
OperandRef
::
new_zst
(
bcx
.ccx
,
layout
);
}
if
let
Some
(
o
)
=
self
.maybe_trans_consume_direct
(
bcx
,
lvalue
)
{
return
o
;
}
// for most lvalues, to consume them we just load them
// for most lvalues, to consume them we just load them
// out from their home
// out from their home
self
.trans_lvalue
(
bcx
,
lvalue
)
.load
(
bcx
)
self
.trans_lvalue
(
bcx
,
lvalue
)
.load
(
bcx
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录