Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
e69dacb4
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
e69dacb4
编写于
1月 05, 2018
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc_trans: rename ccx to cx.
上级
fb7de6a0
变更
41
展开全部
隐藏空白更改
内联
并排
Showing
41 changed file
with
1193 addition
and
1193 deletion
+1193
-1193
src/librustc_trans/abi.rs
src/librustc_trans/abi.rs
+91
-91
src/librustc_trans/asm.rs
src/librustc_trans/asm.rs
+8
-8
src/librustc_trans/attributes.rs
src/librustc_trans/attributes.rs
+11
-11
src/librustc_trans/base.rs
src/librustc_trans/base.rs
+98
-98
src/librustc_trans/builder.rs
src/librustc_trans/builder.rs
+30
-30
src/librustc_trans/cabi_aarch64.rs
src/librustc_trans/cabi_aarch64.rs
+10
-10
src/librustc_trans/cabi_arm.rs
src/librustc_trans/cabi_arm.rs
+11
-11
src/librustc_trans/cabi_asmjs.rs
src/librustc_trans/cabi_asmjs.rs
+4
-4
src/librustc_trans/cabi_mips.rs
src/librustc_trans/cabi_mips.rs
+7
-7
src/librustc_trans/cabi_mips64.rs
src/librustc_trans/cabi_mips64.rs
+7
-7
src/librustc_trans/cabi_powerpc.rs
src/librustc_trans/cabi_powerpc.rs
+7
-7
src/librustc_trans/cabi_powerpc64.rs
src/librustc_trans/cabi_powerpc64.rs
+11
-11
src/librustc_trans/cabi_s390x.rs
src/librustc_trans/cabi_s390x.rs
+6
-6
src/librustc_trans/cabi_sparc.rs
src/librustc_trans/cabi_sparc.rs
+7
-7
src/librustc_trans/cabi_sparc64.rs
src/librustc_trans/cabi_sparc64.rs
+10
-10
src/librustc_trans/cabi_x86.rs
src/librustc_trans/cabi_x86.rs
+6
-6
src/librustc_trans/cabi_x86_64.rs
src/librustc_trans/cabi_x86_64.rs
+7
-7
src/librustc_trans/callee.rs
src/librustc_trans/callee.rs
+17
-17
src/librustc_trans/common.rs
src/librustc_trans/common.rs
+18
-18
src/librustc_trans/consts.rs
src/librustc_trans/consts.rs
+58
-58
src/librustc_trans/context.rs
src/librustc_trans/context.rs
+24
-24
src/librustc_trans/debuginfo/create_scope_map.rs
src/librustc_trans/debuginfo/create_scope_map.rs
+8
-8
src/librustc_trans/debuginfo/gdb.rs
src/librustc_trans/debuginfo/gdb.rs
+14
-14
src/librustc_trans/debuginfo/metadata.rs
src/librustc_trans/debuginfo/metadata.rs
+6
-6
src/librustc_trans/debuginfo/mod.rs
src/librustc_trans/debuginfo/mod.rs
+2
-2
src/librustc_trans/debuginfo/namespace.rs
src/librustc_trans/debuginfo/namespace.rs
+12
-12
src/librustc_trans/debuginfo/source_loc.rs
src/librustc_trans/debuginfo/source_loc.rs
+2
-2
src/librustc_trans/declare.rs
src/librustc_trans/declare.rs
+29
-29
src/librustc_trans/glue.rs
src/librustc_trans/glue.rs
+14
-14
src/librustc_trans/intrinsic.rs
src/librustc_trans/intrinsic.rs
+124
-124
src/librustc_trans/meth.rs
src/librustc_trans/meth.rs
+18
-18
src/librustc_trans/mir/analyze.rs
src/librustc_trans/mir/analyze.rs
+10
-10
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/block.rs
+47
-47
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/constant.rs
+149
-149
src/librustc_trans/mir/mod.rs
src/librustc_trans/mir/mod.rs
+21
-21
src/librustc_trans/mir/operand.rs
src/librustc_trans/mir/operand.rs
+22
-22
src/librustc_trans/mir/place.rs
src/librustc_trans/mir/place.rs
+42
-42
src/librustc_trans/mir/rvalue.rs
src/librustc_trans/mir/rvalue.rs
+50
-50
src/librustc_trans/trans_item.rs
src/librustc_trans/trans_item.rs
+37
-37
src/librustc_trans/type_.rs
src/librustc_trans/type_.rs
+67
-67
src/librustc_trans/type_of.rs
src/librustc_trans/type_of.rs
+71
-71
未找到文件。
src/librustc_trans/abi.rs
浏览文件 @
e69dacb4
...
...
@@ -209,8 +209,8 @@ impl Reg {
}
impl
Reg
{
pub
fn
align
(
&
self
,
c
c
x
:
&
CodegenCx
)
->
Align
{
let
dl
=
c
c
x
.data_layout
();
pub
fn
align
(
&
self
,
cx
:
&
CodegenCx
)
->
Align
{
let
dl
=
cx
.data_layout
();
match
self
.kind
{
RegKind
::
Integer
=>
{
match
self
.size
.bits
()
{
...
...
@@ -234,18 +234,18 @@ pub fn align(&self, ccx: &CodegenCx) -> Align {
}
}
pub
fn
llvm_type
(
&
self
,
c
c
x
:
&
CodegenCx
)
->
Type
{
pub
fn
llvm_type
(
&
self
,
cx
:
&
CodegenCx
)
->
Type
{
match
self
.kind
{
RegKind
::
Integer
=>
Type
::
ix
(
c
c
x
,
self
.size
.bits
()),
RegKind
::
Integer
=>
Type
::
ix
(
cx
,
self
.size
.bits
()),
RegKind
::
Float
=>
{
match
self
.size
.bits
()
{
32
=>
Type
::
f32
(
c
c
x
),
64
=>
Type
::
f64
(
c
c
x
),
32
=>
Type
::
f32
(
cx
),
64
=>
Type
::
f64
(
cx
),
_
=>
bug!
(
"unsupported float: {:?}"
,
self
)
}
}
RegKind
::
Vector
=>
{
Type
::
vector
(
&
Type
::
i8
(
c
c
x
),
self
.size
.bytes
())
Type
::
vector
(
&
Type
::
i8
(
cx
),
self
.size
.bytes
())
}
}
}
...
...
@@ -276,12 +276,12 @@ fn from(unit: Reg) -> Uniform {
}
impl
Uniform
{
pub
fn
align
(
&
self
,
c
c
x
:
&
CodegenCx
)
->
Align
{
self
.unit
.align
(
c
c
x
)
pub
fn
align
(
&
self
,
cx
:
&
CodegenCx
)
->
Align
{
self
.unit
.align
(
cx
)
}
pub
fn
llvm_type
(
&
self
,
c
c
x
:
&
CodegenCx
)
->
Type
{
let
llunit
=
self
.unit
.llvm_type
(
c
c
x
);
pub
fn
llvm_type
(
&
self
,
cx
:
&
CodegenCx
)
->
Type
{
let
llunit
=
self
.unit
.llvm_type
(
cx
);
if
self
.total
<=
self
.unit.size
{
return
llunit
;
...
...
@@ -298,16 +298,16 @@ pub fn llvm_type(&self, ccx: &CodegenCx) -> Type {
assert_eq!
(
self
.unit.kind
,
RegKind
::
Integer
);
let
args
:
Vec
<
_
>
=
(
0
..
count
)
.map
(|
_
|
llunit
)
.chain
(
iter
::
once
(
Type
::
ix
(
c
c
x
,
rem_bytes
*
8
)))
.chain
(
iter
::
once
(
Type
::
ix
(
cx
,
rem_bytes
*
8
)))
.collect
();
Type
::
struct_
(
c
c
x
,
&
args
,
false
)
Type
::
struct_
(
cx
,
&
args
,
false
)
}
}
pub
trait
LayoutExt
<
'tcx
>
{
fn
is_aggregate
(
&
self
)
->
bool
;
fn
homogeneous_aggregate
<
'a
>
(
&
self
,
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
Option
<
Reg
>
;
fn
homogeneous_aggregate
<
'a
>
(
&
self
,
cx
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
Option
<
Reg
>
;
}
impl
<
'tcx
>
LayoutExt
<
'tcx
>
for
TyLayout
<
'tcx
>
{
...
...
@@ -321,7 +321,7 @@ fn is_aggregate(&self) -> bool {
}
}
fn
homogeneous_aggregate
<
'a
>
(
&
self
,
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
Option
<
Reg
>
{
fn
homogeneous_aggregate
<
'a
>
(
&
self
,
cx
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
Option
<
Reg
>
{
match
self
.abi
{
layout
::
Abi
::
Uninhabited
=>
None
,
...
...
@@ -354,7 +354,7 @@ fn homogeneous_aggregate<'a>(&self, ccx: &CodegenCx<'a, 'tcx>) -> Option<Reg> {
let
is_union
=
match
self
.fields
{
layout
::
FieldPlacement
::
Array
{
count
,
..
}
=>
{
if
count
>
0
{
return
self
.field
(
c
cx
,
0
)
.homogeneous_aggregate
(
c
cx
);
return
self
.field
(
c
x
,
0
)
.homogeneous_aggregate
(
cx
);
}
else
{
return
None
;
}
...
...
@@ -368,8 +368,8 @@ fn homogeneous_aggregate<'a>(&self, ccx: &CodegenCx<'a, 'tcx>) -> Option<Reg> {
return
None
;
}
let
field
=
self
.field
(
c
c
x
,
i
);
match
(
result
,
field
.homogeneous_aggregate
(
c
c
x
))
{
let
field
=
self
.field
(
cx
,
i
);
match
(
result
,
field
.homogeneous_aggregate
(
cx
))
{
// The field itself must be a homogeneous aggregate.
(
_
,
None
)
=>
return
None
,
// If this is the first field, record the unit.
...
...
@@ -423,34 +423,34 @@ fn from(uniform: Uniform) -> CastTarget {
}
impl
CastTarget
{
pub
fn
size
(
&
self
,
c
c
x
:
&
CodegenCx
)
->
Size
{
pub
fn
size
(
&
self
,
cx
:
&
CodegenCx
)
->
Size
{
match
*
self
{
CastTarget
::
Uniform
(
u
)
=>
u
.total
,
CastTarget
::
Pair
(
a
,
b
)
=>
{
(
a
.size
.abi_align
(
a
.align
(
c
c
x
))
+
b
.size
)
.abi_align
(
self
.align
(
c
c
x
))
(
a
.size
.abi_align
(
a
.align
(
cx
))
+
b
.size
)
.abi_align
(
self
.align
(
cx
))
}
}
}
pub
fn
align
(
&
self
,
c
c
x
:
&
CodegenCx
)
->
Align
{
pub
fn
align
(
&
self
,
cx
:
&
CodegenCx
)
->
Align
{
match
*
self
{
CastTarget
::
Uniform
(
u
)
=>
u
.align
(
c
c
x
),
CastTarget
::
Uniform
(
u
)
=>
u
.align
(
cx
),
CastTarget
::
Pair
(
a
,
b
)
=>
{
c
c
x
.data_layout
()
.aggregate_align
.max
(
a
.align
(
c
c
x
))
.max
(
b
.align
(
c
c
x
))
cx
.data_layout
()
.aggregate_align
.max
(
a
.align
(
cx
))
.max
(
b
.align
(
cx
))
}
}
}
pub
fn
llvm_type
(
&
self
,
c
c
x
:
&
CodegenCx
)
->
Type
{
pub
fn
llvm_type
(
&
self
,
cx
:
&
CodegenCx
)
->
Type
{
match
*
self
{
CastTarget
::
Uniform
(
u
)
=>
u
.llvm_type
(
c
c
x
),
CastTarget
::
Uniform
(
u
)
=>
u
.llvm_type
(
cx
),
CastTarget
::
Pair
(
a
,
b
)
=>
{
Type
::
struct_
(
c
c
x
,
&
[
a
.llvm_type
(
c
c
x
),
b
.llvm_type
(
c
c
x
)
Type
::
struct_
(
cx
,
&
[
a
.llvm_type
(
cx
),
b
.llvm_type
(
cx
)
],
false
)
}
}
...
...
@@ -547,8 +547,8 @@ pub fn is_ignore(&self) -> bool {
/// Get the LLVM type for an place of the original Rust type of
/// this argument/return, i.e. the result of `type_of::type_of`.
pub
fn
memory_ty
(
&
self
,
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
Type
{
self
.layout
.llvm_type
(
c
c
x
)
pub
fn
memory_ty
(
&
self
,
cx
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
Type
{
self
.layout
.llvm_type
(
cx
)
}
/// Store a direct/indirect value described by this ArgType into a
...
...
@@ -559,7 +559,7 @@ pub fn store(&self, bcx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>)
if
self
.is_ignore
()
{
return
;
}
let
c
cx
=
bcx
.c
cx
;
let
c
x
=
bcx
.
cx
;
if
self
.is_indirect
()
{
OperandValue
::
Ref
(
val
,
self
.layout.align
)
.store
(
bcx
,
dst
)
}
else
if
let
PassMode
::
Cast
(
cast
)
=
self
.mode
{
...
...
@@ -567,7 +567,7 @@ pub fn store(&self, bcx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>)
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
let
can_store_through_cast_ptr
=
false
;
if
can_store_through_cast_ptr
{
let
cast_dst
=
bcx
.pointercast
(
dst
.llval
,
cast
.llvm_type
(
c
c
x
)
.ptr_to
());
let
cast_dst
=
bcx
.pointercast
(
dst
.llval
,
cast
.llvm_type
(
cx
)
.ptr_to
());
bcx
.store
(
val
,
cast_dst
,
self
.layout.align
);
}
else
{
// The actual return type is a struct, but the ABI
...
...
@@ -585,9 +585,9 @@ pub fn store(&self, bcx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>)
// bitcasting to the struct type yields invalid cast errors.
// We instead thus allocate some scratch space...
let
scratch_size
=
cast
.size
(
c
c
x
);
let
scratch_align
=
cast
.align
(
c
c
x
);
let
llscratch
=
bcx
.alloca
(
cast
.llvm_type
(
c
c
x
),
"abi_cast"
,
scratch_align
);
let
scratch_size
=
cast
.size
(
cx
);
let
scratch_align
=
cast
.align
(
cx
);
let
llscratch
=
bcx
.alloca
(
cast
.llvm_type
(
cx
),
"abi_cast"
,
scratch_align
);
bcx
.lifetime_start
(
llscratch
,
scratch_size
);
// ...where we first store the value...
...
...
@@ -595,9 +595,9 @@ pub fn store(&self, bcx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>)
// ...and then memcpy it to the intended destination.
base
::
call_memcpy
(
bcx
,
bcx
.pointercast
(
dst
.llval
,
Type
::
i8p
(
c
c
x
)),
bcx
.pointercast
(
llscratch
,
Type
::
i8p
(
c
c
x
)),
C_usize
(
c
c
x
,
self
.layout.size
.bytes
()),
bcx
.pointercast
(
dst
.llval
,
Type
::
i8p
(
cx
)),
bcx
.pointercast
(
llscratch
,
Type
::
i8p
(
cx
)),
C_usize
(
cx
,
self
.layout.size
.bytes
()),
self
.layout.align
.min
(
scratch_align
));
bcx
.lifetime_end
(
llscratch
,
scratch_size
);
...
...
@@ -647,26 +647,26 @@ pub struct FnType<'tcx> {
}
impl
<
'a
,
'tcx
>
FnType
<
'tcx
>
{
pub
fn
of_instance
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
instance
:
&
ty
::
Instance
<
'tcx
>
)
pub
fn
of_instance
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
instance
:
&
ty
::
Instance
<
'tcx
>
)
->
Self
{
let
fn_ty
=
instance
.ty
(
c
c
x
.tcx
);
let
sig
=
ty_fn_sig
(
c
c
x
,
fn_ty
);
let
sig
=
c
c
x
.tcx
.erase_late_bound_regions_and_normalize
(
&
sig
);
FnType
::
new
(
c
c
x
,
sig
,
&
[])
let
fn_ty
=
instance
.ty
(
cx
.tcx
);
let
sig
=
ty_fn_sig
(
cx
,
fn_ty
);
let
sig
=
cx
.tcx
.erase_late_bound_regions_and_normalize
(
&
sig
);
FnType
::
new
(
cx
,
sig
,
&
[])
}
pub
fn
new
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
new
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
sig
:
ty
::
FnSig
<
'tcx
>
,
extra_args
:
&
[
Ty
<
'tcx
>
])
->
FnType
<
'tcx
>
{
let
mut
fn_ty
=
FnType
::
unadjusted
(
c
c
x
,
sig
,
extra_args
);
fn_ty
.adjust_for_abi
(
c
c
x
,
sig
.abi
);
let
mut
fn_ty
=
FnType
::
unadjusted
(
cx
,
sig
,
extra_args
);
fn_ty
.adjust_for_abi
(
cx
,
sig
.abi
);
fn_ty
}
pub
fn
new_vtable
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
new_vtable
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
sig
:
ty
::
FnSig
<
'tcx
>
,
extra_args
:
&
[
Ty
<
'tcx
>
])
->
FnType
<
'tcx
>
{
let
mut
fn_ty
=
FnType
::
unadjusted
(
c
c
x
,
sig
,
extra_args
);
let
mut
fn_ty
=
FnType
::
unadjusted
(
cx
,
sig
,
extra_args
);
// Don't pass the vtable, it's not an argument of the virtual fn.
{
let
self_arg
=
&
mut
fn_ty
.args
[
0
];
...
...
@@ -681,20 +681,20 @@ pub fn new_vtable(ccx: &CodegenCx<'a, 'tcx>,
.unwrap_or_else
(||
{
bug!
(
"FnType::new_vtable: non-pointer self {:?}"
,
self_arg
)
})
.ty
;
let
fat_ptr_ty
=
c
c
x
.tcx
.mk_mut_ptr
(
pointee
);
self_arg
.layout
=
c
cx
.layout_of
(
fat_ptr_ty
)
.field
(
c
cx
,
0
);
let
fat_ptr_ty
=
cx
.tcx
.mk_mut_ptr
(
pointee
);
self_arg
.layout
=
c
x
.layout_of
(
fat_ptr_ty
)
.field
(
cx
,
0
);
}
fn_ty
.adjust_for_abi
(
c
c
x
,
sig
.abi
);
fn_ty
.adjust_for_abi
(
cx
,
sig
.abi
);
fn_ty
}
pub
fn
unadjusted
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
unadjusted
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
sig
:
ty
::
FnSig
<
'tcx
>
,
extra_args
:
&
[
Ty
<
'tcx
>
])
->
FnType
<
'tcx
>
{
debug!
(
"FnType::unadjusted({:?}, {:?})"
,
sig
,
extra_args
);
use
self
::
Abi
::
*
;
let
cconv
=
match
c
c
x
.sess
()
.target.target
.adjust_abi
(
sig
.abi
)
{
let
cconv
=
match
cx
.sess
()
.target.target
.adjust_abi
(
sig
.abi
)
{
RustIntrinsic
|
PlatformIntrinsic
|
Rust
|
RustCall
=>
llvm
::
CCallConv
,
...
...
@@ -737,7 +737,7 @@ pub fn unadjusted(ccx: &CodegenCx<'a, 'tcx>,
extra_args
};
let
target
=
&
c
c
x
.sess
()
.target.target
;
let
target
=
&
cx
.sess
()
.target.target
;
let
win_x64_gnu
=
target
.target_os
==
"windows"
&&
target
.arch
==
"x86_64"
&&
target
.target_env
==
"gnu"
;
...
...
@@ -772,7 +772,7 @@ pub fn unadjusted(ccx: &CodegenCx<'a, 'tcx>,
}
}
if
let
Some
(
pointee
)
=
layout
.pointee_info_at
(
c
c
x
,
offset
)
{
if
let
Some
(
pointee
)
=
layout
.pointee_info_at
(
cx
,
offset
)
{
if
let
Some
(
kind
)
=
pointee
.safe
{
attrs
.pointee_size
=
pointee
.size
;
attrs
.pointee_align
=
Some
(
pointee
.align
);
...
...
@@ -809,7 +809,7 @@ pub fn unadjusted(ccx: &CodegenCx<'a, 'tcx>,
};
let
arg_of
=
|
ty
:
Ty
<
'tcx
>
,
is_return
:
bool
|
{
let
mut
arg
=
ArgType
::
new
(
c
c
x
.layout_of
(
ty
));
let
mut
arg
=
ArgType
::
new
(
cx
.layout_of
(
ty
));
if
arg
.layout
.is_zst
()
{
// For some forsaken reason, x86_64-pc-windows-gnu
// doesn't ignore zero-sized struct arguments.
...
...
@@ -832,7 +832,7 @@ pub fn unadjusted(ccx: &CodegenCx<'a, 'tcx>,
adjust_for_rust_scalar
(
&
mut
b_attrs
,
b
,
arg
.layout
,
a
.value
.size
(
c
cx
)
.abi_align
(
b
.value
.align
(
c
cx
)),
a
.value
.size
(
c
x
)
.abi_align
(
b
.value
.align
(
cx
)),
false
);
arg
.mode
=
PassMode
::
Pair
(
a_attrs
,
b_attrs
);
return
arg
;
...
...
@@ -863,7 +863,7 @@ pub fn unadjusted(ccx: &CodegenCx<'a, 'tcx>,
}
fn
adjust_for_abi
(
&
mut
self
,
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
abi
:
Abi
)
{
if
abi
==
Abi
::
Unadjusted
{
return
}
...
...
@@ -878,7 +878,7 @@ fn adjust_for_abi(&mut self,
}
let
size
=
arg
.layout.size
;
if
size
>
layout
::
Pointer
.size
(
c
c
x
)
{
if
size
>
layout
::
Pointer
.size
(
cx
)
{
arg
.make_indirect
();
}
else
{
// We want to pass small aggregates as immediates, but using
...
...
@@ -900,38 +900,38 @@ fn adjust_for_abi(&mut self,
return
;
}
match
&
c
c
x
.sess
()
.target.target.arch
[
..
]
{
match
&
cx
.sess
()
.target.target.arch
[
..
]
{
"x86"
=>
{
let
flavor
=
if
abi
==
Abi
::
Fastcall
{
cabi_x86
::
Flavor
::
Fastcall
}
else
{
cabi_x86
::
Flavor
::
General
};
cabi_x86
::
compute_abi_info
(
c
c
x
,
self
,
flavor
);
cabi_x86
::
compute_abi_info
(
cx
,
self
,
flavor
);
},
"x86_64"
=>
if
abi
==
Abi
::
SysV64
{
cabi_x86_64
::
compute_abi_info
(
c
c
x
,
self
);
}
else
if
abi
==
Abi
::
Win64
||
c
c
x
.sess
()
.target.target.options.is_like_windows
{
cabi_x86_64
::
compute_abi_info
(
cx
,
self
);
}
else
if
abi
==
Abi
::
Win64
||
cx
.sess
()
.target.target.options.is_like_windows
{
cabi_x86_win64
::
compute_abi_info
(
self
);
}
else
{
cabi_x86_64
::
compute_abi_info
(
c
c
x
,
self
);
cabi_x86_64
::
compute_abi_info
(
cx
,
self
);
},
"aarch64"
=>
cabi_aarch64
::
compute_abi_info
(
c
c
x
,
self
),
"arm"
=>
cabi_arm
::
compute_abi_info
(
c
c
x
,
self
),
"mips"
=>
cabi_mips
::
compute_abi_info
(
c
c
x
,
self
),
"mips64"
=>
cabi_mips64
::
compute_abi_info
(
c
c
x
,
self
),
"powerpc"
=>
cabi_powerpc
::
compute_abi_info
(
c
c
x
,
self
),
"powerpc64"
=>
cabi_powerpc64
::
compute_abi_info
(
c
c
x
,
self
),
"s390x"
=>
cabi_s390x
::
compute_abi_info
(
c
c
x
,
self
),
"asmjs"
=>
cabi_asmjs
::
compute_abi_info
(
c
c
x
,
self
),
"wasm32"
=>
cabi_asmjs
::
compute_abi_info
(
c
c
x
,
self
),
"aarch64"
=>
cabi_aarch64
::
compute_abi_info
(
cx
,
self
),
"arm"
=>
cabi_arm
::
compute_abi_info
(
cx
,
self
),
"mips"
=>
cabi_mips
::
compute_abi_info
(
cx
,
self
),
"mips64"
=>
cabi_mips64
::
compute_abi_info
(
cx
,
self
),
"powerpc"
=>
cabi_powerpc
::
compute_abi_info
(
cx
,
self
),
"powerpc64"
=>
cabi_powerpc64
::
compute_abi_info
(
cx
,
self
),
"s390x"
=>
cabi_s390x
::
compute_abi_info
(
cx
,
self
),
"asmjs"
=>
cabi_asmjs
::
compute_abi_info
(
cx
,
self
),
"wasm32"
=>
cabi_asmjs
::
compute_abi_info
(
cx
,
self
),
"msp430"
=>
cabi_msp430
::
compute_abi_info
(
self
),
"sparc"
=>
cabi_sparc
::
compute_abi_info
(
c
c
x
,
self
),
"sparc64"
=>
cabi_sparc64
::
compute_abi_info
(
c
c
x
,
self
),
"sparc"
=>
cabi_sparc
::
compute_abi_info
(
cx
,
self
),
"sparc64"
=>
cabi_sparc64
::
compute_abi_info
(
cx
,
self
),
"nvptx"
=>
cabi_nvptx
::
compute_abi_info
(
self
),
"nvptx64"
=>
cabi_nvptx64
::
compute_abi_info
(
self
),
"hexagon"
=>
cabi_hexagon
::
compute_abi_info
(
self
),
a
=>
c
c
x
.sess
()
.fatal
(
&
format!
(
"unrecognized arch
\"
{}
\"
in target specification"
,
a
))
a
=>
cx
.sess
()
.fatal
(
&
format!
(
"unrecognized arch
\"
{}
\"
in target specification"
,
a
))
}
if
let
PassMode
::
Indirect
(
ref
mut
attrs
)
=
self
.ret.mode
{
...
...
@@ -939,37 +939,37 @@ fn adjust_for_abi(&mut self,
}
}
pub
fn
llvm_type
(
&
self
,
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
Type
{
pub
fn
llvm_type
(
&
self
,
cx
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
Type
{
let
mut
llargument_tys
=
Vec
::
new
();
let
llreturn_ty
=
match
self
.ret.mode
{
PassMode
::
Ignore
=>
Type
::
void
(
c
c
x
),
PassMode
::
Ignore
=>
Type
::
void
(
cx
),
PassMode
::
Direct
(
_
)
|
PassMode
::
Pair
(
..
)
=>
{
self
.ret.layout
.immediate_llvm_type
(
c
c
x
)
self
.ret.layout
.immediate_llvm_type
(
cx
)
}
PassMode
::
Cast
(
cast
)
=>
cast
.llvm_type
(
c
c
x
),
PassMode
::
Cast
(
cast
)
=>
cast
.llvm_type
(
cx
),
PassMode
::
Indirect
(
_
)
=>
{
llargument_tys
.push
(
self
.ret
.memory_ty
(
c
c
x
)
.ptr_to
());
Type
::
void
(
c
c
x
)
llargument_tys
.push
(
self
.ret
.memory_ty
(
cx
)
.ptr_to
());
Type
::
void
(
cx
)
}
};
for
arg
in
&
self
.args
{
// add padding
if
let
Some
(
ty
)
=
arg
.pad
{
llargument_tys
.push
(
ty
.llvm_type
(
c
c
x
));
llargument_tys
.push
(
ty
.llvm_type
(
cx
));
}
let
llarg_ty
=
match
arg
.mode
{
PassMode
::
Ignore
=>
continue
,
PassMode
::
Direct
(
_
)
=>
arg
.layout
.immediate_llvm_type
(
c
c
x
),
PassMode
::
Direct
(
_
)
=>
arg
.layout
.immediate_llvm_type
(
cx
),
PassMode
::
Pair
(
..
)
=>
{
llargument_tys
.push
(
arg
.layout
.scalar_pair_element_llvm_type
(
c
c
x
,
0
));
llargument_tys
.push
(
arg
.layout
.scalar_pair_element_llvm_type
(
c
c
x
,
1
));
llargument_tys
.push
(
arg
.layout
.scalar_pair_element_llvm_type
(
cx
,
0
));
llargument_tys
.push
(
arg
.layout
.scalar_pair_element_llvm_type
(
cx
,
1
));
continue
;
}
PassMode
::
Cast
(
cast
)
=>
cast
.llvm_type
(
c
c
x
),
PassMode
::
Indirect
(
_
)
=>
arg
.memory_ty
(
c
c
x
)
.ptr_to
(),
PassMode
::
Cast
(
cast
)
=>
cast
.llvm_type
(
cx
),
PassMode
::
Indirect
(
_
)
=>
arg
.memory_ty
(
cx
)
.ptr_to
(),
};
llargument_tys
.push
(
llarg_ty
);
}
...
...
src/librustc_trans/asm.rs
浏览文件 @
e69dacb4
...
...
@@ -45,7 +45,7 @@ pub fn trans_inline_asm<'a, 'tcx>(
if
out
.is_indirect
{
indirect_outputs
.push
(
place
.load
(
bcx
)
.immediate
());
}
else
{
output_types
.push
(
place
.layout
.llvm_type
(
bcx
.c
c
x
));
output_types
.push
(
place
.layout
.llvm_type
(
bcx
.cx
));
}
}
if
!
indirect_outputs
.is_empty
()
{
...
...
@@ -76,9 +76,9 @@ pub fn trans_inline_asm<'a, 'tcx>(
// Depending on how many outputs we have, the return type is different
let
num_outputs
=
output_types
.len
();
let
output_type
=
match
num_outputs
{
0
=>
Type
::
void
(
bcx
.c
c
x
),
0
=>
Type
::
void
(
bcx
.cx
),
1
=>
output_types
[
0
],
_
=>
Type
::
struct_
(
bcx
.c
c
x
,
&
output_types
,
false
)
_
=>
Type
::
struct_
(
bcx
.cx
,
&
output_types
,
false
)
};
let
dialect
=
match
ia
.dialect
{
...
...
@@ -109,20 +109,20 @@ pub fn trans_inline_asm<'a, 'tcx>(
// back to source locations. See #17552.
unsafe
{
let
key
=
"srcloc"
;
let
kind
=
llvm
::
LLVMGetMDKindIDInContext
(
bcx
.c
c
x.llcx
,
let
kind
=
llvm
::
LLVMGetMDKindIDInContext
(
bcx
.cx.llcx
,
key
.as_ptr
()
as
*
const
c_char
,
key
.len
()
as
c_uint
);
let
val
:
llvm
::
ValueRef
=
C_i32
(
bcx
.c
c
x
,
ia
.ctxt
.outer
()
.as_u32
()
as
i32
);
let
val
:
llvm
::
ValueRef
=
C_i32
(
bcx
.cx
,
ia
.ctxt
.outer
()
.as_u32
()
as
i32
);
llvm
::
LLVMSetMetadata
(
r
,
kind
,
llvm
::
LLVMMDNodeInContext
(
bcx
.c
c
x.llcx
,
&
val
,
1
));
llvm
::
LLVMMDNodeInContext
(
bcx
.cx.llcx
,
&
val
,
1
));
}
}
pub
fn
trans_global_asm
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
trans_global_asm
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ga
:
&
hir
::
GlobalAsm
)
{
let
asm
=
CString
::
new
(
ga
.asm
.as_str
()
.as_bytes
())
.unwrap
();
unsafe
{
llvm
::
LLVMRustAppendModuleInlineAsm
(
c
c
x
.llmod
,
asm
.as_ptr
());
llvm
::
LLVMRustAppendModuleInlineAsm
(
cx
.llmod
,
asm
.as_ptr
());
}
}
src/librustc_trans/attributes.rs
浏览文件 @
e69dacb4
...
...
@@ -67,27 +67,27 @@ pub fn naked(val: ValueRef, is_naked: bool) {
Attribute
::
Naked
.toggle_llfn
(
Function
,
val
,
is_naked
);
}
pub
fn
set_frame_pointer_elimination
(
c
c
x
:
&
CodegenCx
,
llfn
:
ValueRef
)
{
pub
fn
set_frame_pointer_elimination
(
cx
:
&
CodegenCx
,
llfn
:
ValueRef
)
{
// FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
// parameter.
if
c
c
x
.sess
()
.must_not_eliminate_frame_pointers
()
{
if
cx
.sess
()
.must_not_eliminate_frame_pointers
()
{
llvm
::
AddFunctionAttrStringValue
(
llfn
,
llvm
::
AttributePlace
::
Function
,
cstr
(
"no-frame-pointer-elim
\0
"
),
cstr
(
"true
\0
"
));
}
}
pub
fn
set_probestack
(
c
c
x
:
&
CodegenCx
,
llfn
:
ValueRef
)
{
pub
fn
set_probestack
(
cx
:
&
CodegenCx
,
llfn
:
ValueRef
)
{
// Only use stack probes if the target specification indicates that we
// should be using stack probes
if
!
c
c
x
.sess
()
.target.target.options.stack_probes
{
if
!
cx
.sess
()
.target.target.options.stack_probes
{
return
}
// Currently stack probes seem somewhat incompatible with the address
// sanitizer. With asan we're already protected from stack overflow anyway
// so we don't really need stack probes regardless.
match
c
c
x
.sess
()
.opts.debugging_opts.sanitizer
{
match
cx
.sess
()
.opts.debugging_opts.sanitizer
{
Some
(
Sanitizer
::
Address
)
=>
return
,
_
=>
{}
}
...
...
@@ -101,13 +101,13 @@ pub fn set_probestack(ccx: &CodegenCx, llfn: ValueRef) {
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
/// attributes.
pub
fn
from_fn_attrs
(
c
c
x
:
&
CodegenCx
,
llfn
:
ValueRef
,
id
:
DefId
)
{
pub
fn
from_fn_attrs
(
cx
:
&
CodegenCx
,
llfn
:
ValueRef
,
id
:
DefId
)
{
use
syntax
::
attr
::
*
;
let
attrs
=
c
c
x
.tcx
.get_attrs
(
id
);
inline
(
llfn
,
find_inline_attr
(
Some
(
c
c
x
.sess
()
.diagnostic
()),
&
attrs
));
let
attrs
=
cx
.tcx
.get_attrs
(
id
);
inline
(
llfn
,
find_inline_attr
(
Some
(
cx
.sess
()
.diagnostic
()),
&
attrs
));
set_frame_pointer_elimination
(
c
c
x
,
llfn
);
set_probestack
(
c
c
x
,
llfn
);
set_frame_pointer_elimination
(
cx
,
llfn
);
set_probestack
(
cx
,
llfn
);
for
attr
in
attrs
.iter
()
{
if
attr
.check_name
(
"cold"
)
{
...
...
@@ -124,7 +124,7 @@ pub fn from_fn_attrs(ccx: &CodegenCx, llfn: ValueRef, id: DefId) {
}
}
let
target_features
=
c
c
x
.tcx
.target_features_enabled
(
id
);
let
target_features
=
cx
.tcx
.target_features_enabled
(
id
);
if
!
target_features
.is_empty
()
{
let
val
=
CString
::
new
(
target_features
.join
(
","
))
.unwrap
();
llvm
::
AddFunctionAttrStringValue
(
...
...
src/librustc_trans/base.rs
浏览文件 @
e69dacb4
此差异已折叠。
点击以展开。
src/librustc_trans/builder.rs
浏览文件 @
e69dacb4
...
...
@@ -32,7 +32,7 @@
#[must_use]
pub
struct
Builder
<
'a
,
'tcx
:
'a
>
{
pub
llbuilder
:
BuilderRef
,
pub
c
c
x
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
pub
cx
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
}
impl
<
'a
,
'tcx
>
Drop
for
Builder
<
'a
,
'tcx
>
{
...
...
@@ -51,12 +51,12 @@ fn noname() -> *const c_char {
}
impl
<
'a
,
'tcx
>
Builder
<
'a
,
'tcx
>
{
pub
fn
new_block
<
'b
>
(
c
c
x
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
llfn
:
ValueRef
,
name
:
&
'b
str
)
->
Self
{
let
builder
=
Builder
::
with_c
cx
(
c
cx
);
pub
fn
new_block
<
'b
>
(
cx
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
llfn
:
ValueRef
,
name
:
&
'b
str
)
->
Self
{
let
builder
=
Builder
::
with_c
x
(
cx
);
let
llbb
=
unsafe
{
let
name
=
CString
::
new
(
name
)
.unwrap
();
llvm
::
LLVMAppendBasicBlockInContext
(
c
c
x
.llcx
,
cx
.llcx
,
llfn
,
name
.as_ptr
()
)
...
...
@@ -65,27 +65,27 @@ pub fn new_block<'b>(ccx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, name: &'b str
builder
}
pub
fn
with_c
cx
(
c
cx
:
&
'a
CodegenCx
<
'a
,
'tcx
>
)
->
Self
{
pub
fn
with_c
x
(
cx
:
&
'a
CodegenCx
<
'a
,
'tcx
>
)
->
Self
{
// Create a fresh builder from the crate context.
let
llbuilder
=
unsafe
{
llvm
::
LLVMCreateBuilderInContext
(
c
c
x
.llcx
)
llvm
::
LLVMCreateBuilderInContext
(
cx
.llcx
)
};
Builder
{
llbuilder
,
c
c
x
,
cx
,
}
}
pub
fn
build_sibling_block
<
'b
>
(
&
self
,
name
:
&
'b
str
)
->
Builder
<
'a
,
'tcx
>
{
Builder
::
new_block
(
self
.c
c
x
,
self
.llfn
(),
name
)
Builder
::
new_block
(
self
.cx
,
self
.llfn
(),
name
)
}
pub
fn
sess
(
&
self
)
->
&
Session
{
self
.c
c
x
.sess
()
self
.cx
.sess
()
}
pub
fn
tcx
(
&
self
)
->
TyCtxt
<
'a
,
'tcx
,
'tcx
>
{
self
.c
c
x.tcx
self
.cx.tcx
}
pub
fn
llfn
(
&
self
)
->
ValueRef
{
...
...
@@ -101,11 +101,11 @@ pub fn llbb(&self) -> BasicBlockRef {
}
fn
count_insn
(
&
self
,
category
:
&
str
)
{
if
self
.c
c
x
.sess
()
.trans_stats
()
{
self
.c
c
x.stats
.borrow_mut
()
.n_llvm_insns
+=
1
;
if
self
.cx
.sess
()
.trans_stats
()
{
self
.cx.stats
.borrow_mut
()
.n_llvm_insns
+=
1
;
}
if
self
.c
c
x
.sess
()
.count_llvm_insns
()
{
*
self
.c
c
x.stats
if
self
.cx
.sess
()
.count_llvm_insns
()
{
*
self
.cx.stats
.borrow_mut
()
.llvm_insns
.entry
(
category
.to_string
())
...
...
@@ -489,7 +489,7 @@ pub fn not(&self, v: ValueRef) -> ValueRef {
}
pub
fn
alloca
(
&
self
,
ty
:
Type
,
name
:
&
str
,
align
:
Align
)
->
ValueRef
{
let
builder
=
Builder
::
with_c
cx
(
self
.c
cx
);
let
builder
=
Builder
::
with_c
x
(
self
.
cx
);
builder
.position_at_start
(
unsafe
{
llvm
::
LLVMGetFirstBasicBlock
(
self
.llfn
())
});
...
...
@@ -558,7 +558,7 @@ pub fn range_metadata(&self, load: ValueRef, range: Range<u128>) {
];
llvm
::
LLVMSetMetadata
(
load
,
llvm
::
MD_range
as
c_uint
,
llvm
::
LLVMMDNodeInContext
(
self
.c
c
x.llcx
,
llvm
::
LLVMMDNodeInContext
(
self
.cx.llcx
,
v
.as_ptr
(),
v
.len
()
as
c_uint
));
}
...
...
@@ -567,7 +567,7 @@ pub fn range_metadata(&self, load: ValueRef, range: Range<u128>) {
pub
fn
nonnull_metadata
(
&
self
,
load
:
ValueRef
)
{
unsafe
{
llvm
::
LLVMSetMetadata
(
load
,
llvm
::
MD_nonnull
as
c_uint
,
llvm
::
LLVMMDNodeInContext
(
self
.c
c
x.llcx
,
ptr
::
null
(),
0
));
llvm
::
LLVMMDNodeInContext
(
self
.cx.llcx
,
ptr
::
null
(),
0
));
}
}
...
...
@@ -620,8 +620,8 @@ pub fn nontemporal_store(&self, val: ValueRef, ptr: ValueRef) -> ValueRef {
// point to a metadata value of the integer 1. Who knew?
//
// [1]: http://llvm.org/docs/LangRef.html#store-instruction
let
one
=
C_i32
(
self
.c
c
x
,
1
);
let
node
=
llvm
::
LLVMMDNodeInContext
(
self
.c
c
x.llcx
,
let
one
=
C_i32
(
self
.cx
,
1
);
let
node
=
llvm
::
LLVMMDNodeInContext
(
self
.cx.llcx
,
&
one
,
1
);
llvm
::
LLVMSetMetadata
(
insn
,
...
...
@@ -840,24 +840,24 @@ pub fn phi(&self, ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRe
}
pub
fn
add_span_comment
(
&
self
,
sp
:
Span
,
text
:
&
str
)
{
if
self
.c
c
x
.sess
()
.asm_comments
()
{
if
self
.cx
.sess
()
.asm_comments
()
{
let
s
=
format!
(
"{} ({})"
,
text
,
self
.c
c
x
.sess
()
.codemap
()
.span_to_string
(
sp
));
self
.cx
.sess
()
.codemap
()
.span_to_string
(
sp
));
debug!
(
"{}"
,
s
);
self
.add_comment
(
&
s
);
}
}
pub
fn
add_comment
(
&
self
,
text
:
&
str
)
{
if
self
.c
c
x
.sess
()
.asm_comments
()
{
if
self
.cx
.sess
()
.asm_comments
()
{
let
sanitized
=
text
.replace
(
"$"
,
""
);
let
comment_text
=
format!
(
"{} {}"
,
"#"
,
sanitized
.replace
(
"
\n
"
,
"
\n\t
# "
));
self
.count_insn
(
"inlineasm"
);
let
comment_text
=
CString
::
new
(
comment_text
)
.unwrap
();
let
asm
=
unsafe
{
llvm
::
LLVMConstInlineAsm
(
Type
::
func
(
&
[],
&
Type
::
void
(
self
.c
c
x
))
.to_ref
(),
llvm
::
LLVMConstInlineAsm
(
Type
::
func
(
&
[],
&
Type
::
void
(
self
.cx
))
.to_ref
(),
comment_text
.as_ptr
(),
noname
(),
False
,
False
)
};
...
...
@@ -949,8 +949,8 @@ pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef {
unsafe
{
let
elt_ty
=
val_ty
(
elt
);
let
undef
=
llvm
::
LLVMGetUndef
(
Type
::
vector
(
&
elt_ty
,
num_elts
as
u64
)
.to_ref
());
let
vec
=
self
.insert_element
(
undef
,
elt
,
C_i32
(
self
.c
c
x
,
0
));
let
vec_i32_ty
=
Type
::
vector
(
&
Type
::
i32
(
self
.c
c
x
),
num_elts
as
u64
);
let
vec
=
self
.insert_element
(
undef
,
elt
,
C_i32
(
self
.cx
,
0
));
let
vec_i32_ty
=
Type
::
vector
(
&
Type
::
i32
(
self
.cx
),
num_elts
as
u64
);
self
.shuffle_vector
(
vec
,
undef
,
C_null
(
vec_i32_ty
))
}
}
...
...
@@ -1160,7 +1160,7 @@ pub fn add_incoming_to_phi(&self, phi: ValueRef, val: ValueRef, bb: BasicBlockRe
pub
fn
set_invariant_load
(
&
self
,
load
:
ValueRef
)
{
unsafe
{
llvm
::
LLVMSetMetadata
(
load
,
llvm
::
MD_invariant_load
as
c_uint
,
llvm
::
LLVMMDNodeInContext
(
self
.c
c
x.llcx
,
ptr
::
null
(),
0
));
llvm
::
LLVMMDNodeInContext
(
self
.cx.llcx
,
ptr
::
null
(),
0
));
}
}
...
...
@@ -1245,7 +1245,7 @@ pub fn lifetime_end(&self, ptr: ValueRef, size: Size) {
/// If LLVM lifetime intrinsic support is disabled (i.e. optimizations
/// off) or `ptr` is zero-sized, then no-op (does not call `emit`).
fn
call_lifetime_intrinsic
(
&
self
,
intrinsic
:
&
str
,
ptr
:
ValueRef
,
size
:
Size
)
{
if
self
.c
c
x
.sess
()
.opts.optimize
==
config
::
OptLevel
::
No
{
if
self
.cx
.sess
()
.opts.optimize
==
config
::
OptLevel
::
No
{
return
;
}
...
...
@@ -1254,9 +1254,9 @@ fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: ValueRef, size: Size) {
return
;
}
let
lifetime_intrinsic
=
self
.c
c
x
.get_intrinsic
(
intrinsic
);
let
lifetime_intrinsic
=
self
.cx
.get_intrinsic
(
intrinsic
);
let
ptr
=
self
.pointercast
(
ptr
,
Type
::
i8p
(
self
.c
c
x
));
self
.call
(
lifetime_intrinsic
,
&
[
C_u64
(
self
.c
c
x
,
size
),
ptr
],
None
);
let
ptr
=
self
.pointercast
(
ptr
,
Type
::
i8p
(
self
.cx
));
self
.call
(
lifetime_intrinsic
,
&
[
C_u64
(
self
.cx
,
size
),
ptr
],
None
);
}
}
src/librustc_trans/cabi_aarch64.rs
浏览文件 @
e69dacb4
...
...
@@ -11,13 +11,13 @@
use
abi
::{
FnType
,
ArgType
,
LayoutExt
,
Reg
,
RegKind
,
Uniform
};
use
context
::
CodegenCx
;
fn
is_homogeneous_aggregate
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
fn
is_homogeneous_aggregate
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
->
Option
<
Uniform
>
{
arg
.layout
.homogeneous_aggregate
(
c
c
x
)
.and_then
(|
unit
|
{
arg
.layout
.homogeneous_aggregate
(
cx
)
.and_then
(|
unit
|
{
let
size
=
arg
.layout.size
;
// Ensure we have at most four uniquely addressable members.
if
size
>
unit
.size
.checked_mul
(
4
,
c
c
x
)
.unwrap
()
{
if
size
>
unit
.size
.checked_mul
(
4
,
cx
)
.unwrap
()
{
return
None
;
}
...
...
@@ -38,12 +38,12 @@ fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, arg: &mut ArgTy
})
}
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
)
{
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
)
{
if
!
ret
.layout
.is_aggregate
()
{
ret
.extend_integer_width_to
(
32
);
return
;
}
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
c
c
x
,
ret
)
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
cx
,
ret
)
{
ret
.cast_to
(
uniform
);
return
;
}
...
...
@@ -69,12 +69,12 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>)
ret
.make_indirect
();
}
fn
classify_arg_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
{
fn
classify_arg_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
{
if
!
arg
.layout
.is_aggregate
()
{
arg
.extend_integer_width_to
(
32
);
return
;
}
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
c
c
x
,
arg
)
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
cx
,
arg
)
{
arg
.cast_to
(
uniform
);
return
;
}
...
...
@@ -100,13 +100,13 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>)
arg
.make_indirect
();
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
);
classify_arg_ty
(
cx
,
arg
);
}
}
src/librustc_trans/cabi_arm.rs
浏览文件 @
e69dacb4
...
...
@@ -12,13 +12,13 @@
use
context
::
CodegenCx
;
use
llvm
::
CallConv
;
fn
is_homogeneous_aggregate
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
fn
is_homogeneous_aggregate
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
->
Option
<
Uniform
>
{
arg
.layout
.homogeneous_aggregate
(
c
c
x
)
.and_then
(|
unit
|
{
arg
.layout
.homogeneous_aggregate
(
cx
)
.and_then
(|
unit
|
{
let
size
=
arg
.layout.size
;
// Ensure we have at most four uniquely addressable members.
if
size
>
unit
.size
.checked_mul
(
4
,
c
c
x
)
.unwrap
()
{
if
size
>
unit
.size
.checked_mul
(
4
,
cx
)
.unwrap
()
{
return
None
;
}
...
...
@@ -39,14 +39,14 @@ fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, arg: &mut ArgTy
})
}
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
,
vfp
:
bool
)
{
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
,
vfp
:
bool
)
{
if
!
ret
.layout
.is_aggregate
()
{
ret
.extend_integer_width_to
(
32
);
return
;
}
if
vfp
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
c
c
x
,
ret
)
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
cx
,
ret
)
{
ret
.cast_to
(
uniform
);
return
;
}
...
...
@@ -71,14 +71,14 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>,
ret
.make_indirect
();
}
fn
classify_arg_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
,
vfp
:
bool
)
{
fn
classify_arg_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
,
vfp
:
bool
)
{
if
!
arg
.layout
.is_aggregate
()
{
arg
.extend_integer_width_to
(
32
);
return
;
}
if
vfp
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
c
c
x
,
arg
)
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
cx
,
arg
)
{
arg
.cast_to
(
uniform
);
return
;
}
...
...
@@ -92,19 +92,19 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>,
});
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
// If this is a target with a hard-float ABI, and the function is not explicitly
// `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates.
let
vfp
=
c
c
x
.sess
()
.target.target.llvm_target
.ends_with
(
"hf"
)
let
vfp
=
cx
.sess
()
.target.target.llvm_target
.ends_with
(
"hf"
)
&&
fty
.cconv
!=
CallConv
::
ArmAapcsCallConv
&&
!
fty
.variadic
;
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
,
vfp
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
,
vfp
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
,
vfp
);
classify_arg_ty
(
cx
,
arg
,
vfp
);
}
}
src/librustc_trans/cabi_asmjs.rs
浏览文件 @
e69dacb4
...
...
@@ -16,9 +16,9 @@
// See the https://github.com/kripken/emscripten-fastcomp-clang repository.
// The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions.
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
)
{
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
)
{
if
ret
.layout
.is_aggregate
()
{
if
let
Some
(
unit
)
=
ret
.layout
.homogeneous_aggregate
(
c
c
x
)
{
if
let
Some
(
unit
)
=
ret
.layout
.homogeneous_aggregate
(
cx
)
{
let
size
=
ret
.layout.size
;
if
unit
.size
==
size
{
ret
.cast_to
(
Uniform
{
...
...
@@ -39,9 +39,9 @@ fn classify_arg_ty(arg: &mut ArgType) {
}
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
);
}
for
arg
in
&
mut
fty
.args
{
...
...
src/librustc_trans/cabi_mips.rs
浏览文件 @
e69dacb4
...
...
@@ -13,19 +13,19 @@
use
rustc
::
ty
::
layout
::
Size
;
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
,
offset
:
&
mut
Size
)
{
if
!
ret
.layout
.is_aggregate
()
{
ret
.extend_integer_width_to
(
32
);
}
else
{
ret
.make_indirect
();
*
offset
+=
c
c
x
.tcx.data_layout.pointer_size
;
*
offset
+=
cx
.tcx.data_layout.pointer_size
;
}
}
fn
classify_arg_ty
(
c
c
x
:
&
CodegenCx
,
arg
:
&
mut
ArgType
,
offset
:
&
mut
Size
)
{
let
dl
=
&
c
c
x
.tcx.data_layout
;
fn
classify_arg_ty
(
cx
:
&
CodegenCx
,
arg
:
&
mut
ArgType
,
offset
:
&
mut
Size
)
{
let
dl
=
&
cx
.tcx.data_layout
;
let
size
=
arg
.layout.size
;
let
align
=
arg
.layout.align
.max
(
dl
.i32_align
)
.min
(
dl
.i64_align
);
...
...
@@ -44,14 +44,14 @@ fn classify_arg_ty(ccx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) {
*
offset
=
offset
.abi_align
(
align
)
+
size
.abi_align
(
align
);
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
let
mut
offset
=
Size
::
from_bytes
(
0
);
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
,
&
mut
offset
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
,
&
mut
offset
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
,
&
mut
offset
);
classify_arg_ty
(
cx
,
arg
,
&
mut
offset
);
}
}
src/librustc_trans/cabi_mips64.rs
浏览文件 @
e69dacb4
...
...
@@ -13,19 +13,19 @@
use
rustc
::
ty
::
layout
::
Size
;
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
,
offset
:
&
mut
Size
)
{
if
!
ret
.layout
.is_aggregate
()
{
ret
.extend_integer_width_to
(
64
);
}
else
{
ret
.make_indirect
();
*
offset
+=
c
c
x
.tcx.data_layout.pointer_size
;
*
offset
+=
cx
.tcx.data_layout.pointer_size
;
}
}
fn
classify_arg_ty
(
c
c
x
:
&
CodegenCx
,
arg
:
&
mut
ArgType
,
offset
:
&
mut
Size
)
{
let
dl
=
&
c
c
x
.tcx.data_layout
;
fn
classify_arg_ty
(
cx
:
&
CodegenCx
,
arg
:
&
mut
ArgType
,
offset
:
&
mut
Size
)
{
let
dl
=
&
cx
.tcx.data_layout
;
let
size
=
arg
.layout.size
;
let
align
=
arg
.layout.align
.max
(
dl
.i32_align
)
.min
(
dl
.i64_align
);
...
...
@@ -44,14 +44,14 @@ fn classify_arg_ty(ccx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) {
*
offset
=
offset
.abi_align
(
align
)
+
size
.abi_align
(
align
);
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
let
mut
offset
=
Size
::
from_bytes
(
0
);
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
,
&
mut
offset
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
,
&
mut
offset
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
,
&
mut
offset
);
classify_arg_ty
(
cx
,
arg
,
&
mut
offset
);
}
}
src/librustc_trans/cabi_powerpc.rs
浏览文件 @
e69dacb4
...
...
@@ -13,19 +13,19 @@
use
rustc
::
ty
::
layout
::
Size
;
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
,
offset
:
&
mut
Size
)
{
if
!
ret
.layout
.is_aggregate
()
{
ret
.extend_integer_width_to
(
32
);
}
else
{
ret
.make_indirect
();
*
offset
+=
c
c
x
.tcx.data_layout.pointer_size
;
*
offset
+=
cx
.tcx.data_layout.pointer_size
;
}
}
fn
classify_arg_ty
(
c
c
x
:
&
CodegenCx
,
arg
:
&
mut
ArgType
,
offset
:
&
mut
Size
)
{
let
dl
=
&
c
c
x
.tcx.data_layout
;
fn
classify_arg_ty
(
cx
:
&
CodegenCx
,
arg
:
&
mut
ArgType
,
offset
:
&
mut
Size
)
{
let
dl
=
&
cx
.tcx.data_layout
;
let
size
=
arg
.layout.size
;
let
align
=
arg
.layout.align
.max
(
dl
.i32_align
)
.min
(
dl
.i64_align
);
...
...
@@ -44,14 +44,14 @@ fn classify_arg_ty(ccx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) {
*
offset
=
offset
.abi_align
(
align
)
+
size
.abi_align
(
align
);
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
let
mut
offset
=
Size
::
from_bytes
(
0
);
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
,
&
mut
offset
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
,
&
mut
offset
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
,
&
mut
offset
);
classify_arg_ty
(
cx
,
arg
,
&
mut
offset
);
}
}
src/librustc_trans/cabi_powerpc64.rs
浏览文件 @
e69dacb4
...
...
@@ -23,15 +23,15 @@ enum ABI {
}
use
self
::
ABI
::
*
;
fn
is_homogeneous_aggregate
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
is_homogeneous_aggregate
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
,
abi
:
ABI
)
->
Option
<
Uniform
>
{
arg
.layout
.homogeneous_aggregate
(
c
c
x
)
.and_then
(|
unit
|
{
arg
.layout
.homogeneous_aggregate
(
cx
)
.and_then
(|
unit
|
{
// ELFv1 only passes one-member aggregates transparently.
// ELFv2 passes up to eight uniquely addressable members.
if
(
abi
==
ELFv1
&&
arg
.layout.size
>
unit
.size
)
||
arg
.layout.size
>
unit
.size
.checked_mul
(
8
,
c
c
x
)
.unwrap
()
{
||
arg
.layout.size
>
unit
.size
.checked_mul
(
8
,
cx
)
.unwrap
()
{
return
None
;
}
...
...
@@ -52,7 +52,7 @@ fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
})
}
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
,
abi
:
ABI
)
{
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
,
abi
:
ABI
)
{
if
!
ret
.layout
.is_aggregate
()
{
ret
.extend_integer_width_to
(
64
);
return
;
...
...
@@ -64,7 +64,7 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>,
return
;
}
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
c
c
x
,
ret
,
abi
)
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
cx
,
ret
,
abi
)
{
ret
.cast_to
(
uniform
);
return
;
}
...
...
@@ -92,13 +92,13 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>,
ret
.make_indirect
();
}
fn
classify_arg_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
,
abi
:
ABI
)
{
fn
classify_arg_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
,
abi
:
ABI
)
{
if
!
arg
.layout
.is_aggregate
()
{
arg
.extend_integer_width_to
(
64
);
return
;
}
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
c
c
x
,
arg
,
abi
)
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
cx
,
arg
,
abi
)
{
arg
.cast_to
(
uniform
);
return
;
}
...
...
@@ -128,19 +128,19 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>,
});
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
let
abi
=
match
c
c
x
.sess
()
.target.target.target_endian
.as_str
()
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
let
abi
=
match
cx
.sess
()
.target.target.target_endian
.as_str
()
{
"big"
=>
ELFv1
,
"little"
=>
ELFv2
,
_
=>
unimplemented!
(),
};
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
,
abi
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
,
abi
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
,
abi
);
classify_arg_ty
(
cx
,
arg
,
abi
);
}
}
src/librustc_trans/cabi_s390x.rs
浏览文件 @
e69dacb4
...
...
@@ -24,7 +24,7 @@ fn classify_ret_ty(ret: &mut ArgType) {
}
}
fn
is_single_fp_element
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
is_single_fp_element
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
layout
:
TyLayout
<
'tcx
>
)
->
bool
{
match
layout
.abi
{
layout
::
Abi
::
Scalar
(
ref
scalar
)
=>
{
...
...
@@ -35,7 +35,7 @@ fn is_single_fp_element<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
}
layout
::
Abi
::
Aggregate
{
..
}
=>
{
if
layout
.fields
.count
()
==
1
&&
layout
.fields
.offset
(
0
)
.bytes
()
==
0
{
is_single_fp_element
(
c
cx
,
layout
.field
(
c
cx
,
0
))
is_single_fp_element
(
c
x
,
layout
.field
(
cx
,
0
))
}
else
{
false
}
...
...
@@ -44,13 +44,13 @@ fn is_single_fp_element<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
}
}
fn
classify_arg_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
{
fn
classify_arg_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
{
if
!
arg
.layout
.is_aggregate
()
&&
arg
.layout.size
.bits
()
<=
64
{
arg
.extend_integer_width_to
(
64
);
return
;
}
if
is_single_fp_element
(
c
c
x
,
arg
.layout
)
{
if
is_single_fp_element
(
cx
,
arg
.layout
)
{
match
arg
.layout.size
.bytes
()
{
4
=>
arg
.cast_to
(
Reg
::
f32
()),
8
=>
arg
.cast_to
(
Reg
::
f64
()),
...
...
@@ -67,13 +67,13 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>)
}
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
&
mut
fty
.ret
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
);
classify_arg_ty
(
cx
,
arg
);
}
}
src/librustc_trans/cabi_sparc.rs
浏览文件 @
e69dacb4
...
...
@@ -13,19 +13,19 @@
use
rustc
::
ty
::
layout
::
Size
;
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
,
offset
:
&
mut
Size
)
{
if
!
ret
.layout
.is_aggregate
()
{
ret
.extend_integer_width_to
(
32
);
}
else
{
ret
.make_indirect
();
*
offset
+=
c
c
x
.tcx.data_layout.pointer_size
;
*
offset
+=
cx
.tcx.data_layout.pointer_size
;
}
}
fn
classify_arg_ty
(
c
c
x
:
&
CodegenCx
,
arg
:
&
mut
ArgType
,
offset
:
&
mut
Size
)
{
let
dl
=
&
c
c
x
.tcx.data_layout
;
fn
classify_arg_ty
(
cx
:
&
CodegenCx
,
arg
:
&
mut
ArgType
,
offset
:
&
mut
Size
)
{
let
dl
=
&
cx
.tcx.data_layout
;
let
size
=
arg
.layout.size
;
let
align
=
arg
.layout.align
.max
(
dl
.i32_align
)
.min
(
dl
.i64_align
);
...
...
@@ -44,14 +44,14 @@ fn classify_arg_ty(ccx: &CodegenCx, arg: &mut ArgType, offset: &mut Size) {
*
offset
=
offset
.abi_align
(
align
)
+
size
.abi_align
(
align
);
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
let
mut
offset
=
Size
::
from_bytes
(
0
);
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
,
&
mut
offset
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
,
&
mut
offset
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
,
&
mut
offset
);
classify_arg_ty
(
cx
,
arg
,
&
mut
offset
);
}
}
src/librustc_trans/cabi_sparc64.rs
浏览文件 @
e69dacb4
...
...
@@ -13,11 +13,11 @@
use
abi
::{
FnType
,
ArgType
,
LayoutExt
,
Reg
,
RegKind
,
Uniform
};
use
context
::
CodegenCx
;
fn
is_homogeneous_aggregate
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
fn
is_homogeneous_aggregate
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
->
Option
<
Uniform
>
{
arg
.layout
.homogeneous_aggregate
(
c
c
x
)
.and_then
(|
unit
|
{
arg
.layout
.homogeneous_aggregate
(
cx
)
.and_then
(|
unit
|
{
// Ensure we have at most eight uniquely addressable members.
if
arg
.layout.size
>
unit
.size
.checked_mul
(
8
,
c
c
x
)
.unwrap
()
{
if
arg
.layout.size
>
unit
.size
.checked_mul
(
8
,
cx
)
.unwrap
()
{
return
None
;
}
...
...
@@ -38,13 +38,13 @@ fn is_homogeneous_aggregate<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, arg: &mut ArgTy
})
}
fn
classify_ret_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
)
{
fn
classify_ret_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ret
:
&
mut
ArgType
<
'tcx
>
)
{
if
!
ret
.layout
.is_aggregate
()
{
ret
.extend_integer_width_to
(
64
);
return
;
}
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
c
c
x
,
ret
)
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
cx
,
ret
)
{
ret
.cast_to
(
uniform
);
return
;
}
...
...
@@ -72,13 +72,13 @@ fn classify_ret_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, ret: &mut ArgType<'tcx>)
ret
.make_indirect
();
}
fn
classify_arg_ty
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
{
fn
classify_arg_ty
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
mut
ArgType
<
'tcx
>
)
{
if
!
arg
.layout
.is_aggregate
()
{
arg
.extend_integer_width_to
(
64
);
return
;
}
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
c
c
x
,
arg
)
{
if
let
Some
(
uniform
)
=
is_homogeneous_aggregate
(
cx
,
arg
)
{
arg
.cast_to
(
uniform
);
return
;
}
...
...
@@ -90,13 +90,13 @@ fn classify_arg_ty<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, arg: &mut ArgType<'tcx>)
});
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
if
!
fty
.ret
.is_ignore
()
{
classify_ret_ty
(
c
c
x
,
&
mut
fty
.ret
);
classify_ret_ty
(
cx
,
&
mut
fty
.ret
);
}
for
arg
in
&
mut
fty
.args
{
if
arg
.is_ignore
()
{
continue
;
}
classify_arg_ty
(
c
c
x
,
arg
);
classify_arg_ty
(
cx
,
arg
);
}
}
src/librustc_trans/cabi_x86.rs
浏览文件 @
e69dacb4
...
...
@@ -19,7 +19,7 @@ pub enum Flavor {
Fastcall
}
fn
is_single_fp_element
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
is_single_fp_element
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
layout
:
TyLayout
<
'tcx
>
)
->
bool
{
match
layout
.abi
{
layout
::
Abi
::
Scalar
(
ref
scalar
)
=>
{
...
...
@@ -30,7 +30,7 @@ fn is_single_fp_element<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
}
layout
::
Abi
::
Aggregate
{
..
}
=>
{
if
layout
.fields
.count
()
==
1
&&
layout
.fields
.offset
(
0
)
.bytes
()
==
0
{
is_single_fp_element
(
c
cx
,
layout
.field
(
c
cx
,
0
))
is_single_fp_element
(
c
x
,
layout
.field
(
cx
,
0
))
}
else
{
false
}
...
...
@@ -39,7 +39,7 @@ fn is_single_fp_element<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
}
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
,
flavor
:
Flavor
)
{
if
!
fty
.ret
.is_ignore
()
{
...
...
@@ -51,12 +51,12 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
// Some links:
// http://www.angelcode.com/dev/callconv/callconv.html
// Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp
let
t
=
&
c
c
x
.sess
()
.target.target
;
let
t
=
&
cx
.sess
()
.target.target
;
if
t
.options.is_like_osx
||
t
.options.is_like_windows
||
t
.options.is_like_openbsd
{
// According to Clang, everyone but MSVC returns single-element
// float aggregates directly in a floating-point register.
if
!
t
.options.is_like_msvc
&&
is_single_fp_element
(
c
c
x
,
fty
.ret.layout
)
{
if
!
t
.options.is_like_msvc
&&
is_single_fp_element
(
cx
,
fty
.ret.layout
)
{
match
fty
.ret.layout.size
.bytes
()
{
4
=>
fty
.ret
.cast_to
(
Reg
::
f32
()),
8
=>
fty
.ret
.cast_to
(
Reg
::
f64
()),
...
...
@@ -112,7 +112,7 @@ pub fn compute_abi_info<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
};
// At this point we know this must be a primitive of sorts.
let
unit
=
arg
.layout
.homogeneous_aggregate
(
c
c
x
)
.unwrap
();
let
unit
=
arg
.layout
.homogeneous_aggregate
(
cx
)
.unwrap
();
assert_eq!
(
unit
.size
,
arg
.layout.size
);
if
unit
.kind
==
RegKind
::
Float
{
continue
;
...
...
src/librustc_trans/cabi_x86_64.rs
浏览文件 @
e69dacb4
...
...
@@ -31,7 +31,7 @@ enum Class {
const
LARGEST_VECTOR_SIZE
:
usize
=
512
;
const
MAX_EIGHTBYTES
:
usize
=
LARGEST_VECTOR_SIZE
/
64
;
fn
classify_arg
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
ArgType
<
'tcx
>
)
fn
classify_arg
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
arg
:
&
ArgType
<
'tcx
>
)
->
Result
<
[
Class
;
MAX_EIGHTBYTES
],
Memory
>
{
fn
unify
(
cls
:
&
mut
[
Class
],
off
:
Size
,
...
...
@@ -52,7 +52,7 @@ fn unify(cls: &mut [Class],
cls
[
i
]
=
to_write
;
}
fn
classify
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
classify
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
layout
:
TyLayout
<
'tcx
>
,
cls
:
&
mut
[
Class
],
off
:
Size
)
...
...
@@ -82,7 +82,7 @@ fn classify<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
// everything after the first one is the upper
// half of a register.
let
stride
=
element
.value
.size
(
c
c
x
);
let
stride
=
element
.value
.size
(
cx
);
for
i
in
1
..
count
{
let
field_off
=
off
+
stride
*
i
;
unify
(
cls
,
field_off
,
Class
::
SseUp
);
...
...
@@ -95,7 +95,7 @@ fn classify<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
layout
::
Variants
::
Single
{
..
}
=>
{
for
i
in
0
..
layout
.fields
.count
()
{
let
field_off
=
off
+
layout
.fields
.offset
(
i
);
classify
(
c
cx
,
layout
.field
(
c
cx
,
i
),
cls
,
field_off
)
?
;
classify
(
c
x
,
layout
.field
(
cx
,
i
),
cls
,
field_off
)
?
;
}
}
layout
::
Variants
::
Tagged
{
..
}
|
...
...
@@ -114,7 +114,7 @@ fn classify<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
}
let
mut
cls
=
[
Class
::
None
;
MAX_EIGHTBYTES
];
classify
(
c
c
x
,
arg
.layout
,
&
mut
cls
,
Size
::
from_bytes
(
0
))
?
;
classify
(
cx
,
arg
.layout
,
&
mut
cls
,
Size
::
from_bytes
(
0
))
?
;
if
n
>
2
{
if
cls
[
0
]
!=
Class
::
Sse
{
return
Err
(
Memory
);
...
...
@@ -189,12 +189,12 @@ fn cast_target(cls: &[Class], size: Size) -> CastTarget {
target
}
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
pub
fn
compute_abi_info
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
fty
:
&
mut
FnType
<
'tcx
>
)
{
let
mut
int_regs
=
6
;
// RDI, RSI, RDX, RCX, R8, R9
let
mut
sse_regs
=
8
;
// XMM0-7
let
mut
x86_64_ty
=
|
arg
:
&
mut
ArgType
<
'tcx
>
,
is_arg
:
bool
|
{
let
cls
=
classify_arg
(
c
c
x
,
arg
);
let
cls
=
classify_arg
(
cx
,
arg
);
let
mut
needed_int
=
0
;
let
mut
needed_sse
=
0
;
...
...
src/librustc_trans/callee.rs
浏览文件 @
e69dacb4
...
...
@@ -34,13 +34,13 @@
///
/// # Parameters
///
/// - `c
c
x`: the crate context
/// - `cx`: the crate context
/// - `instance`: the instance to be instantiated
pub
fn
get_fn
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
get_fn
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
instance
:
Instance
<
'tcx
>
)
->
ValueRef
{
let
tcx
=
c
c
x
.tcx
;
let
tcx
=
cx
.tcx
;
debug!
(
"get_fn(instance={:?})"
,
instance
);
...
...
@@ -48,8 +48,8 @@ pub fn get_fn<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
assert
!
(
!
instance
.substs
.has_escaping_regions
());
assert
!
(
!
instance
.substs
.has_param_types
());
let
fn_ty
=
instance
.ty
(
c
c
x
.tcx
);
if
let
Some
(
&
llfn
)
=
c
c
x
.instances
.borrow
()
.get
(
&
instance
)
{
let
fn_ty
=
instance
.ty
(
cx
.tcx
);
if
let
Some
(
&
llfn
)
=
cx
.instances
.borrow
()
.get
(
&
instance
)
{
return
llfn
;
}
...
...
@@ -57,10 +57,10 @@ pub fn get_fn<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
debug!
(
"get_fn({:?}: {:?}) => {}"
,
instance
,
fn_ty
,
sym
);
// Create a fn pointer with the substituted signature.
let
fn_ptr_ty
=
tcx
.mk_fn_ptr
(
common
::
ty_fn_sig
(
c
c
x
,
fn_ty
));
let
llptrty
=
c
cx
.layout_of
(
fn_ptr_ty
)
.llvm_type
(
c
cx
);
let
fn_ptr_ty
=
tcx
.mk_fn_ptr
(
common
::
ty_fn_sig
(
cx
,
fn_ty
));
let
llptrty
=
c
x
.layout_of
(
fn_ptr_ty
)
.llvm_type
(
cx
);
let
llfn
=
if
let
Some
(
llfn
)
=
declare
::
get_declared_value
(
c
c
x
,
&
sym
)
{
let
llfn
=
if
let
Some
(
llfn
)
=
declare
::
get_declared_value
(
cx
,
&
sym
)
{
// This is subtle and surprising, but sometimes we have to bitcast
// the resulting fn pointer. The reason has to do with external
// functions. If you have two crates that both bind the same C
...
...
@@ -92,14 +92,14 @@ pub fn get_fn<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
llfn
}
}
else
{
let
llfn
=
declare
::
declare_fn
(
c
c
x
,
&
sym
,
fn_ty
);
let
llfn
=
declare
::
declare_fn
(
cx
,
&
sym
,
fn_ty
);
assert_eq!
(
common
::
val_ty
(
llfn
),
llptrty
);
debug!
(
"get_fn: not casting pointer!"
);
if
instance
.def
.is_inline
(
tcx
)
{
attributes
::
inline
(
llfn
,
attributes
::
InlineAttr
::
Hint
);
}
attributes
::
from_fn_attrs
(
c
c
x
,
llfn
,
instance
.def
.def_id
());
attributes
::
from_fn_attrs
(
cx
,
llfn
,
instance
.def
.def_id
());
let
instance_def_id
=
instance
.def_id
();
...
...
@@ -149,9 +149,9 @@ pub fn get_fn<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
unsafe
{
llvm
::
LLVMRustSetLinkage
(
llfn
,
llvm
::
Linkage
::
ExternalLinkage
);
if
c
c
x
.tcx
.is_translated_function
(
instance_def_id
)
{
if
cx
.tcx
.is_translated_function
(
instance_def_id
)
{
if
instance_def_id
.is_local
()
{
if
!
c
c
x
.tcx
.is_exported_symbol
(
instance_def_id
)
{
if
!
cx
.tcx
.is_exported_symbol
(
instance_def_id
)
{
llvm
::
LLVMRustSetVisibility
(
llfn
,
llvm
::
Visibility
::
Hidden
);
}
}
else
{
...
...
@@ -160,7 +160,7 @@ pub fn get_fn<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
}
}
if
c
c
x
.use_dll_storage_attrs
&&
if
cx
.use_dll_storage_attrs
&&
tcx
.is_dllimport_foreign_item
(
instance_def_id
)
{
unsafe
{
...
...
@@ -171,20 +171,20 @@ pub fn get_fn<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
llfn
};
c
c
x
.instances
.borrow_mut
()
.insert
(
instance
,
llfn
);
cx
.instances
.borrow_mut
()
.insert
(
instance
,
llfn
);
llfn
}
pub
fn
resolve_and_get_fn
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
resolve_and_get_fn
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
def_id
:
DefId
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
ValueRef
{
get_fn
(
c
c
x
,
cx
,
ty
::
Instance
::
resolve
(
c
c
x
.tcx
,
cx
.tcx
,
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
),
def_id
,
substs
...
...
src/librustc_trans/common.rs
浏览文件 @
e69dacb4
...
...
@@ -152,34 +152,34 @@ pub fn C_uint_big(t: Type, u: u128) -> ValueRef {
}
}
pub
fn
C_bool
(
c
c
x
:
&
CodegenCx
,
val
:
bool
)
->
ValueRef
{
C_uint
(
Type
::
i1
(
c
c
x
),
val
as
u64
)
pub
fn
C_bool
(
cx
:
&
CodegenCx
,
val
:
bool
)
->
ValueRef
{
C_uint
(
Type
::
i1
(
cx
),
val
as
u64
)
}
pub
fn
C_i32
(
c
c
x
:
&
CodegenCx
,
i
:
i32
)
->
ValueRef
{
C_int
(
Type
::
i32
(
c
c
x
),
i
as
i64
)
pub
fn
C_i32
(
cx
:
&
CodegenCx
,
i
:
i32
)
->
ValueRef
{
C_int
(
Type
::
i32
(
cx
),
i
as
i64
)
}
pub
fn
C_u32
(
c
c
x
:
&
CodegenCx
,
i
:
u32
)
->
ValueRef
{
C_uint
(
Type
::
i32
(
c
c
x
),
i
as
u64
)
pub
fn
C_u32
(
cx
:
&
CodegenCx
,
i
:
u32
)
->
ValueRef
{
C_uint
(
Type
::
i32
(
cx
),
i
as
u64
)
}
pub
fn
C_u64
(
c
c
x
:
&
CodegenCx
,
i
:
u64
)
->
ValueRef
{
C_uint
(
Type
::
i64
(
c
c
x
),
i
)
pub
fn
C_u64
(
cx
:
&
CodegenCx
,
i
:
u64
)
->
ValueRef
{
C_uint
(
Type
::
i64
(
cx
),
i
)
}
pub
fn
C_usize
(
c
c
x
:
&
CodegenCx
,
i
:
u64
)
->
ValueRef
{
let
bit_size
=
c
c
x
.data_layout
()
.pointer_size
.bits
();
pub
fn
C_usize
(
cx
:
&
CodegenCx
,
i
:
u64
)
->
ValueRef
{
let
bit_size
=
cx
.data_layout
()
.pointer_size
.bits
();
if
bit_size
<
64
{
// make sure it doesn't overflow
assert
!
(
i
<
(
1
<<
bit_size
));
}
C_uint
(
c
c
x
.isize_ty
,
i
)
C_uint
(
cx
.isize_ty
,
i
)
}
pub
fn
C_u8
(
c
c
x
:
&
CodegenCx
,
i
:
u8
)
->
ValueRef
{
C_uint
(
Type
::
i8
(
c
c
x
),
i
as
u64
)
pub
fn
C_u8
(
cx
:
&
CodegenCx
,
i
:
u8
)
->
ValueRef
{
C_uint
(
Type
::
i8
(
cx
),
i
as
u64
)
}
...
...
@@ -382,16 +382,16 @@ pub fn shift_mask_val<'a, 'tcx>(
}
}
pub
fn
ty_fn_sig
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
ty_fn_sig
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
ty
::
PolyFnSig
<
'tcx
>
{
match
ty
.sty
{
ty
::
TyFnDef
(
..
)
|
// Shims currently have type TyFnPtr. Not sure this should remain.
ty
::
TyFnPtr
(
_
)
=>
ty
.fn_sig
(
c
c
x
.tcx
),
ty
::
TyFnPtr
(
_
)
=>
ty
.fn_sig
(
cx
.tcx
),
ty
::
TyClosure
(
def_id
,
substs
)
=>
{
let
tcx
=
c
c
x
.tcx
;
let
tcx
=
cx
.tcx
;
let
sig
=
substs
.closure_sig
(
def_id
,
tcx
);
let
env_ty
=
tcx
.closure_env_ty
(
def_id
,
substs
)
.unwrap
();
...
...
@@ -404,8 +404,8 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
))
}
ty
::
TyGenerator
(
def_id
,
substs
,
_
)
=>
{
let
tcx
=
c
c
x
.tcx
;
let
sig
=
substs
.generator_poly_sig
(
def_id
,
c
c
x
.tcx
);
let
tcx
=
cx
.tcx
;
let
sig
=
substs
.generator_poly_sig
(
def_id
,
cx
.tcx
);
let
env_region
=
ty
::
ReLateBound
(
ty
::
DebruijnIndex
::
new
(
1
),
ty
::
BrEnv
);
let
env_ty
=
tcx
.mk_mut_ref
(
tcx
.mk_region
(
env_region
),
ty
);
...
...
src/librustc_trans/consts.rs
浏览文件 @
e69dacb4
...
...
@@ -43,17 +43,17 @@ pub fn bitcast(val: ValueRef, ty: Type) -> ValueRef {
}
}
fn
set_global_alignment
(
c
c
x
:
&
CodegenCx
,
fn
set_global_alignment
(
cx
:
&
CodegenCx
,
gv
:
ValueRef
,
mut
align
:
Align
)
{
// The target may require greater alignment for globals than the type does.
// Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
// which can force it to be smaller. Rust doesn't support this yet.
if
let
Some
(
min
)
=
c
c
x
.sess
()
.target.target.options.min_global_align
{
if
let
Some
(
min
)
=
cx
.sess
()
.target.target.options.min_global_align
{
match
ty
::
layout
::
Align
::
from_bits
(
min
,
min
)
{
Ok
(
min
)
=>
align
=
align
.max
(
min
),
Err
(
err
)
=>
{
c
c
x
.sess
()
.err
(
&
format!
(
"invalid minimum global alignment: {}"
,
err
));
cx
.sess
()
.err
(
&
format!
(
"invalid minimum global alignment: {}"
,
err
));
}
}
}
...
...
@@ -62,30 +62,30 @@ fn set_global_alignment(ccx: &CodegenCx,
}
}
pub
fn
addr_of_mut
(
c
c
x
:
&
CodegenCx
,
pub
fn
addr_of_mut
(
cx
:
&
CodegenCx
,
cv
:
ValueRef
,
align
:
Align
,
kind
:
&
str
)
->
ValueRef
{
unsafe
{
let
name
=
c
c
x
.generate_local_symbol_name
(
kind
);
let
gv
=
declare
::
define_global
(
c
c
x
,
&
name
[
..
],
val_ty
(
cv
))
.unwrap_or_else
(||{
let
name
=
cx
.generate_local_symbol_name
(
kind
);
let
gv
=
declare
::
define_global
(
cx
,
&
name
[
..
],
val_ty
(
cv
))
.unwrap_or_else
(||{
bug!
(
"symbol `{}` is already defined"
,
name
);
});
llvm
::
LLVMSetInitializer
(
gv
,
cv
);
set_global_alignment
(
c
c
x
,
gv
,
align
);
set_global_alignment
(
cx
,
gv
,
align
);
llvm
::
LLVMRustSetLinkage
(
gv
,
llvm
::
Linkage
::
PrivateLinkage
);
SetUnnamedAddr
(
gv
,
true
);
gv
}
}
pub
fn
addr_of
(
c
c
x
:
&
CodegenCx
,
pub
fn
addr_of
(
cx
:
&
CodegenCx
,
cv
:
ValueRef
,
align
:
Align
,
kind
:
&
str
)
->
ValueRef
{
if
let
Some
(
&
gv
)
=
c
c
x
.const_globals
.borrow
()
.get
(
&
cv
)
{
if
let
Some
(
&
gv
)
=
cx
.const_globals
.borrow
()
.get
(
&
cv
)
{
unsafe
{
// Upgrade the alignment in cases where the same constant is used with different
// alignment requirements
...
...
@@ -96,42 +96,42 @@ pub fn addr_of(ccx: &CodegenCx,
}
return
gv
;
}
let
gv
=
addr_of_mut
(
c
c
x
,
cv
,
align
,
kind
);
let
gv
=
addr_of_mut
(
cx
,
cv
,
align
,
kind
);
unsafe
{
llvm
::
LLVMSetGlobalConstant
(
gv
,
True
);
}
c
c
x
.const_globals
.borrow_mut
()
.insert
(
cv
,
gv
);
cx
.const_globals
.borrow_mut
()
.insert
(
cv
,
gv
);
gv
}
pub
fn
get_static
(
c
c
x
:
&
CodegenCx
,
def_id
:
DefId
)
->
ValueRef
{
let
instance
=
Instance
::
mono
(
c
c
x
.tcx
,
def_id
);
if
let
Some
(
&
g
)
=
c
c
x
.instances
.borrow
()
.get
(
&
instance
)
{
pub
fn
get_static
(
cx
:
&
CodegenCx
,
def_id
:
DefId
)
->
ValueRef
{
let
instance
=
Instance
::
mono
(
cx
.tcx
,
def_id
);
if
let
Some
(
&
g
)
=
cx
.instances
.borrow
()
.get
(
&
instance
)
{
return
g
;
}
let
ty
=
instance
.ty
(
c
c
x
.tcx
);
let
g
=
if
let
Some
(
id
)
=
c
c
x
.tcx.hir
.as_local_node_id
(
def_id
)
{
let
ty
=
instance
.ty
(
cx
.tcx
);
let
g
=
if
let
Some
(
id
)
=
cx
.tcx.hir
.as_local_node_id
(
def_id
)
{
let
llty
=
c
cx
.layout_of
(
ty
)
.llvm_type
(
c
cx
);
let
(
g
,
attrs
)
=
match
c
c
x
.tcx.hir
.get
(
id
)
{
let
llty
=
c
x
.layout_of
(
ty
)
.llvm_type
(
cx
);
let
(
g
,
attrs
)
=
match
cx
.tcx.hir
.get
(
id
)
{
hir_map
::
NodeItem
(
&
hir
::
Item
{
ref
attrs
,
span
,
node
:
hir
::
ItemStatic
(
..
),
..
})
=>
{
let
sym
=
MonoItem
::
Static
(
id
)
.symbol_name
(
c
c
x
.tcx
);
let
sym
=
MonoItem
::
Static
(
id
)
.symbol_name
(
cx
.tcx
);
let
defined_in_current_codegen_unit
=
c
c
x
.codegen_unit
let
defined_in_current_codegen_unit
=
cx
.codegen_unit
.items
()
.contains_key
(
&
MonoItem
::
Static
(
id
));
assert
!
(
!
defined_in_current_codegen_unit
);
if
declare
::
get_declared_value
(
c
c
x
,
&
sym
[
..
])
.is_some
()
{
if
declare
::
get_declared_value
(
cx
,
&
sym
[
..
])
.is_some
()
{
span_bug!
(
span
,
"trans: Conflicting symbol names for static?"
);
}
let
g
=
declare
::
define_global
(
c
c
x
,
&
sym
[
..
],
llty
)
.unwrap
();
let
g
=
declare
::
define_global
(
cx
,
&
sym
[
..
],
llty
)
.unwrap
();
if
!
c
c
x
.tcx
.is_exported_symbol
(
def_id
)
{
if
!
cx
.tcx
.is_exported_symbol
(
def_id
)
{
unsafe
{
llvm
::
LLVMRustSetVisibility
(
g
,
llvm
::
Visibility
::
Hidden
);
}
...
...
@@ -143,7 +143,7 @@ pub fn get_static(ccx: &CodegenCx, def_id: DefId) -> ValueRef {
hir_map
::
NodeForeignItem
(
&
hir
::
ForeignItem
{
ref
attrs
,
span
,
node
:
hir
::
ForeignItemStatic
(
..
),
..
})
=>
{
let
sym
=
c
c
x
.tcx
.symbol_name
(
instance
);
let
sym
=
cx
.tcx
.symbol_name
(
instance
);
let
g
=
if
let
Some
(
name
)
=
attr
::
first_attr_value_str_by_name
(
&
attrs
,
"linkage"
)
{
// If this is a static with a linkage specified, then we need to handle
...
...
@@ -154,18 +154,18 @@ pub fn get_static(ccx: &CodegenCx, def_id: DefId) -> ValueRef {
let
linkage
=
match
base
::
linkage_by_name
(
&
name
.as_str
())
{
Some
(
linkage
)
=>
linkage
,
None
=>
{
c
c
x
.sess
()
.span_fatal
(
span
,
"invalid linkage specified"
);
cx
.sess
()
.span_fatal
(
span
,
"invalid linkage specified"
);
}
};
let
llty2
=
match
ty
.sty
{
ty
::
TyRawPtr
(
ref
mt
)
=>
c
cx
.layout_of
(
mt
.ty
)
.llvm_type
(
c
cx
),
ty
::
TyRawPtr
(
ref
mt
)
=>
c
x
.layout_of
(
mt
.ty
)
.llvm_type
(
cx
),
_
=>
{
c
c
x
.sess
()
.span_fatal
(
span
,
"must have type `*const T` or `*mut T`"
);
cx
.sess
()
.span_fatal
(
span
,
"must have type `*const T` or `*mut T`"
);
}
};
unsafe
{
// Declare a symbol `foo` with the desired linkage.
let
g1
=
declare
::
declare_global
(
c
c
x
,
&
sym
,
llty2
);
let
g1
=
declare
::
declare_global
(
cx
,
&
sym
,
llty2
);
llvm
::
LLVMRustSetLinkage
(
g1
,
base
::
linkage_to_llvm
(
linkage
));
// Declare an internal global `extern_with_linkage_foo` which
...
...
@@ -176,8 +176,8 @@ pub fn get_static(ccx: &CodegenCx, def_id: DefId) -> ValueRef {
// zero.
let
mut
real_name
=
"_rust_extern_with_linkage_"
.to_string
();
real_name
.push_str
(
&
sym
);
let
g2
=
declare
::
define_global
(
c
c
x
,
&
real_name
,
llty
)
.unwrap_or_else
(||{
c
c
x
.sess
()
.span_fatal
(
span
,
let
g2
=
declare
::
define_global
(
cx
,
&
real_name
,
llty
)
.unwrap_or_else
(||{
cx
.sess
()
.span_fatal
(
span
,
&
format!
(
"symbol `{}` is already defined"
,
&
sym
))
});
llvm
::
LLVMRustSetLinkage
(
g2
,
llvm
::
Linkage
::
InternalLinkage
);
...
...
@@ -186,7 +186,7 @@ pub fn get_static(ccx: &CodegenCx, def_id: DefId) -> ValueRef {
}
}
else
{
// Generate an external declaration.
declare
::
declare_global
(
c
c
x
,
&
sym
,
llty
)
declare
::
declare_global
(
cx
,
&
sym
,
llty
)
};
(
g
,
attrs
)
...
...
@@ -197,29 +197,29 @@ pub fn get_static(ccx: &CodegenCx, def_id: DefId) -> ValueRef {
for
attr
in
attrs
{
if
attr
.check_name
(
"thread_local"
)
{
llvm
::
set_thread_local_mode
(
g
,
c
c
x
.tls_model
);
llvm
::
set_thread_local_mode
(
g
,
cx
.tls_model
);
}
}
g
}
else
{
let
sym
=
c
c
x
.tcx
.symbol_name
(
instance
);
let
sym
=
cx
.tcx
.symbol_name
(
instance
);
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
// FIXME(nagisa): investigate whether it can be changed into define_global
let
g
=
declare
::
declare_global
(
c
cx
,
&
sym
,
ccx
.layout_of
(
ty
)
.llvm_type
(
c
cx
));
let
g
=
declare
::
declare_global
(
c
x
,
&
sym
,
cx
.layout_of
(
ty
)
.llvm_type
(
cx
));
// Thread-local statics in some other crate need to *always* be linked
// against in a thread-local fashion, so we need to be sure to apply the
// thread-local attribute locally if it was present remotely. If we
// don't do this then linker errors can be generated where the linker
// complains that one object files has a thread local version of the
// symbol and another one doesn't.
for
attr
in
c
c
x
.tcx
.get_attrs
(
def_id
)
.iter
()
{
for
attr
in
cx
.tcx
.get_attrs
(
def_id
)
.iter
()
{
if
attr
.check_name
(
"thread_local"
)
{
llvm
::
set_thread_local_mode
(
g
,
c
c
x
.tls_model
);
llvm
::
set_thread_local_mode
(
g
,
cx
.tls_model
);
}
}
if
c
cx
.use_dll_storage_attrs
&&
!
c
cx
.tcx
.is_foreign_item
(
def_id
)
{
if
c
x
.use_dll_storage_attrs
&&
!
cx
.tcx
.is_foreign_item
(
def_id
)
{
// This item is external but not foreign, i.e. it originates from an external Rust
// crate. Since we don't know whether this crate will be linked dynamically or
// statically in the final application, we always mark such symbols as 'dllimport'.
...
...
@@ -232,42 +232,42 @@ pub fn get_static(ccx: &CodegenCx, def_id: DefId) -> ValueRef {
g
};
if
c
cx
.use_dll_storage_attrs
&&
c
cx
.tcx
.is_dllimport_foreign_item
(
def_id
)
{
if
c
x
.use_dll_storage_attrs
&&
cx
.tcx
.is_dllimport_foreign_item
(
def_id
)
{
// For foreign (native) libs we know the exact storage type to use.
unsafe
{
llvm
::
LLVMSetDLLStorageClass
(
g
,
llvm
::
DLLStorageClass
::
DllImport
);
}
}
c
c
x
.instances
.borrow_mut
()
.insert
(
instance
,
g
);
c
c
x
.statics
.borrow_mut
()
.insert
(
g
,
def_id
);
cx
.instances
.borrow_mut
()
.insert
(
instance
,
g
);
cx
.statics
.borrow_mut
()
.insert
(
g
,
def_id
);
g
}
pub
fn
trans_static
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
trans_static
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
m
:
hir
::
Mutability
,
id
:
ast
::
NodeId
,
attrs
:
&
[
ast
::
Attribute
])
->
Result
<
ValueRef
,
ConstEvalErr
<
'tcx
>>
{
unsafe
{
let
def_id
=
c
c
x
.tcx.hir
.local_def_id
(
id
);
let
g
=
get_static
(
c
c
x
,
def_id
);
let
def_id
=
cx
.tcx.hir
.local_def_id
(
id
);
let
g
=
get_static
(
cx
,
def_id
);
let
v
=
::
mir
::
trans_static_initializer
(
c
c
x
,
def_id
)
?
;
let
v
=
::
mir
::
trans_static_initializer
(
cx
,
def_id
)
?
;
// boolean SSA values are i1, but they have to be stored in i8 slots,
// otherwise some LLVM optimization passes don't work as expected
let
mut
val_llty
=
val_ty
(
v
);
let
v
=
if
val_llty
==
Type
::
i1
(
c
c
x
)
{
val_llty
=
Type
::
i8
(
c
c
x
);
let
v
=
if
val_llty
==
Type
::
i1
(
cx
)
{
val_llty
=
Type
::
i8
(
cx
);
llvm
::
LLVMConstZExt
(
v
,
val_llty
.to_ref
())
}
else
{
v
};
let
instance
=
Instance
::
mono
(
c
c
x
.tcx
,
def_id
);
let
ty
=
instance
.ty
(
c
c
x
.tcx
);
let
llty
=
c
cx
.layout_of
(
ty
)
.llvm_type
(
c
cx
);
let
instance
=
Instance
::
mono
(
cx
.tcx
,
def_id
);
let
ty
=
instance
.ty
(
cx
.tcx
);
let
llty
=
c
x
.layout_of
(
ty
)
.llvm_type
(
cx
);
let
g
=
if
val_llty
==
llty
{
g
}
else
{
...
...
@@ -282,7 +282,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
let
visibility
=
llvm
::
LLVMRustGetVisibility
(
g
);
let
new_g
=
llvm
::
LLVMRustGetOrInsertGlobal
(
c
c
x
.llmod
,
name_string
.as_ptr
(),
val_llty
.to_ref
());
cx
.llmod
,
name_string
.as_ptr
(),
val_llty
.to_ref
());
llvm
::
LLVMRustSetLinkage
(
new_g
,
linkage
);
llvm
::
LLVMRustSetVisibility
(
new_g
,
visibility
);
...
...
@@ -290,32 +290,32 @@ pub fn trans_static<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
// To avoid breaking any invariants, we leave around the old
// global for the moment; we'll replace all references to it
// with the new global later. (See base::trans_crate.)
c
c
x
.statics_to_rauw
.borrow_mut
()
.push
((
g
,
new_g
));
cx
.statics_to_rauw
.borrow_mut
()
.push
((
g
,
new_g
));
new_g
};
set_global_alignment
(
c
cx
,
g
,
c
cx
.align_of
(
ty
));
set_global_alignment
(
c
x
,
g
,
cx
.align_of
(
ty
));
llvm
::
LLVMSetInitializer
(
g
,
v
);
// As an optimization, all shared statics which do not have interior
// mutability are placed into read-only memory.
if
m
!=
hir
::
MutMutable
{
if
c
c
x
.type_is_freeze
(
ty
)
{
if
cx
.type_is_freeze
(
ty
)
{
llvm
::
LLVMSetGlobalConstant
(
g
,
llvm
::
True
);
}
}
debuginfo
::
create_global_var_metadata
(
c
c
x
,
id
,
g
);
debuginfo
::
create_global_var_metadata
(
cx
,
id
,
g
);
if
attr
::
contains_name
(
attrs
,
"thread_local"
)
{
llvm
::
set_thread_local_mode
(
g
,
c
c
x
.tls_model
);
llvm
::
set_thread_local_mode
(
g
,
cx
.tls_model
);
}
base
::
set_link_section
(
c
c
x
,
g
,
attrs
);
base
::
set_link_section
(
cx
,
g
,
attrs
);
if
attr
::
contains_name
(
attrs
,
"used"
)
{
// This static will be stored in the llvm.used variable which is an array of i8*
let
cast
=
llvm
::
LLVMConstPointerCast
(
g
,
Type
::
i8p
(
c
c
x
)
.to_ref
());
c
c
x
.used_statics
.borrow_mut
()
.push
(
cast
);
let
cast
=
llvm
::
LLVMConstPointerCast
(
g
,
Type
::
i8p
(
cx
)
.to_ref
());
cx
.used_statics
.borrow_mut
()
.push
(
cast
);
}
Ok
(
g
)
...
...
src/librustc_trans/context.rs
浏览文件 @
e69dacb4
...
...
@@ -280,7 +280,7 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
None
};
let
mut
c
c
x
=
CodegenCx
{
let
mut
cx
=
CodegenCx
{
tcx
,
check_overflow
,
use_dll_storage_attrs
,
...
...
@@ -308,8 +308,8 @@ pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
intrinsics
:
RefCell
::
new
(
FxHashMap
()),
local_gen_sym_counter
:
Cell
::
new
(
0
),
};
c
cx
.isize_ty
=
Type
::
isize
(
&
c
cx
);
c
c
x
c
x
.isize_ty
=
Type
::
isize
(
&
cx
);
cx
}
}
...
...
@@ -474,47 +474,47 @@ fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
}
/// Declare any llvm intrinsics that you might need
fn
declare_intrinsic
(
c
c
x
:
&
CodegenCx
,
key
:
&
str
)
->
Option
<
ValueRef
>
{
fn
declare_intrinsic
(
cx
:
&
CodegenCx
,
key
:
&
str
)
->
Option
<
ValueRef
>
{
macro_rules!
ifn
{
(
$name:expr
,
fn
()
->
$ret:expr
)
=>
(
if
key
==
$name
{
let
f
=
declare
::
declare_cfn
(
c
c
x
,
$name
,
Type
::
func
(
&
[],
&
$ret
));
let
f
=
declare
::
declare_cfn
(
cx
,
$name
,
Type
::
func
(
&
[],
&
$ret
));
llvm
::
SetUnnamedAddr
(
f
,
false
);
c
c
x
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
cx
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
return
Some
(
f
);
}
);
(
$name:expr
,
fn
(
...
)
->
$ret:expr
)
=>
(
if
key
==
$name
{
let
f
=
declare
::
declare_cfn
(
c
c
x
,
$name
,
Type
::
variadic_func
(
&
[],
&
$ret
));
let
f
=
declare
::
declare_cfn
(
cx
,
$name
,
Type
::
variadic_func
(
&
[],
&
$ret
));
llvm
::
SetUnnamedAddr
(
f
,
false
);
c
c
x
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
cx
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
return
Some
(
f
);
}
);
(
$name:expr
,
fn
(
$
(
$arg:expr
),
*
)
->
$ret:expr
)
=>
(
if
key
==
$name
{
let
f
=
declare
::
declare_cfn
(
c
c
x
,
$name
,
Type
::
func
(
&
[
$
(
$arg
),
*
],
&
$ret
));
let
f
=
declare
::
declare_cfn
(
cx
,
$name
,
Type
::
func
(
&
[
$
(
$arg
),
*
],
&
$ret
));
llvm
::
SetUnnamedAddr
(
f
,
false
);
c
c
x
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
cx
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
return
Some
(
f
);
}
);
}
macro_rules!
mk_struct
{
(
$
(
$field_ty:expr
),
*
)
=>
(
Type
::
struct_
(
c
c
x
,
&
[
$
(
$field_ty
),
*
],
false
))
(
$
(
$field_ty:expr
),
*
)
=>
(
Type
::
struct_
(
cx
,
&
[
$
(
$field_ty
),
*
],
false
))
}
let
i8p
=
Type
::
i8p
(
c
c
x
);
let
void
=
Type
::
void
(
c
c
x
);
let
i1
=
Type
::
i1
(
c
c
x
);
let
t_i8
=
Type
::
i8
(
c
c
x
);
let
t_i16
=
Type
::
i16
(
c
c
x
);
let
t_i32
=
Type
::
i32
(
c
c
x
);
let
t_i64
=
Type
::
i64
(
c
c
x
);
let
t_i128
=
Type
::
i128
(
c
c
x
);
let
t_f32
=
Type
::
f32
(
c
c
x
);
let
t_f64
=
Type
::
f64
(
c
c
x
);
let
i8p
=
Type
::
i8p
(
cx
);
let
void
=
Type
::
void
(
cx
);
let
i1
=
Type
::
i1
(
cx
);
let
t_i8
=
Type
::
i8
(
cx
);
let
t_i16
=
Type
::
i16
(
cx
);
let
t_i32
=
Type
::
i32
(
cx
);
let
t_i64
=
Type
::
i64
(
cx
);
let
t_i128
=
Type
::
i128
(
cx
);
let
t_f32
=
Type
::
f32
(
cx
);
let
t_f64
=
Type
::
f64
(
cx
);
ifn!
(
"llvm.memcpy.p0i8.p0i8.i16"
,
fn
(
i8p
,
i8p
,
t_i16
,
t_i32
,
i1
)
->
void
);
ifn!
(
"llvm.memcpy.p0i8.p0i8.i32"
,
fn
(
i8p
,
i8p
,
t_i32
,
t_i32
,
i1
)
->
void
);
...
...
@@ -646,9 +646,9 @@ fn declare_intrinsic(ccx: &CodegenCx, key: &str) -> Option<ValueRef> {
ifn!
(
"llvm.assume"
,
fn
(
i1
)
->
void
);
ifn!
(
"llvm.prefetch"
,
fn
(
i8p
,
t_i32
,
t_i32
,
t_i32
)
->
void
);
if
c
c
x
.sess
()
.opts.debuginfo
!=
NoDebugInfo
{
ifn!
(
"llvm.dbg.declare"
,
fn
(
Type
::
metadata
(
c
cx
),
Type
::
metadata
(
c
cx
))
->
void
);
ifn!
(
"llvm.dbg.value"
,
fn
(
Type
::
metadata
(
c
cx
),
t_i64
,
Type
::
metadata
(
c
cx
))
->
void
);
if
cx
.sess
()
.opts.debuginfo
!=
NoDebugInfo
{
ifn!
(
"llvm.dbg.declare"
,
fn
(
Type
::
metadata
(
c
x
),
Type
::
metadata
(
cx
))
->
void
);
ifn!
(
"llvm.dbg.value"
,
fn
(
Type
::
metadata
(
c
x
),
t_i64
,
Type
::
metadata
(
cx
))
->
void
);
}
return
None
;
}
src/librustc_trans/debuginfo/create_scope_map.rs
浏览文件 @
e69dacb4
...
...
@@ -44,7 +44,7 @@ pub fn is_valid(&self) -> bool {
/// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
/// If debuginfo is disabled, the returned vector is empty.
pub
fn
create_mir_scopes
(
c
c
x
:
&
CodegenCx
,
mir
:
&
Mir
,
debug_context
:
&
FunctionDebugContext
)
pub
fn
create_mir_scopes
(
cx
:
&
CodegenCx
,
mir
:
&
Mir
,
debug_context
:
&
FunctionDebugContext
)
->
IndexVec
<
VisibilityScope
,
MirDebugScope
>
{
let
null_scope
=
MirDebugScope
{
scope_metadata
:
ptr
::
null_mut
(),
...
...
@@ -71,13 +71,13 @@ pub fn create_mir_scopes(ccx: &CodegenCx, mir: &Mir, debug_context: &FunctionDeb
// Instantiate all scopes.
for
idx
in
0
..
mir
.visibility_scopes
.len
()
{
let
scope
=
VisibilityScope
::
new
(
idx
);
make_mir_scope
(
c
c
x
,
&
mir
,
&
has_variables
,
debug_context
,
scope
,
&
mut
scopes
);
make_mir_scope
(
cx
,
&
mir
,
&
has_variables
,
debug_context
,
scope
,
&
mut
scopes
);
}
scopes
}
fn
make_mir_scope
(
c
c
x
:
&
CodegenCx
,
fn
make_mir_scope
(
cx
:
&
CodegenCx
,
mir
:
&
Mir
,
has_variables
:
&
BitVector
,
debug_context
:
&
FunctionDebugContextData
,
...
...
@@ -89,11 +89,11 @@ fn make_mir_scope(ccx: &CodegenCx,
let
scope_data
=
&
mir
.visibility_scopes
[
scope
];
let
parent_scope
=
if
let
Some
(
parent
)
=
scope_data
.parent_scope
{
make_mir_scope
(
c
c
x
,
mir
,
has_variables
,
debug_context
,
parent
,
scopes
);
make_mir_scope
(
cx
,
mir
,
has_variables
,
debug_context
,
parent
,
scopes
);
scopes
[
parent
]
}
else
{
// The root is the function itself.
let
loc
=
span_start
(
c
c
x
,
mir
.span
);
let
loc
=
span_start
(
cx
,
mir
.span
);
scopes
[
scope
]
=
MirDebugScope
{
scope_metadata
:
debug_context
.fn_metadata
,
file_start_pos
:
loc
.file.start_pos
,
...
...
@@ -115,14 +115,14 @@ fn make_mir_scope(ccx: &CodegenCx,
}
}
let
loc
=
span_start
(
c
c
x
,
scope_data
.span
);
let
file_metadata
=
file_metadata
(
c
c
x
,
let
loc
=
span_start
(
cx
,
scope_data
.span
);
let
file_metadata
=
file_metadata
(
cx
,
&
loc
.file.name
,
debug_context
.defining_crate
);
let
scope_metadata
=
unsafe
{
llvm
::
LLVMRustDIBuilderCreateLexicalBlock
(
DIB
(
c
c
x
),
DIB
(
cx
),
parent_scope
.scope_metadata
,
file_metadata
,
loc
.line
as
c_uint
,
...
...
src/librustc_trans/debuginfo/gdb.rs
浏览文件 @
e69dacb4
...
...
@@ -24,12 +24,12 @@
/// Inserts a side-effect free instruction sequence that makes sure that the
/// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
pub
fn
insert_reference_to_gdb_debug_scripts_section_global
(
c
c
x
:
&
CodegenCx
,
builder
:
&
Builder
)
{
if
needs_gdb_debug_scripts_section
(
c
c
x
)
{
let
gdb_debug_scripts_section_global
=
get_or_insert_gdb_debug_scripts_section_global
(
c
c
x
);
pub
fn
insert_reference_to_gdb_debug_scripts_section_global
(
cx
:
&
CodegenCx
,
builder
:
&
Builder
)
{
if
needs_gdb_debug_scripts_section
(
cx
)
{
let
gdb_debug_scripts_section_global
=
get_or_insert_gdb_debug_scripts_section_global
(
cx
);
// Load just the first byte as that's all that's necessary to force
// LLVM to keep around the reference to the global.
let
indices
=
[
C_i32
(
c
cx
,
0
),
C_i32
(
c
cx
,
0
)];
let
indices
=
[
C_i32
(
c
x
,
0
),
C_i32
(
cx
,
0
)];
let
element
=
builder
.inbounds_gep
(
gdb_debug_scripts_section_global
,
&
indices
);
let
volative_load_instruction
=
builder
.volatile_load
(
element
);
unsafe
{
...
...
@@ -40,13 +40,13 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CodegenCx, bui
/// Allocates the global variable responsible for the .debug_gdb_scripts binary
/// section.
pub
fn
get_or_insert_gdb_debug_scripts_section_global
(
c
c
x
:
&
CodegenCx
)
pub
fn
get_or_insert_gdb_debug_scripts_section_global
(
cx
:
&
CodegenCx
)
->
llvm
::
ValueRef
{
let
c_section_var_name
=
"__rustc_debug_gdb_scripts_section__
\0
"
;
let
section_var_name
=
&
c_section_var_name
[
..
c_section_var_name
.len
()
-
1
];
let
section_var
=
unsafe
{
llvm
::
LLVMGetNamedGlobal
(
c
c
x
.llmod
,
llvm
::
LLVMGetNamedGlobal
(
cx
.llmod
,
c_section_var_name
.as_ptr
()
as
*
const
_
)
};
...
...
@@ -55,15 +55,15 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CodegenCx)
let
section_contents
=
b
"
\x01
gdb_load_rust_pretty_printers.py
\0
"
;
unsafe
{
let
llvm_type
=
Type
::
array
(
&
Type
::
i8
(
c
c
x
),
let
llvm_type
=
Type
::
array
(
&
Type
::
i8
(
cx
),
section_contents
.len
()
as
u64
);
let
section_var
=
declare
::
define_global
(
c
c
x
,
section_var_name
,
let
section_var
=
declare
::
define_global
(
cx
,
section_var_name
,
llvm_type
)
.unwrap_or_else
(||{
bug!
(
"symbol `{}` is already defined"
,
section_var_name
)
});
llvm
::
LLVMSetSection
(
section_var
,
section_name
.as_ptr
()
as
*
const
_
);
llvm
::
LLVMSetInitializer
(
section_var
,
C_bytes
(
c
c
x
,
section_contents
));
llvm
::
LLVMSetInitializer
(
section_var
,
C_bytes
(
cx
,
section_contents
));
llvm
::
LLVMSetGlobalConstant
(
section_var
,
llvm
::
True
);
llvm
::
LLVMSetUnnamedAddr
(
section_var
,
llvm
::
True
);
llvm
::
LLVMRustSetLinkage
(
section_var
,
llvm
::
Linkage
::
LinkOnceODRLinkage
);
...
...
@@ -77,13 +77,13 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CodegenCx)
}
}
pub
fn
needs_gdb_debug_scripts_section
(
c
c
x
:
&
CodegenCx
)
->
bool
{
pub
fn
needs_gdb_debug_scripts_section
(
cx
:
&
CodegenCx
)
->
bool
{
let
omit_gdb_pretty_printer_section
=
attr
::
contains_name
(
&
c
c
x
.tcx.hir
.krate_attrs
(),
attr
::
contains_name
(
&
cx
.tcx.hir
.krate_attrs
(),
"omit_gdb_pretty_printer_section"
);
!
omit_gdb_pretty_printer_section
&&
!
c
c
x
.sess
()
.target.target.options.is_like_osx
&&
!
c
c
x
.sess
()
.target.target.options.is_like_windows
&&
c
c
x
.sess
()
.opts.debuginfo
!=
NoDebugInfo
!
cx
.sess
()
.target.target.options.is_like_osx
&&
!
cx
.sess
()
.target.target.options.is_like_windows
&&
cx
.sess
()
.opts.debuginfo
!=
NoDebugInfo
}
src/librustc_trans/debuginfo/metadata.rs
浏览文件 @
e69dacb4
...
...
@@ -1210,7 +1210,7 @@ fn create_member_descriptions<'a>(&self, cx: &CodegenCx<'a, 'tcx>)
// of discriminant instead of us having to recover its path.
// Right now it's not even going to work for `niche_start > 0`,
// and for multiple niche variants it only supports the first.
fn
compute_field_path
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
fn
compute_field_path
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
name
:
&
mut
String
,
layout
:
TyLayout
<
'tcx
>
,
offset
:
Size
,
...
...
@@ -1221,10 +1221,10 @@ fn compute_field_path<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
continue
;
}
let
inner_offset
=
offset
-
field_offset
;
let
field
=
layout
.field
(
c
c
x
,
i
);
let
field
=
layout
.field
(
cx
,
i
);
if
inner_offset
+
size
<=
field
.size
{
write!
(
name
,
"{}$"
,
i
)
.unwrap
();
compute_field_path
(
c
c
x
,
name
,
field
,
inner_offset
,
size
);
compute_field_path
(
cx
,
name
,
field
,
inner_offset
,
size
);
}
}
}
...
...
@@ -1689,15 +1689,15 @@ pub fn create_global_var_metadata(cx: &CodegenCx,
}
// Creates an "extension" of an existing DIScope into another file.
pub
fn
extend_scope_to_file
(
c
c
x
:
&
CodegenCx
,
pub
fn
extend_scope_to_file
(
cx
:
&
CodegenCx
,
scope_metadata
:
DIScope
,
file
:
&
syntax_pos
::
FileMap
,
defining_crate
:
CrateNum
)
->
DILexicalBlock
{
let
file_metadata
=
file_metadata
(
c
c
x
,
&
file
.name
,
defining_crate
);
let
file_metadata
=
file_metadata
(
cx
,
&
file
.name
,
defining_crate
);
unsafe
{
llvm
::
LLVMRustDIBuilderCreateLexicalBlockFile
(
DIB
(
c
c
x
),
DIB
(
cx
),
scope_metadata
,
file_metadata
)
}
...
...
src/librustc_trans/debuginfo/mod.rs
浏览文件 @
e69dacb4
...
...
@@ -417,7 +417,7 @@ fn get_type_parameter_names(cx: &CodegenCx, generics: &ty::Generics) -> Vec<ast:
names
}
fn
get_containing_scope
<
'c
cx
,
'tcx
>
(
cx
:
&
CodegenCx
<
'c
cx
,
'tcx
>
,
fn
get_containing_scope
<
'c
x
,
'tcx
>
(
cx
:
&
CodegenCx
<
'
cx
,
'tcx
>
,
instance
:
Instance
<
'tcx
>
)
->
DIScope
{
// First, let's see if this is a method within an inherent impl. Because
...
...
@@ -463,7 +463,7 @@ pub fn declare_local<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
variable_access
:
VariableAccess
,
variable_kind
:
VariableKind
,
span
:
Span
)
{
let
cx
=
bcx
.c
c
x
;
let
cx
=
bcx
.cx
;
let
file
=
span_start
(
cx
,
span
)
.file
;
let
file_metadata
=
file_metadata
(
cx
,
...
...
src/librustc_trans/debuginfo/namespace.rs
浏览文件 @
e69dacb4
...
...
@@ -26,38 +26,38 @@
use
std
::
ptr
;
pub
fn
mangled_name_of_instance
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
instance
:
Instance
<
'tcx
>
,
)
->
ty
::
SymbolName
{
let
tcx
=
c
c
x
.tcx
;
let
tcx
=
cx
.tcx
;
tcx
.symbol_name
(
instance
)
}
pub
fn
mangled_name_of_item
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
node_id
:
ast
::
NodeId
,
)
->
ty
::
SymbolName
{
let
tcx
=
c
c
x
.tcx
;
let
tcx
=
cx
.tcx
;
let
node_def_id
=
tcx
.hir
.local_def_id
(
node_id
);
let
instance
=
Instance
::
mono
(
tcx
,
node_def_id
);
tcx
.symbol_name
(
instance
)
}
pub
fn
item_namespace
(
c
c
x
:
&
CodegenCx
,
def_id
:
DefId
)
->
DIScope
{
if
let
Some
(
&
scope
)
=
debug_context
(
c
c
x
)
.namespace_map
.borrow
()
.get
(
&
def_id
)
{
pub
fn
item_namespace
(
cx
:
&
CodegenCx
,
def_id
:
DefId
)
->
DIScope
{
if
let
Some
(
&
scope
)
=
debug_context
(
cx
)
.namespace_map
.borrow
()
.get
(
&
def_id
)
{
return
scope
;
}
let
def_key
=
c
c
x
.tcx
.def_key
(
def_id
);
let
def_key
=
cx
.tcx
.def_key
(
def_id
);
let
parent_scope
=
def_key
.parent
.map_or
(
ptr
::
null_mut
(),
|
parent
|
{
item_namespace
(
c
c
x
,
DefId
{
item_namespace
(
cx
,
DefId
{
krate
:
def_id
.krate
,
index
:
parent
})
});
let
namespace_name
=
match
def_key
.disambiguated_data.data
{
DefPathData
::
CrateRoot
=>
c
c
x
.tcx
.crate_name
(
def_id
.krate
)
.as_str
(),
DefPathData
::
CrateRoot
=>
cx
.tcx
.crate_name
(
def_id
.krate
)
.as_str
(),
data
=>
data
.as_interned_str
()
};
...
...
@@ -65,13 +65,13 @@ pub fn item_namespace(ccx: &CodegenCx, def_id: DefId) -> DIScope {
let
scope
=
unsafe
{
llvm
::
LLVMRustDIBuilderCreateNameSpace
(
DIB
(
c
c
x
),
DIB
(
cx
),
parent_scope
,
namespace_name
.as_ptr
(),
unknown_file_metadata
(
c
c
x
),
unknown_file_metadata
(
cx
),
UNKNOWN_LINE_NUMBER
)
};
debug_context
(
c
c
x
)
.namespace_map
.borrow_mut
()
.insert
(
def_id
,
scope
);
debug_context
(
cx
)
.namespace_map
.borrow_mut
()
.insert
(
def_id
,
scope
);
scope
}
src/librustc_trans/debuginfo/source_loc.rs
浏览文件 @
e69dacb4
...
...
@@ -39,7 +39,7 @@ pub fn set_source_location(
let
dbg_loc
=
if
function_debug_context
.source_locations_enabled
.get
()
{
debug!
(
"set_source_location: {}"
,
builder
.sess
()
.codemap
()
.span_to_string
(
span
));
let
loc
=
span_start
(
builder
.c
c
x
,
span
);
let
loc
=
span_start
(
builder
.cx
,
span
);
InternalDebugLocation
::
new
(
scope
,
loc
.line
,
loc
.col
.to_usize
())
}
else
{
UnknownLocation
...
...
@@ -88,7 +88,7 @@ pub fn set_debug_location(builder: &Builder, debug_location: InternalDebugLocati
unsafe
{
llvm
::
LLVMRustDIBuilderCreateDebugLocation
(
debug_context
(
builder
.c
c
x
)
.llcontext
,
debug_context
(
builder
.cx
)
.llcontext
,
line
as
c_uint
,
col
as
c_uint
,
scope
,
...
...
src/librustc_trans/declare.rs
浏览文件 @
e69dacb4
...
...
@@ -39,13 +39,13 @@
///
/// If there’s a value with the same name already declared, the function will
/// return its ValueRef instead.
pub
fn
declare_global
(
c
c
x
:
&
CodegenCx
,
name
:
&
str
,
ty
:
Type
)
->
llvm
::
ValueRef
{
pub
fn
declare_global
(
cx
:
&
CodegenCx
,
name
:
&
str
,
ty
:
Type
)
->
llvm
::
ValueRef
{
debug!
(
"declare_global(name={:?})"
,
name
);
let
namebuf
=
CString
::
new
(
name
)
.unwrap_or_else
(|
_
|{
bug!
(
"name {:?} contains an interior null byte"
,
name
)
});
unsafe
{
llvm
::
LLVMRustGetOrInsertGlobal
(
c
c
x
.llmod
,
namebuf
.as_ptr
(),
ty
.to_ref
())
llvm
::
LLVMRustGetOrInsertGlobal
(
cx
.llmod
,
namebuf
.as_ptr
(),
ty
.to_ref
())
}
}
...
...
@@ -54,13 +54,13 @@ pub fn declare_global(ccx: &CodegenCx, name: &str, ty: Type) -> llvm::ValueRef {
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing ValueRef instead.
fn
declare_raw_fn
(
c
c
x
:
&
CodegenCx
,
name
:
&
str
,
callconv
:
llvm
::
CallConv
,
ty
:
Type
)
->
ValueRef
{
fn
declare_raw_fn
(
cx
:
&
CodegenCx
,
name
:
&
str
,
callconv
:
llvm
::
CallConv
,
ty
:
Type
)
->
ValueRef
{
debug!
(
"declare_raw_fn(name={:?}, ty={:?})"
,
name
,
ty
);
let
namebuf
=
CString
::
new
(
name
)
.unwrap_or_else
(|
_
|{
bug!
(
"name {:?} contains an interior null byte"
,
name
)
});
let
llfn
=
unsafe
{
llvm
::
LLVMRustGetOrInsertFunction
(
c
c
x
.llmod
,
namebuf
.as_ptr
(),
ty
.to_ref
())
llvm
::
LLVMRustGetOrInsertFunction
(
cx
.llmod
,
namebuf
.as_ptr
(),
ty
.to_ref
())
};
llvm
::
SetFunctionCallConv
(
llfn
,
callconv
);
...
...
@@ -68,12 +68,12 @@ fn declare_raw_fn(ccx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Typ
// be merged.
llvm
::
SetUnnamedAddr
(
llfn
,
true
);
if
c
c
x
.tcx.sess.opts.cg.no_redzone
.unwrap_or
(
c
c
x
.tcx.sess.target.target.options.disable_redzone
)
{
if
cx
.tcx.sess.opts.cg.no_redzone
.unwrap_or
(
cx
.tcx.sess.target.target.options.disable_redzone
)
{
llvm
::
Attribute
::
NoRedZone
.apply_llfn
(
Function
,
llfn
);
}
if
let
Some
(
ref
sanitizer
)
=
c
c
x
.tcx.sess.opts.debugging_opts.sanitizer
{
if
let
Some
(
ref
sanitizer
)
=
cx
.tcx.sess.opts.debugging_opts.sanitizer
{
match
*
sanitizer
{
Sanitizer
::
Address
=>
{
llvm
::
Attribute
::
SanitizeAddress
.apply_llfn
(
Function
,
llfn
);
...
...
@@ -88,7 +88,7 @@ fn declare_raw_fn(ccx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Typ
}
}
match
c
c
x
.tcx.sess.opts.cg.opt_level
.as_ref
()
.map
(
String
::
as_ref
)
{
match
cx
.tcx.sess.opts.cg.opt_level
.as_ref
()
.map
(
String
::
as_ref
)
{
Some
(
"s"
)
=>
{
llvm
::
Attribute
::
OptimizeForSize
.apply_llfn
(
Function
,
llfn
);
},
...
...
@@ -99,7 +99,7 @@ fn declare_raw_fn(ccx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Typ
_
=>
{},
}
if
c
c
x
.tcx.sess
.panic_strategy
()
!=
PanicStrategy
::
Unwind
{
if
cx
.tcx.sess
.panic_strategy
()
!=
PanicStrategy
::
Unwind
{
attributes
::
unwind
(
llfn
,
false
);
}
...
...
@@ -114,8 +114,8 @@ fn declare_raw_fn(ccx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Typ
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing ValueRef instead.
pub
fn
declare_cfn
(
c
c
x
:
&
CodegenCx
,
name
:
&
str
,
fn_type
:
Type
)
->
ValueRef
{
declare_raw_fn
(
c
c
x
,
name
,
llvm
::
CCallConv
,
fn_type
)
pub
fn
declare_cfn
(
cx
:
&
CodegenCx
,
name
:
&
str
,
fn_type
:
Type
)
->
ValueRef
{
declare_raw_fn
(
cx
,
name
,
llvm
::
CCallConv
,
fn_type
)
}
...
...
@@ -123,15 +123,15 @@ pub fn declare_cfn(ccx: &CodegenCx, name: &str, fn_type: Type) -> ValueRef {
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing ValueRef instead.
pub
fn
declare_fn
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
name
:
&
str
,
pub
fn
declare_fn
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
name
:
&
str
,
fn_type
:
Ty
<
'tcx
>
)
->
ValueRef
{
debug!
(
"declare_rust_fn(name={:?}, fn_type={:?})"
,
name
,
fn_type
);
let
sig
=
common
::
ty_fn_sig
(
c
c
x
,
fn_type
);
let
sig
=
c
c
x
.tcx
.erase_late_bound_regions_and_normalize
(
&
sig
);
let
sig
=
common
::
ty_fn_sig
(
cx
,
fn_type
);
let
sig
=
cx
.tcx
.erase_late_bound_regions_and_normalize
(
&
sig
);
debug!
(
"declare_rust_fn (after region erasure) sig={:?}"
,
sig
);
let
fty
=
FnType
::
new
(
c
c
x
,
sig
,
&
[]);
let
llfn
=
declare_raw_fn
(
c
cx
,
name
,
fty
.cconv
,
fty
.llvm_type
(
c
cx
));
let
fty
=
FnType
::
new
(
cx
,
sig
,
&
[]);
let
llfn
=
declare_raw_fn
(
c
x
,
name
,
fty
.cconv
,
fty
.llvm_type
(
cx
));
// FIXME(canndrew): This is_never should really be an is_uninhabited
if
sig
.output
()
.is_never
()
{
...
...
@@ -154,11 +154,11 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>, name: &str,
/// return None if the name already has a definition associated with it. In that
/// case an error should be reported to the user, because it usually happens due
/// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
pub
fn
define_global
(
c
c
x
:
&
CodegenCx
,
name
:
&
str
,
ty
:
Type
)
->
Option
<
ValueRef
>
{
if
get_defined_value
(
c
c
x
,
name
)
.is_some
()
{
pub
fn
define_global
(
cx
:
&
CodegenCx
,
name
:
&
str
,
ty
:
Type
)
->
Option
<
ValueRef
>
{
if
get_defined_value
(
cx
,
name
)
.is_some
()
{
None
}
else
{
Some
(
declare_global
(
c
c
x
,
name
,
ty
))
Some
(
declare_global
(
cx
,
name
,
ty
))
}
}
...
...
@@ -167,13 +167,13 @@ pub fn define_global(ccx: &CodegenCx, name: &str, ty: Type) -> Option<ValueRef>
/// Use this function when you intend to define a function. This function will
/// return panic if the name already has a definition associated with it. This
/// can happen with #[no_mangle] or #[export_name], for example.
pub
fn
define_fn
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
define_fn
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
name
:
&
str
,
fn_type
:
Ty
<
'tcx
>
)
->
ValueRef
{
if
get_defined_value
(
c
c
x
,
name
)
.is_some
()
{
c
c
x
.sess
()
.fatal
(
&
format!
(
"symbol `{}` already defined"
,
name
))
if
get_defined_value
(
cx
,
name
)
.is_some
()
{
cx
.sess
()
.fatal
(
&
format!
(
"symbol `{}` already defined"
,
name
))
}
else
{
declare_fn
(
c
c
x
,
name
,
fn_type
)
declare_fn
(
cx
,
name
,
fn_type
)
}
}
...
...
@@ -182,22 +182,22 @@ pub fn define_fn<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
/// Use this function when you intend to define a function. This function will
/// return panic if the name already has a definition associated with it. This
/// can happen with #[no_mangle] or #[export_name], for example.
pub
fn
define_internal_fn
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
define_internal_fn
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
name
:
&
str
,
fn_type
:
Ty
<
'tcx
>
)
->
ValueRef
{
let
llfn
=
define_fn
(
c
c
x
,
name
,
fn_type
);
let
llfn
=
define_fn
(
cx
,
name
,
fn_type
);
unsafe
{
llvm
::
LLVMRustSetLinkage
(
llfn
,
llvm
::
Linkage
::
InternalLinkage
)
};
llfn
}
/// Get declared value by name.
pub
fn
get_declared_value
(
c
c
x
:
&
CodegenCx
,
name
:
&
str
)
->
Option
<
ValueRef
>
{
pub
fn
get_declared_value
(
cx
:
&
CodegenCx
,
name
:
&
str
)
->
Option
<
ValueRef
>
{
debug!
(
"get_declared_value(name={:?})"
,
name
);
let
namebuf
=
CString
::
new
(
name
)
.unwrap_or_else
(|
_
|{
bug!
(
"name {:?} contains an interior null byte"
,
name
)
});
let
val
=
unsafe
{
llvm
::
LLVMRustGetNamedValue
(
c
c
x
.llmod
,
namebuf
.as_ptr
())
};
let
val
=
unsafe
{
llvm
::
LLVMRustGetNamedValue
(
cx
.llmod
,
namebuf
.as_ptr
())
};
if
val
.is_null
()
{
debug!
(
"get_declared_value: {:?} value is null"
,
name
);
None
...
...
@@ -209,8 +209,8 @@ pub fn get_declared_value(ccx: &CodegenCx, name: &str) -> Option<ValueRef> {
/// Get defined or externally defined (AvailableExternally linkage) value by
/// name.
pub
fn
get_defined_value
(
c
c
x
:
&
CodegenCx
,
name
:
&
str
)
->
Option
<
ValueRef
>
{
get_declared_value
(
c
c
x
,
name
)
.and_then
(|
val
|{
pub
fn
get_defined_value
(
cx
:
&
CodegenCx
,
name
:
&
str
)
->
Option
<
ValueRef
>
{
get_declared_value
(
cx
,
name
)
.and_then
(|
val
|{
let
declaration
=
unsafe
{
llvm
::
LLVMIsDeclaration
(
val
)
!=
0
};
...
...
src/librustc_trans/glue.rs
浏览文件 @
e69dacb4
...
...
@@ -27,12 +27,12 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
->
(
ValueRef
,
ValueRef
)
{
debug!
(
"calculate size of DST: {}; with lost info: {:?}"
,
t
,
Value
(
info
));
if
bcx
.c
c
x
.type_is_sized
(
t
)
{
let
(
size
,
align
)
=
bcx
.c
c
x
.size_and_align_of
(
t
);
if
bcx
.cx
.type_is_sized
(
t
)
{
let
(
size
,
align
)
=
bcx
.cx
.size_and_align_of
(
t
);
debug!
(
"size_and_align_of_dst t={} info={:?} size: {:?} align: {:?}"
,
t
,
Value
(
info
),
size
,
align
);
let
size
=
C_usize
(
bcx
.c
c
x
,
size
.bytes
());
let
align
=
C_usize
(
bcx
.c
c
x
,
align
.abi
());
let
size
=
C_usize
(
bcx
.cx
,
size
.bytes
());
let
align
=
C_usize
(
bcx
.cx
,
align
.abi
());
return
(
size
,
align
);
}
assert
!
(
!
info
.is_null
());
...
...
@@ -45,17 +45,17 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
let
unit
=
t
.sequence_element_type
(
bcx
.tcx
());
// The info in this case is the length of the str, so the size is that
// times the unit size.
let
(
size
,
align
)
=
bcx
.c
c
x
.size_and_align_of
(
unit
);
(
bcx
.mul
(
info
,
C_usize
(
bcx
.c
c
x
,
size
.bytes
())),
C_usize
(
bcx
.c
c
x
,
align
.abi
()))
let
(
size
,
align
)
=
bcx
.cx
.size_and_align_of
(
unit
);
(
bcx
.mul
(
info
,
C_usize
(
bcx
.cx
,
size
.bytes
())),
C_usize
(
bcx
.cx
,
align
.abi
()))
}
_
=>
{
let
c
cx
=
bcx
.c
cx
;
let
c
x
=
bcx
.
cx
;
// First get the size of all statically known fields.
// Don't use size_of because it also rounds up to alignment, which we
// want to avoid, as the unsized field's alignment could be smaller.
assert
!
(
!
t
.is_simd
());
let
layout
=
c
c
x
.layout_of
(
t
);
let
layout
=
cx
.layout_of
(
t
);
debug!
(
"DST {} layout: {:?}"
,
t
,
layout
);
let
i
=
layout
.fields
.count
()
-
1
;
...
...
@@ -63,12 +63,12 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
let
sized_align
=
layout
.align
.abi
();
debug!
(
"DST {} statically sized prefix size: {} align: {}"
,
t
,
sized_size
,
sized_align
);
let
sized_size
=
C_usize
(
c
c
x
,
sized_size
);
let
sized_align
=
C_usize
(
c
c
x
,
sized_align
);
let
sized_size
=
C_usize
(
cx
,
sized_size
);
let
sized_align
=
C_usize
(
cx
,
sized_align
);
// Recurse to get the size of the dynamically sized field (must be
// the last field).
let
field_ty
=
layout
.field
(
c
c
x
,
i
)
.ty
;
let
field_ty
=
layout
.field
(
cx
,
i
)
.ty
;
let
(
unsized_size
,
mut
unsized_align
)
=
size_and_align_of_dst
(
bcx
,
field_ty
,
info
);
// FIXME (#26403, #27023): We should be adding padding
...
...
@@ -95,7 +95,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
(
Some
(
sized_align
),
Some
(
unsized_align
))
=>
{
// If both alignments are constant, (the sized_align should always be), then
// pick the correct alignment statically.
C_usize
(
c
c
x
,
std
::
cmp
::
max
(
sized_align
,
unsized_align
)
as
u64
)
C_usize
(
cx
,
std
::
cmp
::
max
(
sized_align
,
unsized_align
)
as
u64
)
}
_
=>
bcx
.select
(
bcx
.icmp
(
llvm
::
IntUGT
,
sized_align
,
unsized_align
),
sized_align
,
...
...
@@ -113,7 +113,7 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
//
// `(size + (align-1)) & -align`
let
addend
=
bcx
.sub
(
align
,
C_usize
(
bcx
.c
c
x
,
1
));
let
addend
=
bcx
.sub
(
align
,
C_usize
(
bcx
.cx
,
1
));
let
size
=
bcx
.and
(
bcx
.add
(
size
,
addend
),
bcx
.neg
(
align
));
(
size
,
align
)
...
...
src/librustc_trans/intrinsic.rs
浏览文件 @
e69dacb4
此差异已折叠。
点击以展开。
src/librustc_trans/meth.rs
浏览文件 @
e69dacb4
...
...
@@ -39,9 +39,9 @@ pub fn get_fn(self, bcx: &Builder<'a, 'tcx>,
// Load the data pointer from the object.
debug!
(
"get_fn({:?}, {:?})"
,
Value
(
llvtable
),
self
);
let
llvtable
=
bcx
.pointercast
(
llvtable
,
fn_ty
.llvm_type
(
bcx
.c
c
x
)
.ptr_to
()
.ptr_to
());
let
llvtable
=
bcx
.pointercast
(
llvtable
,
fn_ty
.llvm_type
(
bcx
.cx
)
.ptr_to
()
.ptr_to
());
let
ptr_align
=
bcx
.tcx
()
.data_layout.pointer_align
;
let
ptr
=
bcx
.load
(
bcx
.inbounds_gep
(
llvtable
,
&
[
C_usize
(
bcx
.c
c
x
,
self
.0
)]),
ptr_align
);
let
ptr
=
bcx
.load
(
bcx
.inbounds_gep
(
llvtable
,
&
[
C_usize
(
bcx
.cx
,
self
.0
)]),
ptr_align
);
bcx
.nonnull_metadata
(
ptr
);
// Vtable loads are invariant
bcx
.set_invariant_load
(
ptr
);
...
...
@@ -52,9 +52,9 @@ pub fn get_usize(self, bcx: &Builder<'a, 'tcx>, llvtable: ValueRef) -> ValueRef
// Load the data pointer from the object.
debug!
(
"get_int({:?}, {:?})"
,
Value
(
llvtable
),
self
);
let
llvtable
=
bcx
.pointercast
(
llvtable
,
Type
::
isize
(
bcx
.c
c
x
)
.ptr_to
());
let
llvtable
=
bcx
.pointercast
(
llvtable
,
Type
::
isize
(
bcx
.cx
)
.ptr_to
());
let
usize_align
=
bcx
.tcx
()
.data_layout.pointer_align
;
let
ptr
=
bcx
.load
(
bcx
.inbounds_gep
(
llvtable
,
&
[
C_usize
(
bcx
.c
c
x
,
self
.0
)]),
usize_align
);
let
ptr
=
bcx
.load
(
bcx
.inbounds_gep
(
llvtable
,
&
[
C_usize
(
bcx
.cx
,
self
.0
)]),
usize_align
);
// Vtable loads are invariant
bcx
.set_invariant_load
(
ptr
);
ptr
...
...
@@ -69,28 +69,28 @@ pub fn get_usize(self, bcx: &Builder<'a, 'tcx>, llvtable: ValueRef) -> ValueRef
/// The `trait_ref` encodes the erased self type. Hence if we are
/// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
/// `trait_ref` would map `T:Trait`.
pub
fn
get_vtable
<
'a
,
'tcx
>
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
get_vtable
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
trait_ref
:
Option
<
ty
::
PolyExistentialTraitRef
<
'tcx
>>
)
->
ValueRef
{
let
tcx
=
c
c
x
.tcx
;
let
tcx
=
cx
.tcx
;
debug!
(
"get_vtable(ty={:?}, trait_ref={:?})"
,
ty
,
trait_ref
);
// Check the cache.
if
let
Some
(
&
val
)
=
c
c
x
.vtables
.borrow
()
.get
(
&
(
ty
,
trait_ref
))
{
if
let
Some
(
&
val
)
=
cx
.vtables
.borrow
()
.get
(
&
(
ty
,
trait_ref
))
{
return
val
;
}
// Not in the cache. Build it.
let
nullptr
=
C_null
(
Type
::
i8p
(
c
c
x
));
let
nullptr
=
C_null
(
Type
::
i8p
(
cx
));
let
(
size
,
align
)
=
c
c
x
.size_and_align_of
(
ty
);
let
(
size
,
align
)
=
cx
.size_and_align_of
(
ty
);
let
mut
components
:
Vec
<
_
>
=
[
callee
::
get_fn
(
c
cx
,
monomorphize
::
resolve_drop_in_place
(
c
cx
.tcx
,
ty
)),
C_usize
(
c
c
x
,
size
.bytes
()),
C_usize
(
c
c
x
,
align
.abi
())
callee
::
get_fn
(
c
x
,
monomorphize
::
resolve_drop_in_place
(
cx
.tcx
,
ty
)),
C_usize
(
cx
,
size
.bytes
()),
C_usize
(
cx
,
align
.abi
())
]
.iter
()
.cloned
()
.collect
();
if
let
Some
(
trait_ref
)
=
trait_ref
{
...
...
@@ -98,18 +98,18 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CodegenCx<'a, 'tcx>,
let
methods
=
tcx
.vtable_methods
(
trait_ref
);
let
methods
=
methods
.iter
()
.cloned
()
.map
(|
opt_mth
|
{
opt_mth
.map_or
(
nullptr
,
|(
def_id
,
substs
)|
{
callee
::
resolve_and_get_fn
(
c
c
x
,
def_id
,
substs
)
callee
::
resolve_and_get_fn
(
cx
,
def_id
,
substs
)
})
});
components
.extend
(
methods
);
}
let
vtable_const
=
C_struct
(
c
c
x
,
&
components
,
false
);
let
align
=
c
c
x
.data_layout
()
.pointer_align
;
let
vtable
=
consts
::
addr_of
(
c
c
x
,
vtable_const
,
align
,
"vtable"
);
let
vtable_const
=
C_struct
(
cx
,
&
components
,
false
);
let
align
=
cx
.data_layout
()
.pointer_align
;
let
vtable
=
consts
::
addr_of
(
cx
,
vtable_const
,
align
,
"vtable"
);
debuginfo
::
create_vtable_metadata
(
c
c
x
,
ty
,
vtable
);
debuginfo
::
create_vtable_metadata
(
cx
,
ty
,
vtable
);
c
c
x
.vtables
.borrow_mut
()
.insert
((
ty
,
trait_ref
),
vtable
);
cx
.vtables
.borrow_mut
()
.insert
((
ty
,
trait_ref
),
vtable
);
vtable
}
src/librustc_trans/mir/analyze.rs
浏览文件 @
e69dacb4
...
...
@@ -31,7 +31,7 @@ pub fn memory_locals<'a, 'tcx>(mircx: &MirContext<'a, 'tcx>) -> BitVector {
for
(
index
,
ty
)
in
mir
.local_decls
.iter
()
.map
(|
l
|
l
.ty
)
.enumerate
()
{
let
ty
=
mircx
.monomorphize
(
&
ty
);
debug!
(
"local {} has type {:?}"
,
index
,
ty
);
let
layout
=
mircx
.c
c
x
.layout_of
(
ty
);
let
layout
=
mircx
.cx
.layout_of
(
ty
);
if
layout
.is_llvm_immediate
()
{
// These sorts of types are immediates that we can store
// in an ValueRef without an alloca.
...
...
@@ -117,7 +117,7 @@ fn visit_terminator_kind(&mut self,
},
..
}),
ref
args
,
..
}
if
Some
(
def_id
)
==
self
.cx.c
c
x.tcx
.lang_items
()
.box_free_fn
()
=>
{
}
if
Some
(
def_id
)
==
self
.cx.cx.tcx
.lang_items
()
.box_free_fn
()
=>
{
// box_free(x) shares with `drop x` the property that it
// is not guaranteed to be statically dominated by the
// definition of x, so x must always be in an alloca.
...
...
@@ -136,7 +136,7 @@ fn visit_place(&mut self,
context
:
PlaceContext
<
'tcx
>
,
location
:
Location
)
{
debug!
(
"visit_place(place={:?}, context={:?})"
,
place
,
context
);
let
c
cx
=
self
.cx.c
cx
;
let
c
x
=
self
.cx.
cx
;
if
let
mir
::
Place
::
Projection
(
ref
proj
)
=
*
place
{
// Allow uses of projections that are ZSTs or from scalar fields.
...
...
@@ -145,18 +145,18 @@ fn visit_place(&mut self,
_
=>
false
};
if
is_consume
{
let
base_ty
=
proj
.base
.ty
(
self
.cx.mir
,
c
c
x
.tcx
);
let
base_ty
=
proj
.base
.ty
(
self
.cx.mir
,
cx
.tcx
);
let
base_ty
=
self
.cx
.monomorphize
(
&
base_ty
);
// ZSTs don't require any actual memory access.
let
elem_ty
=
base_ty
.projection_ty
(
c
cx
.tcx
,
&
proj
.elem
)
.to_ty
(
c
cx
.tcx
);
let
elem_ty
=
base_ty
.projection_ty
(
c
x
.tcx
,
&
proj
.elem
)
.to_ty
(
cx
.tcx
);
let
elem_ty
=
self
.cx
.monomorphize
(
&
elem_ty
);
if
c
c
x
.layout_of
(
elem_ty
)
.is_zst
()
{
if
cx
.layout_of
(
elem_ty
)
.is_zst
()
{
return
;
}
if
let
mir
::
ProjectionElem
::
Field
(
..
)
=
proj
.elem
{
let
layout
=
c
cx
.layout_of
(
base_ty
.to_ty
(
c
cx
.tcx
));
let
layout
=
c
x
.layout_of
(
base_ty
.to_ty
(
cx
.tcx
));
if
layout
.is_llvm_immediate
()
||
layout
.is_llvm_scalar_pair
()
{
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
...
...
@@ -200,11 +200,11 @@ fn visit_local(&mut self,
}
PlaceContext
::
Drop
=>
{
let
ty
=
mir
::
Place
::
Local
(
index
)
.ty
(
self
.cx.mir
,
self
.cx.c
c
x.tcx
);
let
ty
=
self
.cx
.monomorphize
(
&
ty
.to_ty
(
self
.cx.c
c
x.tcx
));
let
ty
=
mir
::
Place
::
Local
(
index
)
.ty
(
self
.cx.mir
,
self
.cx.cx.tcx
);
let
ty
=
self
.cx
.monomorphize
(
&
ty
.to_ty
(
self
.cx.cx.tcx
));
// Only need the place if we're actually dropping it.
if
self
.cx.c
c
x
.type_needs_drop
(
ty
)
{
if
self
.cx.cx
.type_needs_drop
(
ty
)
{
self
.mark_as_memory
(
index
);
}
}
...
...
src/librustc_trans/mir/block.rs
浏览文件 @
e69dacb4
...
...
@@ -174,7 +174,7 @@ fn trans_terminator(&mut self,
lp
=
bcx
.insert_value
(
lp
,
lp1
,
1
);
bcx
.resume
(
lp
);
}
else
{
bcx
.call
(
bcx
.c
c
x
.eh_unwind_resume
(),
&
[
lp0
],
cleanup_bundle
);
bcx
.call
(
bcx
.cx
.eh_unwind_resume
(),
&
[
lp0
],
cleanup_bundle
);
bcx
.unreachable
();
}
}
...
...
@@ -182,7 +182,7 @@ fn trans_terminator(&mut self,
mir
::
TerminatorKind
::
Abort
=>
{
// Call core::intrinsics::abort()
let
fnname
=
bcx
.c
c
x
.get_intrinsic
(
&
(
"llvm.trap"
));
let
fnname
=
bcx
.cx
.get_intrinsic
(
&
(
"llvm.trap"
));
bcx
.call
(
fnname
,
&
[],
None
);
bcx
.unreachable
();
}
...
...
@@ -206,7 +206,7 @@ fn trans_terminator(&mut self,
let
switch
=
bcx
.switch
(
discr
.immediate
(),
llblock
(
self
,
*
otherwise
),
values
.len
());
for
(
value
,
target
)
in
values
.iter
()
.zip
(
targets
)
{
let
val
=
Const
::
from_constint
(
bcx
.c
c
x
,
value
);
let
val
=
Const
::
from_constint
(
bcx
.cx
,
value
);
let
llbb
=
llblock
(
self
,
*
target
);
bcx
.add_case
(
switch
,
val
.llval
,
llbb
)
}
...
...
@@ -253,7 +253,7 @@ fn trans_terminator(&mut self,
}
};
bcx
.load
(
bcx
.pointercast
(
llslot
,
cast_ty
.llvm_type
(
bcx
.c
c
x
)
.ptr_to
()),
bcx
.pointercast
(
llslot
,
cast_ty
.llvm_type
(
bcx
.cx
)
.ptr_to
()),
self
.fn_ty.ret.layout.align
)
}
};
...
...
@@ -267,7 +267,7 @@ fn trans_terminator(&mut self,
mir
::
TerminatorKind
::
Drop
{
ref
location
,
target
,
unwind
}
=>
{
let
ty
=
location
.ty
(
self
.mir
,
bcx
.tcx
())
.to_ty
(
bcx
.tcx
());
let
ty
=
self
.monomorphize
(
&
ty
);
let
drop_fn
=
monomorphize
::
resolve_drop_in_place
(
bcx
.c
c
x.tcx
,
ty
);
let
drop_fn
=
monomorphize
::
resolve_drop_in_place
(
bcx
.cx.tcx
,
ty
);
if
let
ty
::
InstanceDef
::
DropGlue
(
_
,
None
)
=
drop_fn
.def
{
// we don't actually need to drop anything.
...
...
@@ -280,16 +280,16 @@ fn trans_terminator(&mut self,
args
=
&
args
[
..
1
+
place
.has_extra
()
as
usize
];
let
(
drop_fn
,
fn_ty
)
=
match
ty
.sty
{
ty
::
TyDynamic
(
..
)
=>
{
let
fn_ty
=
drop_fn
.ty
(
bcx
.c
c
x.tcx
);
let
sig
=
common
::
ty_fn_sig
(
bcx
.c
c
x
,
fn_ty
);
let
fn_ty
=
drop_fn
.ty
(
bcx
.cx.tcx
);
let
sig
=
common
::
ty_fn_sig
(
bcx
.cx
,
fn_ty
);
let
sig
=
bcx
.tcx
()
.erase_late_bound_regions_and_normalize
(
&
sig
);
let
fn_ty
=
FnType
::
new_vtable
(
bcx
.c
c
x
,
sig
,
&
[]);
let
fn_ty
=
FnType
::
new_vtable
(
bcx
.cx
,
sig
,
&
[]);
args
=
&
args
[
..
1
];
(
meth
::
DESTRUCTOR
.get_fn
(
&
bcx
,
place
.llextra
,
&
fn_ty
),
fn_ty
)
}
_
=>
{
(
callee
::
get_fn
(
bcx
.c
c
x
,
drop_fn
),
FnType
::
of_instance
(
bcx
.c
c
x
,
&
drop_fn
))
(
callee
::
get_fn
(
bcx
.cx
,
drop_fn
),
FnType
::
of_instance
(
bcx
.cx
,
&
drop_fn
))
}
};
do_call
(
self
,
bcx
,
fn_ty
,
drop_fn
,
args
,
...
...
@@ -308,7 +308,7 @@ fn trans_terminator(&mut self,
// NOTE: Unlike binops, negation doesn't have its own
// checked operation, just a comparison with the minimum
// value, so we have to check for the assert message.
if
!
bcx
.c
c
x.check_overflow
{
if
!
bcx
.cx.check_overflow
{
use
rustc_const_math
::
ConstMathErr
::
Overflow
;
use
rustc_const_math
::
Op
::
Neg
;
...
...
@@ -324,8 +324,8 @@ fn trans_terminator(&mut self,
}
// Pass the condition through llvm.expect for branch hinting.
let
expect
=
bcx
.c
c
x
.get_intrinsic
(
&
"llvm.expect.i1"
);
let
cond
=
bcx
.call
(
expect
,
&
[
cond
,
C_bool
(
bcx
.c
c
x
,
expected
)],
None
);
let
expect
=
bcx
.cx
.get_intrinsic
(
&
"llvm.expect.i1"
);
let
cond
=
bcx
.call
(
expect
,
&
[
cond
,
C_bool
(
bcx
.cx
,
expected
)],
None
);
// Create the failure block and the conditional branch to it.
let
lltarget
=
llblock
(
self
,
target
);
...
...
@@ -343,9 +343,9 @@ fn trans_terminator(&mut self,
// Get the location information.
let
loc
=
bcx
.sess
()
.codemap
()
.lookup_char_pos
(
span
.lo
());
let
filename
=
Symbol
::
intern
(
&
loc
.file.name
.to_string
())
.as_str
();
let
filename
=
C_str_slice
(
bcx
.c
c
x
,
filename
);
let
line
=
C_u32
(
bcx
.c
c
x
,
loc
.line
as
u32
);
let
col
=
C_u32
(
bcx
.c
c
x
,
loc
.col
.to_usize
()
as
u32
+
1
);
let
filename
=
C_str_slice
(
bcx
.cx
,
filename
);
let
line
=
C_u32
(
bcx
.cx
,
loc
.line
as
u32
);
let
col
=
C_u32
(
bcx
.cx
,
loc
.col
.to_usize
()
as
u32
+
1
);
let
align
=
tcx
.data_layout.aggregate_align
.max
(
tcx
.data_layout.i32_align
)
.max
(
tcx
.data_layout.pointer_align
);
...
...
@@ -363,8 +363,8 @@ fn trans_terminator(&mut self,
index
:
index
as
u64
}));
let
file_line_col
=
C_struct
(
bcx
.c
c
x
,
&
[
filename
,
line
,
col
],
false
);
let
file_line_col
=
consts
::
addr_of
(
bcx
.c
c
x
,
let
file_line_col
=
C_struct
(
bcx
.cx
,
&
[
filename
,
line
,
col
],
false
);
let
file_line_col
=
consts
::
addr_of
(
bcx
.cx
,
file_line_col
,
align
,
"panic_bounds_check_loc"
);
...
...
@@ -374,11 +374,11 @@ fn trans_terminator(&mut self,
}
mir
::
AssertMessage
::
Math
(
ref
err
)
=>
{
let
msg_str
=
Symbol
::
intern
(
err
.description
())
.as_str
();
let
msg_str
=
C_str_slice
(
bcx
.c
c
x
,
msg_str
);
let
msg_file_line_col
=
C_struct
(
bcx
.c
c
x
,
let
msg_str
=
C_str_slice
(
bcx
.cx
,
msg_str
);
let
msg_file_line_col
=
C_struct
(
bcx
.cx
,
&
[
msg_str
,
filename
,
line
,
col
],
false
);
let
msg_file_line_col
=
consts
::
addr_of
(
bcx
.c
c
x
,
let
msg_file_line_col
=
consts
::
addr_of
(
bcx
.cx
,
msg_file_line_col
,
align
,
"panic_loc"
);
...
...
@@ -394,11 +394,11 @@ fn trans_terminator(&mut self,
"generator resumed after panicking"
};
let
msg_str
=
Symbol
::
intern
(
str
)
.as_str
();
let
msg_str
=
C_str_slice
(
bcx
.c
c
x
,
msg_str
);
let
msg_file_line_col
=
C_struct
(
bcx
.c
c
x
,
let
msg_str
=
C_str_slice
(
bcx
.cx
,
msg_str
);
let
msg_file_line_col
=
C_struct
(
bcx
.cx
,
&
[
msg_str
,
filename
,
line
,
col
],
false
);
let
msg_file_line_col
=
consts
::
addr_of
(
bcx
.c
c
x
,
let
msg_file_line_col
=
consts
::
addr_of
(
bcx
.cx
,
msg_file_line_col
,
align
,
"panic_loc"
);
...
...
@@ -423,8 +423,8 @@ fn trans_terminator(&mut self,
// Obtain the panic entry point.
let
def_id
=
common
::
langcall
(
bcx
.tcx
(),
Some
(
span
),
""
,
lang_item
);
let
instance
=
ty
::
Instance
::
mono
(
bcx
.tcx
(),
def_id
);
let
fn_ty
=
FnType
::
of_instance
(
bcx
.c
c
x
,
&
instance
);
let
llfn
=
callee
::
get_fn
(
bcx
.c
c
x
,
instance
);
let
fn_ty
=
FnType
::
of_instance
(
bcx
.cx
,
&
instance
);
let
llfn
=
callee
::
get_fn
(
bcx
.cx
,
instance
);
// Translate the actual panic invoke/call.
do_call
(
self
,
bcx
,
fn_ty
,
llfn
,
&
args
,
None
,
cleanup
);
...
...
@@ -440,7 +440,7 @@ fn trans_terminator(&mut self,
let
(
instance
,
mut
llfn
)
=
match
callee
.layout.ty.sty
{
ty
::
TyFnDef
(
def_id
,
substs
)
=>
{
(
Some
(
ty
::
Instance
::
resolve
(
bcx
.c
c
x.tcx
,
(
Some
(
ty
::
Instance
::
resolve
(
bcx
.cx.tcx
,
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
),
def_id
,
substs
)
.unwrap
()),
...
...
@@ -479,7 +479,7 @@ fn trans_terminator(&mut self,
let
fn_ty
=
match
def
{
Some
(
ty
::
InstanceDef
::
Virtual
(
..
))
=>
{
FnType
::
new_vtable
(
bcx
.c
c
x
,
sig
,
&
extra_args
)
FnType
::
new_vtable
(
bcx
.cx
,
sig
,
&
extra_args
)
}
Some
(
ty
::
InstanceDef
::
DropGlue
(
_
,
None
))
=>
{
// empty drop glue - a nop.
...
...
@@ -487,7 +487,7 @@ fn trans_terminator(&mut self,
funclet_br
(
self
,
bcx
,
target
);
return
;
}
_
=>
FnType
::
new
(
bcx
.c
c
x
,
sig
,
&
extra_args
)
_
=>
FnType
::
new
(
bcx
.cx
,
sig
,
&
extra_args
)
};
// The arguments we'll be passing. Plus one to account for outptr, if used.
...
...
@@ -509,7 +509,7 @@ fn trans_terminator(&mut self,
let
dest
=
match
ret_dest
{
_
if
fn_ty
.ret
.is_indirect
()
=>
llargs
[
0
],
ReturnDest
::
Nothing
=>
{
C_undef
(
fn_ty
.ret
.memory_ty
(
bcx
.c
c
x
)
.ptr_to
())
C_undef
(
fn_ty
.ret
.memory_ty
(
bcx
.cx
)
.ptr_to
())
}
ReturnDest
::
IndirectOperand
(
dst
,
_
)
|
ReturnDest
::
Store
(
dst
)
=>
dst
.llval
,
...
...
@@ -532,7 +532,7 @@ fn trans_terminator(&mut self,
let
val
=
self
.trans_constant
(
&
bcx
,
constant
);
return
OperandRef
{
val
:
Immediate
(
val
.llval
),
layout
:
bcx
.c
c
x
.layout_of
(
val
.ty
)
layout
:
bcx
.cx
.layout_of
(
val
.ty
)
};
}
}
...
...
@@ -542,7 +542,7 @@ fn trans_terminator(&mut self,
})
.collect
();
let
callee_ty
=
instance
.as_ref
()
.unwrap
()
.ty
(
bcx
.c
c
x.tcx
);
let
callee_ty
=
instance
.as_ref
()
.unwrap
()
.ty
(
bcx
.cx.tcx
);
trans_intrinsic_call
(
&
bcx
,
callee_ty
,
&
fn_ty
,
&
args
,
dest
,
terminator
.source_info.span
);
...
...
@@ -599,7 +599,7 @@ fn trans_terminator(&mut self,
let
fn_ptr
=
match
(
llfn
,
instance
)
{
(
Some
(
llfn
),
_
)
=>
llfn
,
(
None
,
Some
(
instance
))
=>
callee
::
get_fn
(
bcx
.c
c
x
,
instance
),
(
None
,
Some
(
instance
))
=>
callee
::
get_fn
(
bcx
.cx
,
instance
),
_
=>
span_bug!
(
span
,
"no llfn for call"
),
};
...
...
@@ -620,7 +620,7 @@ fn trans_argument(&mut self,
arg
:
&
ArgType
<
'tcx
>
)
{
// Fill padding with undef value, where applicable.
if
let
Some
(
ty
)
=
arg
.pad
{
llargs
.push
(
C_undef
(
ty
.llvm_type
(
bcx
.c
c
x
)));
llargs
.push
(
C_undef
(
ty
.llvm_type
(
bcx
.cx
)));
}
if
arg
.is_ignore
()
{
...
...
@@ -670,7 +670,7 @@ fn trans_argument(&mut self,
if
by_ref
&&
!
arg
.is_indirect
()
{
// Have to load the argument, maybe while casting it.
if
let
PassMode
::
Cast
(
ty
)
=
arg
.mode
{
llval
=
bcx
.load
(
bcx
.pointercast
(
llval
,
ty
.llvm_type
(
bcx
.c
c
x
)
.ptr_to
()),
llval
=
bcx
.load
(
bcx
.pointercast
(
llval
,
ty
.llvm_type
(
bcx
.cx
)
.ptr_to
()),
align
.min
(
arg
.layout.align
));
}
else
{
// We can't use `PlaceRef::load` here because the argument
...
...
@@ -716,13 +716,13 @@ fn trans_arguments_untupled(&mut self,
}
fn
get_personality_slot
(
&
mut
self
,
bcx
:
&
Builder
<
'a
,
'tcx
>
)
->
PlaceRef
<
'tcx
>
{
let
c
cx
=
bcx
.c
cx
;
let
c
x
=
bcx
.
cx
;
if
let
Some
(
slot
)
=
self
.personality_slot
{
slot
}
else
{
let
layout
=
c
cx
.layout_of
(
c
cx
.tcx
.intern_tup
(
&
[
c
cx
.tcx
.mk_mut_ptr
(
c
cx
.tcx.types.u8
),
c
c
x
.tcx.types.i32
let
layout
=
c
x
.layout_of
(
cx
.tcx
.intern_tup
(
&
[
c
x
.tcx
.mk_mut_ptr
(
cx
.tcx.types.u8
),
cx
.tcx.types.i32
],
false
));
let
slot
=
PlaceRef
::
alloca
(
bcx
,
layout
,
"personalityslot"
);
self
.personality_slot
=
Some
(
slot
);
...
...
@@ -745,13 +745,13 @@ fn landing_pad_to(&mut self, target_bb: mir::BasicBlock) -> BasicBlockRef {
}
fn
landing_pad_uncached
(
&
mut
self
,
target_bb
:
BasicBlockRef
)
->
BasicBlockRef
{
if
base
::
wants_msvc_seh
(
self
.c
c
x
.sess
())
{
if
base
::
wants_msvc_seh
(
self
.cx
.sess
())
{
span_bug!
(
self
.mir.span
,
"landing pad was not inserted?"
)
}
let
bcx
=
self
.new_block
(
"cleanup"
);
let
llpersonality
=
self
.c
c
x
.eh_personality
();
let
llpersonality
=
self
.cx
.eh_personality
();
let
llretty
=
self
.landing_pad_type
();
let
lp
=
bcx
.landing_pad
(
llretty
,
llpersonality
,
1
);
bcx
.set_cleanup
(
lp
);
...
...
@@ -765,8 +765,8 @@ fn landing_pad_uncached(&mut self, target_bb: BasicBlockRef) -> BasicBlockRef {
}
fn
landing_pad_type
(
&
self
)
->
Type
{
let
c
cx
=
self
.c
cx
;
Type
::
struct_
(
c
cx
,
&
[
Type
::
i8p
(
ccx
),
Type
::
i32
(
c
cx
)],
false
)
let
c
x
=
self
.
cx
;
Type
::
struct_
(
c
x
,
&
[
Type
::
i8p
(
cx
),
Type
::
i32
(
cx
)],
false
)
}
fn
unreachable_block
(
&
mut
self
)
->
BasicBlockRef
{
...
...
@@ -779,11 +779,11 @@ fn unreachable_block(&mut self) -> BasicBlockRef {
}
pub
fn
new_block
(
&
self
,
name
:
&
str
)
->
Builder
<
'a
,
'tcx
>
{
Builder
::
new_block
(
self
.c
c
x
,
self
.llfn
,
name
)
Builder
::
new_block
(
self
.cx
,
self
.llfn
,
name
)
}
pub
fn
get_builder
(
&
self
,
bb
:
mir
::
BasicBlock
)
->
Builder
<
'a
,
'tcx
>
{
let
builder
=
Builder
::
with_c
cx
(
self
.c
cx
);
let
builder
=
Builder
::
with_c
x
(
self
.
cx
);
builder
.position_at_end
(
self
.blocks
[
bb
]);
builder
}
...
...
@@ -851,7 +851,7 @@ fn trans_transmute(&mut self, bcx: &Builder<'a, 'tcx>,
match
self
.locals
[
index
]
{
LocalRef
::
Place
(
place
)
=>
self
.trans_transmute_into
(
bcx
,
src
,
place
),
LocalRef
::
Operand
(
None
)
=>
{
let
dst_layout
=
bcx
.c
c
x
.layout_of
(
self
.monomorphized_place_ty
(
dst
));
let
dst_layout
=
bcx
.cx
.layout_of
(
self
.monomorphized_place_ty
(
dst
));
assert
!
(
!
dst_layout
.ty
.has_erasable_regions
());
let
place
=
PlaceRef
::
alloca
(
bcx
,
dst_layout
,
"transmute_temp"
);
place
.storage_live
(
bcx
);
...
...
@@ -875,7 +875,7 @@ fn trans_transmute_into(&mut self, bcx: &Builder<'a, 'tcx>,
src
:
&
mir
::
Operand
<
'tcx
>
,
dst
:
PlaceRef
<
'tcx
>
)
{
let
src
=
self
.trans_operand
(
bcx
,
src
);
let
llty
=
src
.layout
.llvm_type
(
bcx
.c
c
x
);
let
llty
=
src
.layout
.llvm_type
(
bcx
.cx
);
let
cast_ptr
=
bcx
.pointercast
(
dst
.llval
,
llty
.ptr_to
());
let
align
=
src
.layout.align
.min
(
dst
.layout.align
);
src
.val
.store
(
bcx
,
PlaceRef
::
new_sized
(
cast_ptr
,
src
.layout
,
align
));
...
...
src/librustc_trans/mir/constant.rs
浏览文件 @
e69dacb4
此差异已折叠。
点击以展开。
src/librustc_trans/mir/mod.rs
浏览文件 @
e69dacb4
...
...
@@ -48,7 +48,7 @@ pub struct MirContext<'a, 'tcx:'a> {
llfn
:
ValueRef
,
c
c
x
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
cx
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
fn_ty
:
FnType
<
'tcx
>
,
...
...
@@ -106,7 +106,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
pub
fn
monomorphize
<
T
>
(
&
self
,
value
:
&
T
)
->
T
where
T
:
TransNormalize
<
'tcx
>
{
self
.c
c
x.tcx
.trans_apply_param_substs
(
self
.param_substs
,
value
)
self
.cx.tcx
.trans_apply_param_substs
(
self
.param_substs
,
value
)
}
pub
fn
set_debug_loc
(
&
mut
self
,
bcx
:
&
Builder
,
source_info
:
mir
::
SourceInfo
)
{
...
...
@@ -128,7 +128,7 @@ pub fn debug_loc(&mut self, source_info: mir::SourceInfo) -> (DIScope, Span) {
// locations of macro expansions with that of the outermost expansion site
// (unless the crate is being compiled with `-Z debug-macros`).
if
source_info
.span
.ctxt
()
==
NO_EXPANSION
||
self
.c
c
x
.sess
()
.opts.debugging_opts.debug_macros
{
self
.cx
.sess
()
.opts.debugging_opts.debug_macros
{
let
scope
=
self
.scope_metadata_for_loc
(
source_info
.scope
,
source_info
.span
.lo
());
(
scope
,
source_info
.span
)
}
else
{
...
...
@@ -158,9 +158,9 @@ fn scope_metadata_for_loc(&self, scope_id: mir::VisibilityScope, pos: BytePos)
let
scope_metadata
=
self
.scopes
[
scope_id
]
.scope_metadata
;
if
pos
<
self
.scopes
[
scope_id
]
.file_start_pos
||
pos
>=
self
.scopes
[
scope_id
]
.file_end_pos
{
let
cm
=
self
.c
c
x
.sess
()
.codemap
();
let
cm
=
self
.cx
.sess
()
.codemap
();
let
defining_crate
=
self
.debug_context
.get_ref
(
DUMMY_SP
)
.defining_crate
;
debuginfo
::
extend_scope_to_file
(
self
.c
c
x
,
debuginfo
::
extend_scope_to_file
(
self
.cx
,
scope_metadata
,
&
cm
.lookup_char_pos
(
pos
)
.file
,
defining_crate
)
...
...
@@ -176,12 +176,12 @@ enum LocalRef<'tcx> {
}
impl
<
'a
,
'tcx
>
LocalRef
<
'tcx
>
{
fn
new_operand
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
layout
:
TyLayout
<
'tcx
>
)
->
LocalRef
<
'tcx
>
{
fn
new_operand
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
layout
:
TyLayout
<
'tcx
>
)
->
LocalRef
<
'tcx
>
{
if
layout
.is_zst
()
{
// Zero-size temporaries aren't always initialized, which
// doesn't matter because they don't contain data, but
// we need something in the operand.
LocalRef
::
Operand
(
Some
(
OperandRef
::
new_zst
(
c
c
x
,
layout
)))
LocalRef
::
Operand
(
Some
(
OperandRef
::
new_zst
(
cx
,
layout
)))
}
else
{
LocalRef
::
Operand
(
None
)
}
...
...
@@ -191,20 +191,20 @@ fn new_operand(ccx: &CodegenCx<'a, 'tcx>, layout: TyLayout<'tcx>) -> LocalRef<'t
///////////////////////////////////////////////////////////////////////////
pub
fn
trans_mir
<
'a
,
'tcx
:
'a
>
(
c
c
x
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
cx
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
llfn
:
ValueRef
,
mir
:
&
'a
Mir
<
'tcx
>
,
instance
:
Instance
<
'tcx
>
,
sig
:
ty
::
FnSig
<
'tcx
>
,
)
{
let
fn_ty
=
FnType
::
new
(
c
c
x
,
sig
,
&
[]);
let
fn_ty
=
FnType
::
new
(
cx
,
sig
,
&
[]);
debug!
(
"fn_ty: {:?}"
,
fn_ty
);
let
debug_context
=
debuginfo
::
create_function_debug_context
(
c
c
x
,
instance
,
sig
,
llfn
,
mir
);
let
bcx
=
Builder
::
new_block
(
c
c
x
,
llfn
,
"start"
);
debuginfo
::
create_function_debug_context
(
cx
,
instance
,
sig
,
llfn
,
mir
);
let
bcx
=
Builder
::
new_block
(
cx
,
llfn
,
"start"
);
if
mir
.basic_blocks
()
.iter
()
.any
(|
bb
|
bb
.is_cleanup
)
{
bcx
.set_personality_fn
(
c
c
x
.eh_personality
());
bcx
.set_personality_fn
(
cx
.eh_personality
());
}
let
cleanup_kinds
=
analyze
::
cleanup_kinds
(
&
mir
);
...
...
@@ -221,14 +221,14 @@ pub fn trans_mir<'a, 'tcx: 'a>(
})
.collect
();
// Compute debuginfo scopes from MIR scopes.
let
scopes
=
debuginfo
::
create_mir_scopes
(
c
c
x
,
mir
,
&
debug_context
);
let
scopes
=
debuginfo
::
create_mir_scopes
(
cx
,
mir
,
&
debug_context
);
let
(
landing_pads
,
funclets
)
=
create_funclets
(
&
bcx
,
&
cleanup_kinds
,
&
block_bcxs
);
let
mut
mircx
=
MirContext
{
mir
,
llfn
,
fn_ty
,
c
c
x
,
cx
,
personality_slot
:
None
,
blocks
:
block_bcxs
,
unreachable_block
:
None
,
...
...
@@ -252,7 +252,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
let
mut
allocate_local
=
|
local
|
{
let
decl
=
&
mir
.local_decls
[
local
];
let
layout
=
bcx
.c
c
x
.layout_of
(
mircx
.monomorphize
(
&
decl
.ty
));
let
layout
=
bcx
.cx
.layout_of
(
mircx
.monomorphize
(
&
decl
.ty
));
assert
!
(
!
layout
.ty
.has_erasable_regions
());
if
let
Some
(
name
)
=
decl
.name
{
...
...
@@ -262,7 +262,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
if
!
memory_locals
.contains
(
local
.index
())
&&
!
dbg
{
debug!
(
"alloc: {:?} ({}) -> operand"
,
local
,
name
);
return
LocalRef
::
new_operand
(
bcx
.c
c
x
,
layout
);
return
LocalRef
::
new_operand
(
bcx
.cx
,
layout
);
}
debug!
(
"alloc: {:?} ({}) -> place"
,
local
,
name
);
...
...
@@ -288,7 +288,7 @@ pub fn trans_mir<'a, 'tcx: 'a>(
// alloca in advance. Instead we wait until we see the
// definition and update the operand there.
debug!
(
"alloc: {:?} -> operand"
,
local
);
LocalRef
::
new_operand
(
bcx
.c
c
x
,
layout
)
LocalRef
::
new_operand
(
bcx
.cx
,
layout
)
}
}
};
...
...
@@ -398,7 +398,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
_
=>
bug!
(
"spread argument isn't a tuple?!"
)
};
let
place
=
PlaceRef
::
alloca
(
bcx
,
bcx
.c
c
x
.layout_of
(
arg_ty
),
&
name
);
let
place
=
PlaceRef
::
alloca
(
bcx
,
bcx
.cx
.layout_of
(
arg_ty
),
&
name
);
for
i
in
0
..
tupled_arg_tys
.len
()
{
let
arg
=
&
mircx
.fn_ty.args
[
idx
];
idx
+=
1
;
...
...
@@ -438,7 +438,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
let
local
=
|
op
|
LocalRef
::
Operand
(
Some
(
op
));
match
arg
.mode
{
PassMode
::
Ignore
=>
{
return
local
(
OperandRef
::
new_zst
(
bcx
.c
c
x
,
arg
.layout
));
return
local
(
OperandRef
::
new_zst
(
bcx
.cx
,
arg
.layout
));
}
PassMode
::
Direct
(
_
)
=>
{
let
llarg
=
llvm
::
get_param
(
bcx
.llfn
(),
llarg_idx
as
c_uint
);
...
...
@@ -512,7 +512,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
// Or is it the closure environment?
let
(
closure_layout
,
env_ref
)
=
match
arg
.layout.ty.sty
{
ty
::
TyRef
(
_
,
mt
)
|
ty
::
TyRawPtr
(
mt
)
=>
(
bcx
.c
c
x
.layout_of
(
mt
.ty
),
true
),
ty
::
TyRef
(
_
,
mt
)
|
ty
::
TyRawPtr
(
mt
)
=>
(
bcx
.cx
.layout_of
(
mt
.ty
),
true
),
_
=>
(
arg
.layout
,
false
)
};
...
...
@@ -531,7 +531,7 @@ fn arg_local_refs<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
// environment into its components so it ends up out of bounds.
let
env_ptr
=
if
!
env_ref
{
let
scratch
=
PlaceRef
::
alloca
(
bcx
,
bcx
.c
c
x
.layout_of
(
tcx
.mk_mut_ptr
(
arg
.layout.ty
)),
bcx
.cx
.layout_of
(
tcx
.mk_mut_ptr
(
arg
.layout.ty
)),
"__debuginfo_env_ptr"
);
bcx
.store
(
place
.llval
,
scratch
.llval
,
scratch
.align
);
scratch
.llval
...
...
src/librustc_trans/mir/operand.rs
浏览文件 @
e69dacb4
...
...
@@ -81,11 +81,11 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
impl
<
'a
,
'tcx
>
OperandRef
<
'tcx
>
{
pub
fn
new_zst
(
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
,
pub
fn
new_zst
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
layout
:
TyLayout
<
'tcx
>
)
->
OperandRef
<
'tcx
>
{
assert
!
(
layout
.is_zst
());
OperandRef
{
val
:
OperandValue
::
Immediate
(
C_undef
(
layout
.immediate_llvm_type
(
c
c
x
))),
val
:
OperandValue
::
Immediate
(
C_undef
(
layout
.immediate_llvm_type
(
cx
))),
layout
}
}
...
...
@@ -99,7 +99,7 @@ pub fn immediate(self) -> ValueRef {
}
}
pub
fn
deref
(
self
,
c
c
x
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
PlaceRef
<
'tcx
>
{
pub
fn
deref
(
self
,
cx
:
&
CodegenCx
<
'a
,
'tcx
>
)
->
PlaceRef
<
'tcx
>
{
let
projected_ty
=
self
.layout.ty
.builtin_deref
(
true
,
ty
::
NoPreference
)
.unwrap_or_else
(||
bug!
(
"deref of non-pointer {:?}"
,
self
))
.ty
;
let
(
llptr
,
llextra
)
=
match
self
.val
{
...
...
@@ -107,7 +107,7 @@ pub fn deref(self, ccx: &CodegenCx<'a, 'tcx>) -> PlaceRef<'tcx> {
OperandValue
::
Pair
(
llptr
,
llextra
)
=>
(
llptr
,
llextra
),
OperandValue
::
Ref
(
..
)
=>
bug!
(
"Deref of by-Ref operand {:?}"
,
self
)
};
let
layout
=
c
c
x
.layout_of
(
projected_ty
);
let
layout
=
cx
.layout_of
(
projected_ty
);
PlaceRef
{
llval
:
llptr
,
llextra
,
...
...
@@ -120,7 +120,7 @@ pub fn deref(self, ccx: &CodegenCx<'a, 'tcx>) -> PlaceRef<'tcx> {
/// For other cases, see `immediate`.
pub
fn
immediate_or_packed_pair
(
self
,
bcx
:
&
Builder
<
'a
,
'tcx
>
)
->
ValueRef
{
if
let
OperandValue
::
Pair
(
a
,
b
)
=
self
.val
{
let
llty
=
self
.layout
.llvm_type
(
bcx
.c
c
x
);
let
llty
=
self
.layout
.llvm_type
(
bcx
.cx
);
debug!
(
"Operand::immediate_or_packed_pair: packing {:?} into {:?}"
,
self
,
llty
);
// Reconstruct the immediate aggregate.
...
...
@@ -152,14 +152,14 @@ pub fn from_immediate_or_packed_pair(bcx: &Builder<'a, 'tcx>,
}
pub
fn
extract_field
(
&
self
,
bcx
:
&
Builder
<
'a
,
'tcx
>
,
i
:
usize
)
->
OperandRef
<
'tcx
>
{
let
field
=
self
.layout
.field
(
bcx
.c
c
x
,
i
);
let
field
=
self
.layout
.field
(
bcx
.cx
,
i
);
let
offset
=
self
.layout.fields
.offset
(
i
);
let
mut
val
=
match
(
self
.val
,
&
self
.layout.abi
)
{
// If we're uninhabited, or the field is ZST, it has no data.
_
if
self
.layout.abi
==
layout
::
Abi
::
Uninhabited
||
field
.is_zst
()
=>
{
return
OperandRef
{
val
:
OperandValue
::
Immediate
(
C_undef
(
field
.immediate_llvm_type
(
bcx
.c
c
x
))),
val
:
OperandValue
::
Immediate
(
C_undef
(
field
.immediate_llvm_type
(
bcx
.cx
))),
layout
:
field
};
}
...
...
@@ -174,12 +174,12 @@ pub fn extract_field(&self, bcx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tc
// Extract a scalar component from a pair.
(
OperandValue
::
Pair
(
a_llval
,
b_llval
),
&
layout
::
Abi
::
ScalarPair
(
ref
a
,
ref
b
))
=>
{
if
offset
.bytes
()
==
0
{
assert_eq!
(
field
.size
,
a
.value
.size
(
bcx
.c
c
x
));
assert_eq!
(
field
.size
,
a
.value
.size
(
bcx
.cx
));
OperandValue
::
Immediate
(
a_llval
)
}
else
{
assert_eq!
(
offset
,
a
.value
.size
(
bcx
.c
c
x
)
.abi_align
(
b
.value
.align
(
bcx
.c
c
x
)));
assert_eq!
(
field
.size
,
b
.value
.size
(
bcx
.c
c
x
));
assert_eq!
(
offset
,
a
.value
.size
(
bcx
.cx
)
.abi_align
(
b
.value
.align
(
bcx
.cx
)));
assert_eq!
(
field
.size
,
b
.value
.size
(
bcx
.cx
));
OperandValue
::
Immediate
(
b_llval
)
}
}
...
...
@@ -187,7 +187,7 @@ pub fn extract_field(&self, bcx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tc
// `#[repr(simd)]` types are also immediate.
(
OperandValue
::
Immediate
(
llval
),
&
layout
::
Abi
::
Vector
{
..
})
=>
{
OperandValue
::
Immediate
(
bcx
.extract_element
(
llval
,
C_usize
(
bcx
.c
c
x
,
i
as
u64
)))
bcx
.extract_element
(
llval
,
C_usize
(
bcx
.cx
,
i
as
u64
)))
}
_
=>
bug!
(
"OperandRef::extract_field({:?}): not applicable"
,
self
)
...
...
@@ -196,11 +196,11 @@ pub fn extract_field(&self, bcx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tc
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
match
val
{
OperandValue
::
Immediate
(
ref
mut
llval
)
=>
{
*
llval
=
bcx
.bitcast
(
*
llval
,
field
.immediate_llvm_type
(
bcx
.c
c
x
));
*
llval
=
bcx
.bitcast
(
*
llval
,
field
.immediate_llvm_type
(
bcx
.cx
));
}
OperandValue
::
Pair
(
ref
mut
a
,
ref
mut
b
)
=>
{
*
a
=
bcx
.bitcast
(
*
a
,
field
.scalar_pair_element_llvm_type
(
bcx
.c
c
x
,
0
));
*
b
=
bcx
.bitcast
(
*
b
,
field
.scalar_pair_element_llvm_type
(
bcx
.c
c
x
,
1
));
*
a
=
bcx
.bitcast
(
*
a
,
field
.scalar_pair_element_llvm_type
(
bcx
.cx
,
0
));
*
b
=
bcx
.bitcast
(
*
b
,
field
.scalar_pair_element_llvm_type
(
bcx
.cx
,
1
));
}
OperandValue
::
Ref
(
..
)
=>
bug!
()
}
...
...
@@ -231,8 +231,8 @@ pub fn store(self, bcx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
for
(
i
,
&
x
)
in
[
a
,
b
]
.iter
()
.enumerate
()
{
let
mut
llptr
=
bcx
.struct_gep
(
dest
.llval
,
i
as
u64
);
// Make sure to always store i1 as i8.
if
common
::
val_ty
(
x
)
==
Type
::
i1
(
bcx
.c
c
x
)
{
llptr
=
bcx
.pointercast
(
llptr
,
Type
::
i8p
(
bcx
.c
c
x
));
if
common
::
val_ty
(
x
)
==
Type
::
i1
(
bcx
.cx
)
{
llptr
=
bcx
.pointercast
(
llptr
,
Type
::
i8p
(
bcx
.cx
));
}
bcx
.store
(
base
::
from_immediate
(
bcx
,
x
),
llptr
,
dest
.align
);
}
...
...
@@ -277,9 +277,9 @@ fn maybe_trans_consume_direct(&mut self,
// ZSTs don't require any actual memory access.
// FIXME(eddyb) deduplicate this with the identical
// checks in `trans_consume` and `extract_field`.
let
elem
=
o
.layout
.field
(
bcx
.c
c
x
,
0
);
let
elem
=
o
.layout
.field
(
bcx
.cx
,
0
);
if
elem
.is_zst
()
{
return
Some
(
OperandRef
::
new_zst
(
bcx
.c
c
x
,
elem
));
return
Some
(
OperandRef
::
new_zst
(
bcx
.cx
,
elem
));
}
}
_
=>
{}
...
...
@@ -298,11 +298,11 @@ pub fn trans_consume(&mut self,
debug!
(
"trans_consume(place={:?})"
,
place
);
let
ty
=
self
.monomorphized_place_ty
(
place
);
let
layout
=
bcx
.c
c
x
.layout_of
(
ty
);
let
layout
=
bcx
.cx
.layout_of
(
ty
);
// ZSTs don't require any actual memory access.
if
layout
.is_zst
()
{
return
OperandRef
::
new_zst
(
bcx
.c
c
x
,
layout
);
return
OperandRef
::
new_zst
(
bcx
.cx
,
layout
);
}
if
let
Some
(
o
)
=
self
.maybe_trans_consume_direct
(
bcx
,
place
)
{
...
...
@@ -329,7 +329,7 @@ pub fn trans_operand(&mut self,
mir
::
Operand
::
Constant
(
ref
constant
)
=>
{
let
val
=
self
.trans_constant
(
&
bcx
,
constant
);
let
operand
=
val
.to_operand
(
bcx
.c
c
x
);
let
operand
=
val
.to_operand
(
bcx
.cx
);
if
let
OperandValue
::
Ref
(
ptr
,
align
)
=
operand
.val
{
// If this is a OperandValue::Ref to an immediate constant, load it.
PlaceRef
::
new_sized
(
ptr
,
operand
.layout
,
align
)
.load
(
bcx
)
...
...
src/librustc_trans/mir/place.rs
浏览文件 @
e69dacb4
此差异已折叠。
点击以展开。
src/librustc_trans/mir/rvalue.rs
浏览文件 @
e69dacb4
此差异已折叠。
点击以展开。
src/librustc_trans/trans_item.rs
浏览文件 @
e69dacb4
此差异已折叠。
点击以展开。
src/librustc_trans/type_.rs
浏览文件 @
e69dacb4
此差异已折叠。
点击以展开。
src/librustc_trans/type_of.rs
浏览文件 @
e69dacb4
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录