Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
6a5b2635
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,发现更多精彩内容 >>
提交
6a5b2635
编写于
11月 03, 2015
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add (and use) an analysis to determine which temps can forgo an alloca.
上级
544b06d4
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
160 addition
and
25 deletion
+160
-25
src/librustc_trans/trans/mir/analyze.rs
src/librustc_trans/trans/mir/analyze.rs
+115
-0
src/librustc_trans/trans/mir/mod.rs
src/librustc_trans/trans/mir/mod.rs
+2
-2
src/librustc_trans/trans/mir/operand.rs
src/librustc_trans/trans/mir/operand.rs
+21
-1
src/librustc_trans/trans/mir/rvalue.rs
src/librustc_trans/trans/mir/rvalue.rs
+22
-22
未找到文件。
src/librustc_trans/trans/mir/analyze.rs
0 → 100644
浏览文件 @
6a5b2635
// Copyright 2012-2014 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.
//! An analysis to determine which temporaries require allocas and
//! which do not.
use
rustc_data_structures
::
fnv
::
FnvHashSet
;
use
rustc_mir
::
repr
as
mir
;
use
rustc_mir
::
visit
::{
Visitor
,
LvalueContext
};
use
trans
::
common
::{
self
,
Block
};
use
super
::
rvalue
;
pub
fn
lvalue_temps
<
'bcx
,
'tcx
>
(
bcx
:
Block
<
'bcx
,
'tcx
>
,
mir
:
&
mir
::
Mir
<
'tcx
>
)
->
FnvHashSet
<
usize
>
{
let
mut
analyzer
=
TempAnalyzer
::
new
();
analyzer
.visit_mir
(
mir
);
for
(
index
,
temp_decl
)
in
mir
.temp_decls
.iter
()
.enumerate
()
{
let
ty
=
bcx
.monomorphize
(
&
temp_decl
.ty
);
debug!
(
"temp {:?} has type {:?}"
,
index
,
ty
);
if
ty
.is_scalar
()
||
ty
.is_unique
()
||
ty
.is_region_ptr
()
||
ty
.is_simd
()
{
// These sorts of types are immediates that we can store
// in an ValueRef without an alloca.
assert
!
(
common
::
type_is_immediate
(
bcx
.ccx
(),
ty
));
}
else
{
// These sorts of types require an alloca. Note that
// type_is_immediate() may *still* be true, particularly
// for newtypes, but we currently force some types
// (e.g. structs) into an alloca unconditionally, just so
// that we don't have to deal with having two pathways
// (gep vs getvalue etc).
analyzer
.mark_as_lvalue
(
index
);
}
}
analyzer
.lvalue_temps
}
struct
TempAnalyzer
{
lvalue_temps
:
FnvHashSet
<
usize
>
,
}
impl
TempAnalyzer
{
fn
new
()
->
TempAnalyzer
{
TempAnalyzer
{
lvalue_temps
:
FnvHashSet
()
}
}
fn
mark_as_lvalue
(
&
mut
self
,
temp
:
usize
)
{
debug!
(
"marking temp {} as lvalue"
,
temp
);
self
.lvalue_temps
.insert
(
temp
);
}
}
impl
<
'tcx
>
Visitor
<
'tcx
>
for
TempAnalyzer
{
fn
visit_assign
(
&
mut
self
,
block
:
mir
::
BasicBlock
,
lvalue
:
&
mir
::
Lvalue
<
'tcx
>
,
rvalue
:
&
mir
::
Rvalue
<
'tcx
>
)
{
debug!
(
"visit_assign(block={:?}, lvalue={:?}, rvalue={:?})"
,
block
,
lvalue
,
rvalue
);
match
*
lvalue
{
mir
::
Lvalue
::
Temp
(
index
)
=>
{
if
!
rvalue
::
rvalue_creates_operand
(
rvalue
)
{
self
.mark_as_lvalue
(
index
as
usize
);
}
}
_
=>
{
self
.visit_lvalue
(
lvalue
,
LvalueContext
::
Store
);
}
}
self
.visit_rvalue
(
rvalue
);
}
fn
visit_lvalue
(
&
mut
self
,
lvalue
:
&
mir
::
Lvalue
<
'tcx
>
,
context
:
LvalueContext
)
{
debug!
(
"visit_lvalue(lvalue={:?}, context={:?})"
,
lvalue
,
context
);
match
*
lvalue
{
mir
::
Lvalue
::
Temp
(
index
)
=>
{
match
context
{
LvalueContext
::
Consume
=>
{
}
LvalueContext
::
Store
|
LvalueContext
::
Drop
|
LvalueContext
::
Inspect
|
LvalueContext
::
Borrow
{
..
}
|
LvalueContext
::
Slice
{
..
}
|
LvalueContext
::
Projection
=>
{
self
.mark_as_lvalue
(
index
as
usize
);
}
}
}
_
=>
{
}
}
self
.super_lvalue
(
lvalue
,
context
);
}
}
src/librustc_trans/trans/mir/mod.rs
浏览文件 @
6a5b2635
...
...
@@ -10,7 +10,6 @@
use
libc
::
c_uint
;
use
llvm
::{
self
,
ValueRef
};
use
rustc_data_structures
::
fnv
::
FnvHashSet
;
use
rustc_mir
::
repr
as
mir
;
use
rustc_mir
::
tcx
::
LvalueTy
;
use
trans
::
base
;
...
...
@@ -79,7 +78,7 @@ pub fn trans_mir<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>) {
// Analyze the temps to determine which must be lvalues
// FIXME
let
lvalue_temps
:
FnvHashSet
<
usize
>
=
(
0
..
mir
.temp_decls
.len
())
.collect
(
);
let
lvalue_temps
=
analyze
::
lvalue_temps
(
bcx
,
mir
);
// Allocate variable and temp allocas
let
vars
=
mir
.var_decls
.iter
()
...
...
@@ -183,6 +182,7 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>,
.collect
()
}
mod
analyze
;
mod
block
;
mod
constant
;
mod
lvalue
;
...
...
src/librustc_trans/trans/mir/operand.rs
浏览文件 @
6a5b2635
...
...
@@ -16,8 +16,9 @@
use
trans
::
common
::
Block
;
use
trans
::
datum
;
use
super
::
MirContext
;
use
super
::
{
MirContext
,
TempRef
}
;
#[derive(Copy,
Clone)]
pub
struct
OperandRef
<
'tcx
>
{
// This will be "indirect" if `appropriate_rvalue_mode` returns
// ByRef, and otherwise ByValue.
...
...
@@ -37,6 +38,25 @@ pub fn trans_operand(&mut self,
match
*
operand
{
mir
::
Operand
::
Consume
(
ref
lvalue
)
=>
{
// watch out for temporaries that do not have an
// alloca; they are handled somewhat differently
if
let
&
mir
::
Lvalue
::
Temp
(
index
)
=
lvalue
{
match
self
.temps
[
index
as
usize
]
{
TempRef
::
Operand
(
Some
(
o
))
=>
{
return
o
;
}
TempRef
::
Operand
(
None
)
=>
{
bcx
.tcx
()
.sess
.bug
(
&
format!
(
"use of {:?} before def"
,
lvalue
));
}
TempRef
::
Lvalue
(
..
)
=>
{
// use path below
}
}
}
// for most lvalues, to consume them we just load them
// out from their home
let
tr_lvalue
=
self
.trans_lvalue
(
bcx
,
lvalue
);
let
ty
=
tr_lvalue
.ty
.to_ty
(
bcx
.tcx
());
debug!
(
"trans_operand: tr_lvalue={} @ {:?}"
,
...
...
src/librustc_trans/trans/mir/rvalue.rs
浏览文件 @
6a5b2635
...
...
@@ -80,7 +80,7 @@ pub fn trans_rvalue(&mut self,
}
_
=>
{
assert
!
(
self
.
rvalue_creates_operand
(
rvalue
));
assert
!
(
rvalue_creates_operand
(
rvalue
));
let
(
bcx
,
temp
)
=
self
.trans_rvalue_operand
(
bcx
,
rvalue
);
build
::
Store
(
bcx
,
temp
.llval
,
lldest
);
bcx
...
...
@@ -88,32 +88,12 @@ pub fn trans_rvalue(&mut self,
}
}
pub
fn
rvalue_creates_operand
(
&
self
,
rvalue
:
&
mir
::
Rvalue
<
'tcx
>
)
->
bool
{
match
*
rvalue
{
mir
::
Rvalue
::
Use
(
..
)
|
// (*)
mir
::
Rvalue
::
Ref
(
..
)
|
mir
::
Rvalue
::
Len
(
..
)
|
mir
::
Rvalue
::
Cast
(
..
)
|
// (*)
mir
::
Rvalue
::
BinaryOp
(
..
)
|
mir
::
Rvalue
::
UnaryOp
(
..
)
|
mir
::
Rvalue
::
Box
(
..
)
=>
true
,
mir
::
Rvalue
::
Repeat
(
..
)
|
mir
::
Rvalue
::
Aggregate
(
..
)
|
mir
::
Rvalue
::
Slice
{
..
}
|
mir
::
Rvalue
::
InlineAsm
(
..
)
=>
false
,
}
// (*) this is only true if the type is suitable
}
pub
fn
trans_rvalue_operand
(
&
mut
self
,
bcx
:
Block
<
'bcx
,
'tcx
>
,
rvalue
:
&
mir
::
Rvalue
<
'tcx
>
)
->
(
Block
<
'bcx
,
'tcx
>
,
OperandRef
<
'tcx
>
)
{
assert
!
(
self
.
rvalue_creates_operand
(
rvalue
),
"cannot trans {:?} to operand"
,
rvalue
);
assert
!
(
rvalue_creates_operand
(
rvalue
),
"cannot trans {:?} to operand"
,
rvalue
);
match
*
rvalue
{
mir
::
Rvalue
::
Use
(
ref
operand
)
=>
{
...
...
@@ -300,3 +280,23 @@ pub fn trans_rvalue_operand(&mut self,
}
}
}
pub
fn
rvalue_creates_operand
<
'tcx
>
(
rvalue
:
&
mir
::
Rvalue
<
'tcx
>
)
->
bool
{
match
*
rvalue
{
mir
::
Rvalue
::
Use
(
..
)
|
// (*)
mir
::
Rvalue
::
Ref
(
..
)
|
mir
::
Rvalue
::
Len
(
..
)
|
mir
::
Rvalue
::
Cast
(
..
)
|
// (*)
mir
::
Rvalue
::
BinaryOp
(
..
)
|
mir
::
Rvalue
::
UnaryOp
(
..
)
|
mir
::
Rvalue
::
Box
(
..
)
=>
true
,
mir
::
Rvalue
::
Repeat
(
..
)
|
mir
::
Rvalue
::
Aggregate
(
..
)
|
mir
::
Rvalue
::
Slice
{
..
}
|
mir
::
Rvalue
::
InlineAsm
(
..
)
=>
false
,
}
// (*) this is only true if the type is suitable
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录