Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
3e98220a
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,发现更多精彩内容 >>
提交
3e98220a
编写于
3月 08, 2016
作者:
E
Eduard Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
mir: Translate intrinsics, via old trans where possible.
上级
ee7687a5
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
106 addition
and
31 deletion
+106
-31
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/callee.rs
+3
-13
src/librustc_trans/trans/intrinsic.rs
src/librustc_trans/trans/intrinsic.rs
+17
-13
src/librustc_trans/trans/mir/block.rs
src/librustc_trans/trans/mir/block.rs
+86
-5
未找到文件。
src/librustc_trans/trans/callee.rs
浏览文件 @
3e98220a
...
...
@@ -36,7 +36,7 @@
use
trans
::
cleanup
;
use
trans
::
cleanup
::
CleanupMethods
;
use
trans
::
closure
;
use
trans
::
common
::{
self
,
Block
,
Result
,
NodeIdAndSpan
,
CrateContext
,
FunctionContext
};
use
trans
::
common
::{
self
,
Block
,
Result
,
CrateContext
,
FunctionContext
};
use
trans
::
common
::{
C_uint
,
C_undef
};
use
trans
::
consts
;
use
trans
::
datum
::
*
;
...
...
@@ -56,7 +56,6 @@
use
middle
::
ty
::{
self
,
Ty
,
TyCtxt
,
TypeFoldable
};
use
rustc_front
::
hir
;
use
syntax
::
ast
;
use
syntax
::
codemap
::
DUMMY_SP
;
use
syntax
::
errors
;
use
syntax
::
ptr
::
P
;
...
...
@@ -624,18 +623,9 @@ fn trans_call_inner<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
assert
!
(
abi
==
Abi
::
RustIntrinsic
||
abi
==
Abi
::
PlatformIntrinsic
);
assert
!
(
dest
.is_some
());
let
call_info
=
match
debug_loc
{
DebugLoc
::
At
(
id
,
span
)
=>
NodeIdAndSpan
{
id
:
id
,
span
:
span
},
DebugLoc
::
None
=>
{
bcx
.sess
()
.bug
(
"No call info for intrinsic call?"
)
}
};
let
arg_cleanup_scope
=
fcx
.push_custom_cleanup_scope
();
return
intrinsic
::
trans_intrinsic_call
(
bcx
,
callee
.ty
,
&
fn_ty
,
arg_cleanup_scope
,
args
,
dest
.unwrap
(),
call_info
);
args
,
dest
.unwrap
(),
debug_loc
);
}
NamedTupleConstructor
(
disr
)
=>
{
assert
!
(
dest
.is_some
());
...
...
src/librustc_trans/trans/intrinsic.rs
浏览文件 @
3e98220a
...
...
@@ -47,7 +47,7 @@
use
rustc
::
lint
;
use
rustc
::
session
::
Session
;
use
syntax
::
codemap
::
Span
;
use
syntax
::
codemap
::
{
Span
,
DUMMY_SP
}
;
use
std
::
cmp
::
Ordering
;
...
...
@@ -173,10 +173,9 @@ pub fn check_intrinsics(ccx: &CrateContext) {
pub
fn
trans_intrinsic_call
<
'a
,
'blk
,
'tcx
>
(
mut
bcx
:
Block
<
'blk
,
'tcx
>
,
callee_ty
:
Ty
<
'tcx
>
,
fn_ty
:
&
FnType
,
cleanup_scope
:
cleanup
::
CustomScopeIndex
,
args
:
callee
::
CallArgs
<
'a
,
'tcx
>
,
dest
:
expr
::
Dest
,
call_
info
:
NodeIdAndSpan
)
call_
debug_location
:
DebugLoc
)
->
Result
<
'blk
,
'tcx
>
{
let
fcx
=
bcx
.fcx
;
let
ccx
=
fcx
.ccx
;
...
...
@@ -195,7 +194,12 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
let
ret_ty
=
sig
.output
;
let
name
=
tcx
.item_name
(
def_id
)
.as_str
();
let
call_debug_location
=
DebugLoc
::
At
(
call_info
.id
,
call_info
.span
);
let
span
=
match
call_debug_location
{
DebugLoc
::
At
(
_
,
span
)
=>
span
,
DebugLoc
::
None
=>
fcx
.span
.unwrap_or
(
DUMMY_SP
)
};
let
cleanup_scope
=
fcx
.push_custom_cleanup_scope
();
// For `transmute` we can just trans the input expr directly into dest
if
name
==
"transmute"
{
...
...
@@ -644,7 +648,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
},
None
=>
{
span_invalid_monomorphization_error
(
tcx
.sess
,
call_info
.
span
,
tcx
.sess
,
span
,
&
format!
(
"invalid monomorphization of `{}` intrinsic:
\
expected basic integer type, found `{}`"
,
name
,
sty
));
C_null
(
llret_ty
)
...
...
@@ -656,7 +660,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
(
_
,
"return_address"
)
=>
{
if
!
fcx
.fn_ty.ret
.is_indirect
()
{
span_err!
(
tcx
.sess
,
call_info
.
span
,
E0510
,
span_err!
(
tcx
.sess
,
span
,
E0510
,
"invalid use of `return_address` intrinsic: function
\
does not use out pointer"
);
C_null
(
Type
::
i8p
(
ccx
))
...
...
@@ -684,7 +688,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
&
llargs
,
ret_ty
,
llret_ty
,
call_debug_location
,
call_info
)
span
)
}
// This requires that atomic intrinsics follow a specific naming pattern:
// "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
...
...
@@ -1404,7 +1408,7 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
ret_ty
:
Ty
<
'tcx
>
,
llret_ty
:
Type
,
call_debug_location
:
DebugLoc
,
call_info
:
NodeIdAnd
Span
)
->
ValueRef
span
:
Span
)
->
ValueRef
{
// macros for error handling:
macro_rules!
emit_error
{
...
...
@@ -1413,7 +1417,7 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
};
(
$msg
:
tt
,
$
(
$fmt
:
tt
)
*
)
=>
{
span_invalid_monomorphization_error
(
bcx
.sess
(),
call_info
.
span
,
bcx
.sess
(),
span
,
&
format!
(
concat!
(
"invalid monomorphization of `{}` intrinsic: "
,
$msg
),
name
,
$
(
$fmt
)
*
));
...
...
@@ -1482,7 +1486,7 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
if
name
.starts_with
(
"simd_shuffle"
)
{
let
n
:
usize
=
match
name
[
"simd_shuffle"
.len
()
..
]
.parse
()
{
Ok
(
n
)
=>
n
,
Err
(
_
)
=>
tcx
.sess
.span_bug
(
call_info
.
span
,
Err
(
_
)
=>
tcx
.sess
.span_bug
(
span
,
"bad `simd_shuffle` instruction only caught in trans?"
)
};
...
...
@@ -1502,14 +1506,14 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
let
vector
=
match
args
{
Some
(
args
)
=>
&
args
[
2
],
None
=>
bcx
.sess
()
.span_bug
(
call_info
.
span
,
None
=>
bcx
.sess
()
.span_bug
(
span
,
"intrinsic call with unexpected argument shape"
),
};
let
vector
=
match
consts
::
const_expr
(
bcx
.ccx
(),
vector
,
substs
,
None
,
consts
::
TrueConst
::
Yes
,
// this should probably help simd error reporting
)
{
Ok
((
vector
,
_
))
=>
vector
,
Err
(
err
)
=>
bcx
.sess
()
.span_fatal
(
call_info
.
span
,
&
err
.description
()),
Err
(
err
)
=>
bcx
.sess
()
.span_fatal
(
span
,
&
err
.description
()),
};
let
indices
:
Option
<
Vec
<
_
>>
=
(
0
..
n
)
...
...
@@ -1652,7 +1656,7 @@ enum Style { Float, Int(/* is signed? */ bool), Unsupported }
simd_or
:
TyUint
,
TyInt
=>
Or
;
simd_xor
:
TyUint
,
TyInt
=>
Xor
;
}
bcx
.sess
()
.span_bug
(
call_info
.
span
,
"unknown SIMD intrinsic"
);
bcx
.sess
()
.span_bug
(
span
,
"unknown SIMD intrinsic"
);
}
// Returns the width of an int TypeVariant, and if it's signed or not
...
...
src/librustc_trans/trans/mir/block.rs
浏览文件 @
3e98220a
...
...
@@ -15,11 +15,11 @@
use
trans
::
adt
;
use
trans
::
base
;
use
trans
::
build
;
use
trans
::
callee
::{
Callee
,
CalleeData
,
Fn
,
Virtual
};
use
trans
::
callee
::{
Callee
,
CalleeData
,
Fn
,
Intrinsic
,
NamedTupleConstructor
,
Virtual
};
use
trans
::
common
::{
self
,
Block
,
BlockAndBuilder
,
C_undef
};
use
trans
::
debuginfo
::
DebugLoc
;
use
trans
::
Disr
;
use
trans
::
machine
::
llalign_of_min
;
use
trans
::
machine
::
{
llalign_of_min
,
llbitsize_of_real
}
;
use
trans
::
meth
;
use
trans
::
type_of
;
use
trans
::
glue
;
...
...
@@ -27,6 +27,7 @@
use
super
::{
MirContext
,
drop
};
use
super
::
lvalue
::
LvalueRef
;
use
super
::
operand
::
OperandRef
;
use
super
::
operand
::
OperandValue
::{
self
,
FatPtr
,
Immediate
,
Ref
};
impl
<
'bcx
,
'tcx
>
MirContext
<
'bcx
,
'tcx
>
{
...
...
@@ -168,8 +169,51 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
_
=>
unreachable!
(
"{} is not callable"
,
callee
.ty
)
};
// We do not translate intrinsics here (they shouldn’t be functions)
assert
!
(
abi
!=
Abi
::
RustIntrinsic
&&
abi
!=
Abi
::
PlatformIntrinsic
);
// Handle intrinsics old trans wants Expr's for, ourselves.
let
intrinsic
=
match
(
&
callee
.ty.sty
,
&
callee
.data
)
{
(
&
ty
::
TyFnDef
(
def_id
,
_
,
_
),
&
Intrinsic
)
=>
{
Some
(
bcx
.tcx
()
.item_name
(
def_id
)
.as_str
())
}
_
=>
None
};
let
intrinsic
=
intrinsic
.as_ref
()
.map
(|
s
|
&
s
[
..
]);
if
intrinsic
==
Some
(
"move_val_init"
)
{
let
&
(
_
,
target
)
=
destination
.as_ref
()
.unwrap
();
// The first argument is a thin destination pointer.
let
llptr
=
self
.trans_operand
(
&
bcx
,
&
args
[
0
])
.immediate
();
let
val
=
self
.trans_operand
(
&
bcx
,
&
args
[
1
]);
self
.store_operand
(
&
bcx
,
llptr
,
val
);
self
.set_operand_dropped
(
&
bcx
,
&
args
[
1
]);
funclet_br
(
bcx
,
self
.llblock
(
target
));
return
;
}
if
intrinsic
==
Some
(
"transmute"
)
{
let
&
(
ref
dest
,
target
)
=
destination
.as_ref
()
.unwrap
();
let
dst
=
self
.trans_lvalue
(
&
bcx
,
dest
);
let
mut
val
=
self
.trans_operand
(
&
bcx
,
&
args
[
0
]);
if
let
ty
::
TyFnDef
(
def_id
,
substs
,
_
)
=
val
.ty.sty
{
let
llouttype
=
type_of
::
type_of
(
bcx
.ccx
(),
dst
.ty
.to_ty
(
bcx
.tcx
()));
let
out_type_size
=
llbitsize_of_real
(
bcx
.ccx
(),
llouttype
);
if
out_type_size
!=
0
{
// FIXME #19925 Remove this hack after a release cycle.
let
f
=
Callee
::
def
(
bcx
.ccx
(),
def_id
,
substs
);
let
datum
=
f
.reify
(
bcx
.ccx
());
val
=
OperandRef
{
val
:
OperandValue
::
Immediate
(
datum
.val
),
ty
:
datum
.ty
};
}
}
let
llty
=
type_of
::
type_of
(
bcx
.ccx
(),
val
.ty
);
let
cast_ptr
=
bcx
.pointercast
(
dst
.llval
,
llty
.ptr_to
());
self
.store_operand
(
&
bcx
,
cast_ptr
,
val
);
self
.set_operand_dropped
(
&
bcx
,
&
args
[
0
]);
funclet_br
(
bcx
,
self
.llblock
(
target
));
return
;
}
let
extra_args
=
&
args
[
sig
.0
.inputs
.len
()
..
];
let
extra_args
=
extra_args
.iter
()
.map
(|
op_arg
|
{
...
...
@@ -215,7 +259,44 @@ pub fn trans_block(&mut self, bb: mir::BasicBlock) {
&
mut
idx
,
&
mut
callee
.data
)
}
let
fn_ptr
=
callee
.reify
(
bcx
.ccx
())
.val
;
let
fn_ptr
=
match
callee
.data
{
NamedTupleConstructor
(
_
)
=>
{
// FIXME translate this like mir::Rvalue::Aggregate.
callee
.reify
(
bcx
.ccx
())
.val
}
Intrinsic
=>
{
use
trans
::
callee
::
ArgVals
;
use
trans
::
expr
::{
Ignore
,
SaveIn
};
use
trans
::
intrinsic
::
trans_intrinsic_call
;
let
(
dest
,
llargs
)
=
if
fn_ty
.ret
.is_indirect
()
{
(
SaveIn
(
llargs
[
0
]),
&
llargs
[
1
..
])
}
else
if
let
Some
(
dest
)
=
ret_dest
{
(
SaveIn
(
dest
.llval
),
&
llargs
[
..
])
}
else
{
(
Ignore
,
&
llargs
[
..
])
};
bcx
.with_block
(|
bcx
|
{
let
res
=
trans_intrinsic_call
(
bcx
,
callee
.ty
,
&
fn_ty
,
ArgVals
(
llargs
),
dest
,
DebugLoc
::
None
);
let
bcx
=
res
.bcx
.build
();
if
let
Some
((
_
,
target
))
=
*
destination
{
for
op
in
args
{
self
.set_operand_dropped
(
&
bcx
,
op
);
}
funclet_br
(
bcx
,
self
.llblock
(
target
));
}
else
{
// trans_intrinsic_call already used Unreachable.
// bcx.unreachable();
}
});
return
;
}
Fn
(
f
)
=>
f
,
Virtual
(
_
)
=>
unreachable!
(
"Virtual fn ptr not extracted"
)
};
// Many different ways to call a function handled here
if
let
Some
(
cleanup
)
=
cleanup
.map
(|
bb
|
self
.bcx
(
bb
))
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录