Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
d77e34f3
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,发现更多精彩内容 >>
提交
d77e34f3
编写于
9月 07, 2018
作者:
D
Denis Merigoux
提交者:
Eduard-Mihai Burtescu
11月 16, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Generalized memset and memcpy
上级
0514c7b1
变更
23
显示空白变更内容
内联
并排
Showing
23 changed file
with
444 addition
and
368 deletion
+444
-368
src/librustc_codegen_llvm/abi.rs
src/librustc_codegen_llvm/abi.rs
+1
-1
src/librustc_codegen_llvm/asm.rs
src/librustc_codegen_llvm/asm.rs
+1
-1
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/base.rs
+21
-19
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/builder.rs
+4
-1
src/librustc_codegen_llvm/callee.rs
src/librustc_codegen_llvm/callee.rs
+1
-1
src/librustc_codegen_llvm/common.rs
src/librustc_codegen_llvm/common.rs
+1
-1
src/librustc_codegen_llvm/consts.rs
src/librustc_codegen_llvm/consts.rs
+1
-1
src/librustc_codegen_llvm/context.rs
src/librustc_codegen_llvm/context.rs
+322
-316
src/librustc_codegen_llvm/debuginfo/gdb.rs
src/librustc_codegen_llvm/debuginfo/gdb.rs
+1
-1
src/librustc_codegen_llvm/interfaces/builder.rs
src/librustc_codegen_llvm/interfaces/builder.rs
+2
-1
src/librustc_codegen_llvm/interfaces/intrinsic.rs
src/librustc_codegen_llvm/interfaces/intrinsic.rs
+25
-0
src/librustc_codegen_llvm/interfaces/mod.rs
src/librustc_codegen_llvm/interfaces/mod.rs
+3
-1
src/librustc_codegen_llvm/interfaces/type_.rs
src/librustc_codegen_llvm/interfaces/type_.rs
+31
-1
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/intrinsic.rs
+3
-1
src/librustc_codegen_llvm/meth.rs
src/librustc_codegen_llvm/meth.rs
+1
-1
src/librustc_codegen_llvm/mir/block.rs
src/librustc_codegen_llvm/mir/block.rs
+3
-1
src/librustc_codegen_llvm/mir/constant.rs
src/librustc_codegen_llvm/mir/constant.rs
+1
-1
src/librustc_codegen_llvm/mir/mod.rs
src/librustc_codegen_llvm/mir/mod.rs
+1
-1
src/librustc_codegen_llvm/mir/operand.rs
src/librustc_codegen_llvm/mir/operand.rs
+1
-1
src/librustc_codegen_llvm/mir/place.rs
src/librustc_codegen_llvm/mir/place.rs
+3
-1
src/librustc_codegen_llvm/mir/rvalue.rs
src/librustc_codegen_llvm/mir/rvalue.rs
+1
-1
src/librustc_codegen_llvm/type_.rs
src/librustc_codegen_llvm/type_.rs
+15
-14
src/librustc_codegen_llvm/type_of.rs
src/librustc_codegen_llvm/type_of.rs
+1
-1
未找到文件。
src/librustc_codegen_llvm/abi.rs
浏览文件 @
d77e34f3
...
...
@@ -18,7 +18,7 @@
use
type_of
::{
LayoutLlvmExt
,
PointerKind
};
use
value
::
Value
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
Derived
TypeMethods
};
use
rustc_target
::
abi
::{
HasDataLayout
,
LayoutOf
,
Size
,
TyLayout
,
Abi
as
LayoutAbi
};
use
rustc
::
ty
::{
self
,
Ty
};
...
...
src/librustc_codegen_llvm/asm.rs
浏览文件 @
d77e34f3
...
...
@@ -15,7 +15,7 @@
use
value
::
Value
;
use
rustc
::
hir
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
Base
TypeMethods
};
use
mir
::
place
::
PlaceRef
;
use
mir
::
operand
::
OperandValue
;
...
...
src/librustc_codegen_llvm/base.rs
浏览文件 @
d77e34f3
...
...
@@ -73,7 +73,9 @@
use
rustc_data_structures
::
sync
::
Lrc
;
use
rustc_data_structures
::
indexed_vec
::
Idx
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
DerivedTypeMethods
,
DerivedIntrinsicMethods
,
};
use
std
::
any
::
Any
;
use
std
::
cmp
;
...
...
@@ -431,13 +433,13 @@ pub fn to_immediate_scalar<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
val
}
pub
fn
call_memcpy
(
bx
:
&
Builder
<
'_
,
'll
,
'_
>
,
dst
:
&
'll
Value
,
pub
fn
call_memcpy
<
'a
,
'tcx
:
'a
,
Builder
:
BuilderMethods
<
'a
,
'tcx
>>
(
bx
:
&
Builder
,
dst
:
Builder
::
Value
,
dst_align
:
Align
,
src
:
&
'll
Value
,
src
:
Builder
::
Value
,
src_align
:
Align
,
n_bytes
:
&
'll
Value
,
n_bytes
:
Builder
::
Value
,
flags
:
MemFlags
,
)
{
if
flags
.contains
(
MemFlags
::
NONTEMPORAL
)
{
...
...
@@ -450,16 +452,16 @@ pub fn call_memcpy(
let
cx
=
bx
.cx
();
let
src_ptr
=
bx
.pointercast
(
src
,
cx
.type_i8p
());
let
dst_ptr
=
bx
.pointercast
(
dst
,
cx
.type_i8p
());
let
size
=
bx
.intcast
(
n_bytes
,
cx
.
isize_ty
,
false
);
let
size
=
bx
.intcast
(
n_bytes
,
cx
.
type_isize
()
,
false
);
let
volatile
=
flags
.contains
(
MemFlags
::
VOLATILE
);
bx
.memcpy
(
dst_ptr
,
dst_align
.abi
(),
src_ptr
,
src_align
.abi
(),
size
,
volatile
);
}
pub
fn
memcpy_ty
(
bx
:
&
Builder
<
'_
,
'll
,
'_
>
,
dst
:
&
'll
Value
,
pub
fn
memcpy_ty
<
'a
,
'tcx
:
'a
,
Builder
:
BuilderMethods
<
'a
,
'tcx
>>
(
bx
:
&
Builder
,
dst
:
Builder
::
Value
,
dst_align
:
Align
,
src
:
&
'll
Value
,
src
:
Builder
::
Value
,
src_align
:
Align
,
layout
:
TyLayout
<
'tcx
>
,
flags
:
MemFlags
,
...
...
@@ -472,15 +474,15 @@ pub fn memcpy_ty(
call_memcpy
(
bx
,
dst
,
dst_align
,
src
,
src_align
,
bx
.cx
()
.const_usize
(
size
),
flags
);
}
pub
fn
call_memset
(
bx
:
&
Builder
<
'_
,
'll
,
'_
>
,
ptr
:
&
'll
Value
,
fill_byte
:
&
'll
Value
,
size
:
&
'll
Value
,
align
:
&
'll
Value
,
pub
fn
call_memset
<
'a
,
'tcx
:
'a
,
Builder
:
BuilderMethods
<
'a
,
'tcx
>>
(
bx
:
&
Builder
,
ptr
:
Builder
::
Value
,
fill_byte
:
Builder
::
Value
,
size
:
Builder
::
Value
,
align
:
Builder
::
Value
,
volatile
:
bool
,
)
->
&
'll
Value
{
let
ptr_width
=
&
bx
.
cx
()
.
sess
()
.target.target.target_pointer_width
;
)
->
Builder
::
Value
{
let
ptr_width
=
&
bx
.sess
()
.target.target.target_pointer_width
;
let
intrinsic_key
=
format!
(
"llvm.memset.p0i8.i{}"
,
ptr_width
);
let
llintrinsicfn
=
bx
.cx
()
.get_intrinsic
(
&
intrinsic_key
);
let
volatile
=
bx
.cx
()
.const_bool
(
volatile
);
...
...
src/librustc_codegen_llvm/builder.rs
浏览文件 @
d77e34f3
...
...
@@ -19,7 +19,10 @@
use
rustc
::
ty
::
layout
::{
Align
,
Size
};
use
rustc
::
session
::{
config
,
Session
};
use
rustc_data_structures
::
small_c_str
::
SmallCStr
;
use
interfaces
::{
BuilderMethods
,
Backend
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
Backend
,
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
DerivedTypeMethods
,
DerivedIntrinsicMethods
,
};
use
syntax
;
use
std
::
borrow
::
Cow
;
...
...
src/librustc_codegen_llvm/callee.rs
浏览文件 @
d77e34f3
...
...
@@ -22,7 +22,7 @@
use
monomorphize
::
Instance
;
use
type_of
::
LayoutLlvmExt
;
use
value
::
Value
;
use
interfaces
::
TypeMethods
;
use
interfaces
::
Base
TypeMethods
;
use
rustc
::
hir
::
def_id
::
DefId
;
use
rustc
::
ty
::{
self
,
TypeFoldable
};
...
...
src/librustc_codegen_llvm/common.rs
浏览文件 @
d77e34f3
...
...
@@ -23,7 +23,7 @@
use
type_
::
Type
;
use
type_of
::
LayoutLlvmExt
;
use
value
::
Value
;
use
interfaces
::{
Backend
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
Backend
,
ConstMethods
,
Base
TypeMethods
};
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
rustc
::
ty
::
layout
::{
HasDataLayout
,
LayoutOf
};
...
...
src/librustc_codegen_llvm/consts.rs
浏览文件 @
d77e34f3
...
...
@@ -24,7 +24,7 @@
use
type_of
::
LayoutLlvmExt
;
use
value
::
Value
;
use
rustc
::
ty
::{
self
,
Ty
};
use
interfaces
::
TypeMethods
;
use
interfaces
::
{
BaseTypeMethods
,
DerivedTypeMethods
}
;
use
rustc
::
ty
::
layout
::{
Align
,
LayoutOf
};
...
...
src/librustc_codegen_llvm/context.rs
浏览文件 @
d77e34f3
...
...
@@ -23,7 +23,8 @@
use
monomorphize
::
partitioning
::
CodegenUnit
;
use
type_
::
Type
;
use
type_of
::
PointeeInfo
;
use
interfaces
::
TypeMethods
;
use
interfaces
::{
BaseTypeMethods
,
DerivedTypeMethods
,
IntrinsicMethods
,
BaseIntrinsicMethods
,
DerivedIntrinsicMethods
};
use
rustc_data_structures
::
base_n
;
use
rustc_data_structures
::
small_c_str
::
SmallCStr
;
...
...
@@ -320,220 +321,73 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
pub
fn
sess
<
'a
>
(
&
'a
self
)
->
&
'a
Session
{
&
self
.tcx.sess
}
pub
fn
get_intrinsic
(
&
self
,
key
:
&
str
)
->
&
'b
Value
{
if
let
Some
(
v
)
=
self
.intrinsics
.borrow
()
.get
(
key
)
.cloned
()
{
return
v
;
}
declare_intrinsic
(
self
,
key
)
.unwrap_or_else
(||
bug!
(
"unknown intrinsic '{}'"
,
key
))
}
}
impl
<
'b
,
'tcx
>
CodegenCx
<
'b
,
'tcx
>
{
/// Generate a new symbol name with the given prefix. This symbol name must
/// only be used for definitions with `internal` or `private` linkage.
pub
fn
generate_local_symbol_name
(
&
self
,
prefix
:
&
str
)
->
String
{
let
idx
=
self
.local_gen_sym_counter
.get
();
self
.local_gen_sym_counter
.set
(
idx
+
1
);
// Include a '.' character, so there can be no accidental conflicts with
// user defined names
let
mut
name
=
String
::
with_capacity
(
prefix
.len
()
+
6
);
name
.push_str
(
prefix
);
name
.push_str
(
"."
);
base_n
::
push_str
(
idx
as
u128
,
base_n
::
ALPHANUMERIC_ONLY
,
&
mut
name
);
name
}
impl
BaseIntrinsicMethods
for
CodegenCx
<
'_
,
'_
>
{}
pub
fn
eh_personality
(
&
self
)
->
&
'b
Value
{
// The exception handling personality function.
//
// If our compilation unit has the `eh_personality` lang item somewhere
// within it, then we just need to codegen that. Otherwise, we're
// building an rlib which will depend on some upstream implementation of
// this function, so we just codegen a generic reference to it. We don't
// specify any of the types for the function, we just make it a symbol
// that LLVM can later use.
//
// Note that MSVC is a little special here in that we don't use the
// `eh_personality` lang item at all. Currently LLVM has support for
// both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
// *name of the personality function* to decide what kind of unwind side
// tables/landing pads to emit. It looks like Dwarf is used by default,
// injecting a dependency on the `_Unwind_Resume` symbol for resuming
// an "exception", but for MSVC we want to force SEH. This means that we
// can't actually have the personality function be our standard
// `rust_eh_personality` function, but rather we wired it up to the
// CRT's custom personality function, which forces LLVM to consider
// landing pads as "landing pads for SEH".
if
let
Some
(
llpersonality
)
=
self
.eh_personality
.get
()
{
return
llpersonality
}
let
tcx
=
self
.tcx
;
let
llfn
=
match
tcx
.lang_items
()
.eh_personality
()
{
Some
(
def_id
)
if
!
base
::
wants_msvc_seh
(
self
.sess
())
=>
{
callee
::
resolve_and_get_fn
(
self
,
def_id
,
tcx
.intern_substs
(
&
[]))
}
_
=>
{
let
name
=
if
base
::
wants_msvc_seh
(
self
.sess
())
{
"__CxxFrameHandler3"
}
else
{
"rust_eh_personality"
};
let
fty
=
&
self
.type_variadic_func
(
&
[],
&
self
.type_i32
());
declare
::
declare_cfn
(
self
,
name
,
fty
)
}
};
attributes
::
apply_target_cpu_attr
(
self
,
llfn
);
self
.eh_personality
.set
(
Some
(
llfn
));
llfn
}
// Returns a Value of the "eh_unwind_resume" lang item if one is defined,
// otherwise declares it as an external function.
pub
fn
eh_unwind_resume
(
&
self
)
->
&
'b
Value
{
use
attributes
;
let
unwresume
=
&
self
.eh_unwind_resume
;
if
let
Some
(
llfn
)
=
unwresume
.get
()
{
return
llfn
;
}
let
tcx
=
self
.tcx
;
assert
!
(
self
.sess
()
.target.target.options.custom_unwind_resume
);
if
let
Some
(
def_id
)
=
tcx
.lang_items
()
.eh_unwind_resume
()
{
let
llfn
=
callee
::
resolve_and_get_fn
(
self
,
def_id
,
tcx
.intern_substs
(
&
[]));
unwresume
.set
(
Some
(
llfn
));
return
llfn
;
}
let
sig
=
ty
::
Binder
::
bind
(
tcx
.mk_fn_sig
(
iter
::
once
(
tcx
.mk_mut_ptr
(
tcx
.types.u8
)),
tcx
.types.never
,
false
,
hir
::
Unsafety
::
Unsafe
,
Abi
::
C
));
let
llfn
=
declare
::
declare_fn
(
self
,
"rust_eh_unwind_resume"
,
sig
);
attributes
::
unwind
(
llfn
,
true
);
attributes
::
apply_target_cpu_attr
(
self
,
llfn
);
unwresume
.set
(
Some
(
llfn
));
llfn
}
pub
fn
type_needs_drop
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
common
::
type_needs_drop
(
self
.tcx
,
ty
)
}
pub
fn
type_is_sized
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
common
::
type_is_sized
(
self
.tcx
,
ty
)
}
pub
fn
type_is_freeze
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
common
::
type_is_freeze
(
self
.tcx
,
ty
)
}
pub
fn
type_has_metadata
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
use
syntax_pos
::
DUMMY_SP
;
if
ty
.is_sized
(
self
.tcx
.at
(
DUMMY_SP
),
ty
::
ParamEnv
::
reveal_all
())
{
return
false
;
}
let
tail
=
self
.tcx
.struct_tail
(
ty
);
match
tail
.sty
{
ty
::
Foreign
(
..
)
=>
false
,
ty
::
Str
|
ty
::
Slice
(
..
)
|
ty
::
Dynamic
(
..
)
=>
true
,
_
=>
bug!
(
"unexpected unsized tail: {:?}"
,
tail
.sty
),
}
}
}
impl
ty
::
layout
::
HasDataLayout
for
CodegenCx
<
'll
,
'tcx
>
{
fn
data_layout
(
&
self
)
->
&
ty
::
layout
::
TargetDataLayout
{
&
self
.tcx.data_layout
}
}
impl
HasTargetSpec
for
CodegenCx
<
'll
,
'tcx
>
{
fn
target_spec
(
&
self
)
->
&
Target
{
&
self
.tcx.sess.target.target
}
}
impl
ty
::
layout
::
HasTyCtxt
<
'tcx
>
for
CodegenCx
<
'll
,
'tcx
>
{
fn
tcx
<
'a
>
(
&
'a
self
)
->
TyCtxt
<
'a
,
'tcx
,
'tcx
>
{
self
.tcx
impl
DerivedIntrinsicMethods
for
CodegenCx
<
'b
,
'tcx
>
{
fn
get_intrinsic
(
&
self
,
key
:
&
str
)
->
&
'b
Value
{
if
let
Some
(
v
)
=
self
.intrinsics
.borrow
()
.get
(
key
)
.cloned
()
{
return
v
;
}
}
impl
LayoutOf
for
CodegenCx
<
'll
,
'tcx
>
{
type
Ty
=
Ty
<
'tcx
>
;
type
TyLayout
=
TyLayout
<
'tcx
>
;
fn
layout_of
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
Self
::
TyLayout
{
self
.tcx
.layout_of
(
ty
::
ParamEnv
::
reveal_all
()
.and
(
ty
))
.unwrap_or_else
(|
e
|
if
let
LayoutError
::
SizeOverflow
(
_
)
=
e
{
self
.sess
()
.fatal
(
&
e
.to_string
())
}
else
{
bug!
(
"failed to get layout for `{}`: {}"
,
ty
,
e
)
})
self
.declare_intrinsic
(
key
)
.unwrap_or_else
(||
bug!
(
"unknown intrinsic '{}'"
,
key
))
}
}
/// Declare any llvm intrinsics that you might need
fn
declare_intrinsic
(
cx
:
&
CodegenCx
<
'll
,
'_
>
,
/// Declare any llvm intrinsics that you might need
fn
declare_intrinsic
(
&
self
,
key
:
&
str
)
->
Option
<&
'll
Value
>
{
)
->
Option
<&
'b
Value
>
{
macro_rules!
ifn
{
(
$name:expr
,
fn
()
->
$ret:expr
)
=>
(
if
key
==
$name
{
let
f
=
declare
::
declare_cfn
(
cx
,
$name
,
cx
.type_func
(
&
[],
$ret
));
let
f
=
declare
::
declare_cfn
(
&
self
,
$name
,
&
self
.type_func
(
&
[],
$ret
));
llvm
::
SetUnnamedAddr
(
f
,
false
);
cx
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
&
self
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
return
Some
(
f
);
}
);
(
$name:expr
,
fn
(
...
)
->
$ret:expr
)
=>
(
if
key
==
$name
{
let
f
=
declare
::
declare_cfn
(
cx
,
$name
,
cx
.type_variadic_func
(
&
[],
$ret
));
let
f
=
declare
::
declare_cfn
(
&
self
,
$name
,
&
self
.type_variadic_func
(
&
[],
$ret
));
llvm
::
SetUnnamedAddr
(
f
,
false
);
cx
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
&
self
.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
(
cx
,
$name
,
cx
.type_func
(
&
[
$
(
$arg
),
*
],
$ret
));
let
f
=
declare
::
declare_cfn
(
&
self
,
$name
,
&
self
.type_func
(
&
[
$
(
$arg
),
*
],
$ret
));
llvm
::
SetUnnamedAddr
(
f
,
false
);
cx
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
&
self
.intrinsics
.borrow_mut
()
.insert
(
$name
,
f
.clone
());
return
Some
(
f
);
}
);
}
macro_rules!
mk_struct
{
(
$
(
$field_ty:expr
),
*
)
=>
(
cx
.type_struct
(
&
[
$
(
$field_ty
),
*
],
false
))
(
$
(
$field_ty:expr
),
*
)
=>
(
&
self
.type_struct
(
&
[
$
(
$field_ty
),
*
],
false
))
}
let
i8p
=
cx
.type_i8p
();
let
void
=
cx
.type_void
();
let
i1
=
cx
.type_i1
();
let
t_i8
=
cx
.type_i8
();
let
t_i16
=
cx
.type_i16
();
let
t_i32
=
cx
.type_i32
();
let
t_i64
=
cx
.type_i64
();
let
t_i128
=
cx
.type_i128
();
let
t_f32
=
cx
.type_f32
();
let
t_f64
=
cx
.type_f64
();
let
i8p
=
&
self
.type_i8p
();
let
void
=
&
self
.type_void
();
let
i1
=
&
self
.type_i1
();
let
t_i8
=
&
self
.type_i8
();
let
t_i16
=
&
self
.type_i16
();
let
t_i32
=
&
self
.type_i32
();
let
t_i64
=
&
self
.type_i64
();
let
t_i128
=
&
self
.type_i128
();
let
t_f32
=
&
self
.type_f32
();
let
t_f64
=
&
self
.type_f64
();
let
t_v2f32
=
cx
.type_vector
(
t_f32
,
2
);
let
t_v4f32
=
cx
.type_vector
(
t_f32
,
4
);
let
t_v8f32
=
cx
.type_vector
(
t_f32
,
8
);
let
t_v16f32
=
cx
.type_vector
(
t_f32
,
16
);
let
t_v2f32
=
&
self
.type_vector
(
t_f32
,
2
);
let
t_v4f32
=
&
self
.type_vector
(
t_f32
,
4
);
let
t_v8f32
=
&
self
.type_vector
(
t_f32
,
8
);
let
t_v16f32
=
&
self
.type_vector
(
t_f32
,
16
);
let
t_v2f64
=
cx
.type_vector
(
t_f64
,
2
);
let
t_v4f64
=
cx
.type_vector
(
t_f64
,
4
);
let
t_v8f64
=
cx
.type_vector
(
t_f64
,
8
);
let
t_v2f64
=
&
self
.type_vector
(
t_f64
,
2
);
let
t_v4f64
=
&
self
.type_vector
(
t_f64
,
4
);
let
t_v8f64
=
&
self
.type_vector
(
t_f64
,
8
);
ifn!
(
"llvm.memset.p0i8.i16"
,
fn
(
i8p
,
t_i8
,
t_i16
,
t_i32
,
i1
)
->
void
);
ifn!
(
"llvm.memset.p0i8.i32"
,
fn
(
i8p
,
t_i8
,
t_i32
,
t_i32
,
i1
)
->
void
);
...
...
@@ -785,10 +639,162 @@ fn declare_intrinsic(
ifn!
(
"llvm.assume"
,
fn
(
i1
)
->
void
);
ifn!
(
"llvm.prefetch"
,
fn
(
i8p
,
t_i32
,
t_i32
,
t_i32
)
->
void
);
if
cx
.sess
()
.opts.debuginfo
!=
DebugInfo
::
None
{
ifn!
(
"llvm.dbg.declare"
,
fn
(
cx
.type_metadata
(),
cx
.type_metadata
())
->
void
);
ifn!
(
"llvm.dbg.value"
,
fn
(
cx
.type_metadata
(),
t_i64
,
cx
.type_metadata
())
->
void
);
if
self
.sess
()
.opts.debuginfo
!=
DebugInfo
::
None
{
ifn!
(
"llvm.dbg.declare"
,
fn
(
&
self
.type_metadata
(),
&
self
.type_metadata
())
->
void
);
ifn!
(
"llvm.dbg.value"
,
fn
(
&
self
.type_metadata
(),
t_i64
,
&
self
.type_metadata
())
->
void
);
}
return
None
;
}
}
None
impl
IntrinsicMethods
for
CodegenCx
<
'a
,
'tcx
>
{}
impl
<
'b
,
'tcx
>
CodegenCx
<
'b
,
'tcx
>
{
/// Generate a new symbol name with the given prefix. This symbol name must
/// only be used for definitions with `internal` or `private` linkage.
pub
fn
generate_local_symbol_name
(
&
self
,
prefix
:
&
str
)
->
String
{
let
idx
=
self
.local_gen_sym_counter
.get
();
self
.local_gen_sym_counter
.set
(
idx
+
1
);
// Include a '.' character, so there can be no accidental conflicts with
// user defined names
let
mut
name
=
String
::
with_capacity
(
prefix
.len
()
+
6
);
name
.push_str
(
prefix
);
name
.push_str
(
"."
);
base_n
::
push_str
(
idx
as
u128
,
base_n
::
ALPHANUMERIC_ONLY
,
&
mut
name
);
name
}
pub
fn
eh_personality
(
&
self
)
->
&
'b
Value
{
// The exception handling personality function.
//
// If our compilation unit has the `eh_personality` lang item somewhere
// within it, then we just need to codegen that. Otherwise, we're
// building an rlib which will depend on some upstream implementation of
// this function, so we just codegen a generic reference to it. We don't
// specify any of the types for the function, we just make it a symbol
// that LLVM can later use.
//
// Note that MSVC is a little special here in that we don't use the
// `eh_personality` lang item at all. Currently LLVM has support for
// both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
// *name of the personality function* to decide what kind of unwind side
// tables/landing pads to emit. It looks like Dwarf is used by default,
// injecting a dependency on the `_Unwind_Resume` symbol for resuming
// an "exception", but for MSVC we want to force SEH. This means that we
// can't actually have the personality function be our standard
// `rust_eh_personality` function, but rather we wired it up to the
// CRT's custom personality function, which forces LLVM to consider
// landing pads as "landing pads for SEH".
if
let
Some
(
llpersonality
)
=
self
.eh_personality
.get
()
{
return
llpersonality
}
let
tcx
=
self
.tcx
;
let
llfn
=
match
tcx
.lang_items
()
.eh_personality
()
{
Some
(
def_id
)
if
!
base
::
wants_msvc_seh
(
self
.sess
())
=>
{
callee
::
resolve_and_get_fn
(
self
,
def_id
,
tcx
.intern_substs
(
&
[]))
}
_
=>
{
let
name
=
if
base
::
wants_msvc_seh
(
self
.sess
())
{
"__CxxFrameHandler3"
}
else
{
"rust_eh_personality"
};
let
fty
=
&
self
.type_variadic_func
(
&
[],
&
self
.type_i32
());
declare
::
declare_cfn
(
self
,
name
,
fty
)
}
};
attributes
::
apply_target_cpu_attr
(
self
,
llfn
);
self
.eh_personality
.set
(
Some
(
llfn
));
llfn
}
// Returns a Value of the "eh_unwind_resume" lang item if one is defined,
// otherwise declares it as an external function.
pub
fn
eh_unwind_resume
(
&
self
)
->
&
'b
Value
{
use
attributes
;
let
unwresume
=
&
self
.eh_unwind_resume
;
if
let
Some
(
llfn
)
=
unwresume
.get
()
{
return
llfn
;
}
let
tcx
=
self
.tcx
;
assert
!
(
self
.sess
()
.target.target.options.custom_unwind_resume
);
if
let
Some
(
def_id
)
=
tcx
.lang_items
()
.eh_unwind_resume
()
{
let
llfn
=
callee
::
resolve_and_get_fn
(
self
,
def_id
,
tcx
.intern_substs
(
&
[]));
unwresume
.set
(
Some
(
llfn
));
return
llfn
;
}
let
sig
=
ty
::
Binder
::
bind
(
tcx
.mk_fn_sig
(
iter
::
once
(
tcx
.mk_mut_ptr
(
tcx
.types.u8
)),
tcx
.types.never
,
false
,
hir
::
Unsafety
::
Unsafe
,
Abi
::
C
));
let
llfn
=
declare
::
declare_fn
(
self
,
"rust_eh_unwind_resume"
,
sig
);
attributes
::
unwind
(
llfn
,
true
);
attributes
::
apply_target_cpu_attr
(
self
,
llfn
);
unwresume
.set
(
Some
(
llfn
));
llfn
}
pub
fn
type_needs_drop
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
common
::
type_needs_drop
(
self
.tcx
,
ty
)
}
pub
fn
type_is_sized
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
common
::
type_is_sized
(
self
.tcx
,
ty
)
}
pub
fn
type_is_freeze
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
common
::
type_is_freeze
(
self
.tcx
,
ty
)
}
pub
fn
type_has_metadata
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
bool
{
use
syntax_pos
::
DUMMY_SP
;
if
ty
.is_sized
(
self
.tcx
.at
(
DUMMY_SP
),
ty
::
ParamEnv
::
reveal_all
())
{
return
false
;
}
let
tail
=
self
.tcx
.struct_tail
(
ty
);
match
tail
.sty
{
ty
::
Foreign
(
..
)
=>
false
,
ty
::
Str
|
ty
::
Slice
(
..
)
|
ty
::
Dynamic
(
..
)
=>
true
,
_
=>
bug!
(
"unexpected unsized tail: {:?}"
,
tail
.sty
),
}
}
}
impl
ty
::
layout
::
HasDataLayout
for
CodegenCx
<
'll
,
'tcx
>
{
fn
data_layout
(
&
self
)
->
&
ty
::
layout
::
TargetDataLayout
{
&
self
.tcx.data_layout
}
}
impl
HasTargetSpec
for
CodegenCx
<
'll
,
'tcx
>
{
fn
target_spec
(
&
self
)
->
&
Target
{
&
self
.tcx.sess.target.target
}
}
impl
ty
::
layout
::
HasTyCtxt
<
'tcx
>
for
CodegenCx
<
'll
,
'tcx
>
{
fn
tcx
<
'a
>
(
&
'a
self
)
->
TyCtxt
<
'a
,
'tcx
,
'tcx
>
{
self
.tcx
}
}
impl
LayoutOf
for
CodegenCx
<
'll
,
'tcx
>
{
type
Ty
=
Ty
<
'tcx
>
;
type
TyLayout
=
TyLayout
<
'tcx
>
;
fn
layout_of
(
&
self
,
ty
:
Ty
<
'tcx
>
)
->
Self
::
TyLayout
{
self
.tcx
.layout_of
(
ty
::
ParamEnv
::
reveal_all
()
.and
(
ty
))
.unwrap_or_else
(|
e
|
if
let
LayoutError
::
SizeOverflow
(
_
)
=
e
{
self
.sess
()
.fatal
(
&
e
.to_string
())
}
else
{
bug!
(
"failed to get layout for `{}`: {}"
,
ty
,
e
)
})
}
}
src/librustc_codegen_llvm/debuginfo/gdb.rs
浏览文件 @
d77e34f3
...
...
@@ -17,7 +17,7 @@
use
declare
;
use
rustc
::
session
::
config
::
DebugInfo
;
use
value
::
Value
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
Base
TypeMethods
};
use
syntax
::
attr
;
...
...
src/librustc_codegen_llvm/interfaces/builder.rs
浏览文件 @
d77e34f3
...
...
@@ -17,6 +17,7 @@
use
super
::
backend
::
Backend
;
use
super
::
type_
::
TypeMethods
;
use
super
::
consts
::
ConstMethods
;
use
super
::
intrinsic
::
IntrinsicMethods
;
use
std
::
borrow
::
Cow
;
use
std
::
ops
::
Range
;
...
...
@@ -24,7 +25,7 @@
pub
trait
BuilderMethods
<
'a
,
'tcx
:
'a
>
:
Backend
{
type
CodegenCx
:
'a
+
TypeMethods
+
ConstMethods
+
Backend
<
type
CodegenCx
:
'a
+
TypeMethods
+
ConstMethods
+
IntrinsicMethods
+
Backend
<
Value
=
Self
::
Value
,
BasicBlock
=
Self
::
BasicBlock
,
Type
=
Self
::
Type
,
...
...
src/librustc_codegen_llvm/interfaces/intrinsic.rs
0 → 100644
浏览文件 @
d77e34f3
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
super
::
backend
::
Backend
;
pub
trait
BaseIntrinsicMethods
:
Backend
{
}
pub
trait
DerivedIntrinsicMethods
:
Backend
{
fn
get_intrinsic
(
&
self
,
key
:
&
str
)
->
Self
::
Value
;
fn
declare_intrinsic
(
&
self
,
key
:
&
str
)
->
Option
<
Self
::
Value
>
;
}
pub
trait
IntrinsicMethods
:
BaseIntrinsicMethods
+
DerivedIntrinsicMethods
{}
src/librustc_codegen_llvm/interfaces/mod.rs
浏览文件 @
d77e34f3
...
...
@@ -12,8 +12,10 @@
mod
backend
;
mod
consts
;
mod
type_
;
mod
intrinsic
;
pub
use
self
::
builder
::
BuilderMethods
;
pub
use
self
::
backend
::
Backend
;
pub
use
self
::
consts
::
ConstMethods
;
pub
use
self
::
type_
::
TypeMethods
;
pub
use
self
::
type_
::{
TypeMethods
,
BaseTypeMethods
,
DerivedTypeMethods
};
pub
use
self
::
intrinsic
::{
IntrinsicMethods
,
BaseIntrinsicMethods
,
DerivedIntrinsicMethods
};
src/librustc_codegen_llvm/interfaces/type_.rs
浏览文件 @
d77e34f3
...
...
@@ -10,8 +10,10 @@
use
super
::
backend
::
Backend
;
use
common
::
TypeKind
;
use
syntax
::
ast
;
use
rustc
::
ty
::
layout
::{
self
,
Align
,
Size
};
pub
trait
TypeMethods
:
Backend
{
pub
trait
Base
TypeMethods
:
Backend
{
fn
type_void
(
&
self
)
->
Self
::
Type
;
fn
type_metadata
(
&
self
)
->
Self
::
Type
;
fn
type_i1
(
&
self
)
->
Self
::
Type
;
...
...
@@ -42,3 +44,31 @@ pub trait TypeMethods: Backend {
fn
val_ty
(
&
self
,
v
:
Self
::
Value
)
->
Self
::
Type
;
}
pub
trait
DerivedTypeMethods
:
Backend
{
fn
type_bool
(
&
self
)
->
Self
::
Type
;
fn
type_i8p
(
&
self
)
->
Self
::
Type
;
fn
type_isize
(
&
self
)
->
Self
::
Type
;
fn
type_int
(
&
self
)
->
Self
::
Type
;
fn
type_int_from_ty
(
&
self
,
t
:
ast
::
IntTy
)
->
Self
::
Type
;
fn
type_uint_from_ty
(
&
self
,
t
:
ast
::
UintTy
)
->
Self
::
Type
;
fn
type_float_from_ty
(
&
self
,
t
:
ast
::
FloatTy
)
->
Self
::
Type
;
fn
type_from_integer
(
&
self
,
i
:
layout
::
Integer
)
->
Self
::
Type
;
fn
type_pointee_for_abi_align
(
&
self
,
align
:
Align
)
->
Self
::
Type
;
fn
type_padding_filler
(
&
self
,
size
:
Size
,
align
:
Align
)
->
Self
::
Type
;
}
pub
trait
TypeMethods
:
BaseTypeMethods
+
DerivedTypeMethods
{}
src/librustc_codegen_llvm/intrinsic.rs
浏览文件 @
d77e34f3
...
...
@@ -32,7 +32,9 @@
use
builder
::
Builder
;
use
value
::
Value
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
DerivedTypeMethods
,
DerivedIntrinsicMethods
,
};
use
rustc
::
session
::
Session
;
use
syntax_pos
::
Span
;
...
...
src/librustc_codegen_llvm/meth.rs
浏览文件 @
d77e34f3
...
...
@@ -16,7 +16,7 @@
use
monomorphize
;
use
value
::
Value
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
Derived
TypeMethods
};
use
rustc
::
ty
::{
self
,
Ty
};
use
rustc
::
ty
::
layout
::
HasDataLayout
;
...
...
src/librustc_codegen_llvm/mir/block.rs
浏览文件 @
d77e34f3
...
...
@@ -26,7 +26,9 @@
use
type_
::
Type
;
use
value
::
Value
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
DerivedTypeMethods
,
DerivedIntrinsicMethods
,
};
use
syntax
::
symbol
::
Symbol
;
use
syntax_pos
::
Pos
;
...
...
src/librustc_codegen_llvm/mir/constant.rs
浏览文件 @
d77e34f3
...
...
@@ -25,7 +25,7 @@
use
syntax
::
ast
::
Mutability
;
use
syntax
::
source_map
::
Span
;
use
value
::
Value
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
Derived
TypeMethods
};
use
super
::
super
::
callee
;
use
super
::
FunctionCx
;
...
...
src/librustc_codegen_llvm/mir/mod.rs
浏览文件 @
d77e34f3
...
...
@@ -24,7 +24,7 @@
use
monomorphize
::
Instance
;
use
abi
::{
ArgTypeExt
,
FnType
,
FnTypeExt
,
PassMode
};
use
value
::
Value
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
DerivedTypeMethods
};
use
syntax_pos
::{
DUMMY_SP
,
NO_EXPANSION
,
BytePos
,
Span
};
use
syntax
::
symbol
::
keywords
;
...
...
src/librustc_codegen_llvm/mir/operand.rs
浏览文件 @
d77e34f3
...
...
@@ -20,7 +20,7 @@
use
type_of
::
LayoutLlvmExt
;
use
glue
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
Type
Methods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
DerivedIntrinsic
Methods
};
use
std
::
fmt
;
...
...
src/librustc_codegen_llvm/mir/place.rs
浏览文件 @
d77e34f3
...
...
@@ -22,7 +22,9 @@
use
glue
;
use
mir
::
constant
::
const_alloc_to_llvm
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
TypeMethods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
DerivedTypeMethods
,
DerivedIntrinsicMethods
,
};
use
super
::{
FunctionCx
,
LocalRef
};
use
super
::
operand
::{
OperandRef
,
OperandValue
};
...
...
src/librustc_codegen_llvm/mir/rvalue.rs
浏览文件 @
d77e34f3
...
...
@@ -26,7 +26,7 @@
use
type_of
::
LayoutLlvmExt
;
use
value
::
Value
;
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
Type
Methods
};
use
interfaces
::{
BuilderMethods
,
ConstMethods
,
BaseTypeMethods
,
DerivedIntrinsic
Methods
};
use
super
::{
FunctionCx
,
LocalRef
};
use
super
::
operand
::{
OperandRef
,
OperandValue
};
...
...
src/librustc_codegen_llvm/type_.rs
浏览文件 @
d77e34f3
...
...
@@ -15,7 +15,7 @@
use
llvm
;
use
llvm
::{
Bool
,
False
,
True
};
use
context
::
CodegenCx
;
use
interfaces
::
TypeMethods
;
use
interfaces
::
{
BaseTypeMethods
,
DerivedTypeMethods
,
TypeMethods
}
;
use
value
::
Value
;
...
...
@@ -42,8 +42,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
impl
TypeMethods
for
CodegenCx
<
'll
,
'tcx
>
{
impl
BaseTypeMethods
for
CodegenCx
<
'll
,
'tcx
>
{
fn
type_void
(
&
self
)
->
&
'll
Type
{
unsafe
{
llvm
::
LLVMVoidTypeInContext
(
self
.llcx
)
...
...
@@ -265,20 +264,20 @@ fn ptr_to(&self) -> &Type {
}
}
impl
CodegenCx
<
'll
,
'tcx
>
{
pub
fn
type_bool
(
&
self
)
->
&
'll
Type
{
impl
DerivedTypeMethods
for
CodegenCx
<
'll
,
'tcx
>
{
fn
type_bool
(
&
self
)
->
&
'll
Type
{
self
.type_i8
()
}
pub
fn
type_i8p
(
&
self
)
->
&
'll
Type
{
fn
type_i8p
(
&
self
)
->
&
'll
Type
{
self
.type_ptr_to
(
self
.type_i8
())
}
pub
fn
type_isize
(
&
self
)
->
&
'll
Type
{
fn
type_isize
(
&
self
)
->
&
'll
Type
{
self
.isize_ty
}
pub
fn
type_int
(
&
self
)
->
&
'll
Type
{
fn
type_int
(
&
self
)
->
&
'll
Type
{
match
&
self
.sess
()
.target.target.target_c_int_width
[
..
]
{
"16"
=>
self
.type_i16
(),
"32"
=>
self
.type_i32
(),
...
...
@@ -287,7 +286,7 @@ pub fn type_int(&self) -> &'ll Type {
}
}
pub
fn
type_int_from_ty
(
fn
type_int_from_ty
(
&
self
,
t
:
ast
::
IntTy
)
->
&
'll
Type
{
...
...
@@ -301,7 +300,7 @@ pub fn type_int_from_ty(
}
}
pub
fn
type_uint_from_ty
(
fn
type_uint_from_ty
(
&
self
,
t
:
ast
::
UintTy
)
->
&
'll
Type
{
...
...
@@ -315,7 +314,7 @@ pub fn type_uint_from_ty(
}
}
pub
fn
type_float_from_ty
(
fn
type_float_from_ty
(
&
self
,
t
:
ast
::
FloatTy
)
->
&
'll
Type
{
...
...
@@ -325,7 +324,7 @@ pub fn type_float_from_ty(
}
}
pub
fn
type_from_integer
(
&
self
,
i
:
layout
::
Integer
)
->
&
'll
Type
{
fn
type_from_integer
(
&
self
,
i
:
layout
::
Integer
)
->
&
'll
Type
{
use
rustc
::
ty
::
layout
::
Integer
::
*
;
match
i
{
I8
=>
self
.type_i8
(),
...
...
@@ -338,7 +337,7 @@ pub fn type_from_integer(&self, i: layout::Integer) -> &'ll Type {
/// Return a LLVM type that has at most the required alignment,
/// as a conservative approximation for unknown pointee types.
pub
fn
type_pointee_for_abi_align
(
&
self
,
align
:
Align
)
->
&
'll
Type
{
fn
type_pointee_for_abi_align
(
&
self
,
align
:
Align
)
->
&
'll
Type
{
// FIXME(eddyb) We could find a better approximation if ity.align < align.
let
ity
=
layout
::
Integer
::
approximate_abi_align
(
self
,
align
);
self
.type_from_integer
(
ity
)
...
...
@@ -346,7 +345,7 @@ pub fn type_pointee_for_abi_align(&self, align: Align) -> &'ll Type {
/// Return a LLVM type that has at most the required alignment,
/// and exactly the required size, as a best-effort padding array.
pub
fn
type_padding_filler
(
fn
type_padding_filler
(
&
self
,
size
:
Size
,
align
:
Align
...
...
@@ -358,3 +357,5 @@ pub fn type_padding_filler(
self
.type_array
(
self
.type_from_integer
(
unit
),
size
/
unit_size
)
}
}
impl
TypeMethods
for
CodegenCx
<
'll
,
'tcx
>
{}
src/librustc_codegen_llvm/type_of.rs
浏览文件 @
d77e34f3
...
...
@@ -16,7 +16,7 @@
use
rustc_target
::
abi
::
FloatTy
;
use
rustc_mir
::
monomorphize
::
item
::
DefPathBasedNames
;
use
type_
::
Type
;
use
interfaces
::
TypeMethods
;
use
interfaces
::
{
BaseTypeMethods
,
DerivedTypeMethods
}
;
use
std
::
fmt
::
Write
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录