Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a5aeb8ed
R
Rust
项目概览
int
/
Rust
12 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a5aeb8ed
编写于
9月 10, 2018
作者:
D
Denis Merigoux
提交者:
Eduard-Mihai Burtescu
11月 16, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Transfered memcpy and memset to BuilderMethods
上级
3c082a23
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
110 addition
and
99 deletion
+110
-99
src/librustc_codegen_llvm/abi.rs
src/librustc_codegen_llvm/abi.rs
+8
-8
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/base.rs
+1
-40
src/librustc_codegen_llvm/builder.rs
src/librustc_codegen_llvm/builder.rs
+49
-10
src/librustc_codegen_llvm/interfaces/builder.rs
src/librustc_codegen_llvm/interfaces/builder.rs
+14
-6
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/intrinsic.rs
+32
-23
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
+2
-7
src/librustc_codegen_llvm/mir/rvalue.rs
src/librustc_codegen_llvm/mir/rvalue.rs
+3
-4
未找到文件。
src/librustc_codegen_llvm/abi.rs
浏览文件 @
a5aeb8ed
...
...
@@ -9,7 +9,6 @@
// except according to those terms.
use
llvm
::{
self
,
AttributePlace
};
use
base
;
use
builder
::{
Builder
,
MemFlags
};
use
context
::
CodegenCx
;
use
mir
::
place
::
PlaceRef
;
...
...
@@ -239,13 +238,14 @@ fn store(
bx
.store
(
val
,
llscratch
,
scratch_align
);
// ...and then memcpy it to the intended destination.
base
::
call_memcpy
(
bx
,
bx
.pointercast
(
dst
.llval
,
cx
.type_i8p
()),
self
.layout.align
,
bx
.pointercast
(
llscratch
,
cx
.type_i8p
()),
scratch_align
,
cx
.const_usize
(
self
.layout.size
.bytes
()),
MemFlags
::
empty
());
bx
.memcpy
(
bx
.pointercast
(
dst
.llval
,
cx
.type_i8p
()),
self
.layout.align
,
bx
.pointercast
(
llscratch
,
cx
.type_i8p
()),
scratch_align
,
cx
.const_usize
(
self
.layout.size
.bytes
()),
MemFlags
::
empty
()
);
bx
.lifetime_end
(
llscratch
,
scratch_size
);
}
...
...
src/librustc_codegen_llvm/base.rs
浏览文件 @
a5aeb8ed
...
...
@@ -433,30 +433,6 @@ pub fn to_immediate_scalar<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
val
}
pub
fn
call_memcpy
<
'a
,
'tcx
:
'a
,
Builder
:
BuilderMethods
<
'a
,
'tcx
>>
(
bx
:
&
Builder
,
dst
:
Builder
::
Value
,
dst_align
:
Align
,
src
:
Builder
::
Value
,
src_align
:
Align
,
n_bytes
:
Builder
::
Value
,
flags
:
MemFlags
,
)
{
if
flags
.contains
(
MemFlags
::
NONTEMPORAL
)
{
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
let
val
=
bx
.load
(
src
,
src_align
);
let
ptr
=
bx
.pointercast
(
dst
,
bx
.cx
()
.type_ptr_to
(
bx
.cx
()
.val_ty
(
val
)));
bx
.store_with_flags
(
val
,
ptr
,
dst_align
,
flags
);
return
;
}
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
.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
<
'a
,
'tcx
:
'a
,
Builder
:
BuilderMethods
<
'a
,
'tcx
>>
(
bx
:
&
Builder
,
dst
:
Builder
::
Value
,
...
...
@@ -471,22 +447,7 @@ pub fn memcpy_ty<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
return
;
}
call_memcpy
(
bx
,
dst
,
dst_align
,
src
,
src_align
,
bx
.cx
()
.const_usize
(
size
),
flags
);
}
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
,
)
->
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
);
bx
.call
(
llintrinsicfn
,
&
[
ptr
,
fill_byte
,
size
,
align
,
volatile
],
None
)
bx
.memcpy
(
dst
,
dst_align
,
src
,
src_align
,
bx
.cx
()
.const_usize
(
size
),
flags
);
}
pub
fn
codegen_instance
<
'a
,
'tcx
>
(
cx
:
&
CodegenCx
<
'a
,
'tcx
>
,
instance
:
Instance
<
'tcx
>
)
{
...
...
src/librustc_codegen_llvm/builder.rs
浏览文件 @
a5aeb8ed
...
...
@@ -785,24 +785,63 @@ fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
}
}
fn
memcpy
(
&
self
,
dst
:
&
'll
Value
,
dst_align
:
u64
,
src
:
&
'll
Value
,
src_align
:
u64
,
size
:
&
'll
Value
,
is_volatile
:
bool
)
->
&
'll
Value
{
fn
memcpy
(
&
self
,
dst
:
&
'll
Value
,
dst_align
:
Align
,
src
:
&
'll
Value
,
src_align
:
Align
,
size
:
&
'll
Value
,
flags
:
MemFlags
)
{
if
flags
.contains
(
MemFlags
::
NONTEMPORAL
)
{
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
let
val
=
self
.load
(
src
,
src_align
);
let
ptr
=
self
.pointercast
(
dst
,
self
.cx
()
.type_ptr_to
(
self
.cx
()
.val_ty
(
val
)));
self
.store_with_flags
(
val
,
ptr
,
dst_align
,
flags
);
return
;
}
let
size
=
self
.intcast
(
size
,
self
.cx
()
.type_isize
(),
false
);
let
is_volatile
=
flags
.contains
(
MemFlags
::
VOLATILE
);
let
dst
=
self
.pointercast
(
dst
,
self
.cx
()
.type_i8p
());
let
src
=
self
.pointercast
(
src
,
self
.cx
()
.type_i8p
());
unsafe
{
llvm
::
LLVMRustBuildMemCpy
(
self
.llbuilder
,
dst
,
dst_align
as
c_uint
,
src
,
src_align
as
c_uint
,
size
,
is_volatile
)
llvm
::
LLVMRustBuildMemCpy
(
self
.llbuilder
,
dst
,
dst_align
.abi
()
as
c_uint
,
src
,
src_align
.abi
()
as
c_uint
,
size
,
is_volatile
);
}
}
fn
memmove
(
&
self
,
dst
:
&
'll
Value
,
dst_align
:
u64
,
src
:
&
'll
Value
,
src_align
:
u64
,
size
:
&
'll
Value
,
is_volatile
:
bool
)
->
&
'll
Value
{
fn
memmove
(
&
self
,
dst
:
&
'll
Value
,
dst_align
:
Align
,
src
:
&
'll
Value
,
src_align
:
Align
,
size
:
&
'll
Value
,
flags
:
MemFlags
)
{
if
flags
.contains
(
MemFlags
::
NONTEMPORAL
)
{
// HACK(nox): This is inefficient but there is no nontemporal memmove.
let
val
=
self
.load
(
src
,
src_align
);
let
ptr
=
self
.pointercast
(
dst
,
self
.cx
()
.type_ptr_to
(
self
.cx
()
.val_ty
(
val
)));
self
.store_with_flags
(
val
,
ptr
,
dst_align
,
flags
);
return
;
}
let
size
=
self
.intcast
(
size
,
self
.cx
()
.type_isize
(),
false
);
let
is_volatile
=
flags
.contains
(
MemFlags
::
VOLATILE
);
let
dst
=
self
.pointercast
(
dst
,
self
.cx
()
.type_i8p
());
let
src
=
self
.pointercast
(
src
,
self
.cx
()
.type_i8p
());
unsafe
{
llvm
::
LLVMRustBuildMemMove
(
self
.llbuilder
,
dst
,
dst_align
as
c_uint
,
src
,
src_align
as
c_uint
,
size
,
is_volatile
)
llvm
::
LLVMRustBuildMemMove
(
self
.llbuilder
,
dst
,
dst_align
.abi
()
as
c_uint
,
src
,
src_align
.abi
()
as
c_uint
,
size
,
is_volatile
);
}
}
fn
memset
(
&
self
,
ptr
:
&
'll
Value
,
fill_byte
:
&
'll
Value
,
size
:
&
'll
Value
,
align
:
Align
,
flags
:
MemFlags
,
)
{
let
ptr_width
=
&
self
.sess
()
.target.target.target_pointer_width
;
let
intrinsic_key
=
format!
(
"llvm.memset.p0i8.i{}"
,
ptr_width
);
let
llintrinsicfn
=
self
.cx
()
.get_intrinsic
(
&
intrinsic_key
);
let
ptr
=
self
.pointercast
(
ptr
,
self
.cx
()
.type_i8p
());
let
align
=
self
.cx
()
.const_u32
(
align
.abi
()
as
u32
);
let
volatile
=
self
.cx
()
.const_bool
(
flags
.contains
(
MemFlags
::
VOLATILE
));
self
.call
(
llintrinsicfn
,
&
[
ptr
,
fill_byte
,
size
,
align
,
volatile
],
None
);
}
fn
minnum
(
&
self
,
lhs
:
&
'll
Value
,
rhs
:
&
'll
Value
)
->
&
'll
Value
{
self
.count_insn
(
"minnum"
);
unsafe
{
...
...
src/librustc_codegen_llvm/interfaces/builder.rs
浏览文件 @
a5aeb8ed
...
...
@@ -170,12 +170,20 @@ fn inline_asm_call(
)
->
Option
<
Self
::
Value
>
;
fn
memcpy
(
&
self
,
dst
:
Self
::
Value
,
dst_align
:
u64
,
src
:
Self
::
Value
,
src_align
:
u64
,
size
:
Self
::
Value
,
is_volatile
:
bool
)
->
Self
::
Value
;
fn
memmove
(
&
self
,
dst
:
Self
::
Value
,
dst_align
:
u64
,
src
:
Self
::
Value
,
src_align
:
u64
,
size
:
Self
::
Value
,
is_volatile
:
bool
)
->
Self
::
Value
;
fn
memcpy
(
&
self
,
dst
:
Self
::
Value
,
dst_align
:
Align
,
src
:
Self
::
Value
,
src_align
:
Align
,
size
:
Self
::
Value
,
flags
:
MemFlags
);
fn
memmove
(
&
self
,
dst
:
Self
::
Value
,
dst_align
:
Align
,
src
:
Self
::
Value
,
src_align
:
Align
,
size
:
Self
::
Value
,
flags
:
MemFlags
);
fn
memset
(
&
self
,
ptr
:
Self
::
Value
,
fill_byte
:
Self
::
Value
,
size
:
Self
::
Value
,
align
:
Align
,
flags
:
MemFlags
,
);
fn
minnum
(
&
self
,
lhs
:
Self
::
Value
,
rhs
:
Self
::
Value
)
->
Self
::
Value
;
fn
maxnum
(
&
self
,
lhs
:
Self
::
Value
,
rhs
:
Self
::
Value
)
->
Self
::
Value
;
...
...
src/librustc_codegen_llvm/intrinsic.rs
浏览文件 @
a5aeb8ed
...
...
@@ -29,7 +29,7 @@
use
rustc
::
hir
;
use
syntax
::
ast
;
use
syntax
::
symbol
::
Symbol
;
use
builder
::
Builder
;
use
builder
::
{
Builder
,
MemFlags
}
;
use
value
::
Value
;
use
interfaces
::{
...
...
@@ -228,28 +228,34 @@ pub fn codegen_intrinsic_call(
"copy_nonoverlapping"
=>
{
copy_intrinsic
(
bx
,
false
,
false
,
substs
.type_at
(
0
),
args
[
1
]
.immediate
(),
args
[
0
]
.immediate
(),
args
[
2
]
.immediate
())
args
[
1
]
.immediate
(),
args
[
0
]
.immediate
(),
args
[
2
]
.immediate
());
return
;
}
"copy"
=>
{
copy_intrinsic
(
bx
,
true
,
false
,
substs
.type_at
(
0
),
args
[
1
]
.immediate
(),
args
[
0
]
.immediate
(),
args
[
2
]
.immediate
())
args
[
1
]
.immediate
(),
args
[
0
]
.immediate
(),
args
[
2
]
.immediate
());
return
;
}
"write_bytes"
=>
{
memset_intrinsic
(
bx
,
false
,
substs
.type_at
(
0
),
args
[
0
]
.immediate
(),
args
[
1
]
.immediate
(),
args
[
2
]
.immediate
())
args
[
0
]
.immediate
(),
args
[
1
]
.immediate
(),
args
[
2
]
.immediate
());
return
;
}
"volatile_copy_nonoverlapping_memory"
=>
{
copy_intrinsic
(
bx
,
false
,
true
,
substs
.type_at
(
0
),
args
[
0
]
.immediate
(),
args
[
1
]
.immediate
(),
args
[
2
]
.immediate
())
args
[
0
]
.immediate
(),
args
[
1
]
.immediate
(),
args
[
2
]
.immediate
());
return
;
}
"volatile_copy_memory"
=>
{
copy_intrinsic
(
bx
,
true
,
true
,
substs
.type_at
(
0
),
args
[
0
]
.immediate
(),
args
[
1
]
.immediate
(),
args
[
2
]
.immediate
())
args
[
0
]
.immediate
(),
args
[
1
]
.immediate
(),
args
[
2
]
.immediate
());
return
;
}
"volatile_set_memory"
=>
{
memset_intrinsic
(
bx
,
true
,
substs
.type_at
(
0
),
args
[
0
]
.immediate
(),
args
[
1
]
.immediate
(),
args
[
2
]
.immediate
())
args
[
0
]
.immediate
(),
args
[
1
]
.immediate
(),
args
[
2
]
.immediate
());
return
;
}
"volatile_load"
|
"unaligned_volatile_load"
=>
{
let
tp_ty
=
substs
.type_at
(
0
);
...
...
@@ -725,17 +731,18 @@ fn copy_intrinsic(
dst
:
&
'll
Value
,
src
:
&
'll
Value
,
count
:
&
'll
Value
,
)
->
&
'll
Value
{
let
cx
=
bx
.cx
();
let
(
size
,
align
)
=
cx
.size_and_align_of
(
ty
);
let
size
=
cx
.const_usize
(
size
.bytes
());
let
align
=
align
.abi
();
let
dst_ptr
=
bx
.pointercast
(
dst
,
cx
.type_i8p
());
let
src_ptr
=
bx
.pointercast
(
src
,
cx
.type_i8p
());
)
{
let
(
size
,
align
)
=
bx
.cx
()
.size_and_align_of
(
ty
);
let
size
=
bx
.mul
(
bx
.cx
()
.const_usize
(
size
.bytes
()),
count
);
let
flags
=
if
volatile
{
MemFlags
::
VOLATILE
}
else
{
MemFlags
::
empty
()
};
if
allow_overlap
{
bx
.memmove
(
dst
_ptr
,
align
,
src_ptr
,
align
,
bx
.mul
(
size
,
count
),
volatile
)
bx
.memmove
(
dst
,
align
,
src
,
align
,
size
,
flags
);
}
else
{
bx
.memcpy
(
dst
_ptr
,
align
,
src_ptr
,
align
,
bx
.mul
(
size
,
count
),
volatile
)
bx
.memcpy
(
dst
,
align
,
src
,
align
,
size
,
flags
);
}
}
...
...
@@ -746,13 +753,15 @@ fn memset_intrinsic(
dst
:
&
'll
Value
,
val
:
&
'll
Value
,
count
:
&
'll
Value
)
->
&
'll
Value
{
let
cx
=
bx
.cx
();
let
(
size
,
align
)
=
cx
.size_and_align_of
(
ty
);
let
size
=
cx
.const_usize
(
size
.bytes
());
let
align
=
cx
.const_i32
(
align
.abi
()
as
i32
);
let
dst
=
bx
.pointercast
(
dst
,
cx
.type_i8p
());
call_memset
(
bx
,
dst
,
val
,
bx
.mul
(
size
,
count
),
align
,
volatile
)
)
{
let
(
size
,
align
)
=
bx
.cx
()
.size_and_align_of
(
ty
);
let
size
=
bx
.cx
()
.const_usize
(
size
.bytes
());
let
flags
=
if
volatile
{
MemFlags
::
VOLATILE
}
else
{
MemFlags
::
empty
()
};
bx
.memset
(
dst
,
val
,
bx
.mul
(
size
,
count
),
align
,
flags
);
}
fn
try_intrinsic
(
...
...
src/librustc_codegen_llvm/mir/operand.rs
浏览文件 @
a5aeb8ed
...
...
@@ -349,7 +349,7 @@ pub fn store_unsized(
// Allocate an appropriate region on the stack, and copy the value into it
let
(
llsize
,
_
)
=
glue
::
size_and_align_of_dst
(
bx
,
unsized_ty
,
Some
(
llextra
));
let
lldst
=
bx
.array_alloca
(
bx
.cx
()
.type_i8
(),
llsize
,
"unsized_tmp"
,
max_align
);
b
ase
::
call_memcpy
(
bx
,
lldst
,
max_align
,
llptr
,
min_align
,
llsize
,
flags
);
b
x
.memcpy
(
lldst
,
max_align
,
llptr
,
min_align
,
llsize
,
flags
);
// Store the allocated region and the extra to the indirect place.
let
indirect_operand
=
OperandValue
::
Pair
(
lldst
,
llextra
);
...
...
src/librustc_codegen_llvm/mir/place.rs
浏览文件 @
a5aeb8ed
...
...
@@ -14,7 +14,7 @@
use
rustc
::
mir
;
use
rustc
::
mir
::
tcx
::
PlaceTy
;
use
base
;
use
builder
::
Builder
;
use
builder
::
{
Builder
,
MemFlags
}
;
use
common
::{
CodegenCx
,
IntPredicate
};
use
type_of
::
LayoutLlvmExt
;
use
value
::
Value
;
...
...
@@ -381,15 +381,10 @@ pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: Vari
bx
.sess
()
.target.target.arch
==
"aarch64"
{
// Issue #34427: As workaround for LLVM bug on ARM,
// use memset of 0 before assigning niche value.
let
llptr
=
bx
.pointercast
(
self
.llval
,
bx
.cx
()
.type_ptr_to
(
bx
.cx
()
.type_i8
())
);
let
fill_byte
=
bx
.cx
()
.const_u8
(
0
);
let
(
size
,
align
)
=
self
.layout
.size_and_align
();
let
size
=
bx
.cx
()
.const_usize
(
size
.bytes
());
let
align
=
bx
.cx
()
.const_u32
(
align
.abi
()
as
u32
);
base
::
call_memset
(
bx
,
llptr
,
fill_byte
,
size
,
align
,
false
);
bx
.memset
(
self
.llval
,
fill_byte
,
size
,
align
,
MemFlags
::
empty
());
}
let
niche
=
self
.project_field
(
bx
,
0
);
...
...
src/librustc_codegen_llvm/mir/rvalue.rs
浏览文件 @
a5aeb8ed
...
...
@@ -17,7 +17,7 @@
use
std
::{
u128
,
i128
};
use
base
;
use
builder
::
Builder
;
use
builder
::
{
Builder
,
MemFlags
}
;
use
callee
;
use
common
::{
self
,
IntPredicate
,
RealPredicate
};
use
monomorphize
;
...
...
@@ -104,20 +104,19 @@ pub fn codegen_rvalue(&mut self,
let
start
=
dest
.project_index
(
&
bx
,
bx
.cx
()
.const_usize
(
0
))
.llval
;
if
let
OperandValue
::
Immediate
(
v
)
=
cg_elem
.val
{
let
align
=
bx
.cx
()
.const_i32
(
dest
.align
.abi
()
as
i32
);
let
size
=
bx
.cx
()
.const_usize
(
dest
.layout.size
.bytes
());
// Use llvm.memset.p0i8.* to initialize all zero arrays
if
bx
.cx
()
.is_const_integral
(
v
)
&&
bx
.cx
()
.const_to_uint
(
v
)
==
0
{
let
fill
=
bx
.cx
()
.const_u8
(
0
);
b
ase
::
call_memset
(
&
bx
,
start
,
fill
,
size
,
align
,
false
);
b
x
.memset
(
start
,
fill
,
size
,
dest
.align
,
MemFlags
::
empty
()
);
return
bx
;
}
// Use llvm.memset.p0i8.* to initialize byte arrays
let
v
=
base
::
from_immediate
(
&
bx
,
v
);
if
bx
.cx
()
.val_ty
(
v
)
==
bx
.cx
()
.type_i8
()
{
b
ase
::
call_memset
(
&
bx
,
start
,
v
,
size
,
align
,
false
);
b
x
.memset
(
start
,
v
,
size
,
dest
.align
,
MemFlags
::
empty
()
);
return
bx
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录