Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
95c0ad0c
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,发现更多精彩内容 >>
提交
95c0ad0c
编写于
12月 13, 2017
作者:
E
Eduard-Mihai Burtescu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: unpack newtyped of #[repr(simd)] vector types.
上级
707d0708
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
98 addition
and
87 deletion
+98
-87
src/librustc/ty/layout.rs
src/librustc/ty/layout.rs
+28
-14
src/librustc_trans/abi.rs
src/librustc_trans/abi.rs
+2
-2
src/librustc_trans/cabi_x86_64.rs
src/librustc_trans/cabi_x86_64.rs
+4
-3
src/librustc_trans/cabi_x86_win64.rs
src/librustc_trans/cabi_x86_win64.rs
+1
-1
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/constant.rs
+17
-12
src/librustc_trans/mir/operand.rs
src/librustc_trans/mir/operand.rs
+2
-2
src/librustc_trans/type_of.rs
src/librustc_trans/type_of.rs
+44
-53
未找到文件。
src/librustc/ty/layout.rs
浏览文件 @
95c0ad0c
...
...
@@ -758,7 +758,10 @@ pub enum Abi {
Uninhabited
,
Scalar
(
Scalar
),
ScalarPair
(
Scalar
,
Scalar
),
Vector
,
Vector
{
element
:
Scalar
,
count
:
u64
},
Aggregate
{
/// If true, the size is exact, otherwise it's only a lower bound.
sized
:
bool
,
...
...
@@ -773,7 +776,7 @@ pub fn is_unsized(&self) -> bool {
Abi
::
Uninhabited
|
Abi
::
Scalar
(
_
)
|
Abi
::
ScalarPair
(
..
)
|
Abi
::
Vector
=>
false
,
Abi
::
Vector
{
..
}
=>
false
,
Abi
::
Aggregate
{
sized
,
..
}
=>
!
sized
}
}
...
...
@@ -784,7 +787,7 @@ pub fn is_packed(&self) -> bool {
Abi
::
Uninhabited
|
Abi
::
Scalar
(
_
)
|
Abi
::
ScalarPair
(
..
)
|
Abi
::
Vector
=>
false
,
Abi
::
Vector
{
..
}
=>
false
,
Abi
::
Aggregate
{
packed
,
..
}
=>
packed
}
}
...
...
@@ -1083,9 +1086,9 @@ enum StructKind {
align
.abi
()
==
field
.align
.abi
()
&&
size
==
field
.size
{
match
field
.abi
{
// For plain scalars
we can't unpack newtypes
// for `#[repr(C)]`, as that affects C ABIs.
Abi
::
Scalar
(
_
)
if
optimize
=>
{
// For plain scalars
, or vectors of them, we can't unpack
//
newtypes
for `#[repr(C)]`, as that affects C ABIs.
Abi
::
Scalar
(
_
)
|
Abi
::
Vector
{
..
}
if
optimize
=>
{
abi
=
field
.abi
.clone
();
}
// But scalar pairs are Rust-specific and get
...
...
@@ -1320,16 +1323,17 @@ enum StructKind {
// SIMD vector types.
ty
::
TyAdt
(
def
,
..
)
if
def
.repr
.simd
()
=>
{
let
count
=
ty
.simd_size
(
tcx
)
as
u64
;
let
element
=
cx
.layout_of
(
ty
.simd_type
(
tcx
))
?
;
match
element
.abi
{
Abi
::
Scalar
(
_
)
=>
{}
let
count
=
ty
.simd_size
(
tcx
)
as
u64
;
assert
!
(
count
>
0
);
let
scalar
=
match
element
.abi
{
Abi
::
Scalar
(
ref
scalar
)
=>
scalar
.clone
(),
_
=>
{
tcx
.sess
.fatal
(
&
format!
(
"monomorphising SIMD type `{}` with
\
a non-machine element type `{}`"
,
ty
,
element
.ty
));
}
}
}
;
let
size
=
element
.size
.checked_mul
(
count
,
dl
)
.ok_or
(
LayoutError
::
SizeOverflow
(
ty
))
?
;
let
align
=
dl
.vector_align
(
size
);
...
...
@@ -1341,7 +1345,10 @@ enum StructKind {
stride
:
element
.size
,
count
},
abi
:
Abi
::
Vector
,
abi
:
Abi
::
Vector
{
element
:
scalar
,
count
},
size
,
align
,
})
...
...
@@ -2266,8 +2273,9 @@ pub fn is_packed(&self) -> bool {
pub
fn
is_zst
(
&
self
)
->
bool
{
match
self
.abi
{
Abi
::
Uninhabited
=>
true
,
Abi
::
Scalar
(
_
)
|
Abi
::
ScalarPair
(
..
)
=>
false
,
Abi
::
Vector
=>
self
.size
.bytes
()
==
0
,
Abi
::
Scalar
(
_
)
|
Abi
::
ScalarPair
(
..
)
|
Abi
::
Vector
{
..
}
=>
false
,
Abi
::
Aggregate
{
sized
,
..
}
=>
sized
&&
self
.size
.bytes
()
==
0
}
}
...
...
@@ -2322,6 +2330,9 @@ fn find_niche<C>(&self, cx: C, count: u128)
scalar_component
(
b
,
a
.value
.size
(
cx
)
.abi_align
(
b
.value
.align
(
cx
)))
}));
}
Abi
::
Vector
{
ref
element
,
..
}
=>
{
return
Ok
(
scalar_component
(
element
,
Size
::
from_bytes
(
0
)));
}
_
=>
{}
}
...
...
@@ -2424,7 +2435,10 @@ fn hash_stable<W: StableHasherResult>(&self,
a
.hash_stable
(
hcx
,
hasher
);
b
.hash_stable
(
hcx
,
hasher
);
}
Vector
=>
{}
Vector
{
ref
element
,
count
}
=>
{
element
.hash_stable
(
hcx
,
hasher
);
count
.hash_stable
(
hcx
,
hasher
);
}
Aggregate
{
packed
,
sized
}
=>
{
packed
.hash_stable
(
hcx
,
hasher
);
sized
.hash_stable
(
hcx
,
hasher
);
...
...
src/librustc_trans/abi.rs
浏览文件 @
95c0ad0c
...
...
@@ -315,7 +315,7 @@ fn is_aggregate(&self) -> bool {
match
self
.abi
{
layout
::
Abi
::
Uninhabited
|
layout
::
Abi
::
Scalar
(
_
)
|
layout
::
Abi
::
Vector
=>
false
,
layout
::
Abi
::
Vector
{
..
}
=>
false
,
layout
::
Abi
::
ScalarPair
(
..
)
|
layout
::
Abi
::
Aggregate
{
..
}
=>
true
}
...
...
@@ -339,7 +339,7 @@ fn homogeneous_aggregate<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Option<Reg>
})
}
layout
::
Abi
::
Vector
=>
{
layout
::
Abi
::
Vector
{
..
}
=>
{
Some
(
Reg
{
kind
:
RegKind
::
Vector
,
size
:
self
.size
...
...
src/librustc_trans/cabi_x86_64.rs
浏览文件 @
95c0ad0c
...
...
@@ -77,13 +77,14 @@ fn classify<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
unify
(
cls
,
off
,
reg
);
}
layout
::
Abi
::
Vector
=>
{
layout
::
Abi
::
Vector
{
ref
element
,
count
}
=>
{
unify
(
cls
,
off
,
Class
::
Sse
);
// everything after the first one is the upper
// half of a register.
for
i
in
1
..
layout
.fields
.count
()
{
let
field_off
=
off
+
layout
.fields
.offset
(
i
);
let
stride
=
element
.value
.size
(
ccx
);
for
i
in
1
..
count
{
let
field_off
=
off
+
stride
*
i
;
unify
(
cls
,
field_off
,
Class
::
SseUp
);
}
}
...
...
src/librustc_trans/cabi_x86_win64.rs
浏览文件 @
95c0ad0c
...
...
@@ -28,7 +28,7 @@ pub fn compute_abi_info(fty: &mut FnType) {
_
=>
a
.make_indirect
()
}
}
layout
::
Abi
::
Vector
=>
{
layout
::
Abi
::
Vector
{
..
}
=>
{
// FIXME(eddyb) there should be a size cap here
// (probably what clang calls "illegal vectors").
}
...
...
src/librustc_trans/mir/constant.rs
浏览文件 @
95c0ad0c
...
...
@@ -122,17 +122,17 @@ fn get_field(&self, ccx: &CrateContext<'a, 'tcx>, i: usize) -> ValueRef {
if
field
.is_zst
()
{
return
C_undef
(
field
.immediate_llvm_type
(
ccx
));
}
let
offset
=
layout
.fields
.offset
(
i
);
match
layout
.abi
{
layout
::
Abi
::
Scalar
(
_
)
=>
self
.llval
,
layout
::
Abi
::
Scalar
(
_
)
|
layout
::
Abi
::
ScalarPair
(
..
)
|
layout
::
Abi
::
Vector
{
..
}
if
offset
.bytes
()
==
0
&&
field
.size
==
layout
.size
=>
self
.llval
,
layout
::
Abi
::
ScalarPair
(
ref
a
,
ref
b
)
=>
{
let
offset
=
layout
.fields
.offset
(
i
);
if
offset
.bytes
()
==
0
{
if
field
.size
==
layout
.size
{
self
.llval
}
else
{
assert_eq!
(
field
.size
,
a
.value
.size
(
ccx
));
const_get_elt
(
self
.llval
,
0
)
}
assert_eq!
(
field
.size
,
a
.value
.size
(
ccx
));
const_get_elt
(
self
.llval
,
0
)
}
else
{
assert_eq!
(
offset
,
a
.value
.size
(
ccx
)
.abi_align
(
b
.value
.align
(
ccx
)));
...
...
@@ -1131,9 +1131,7 @@ fn trans_const_adt<'a, 'tcx>(
match
l
.variants
{
layout
::
Variants
::
Single
{
index
}
=>
{
assert_eq!
(
variant_index
,
index
);
if
let
layout
::
Abi
::
Vector
=
l
.abi
{
Const
::
new
(
C_vector
(
&
vals
.iter
()
.map
(|
x
|
x
.llval
)
.collect
::
<
Vec
<
_
>>
()),
t
)
}
else
if
let
layout
::
FieldPlacement
::
Union
(
_
)
=
l
.fields
{
if
let
layout
::
FieldPlacement
::
Union
(
_
)
=
l
.fields
{
assert_eq!
(
variant_index
,
0
);
assert_eq!
(
vals
.len
(),
1
);
let
contents
=
[
...
...
@@ -1143,6 +1141,12 @@ fn trans_const_adt<'a, 'tcx>(
Const
::
new
(
C_struct
(
ccx
,
&
contents
,
l
.is_packed
()),
t
)
}
else
{
if
let
layout
::
Abi
::
Vector
{
..
}
=
l
.abi
{
if
let
layout
::
FieldPlacement
::
Array
{
..
}
=
l
.fields
{
return
Const
::
new
(
C_vector
(
&
vals
.iter
()
.map
(|
x
|
x
.llval
)
.collect
::
<
Vec
<
_
>>
()),
t
);
}
}
build_const_struct
(
ccx
,
l
,
vals
,
None
)
}
}
...
...
@@ -1206,7 +1210,8 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
match
layout
.abi
{
layout
::
Abi
::
Scalar
(
_
)
|
layout
::
Abi
::
ScalarPair
(
..
)
if
discr
.is_none
()
=>
{
layout
::
Abi
::
ScalarPair
(
..
)
|
layout
::
Abi
::
Vector
{
..
}
if
discr
.is_none
()
=>
{
let
mut
non_zst_fields
=
vals
.iter
()
.enumerate
()
.map
(|(
i
,
f
)|
{
(
f
,
layout
.fields
.offset
(
i
))
})
.filter
(|
&
(
f
,
_
)|
!
ccx
.layout_of
(
f
.ty
)
.is_zst
());
...
...
src/librustc_trans/mir/operand.rs
浏览文件 @
95c0ad0c
...
...
@@ -163,7 +163,7 @@ pub fn extract_field(&self, bcx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tc
};
}
// Newtype of a scalar
or scalar pai
r.
// Newtype of a scalar
, scalar pair or vecto
r.
(
OperandValue
::
Immediate
(
_
),
_
)
|
(
OperandValue
::
Pair
(
..
),
_
)
if
field
.size
==
self
.layout.size
=>
{
assert_eq!
(
offset
.bytes
(),
0
);
...
...
@@ -184,7 +184,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
(
llval
),
&
layout
::
Abi
::
Vector
{
..
}
)
=>
{
OperandValue
::
Immediate
(
bcx
.extract_element
(
llval
,
C_usize
(
bcx
.ccx
,
i
as
u64
)))
}
...
...
src/librustc_trans/type_of.rs
浏览文件 @
95c0ad0c
...
...
@@ -25,7 +25,7 @@ fn uncached_llvm_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
->
Type
{
match
layout
.abi
{
layout
::
Abi
::
Scalar
(
_
)
=>
bug!
(
"handled elsewhere"
),
layout
::
Abi
::
Vector
=>
{
layout
::
Abi
::
Vector
{
ref
element
,
count
}
=>
{
// LLVM has a separate type for 64-bit SIMD vectors on X86 called
// `x86_mmx` which is needed for some SIMD operations. As a bit of a
// hack (all SIMD definitions are super unstable anyway) we
...
...
@@ -33,15 +33,14 @@ fn uncached_llvm_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// x86_mmx" type. In general there shouldn't be a need for other
// one-element SIMD vectors, so it's assumed this won't clash with
// much else.
let
use_x86_mmx
=
layout
.fields
.count
()
==
1
&&
layout
.size
.bits
()
==
64
&&
let
use_x86_mmx
=
count
==
1
&&
layout
.size
.bits
()
==
64
&&
(
ccx
.sess
()
.target.target.arch
==
"x86"
||
ccx
.sess
()
.target.target.arch
==
"x86_64"
);
if
use_x86_mmx
{
return
Type
::
x86_mmx
(
ccx
)
}
else
{
return
Type
::
vector
(
&
layout
.field
(
ccx
,
0
)
.llvm_type
(
ccx
),
layout
.fields
.count
()
as
u64
);
let
element
=
layout
.scalar_llvm_type_at
(
ccx
,
element
,
Size
::
from_bytes
(
0
));
return
Type
::
vector
(
&
element
,
count
);
}
}
layout
::
Abi
::
ScalarPair
(
..
)
=>
{
...
...
@@ -198,6 +197,8 @@ pub trait LayoutLlvmExt<'tcx> {
fn
is_llvm_scalar_pair
<
'a
>
(
&
self
)
->
bool
;
fn
llvm_type
<
'a
>
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
)
->
Type
;
fn
immediate_llvm_type
<
'a
>
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
)
->
Type
;
fn
scalar_llvm_type_at
<
'a
>
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
scalar
:
&
layout
::
Scalar
,
offset
:
Size
)
->
Type
;
fn
scalar_pair_element_llvm_type
<
'a
>
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
index
:
usize
)
->
Type
;
fn
llvm_field_index
(
&
self
,
index
:
usize
)
->
u64
;
...
...
@@ -210,7 +211,7 @@ fn is_llvm_immediate(&self) -> bool {
match
self
.abi
{
layout
::
Abi
::
Uninhabited
|
layout
::
Abi
::
Scalar
(
_
)
|
layout
::
Abi
::
Vector
=>
true
,
layout
::
Abi
::
Vector
{
..
}
=>
true
,
layout
::
Abi
::
ScalarPair
(
..
)
=>
false
,
layout
::
Abi
::
Aggregate
{
..
}
=>
self
.is_zst
()
}
...
...
@@ -221,7 +222,7 @@ fn is_llvm_scalar_pair<'a>(&self) -> bool {
layout
::
Abi
::
ScalarPair
(
..
)
=>
true
,
layout
::
Abi
::
Uninhabited
|
layout
::
Abi
::
Scalar
(
_
)
|
layout
::
Abi
::
Vector
|
layout
::
Abi
::
Vector
{
..
}
|
layout
::
Abi
::
Aggregate
{
..
}
=>
false
}
}
...
...
@@ -244,34 +245,19 @@ fn llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
if
let
Some
(
&
llty
)
=
ccx
.scalar_lltypes
()
.borrow
()
.get
(
&
self
.ty
)
{
return
llty
;
}
let
llty
=
match
scalar
.value
{
layout
::
Int
(
i
,
_
)
=>
Type
::
from_integer
(
ccx
,
i
),
layout
::
F32
=>
Type
::
f32
(
ccx
),
layout
::
F64
=>
Type
::
f64
(
ccx
),
layout
::
Pointer
=>
{
let
pointee
=
match
self
.ty.sty
{
ty
::
TyRef
(
_
,
ty
::
TypeAndMut
{
ty
,
..
})
|
ty
::
TyRawPtr
(
ty
::
TypeAndMut
{
ty
,
..
})
=>
{
ccx
.layout_of
(
ty
)
.llvm_type
(
ccx
)
}
ty
::
TyAdt
(
def
,
_
)
if
def
.is_box
()
=>
{
ccx
.layout_of
(
self
.ty
.boxed_ty
())
.llvm_type
(
ccx
)
}
ty
::
TyFnPtr
(
sig
)
=>
{
let
sig
=
ccx
.tcx
()
.erase_late_bound_regions_and_normalize
(
&
sig
);
FnType
::
new
(
ccx
,
sig
,
&
[])
.llvm_type
(
ccx
)
}
_
=>
{
// If we know the alignment, pick something better than i8.
if
let
Some
(
pointee
)
=
self
.pointee_info_at
(
ccx
,
Size
::
from_bytes
(
0
))
{
Type
::
pointee_for_abi_align
(
ccx
,
pointee
.align
)
}
else
{
Type
::
i8
(
ccx
)
}
}
};
pointee
.ptr_to
()
let
llty
=
match
self
.ty.sty
{
ty
::
TyRef
(
_
,
ty
::
TypeAndMut
{
ty
,
..
})
|
ty
::
TyRawPtr
(
ty
::
TypeAndMut
{
ty
,
..
})
=>
{
ccx
.layout_of
(
ty
)
.llvm_type
(
ccx
)
.ptr_to
()
}
ty
::
TyAdt
(
def
,
_
)
if
def
.is_box
()
=>
{
ccx
.layout_of
(
self
.ty
.boxed_ty
())
.llvm_type
(
ccx
)
.ptr_to
()
}
ty
::
TyFnPtr
(
sig
)
=>
{
let
sig
=
ccx
.tcx
()
.erase_late_bound_regions_and_normalize
(
&
sig
);
FnType
::
new
(
ccx
,
sig
,
&
[])
.llvm_type
(
ccx
)
.ptr_to
()
}
_
=>
self
.scalar_llvm_type_at
(
ccx
,
scalar
,
Size
::
from_bytes
(
0
))
};
ccx
.scalar_lltypes
()
.borrow_mut
()
.insert
(
self
.ty
,
llty
);
return
llty
;
...
...
@@ -325,6 +311,24 @@ fn immediate_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> Type {
self
.llvm_type
(
ccx
)
}
fn
scalar_llvm_type_at
<
'a
>
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
scalar
:
&
layout
::
Scalar
,
offset
:
Size
)
->
Type
{
match
scalar
.value
{
layout
::
Int
(
i
,
_
)
=>
Type
::
from_integer
(
ccx
,
i
),
layout
::
F32
=>
Type
::
f32
(
ccx
),
layout
::
F64
=>
Type
::
f64
(
ccx
),
layout
::
Pointer
=>
{
// If we know the alignment, pick something better than i8.
let
pointee
=
if
let
Some
(
pointee
)
=
self
.pointee_info_at
(
ccx
,
offset
)
{
Type
::
pointee_for_abi_align
(
ccx
,
pointee
.align
)
}
else
{
Type
::
i8
(
ccx
)
};
pointee
.ptr_to
()
}
}
}
fn
scalar_pair_element_llvm_type
<
'a
>
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
index
:
usize
)
->
Type
{
// HACK(eddyb) special-case fat pointers until LLVM removes
...
...
@@ -358,25 +362,12 @@ fn scalar_pair_element_llvm_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>,
return
Type
::
i1
(
ccx
);
}
match
scalar
.value
{
layout
::
Int
(
i
,
_
)
=>
Type
::
from_integer
(
ccx
,
i
),
layout
::
F32
=>
Type
::
f32
(
ccx
),
layout
::
F64
=>
Type
::
f64
(
ccx
),
layout
::
Pointer
=>
{
// If we know the alignment, pick something better than i8.
let
offset
=
if
index
==
0
{
Size
::
from_bytes
(
0
)
}
else
{
a
.value
.size
(
ccx
)
.abi_align
(
b
.value
.align
(
ccx
))
};
let
pointee
=
if
let
Some
(
pointee
)
=
self
.pointee_info_at
(
ccx
,
offset
)
{
Type
::
pointee_for_abi_align
(
ccx
,
pointee
.align
)
}
else
{
Type
::
i8
(
ccx
)
};
pointee
.ptr_to
()
}
}
let
offset
=
if
index
==
0
{
Size
::
from_bytes
(
0
)
}
else
{
a
.value
.size
(
ccx
)
.abi_align
(
b
.value
.align
(
ccx
))
};
self
.scalar_llvm_type_at
(
ccx
,
scalar
,
offset
)
}
fn
llvm_field_index
(
&
self
,
index
:
usize
)
->
u64
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录