Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
3ebe8679
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
3ebe8679
编写于
5月 11, 2018
作者:
A
Anthony Ramine
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Introduce OperandValue::nontemporal_store and use it in the intrinsics
We use a new MemFlags bitflags type to merge some store code paths.
上级
b638f11b
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
65 addition
and
78 deletion
+65
-78
src/Cargo.lock
src/Cargo.lock
+1
-0
src/librustc_trans/Cargo.toml
src/librustc_trans/Cargo.toml
+1
-0
src/librustc_trans/abi.rs
src/librustc_trans/abi.rs
+2
-2
src/librustc_trans/base.rs
src/librustc_trans/base.rs
+13
-6
src/librustc_trans/builder.rs
src/librustc_trans/builder.rs
+30
-37
src/librustc_trans/intrinsic.rs
src/librustc_trans/intrinsic.rs
+2
-15
src/librustc_trans/lib.rs
src/librustc_trans/lib.rs
+1
-0
src/librustc_trans/mir/block.rs
src/librustc_trans/mir/block.rs
+2
-2
src/librustc_trans/mir/operand.rs
src/librustc_trans/mir/operand.rs
+13
-16
未找到文件。
src/Cargo.lock
浏览文件 @
3ebe8679
...
...
@@ -2178,6 +2178,7 @@ dependencies = [
name = "rustc_trans"
version = "0.0.0"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
...
...
src/librustc_trans/Cargo.toml
浏览文件 @
3ebe8679
...
...
@@ -10,6 +10,7 @@ crate-type = ["dylib"]
test
=
false
[dependencies]
bitflags
=
"1.0.1"
cc
=
"1.0.1"
flate2
=
"1.0"
jobserver
=
"0.1.5"
...
...
src/librustc_trans/abi.rs
浏览文件 @
3ebe8679
...
...
@@ -10,7 +10,7 @@
use
llvm
::{
self
,
ValueRef
,
AttributePlace
};
use
base
;
use
builder
::
Builder
;
use
builder
::
{
Builder
,
MemFlags
}
;
use
common
::{
ty_fn_sig
,
C_usize
};
use
context
::
CodegenCx
;
use
mir
::
place
::
PlaceRef
;
...
...
@@ -221,7 +221,7 @@ fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) {
bx
.pointercast
(
llscratch
,
Type
::
i8p
(
cx
)),
C_usize
(
cx
,
self
.layout.size
.bytes
()),
self
.layout.align
.min
(
scratch_align
),
false
);
MemFlags
::
empty
()
);
bx
.lifetime_end
(
llscratch
,
scratch_size
);
}
...
...
src/librustc_trans/base.rs
浏览文件 @
3ebe8679
...
...
@@ -53,7 +53,7 @@
use
allocator
;
use
mir
::
place
::
PlaceRef
;
use
attributes
;
use
builder
::
Builder
;
use
builder
::
{
Builder
,
MemFlags
}
;
use
callee
;
use
common
::{
C_bool
,
C_bytes_in_context
,
C_i32
,
C_usize
};
use
rustc_mir
::
monomorphize
::
collector
::{
self
,
MonoItemCollectionMode
};
...
...
@@ -320,7 +320,7 @@ pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
if
src_f
.layout.ty
==
dst_f
.layout.ty
{
memcpy_ty
(
bx
,
dst_f
.llval
,
src_f
.llval
,
src_f
.layout
,
src_f
.align
.min
(
dst_f
.align
),
false
);
src_f
.align
.min
(
dst_f
.align
),
MemFlags
::
empty
()
);
}
else
{
coerce_unsized_into
(
bx
,
src_f
,
dst_f
);
}
...
...
@@ -409,7 +409,14 @@ pub fn call_memcpy(bx: &Builder,
src
:
ValueRef
,
n_bytes
:
ValueRef
,
align
:
Align
,
volatile
:
bool
)
{
flags
:
MemFlags
)
{
if
flags
.contains
(
MemFlags
::
NONTEMPORAL
)
{
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
let
val
=
bx
.load
(
src
,
align
);
let
ptr
=
bx
.pointercast
(
dst
,
val_ty
(
val
)
.ptr_to
());
bx
.store_with_flags
(
val
,
ptr
,
align
,
flags
);
return
;
}
let
cx
=
bx
.cx
;
let
ptr_width
=
&
cx
.sess
()
.target.target.target_pointer_width
;
let
key
=
format!
(
"llvm.memcpy.p0i8.p0i8.i{}"
,
ptr_width
);
...
...
@@ -418,7 +425,7 @@ pub fn call_memcpy(bx: &Builder,
let
dst_ptr
=
bx
.pointercast
(
dst
,
Type
::
i8p
(
cx
));
let
size
=
bx
.intcast
(
n_bytes
,
cx
.isize_ty
,
false
);
let
align
=
C_i32
(
cx
,
align
.abi
()
as
i32
);
let
volatile
=
C_bool
(
cx
,
volatile
);
let
volatile
=
C_bool
(
cx
,
flags
.contains
(
MemFlags
::
VOLATILE
)
);
bx
.call
(
memcpy
,
&
[
dst_ptr
,
src_ptr
,
size
,
align
,
volatile
],
None
);
}
...
...
@@ -428,14 +435,14 @@ pub fn memcpy_ty<'a, 'tcx>(
src
:
ValueRef
,
layout
:
TyLayout
<
'tcx
>
,
align
:
Align
,
volatile
:
bool
,
flags
:
MemFlags
,
)
{
let
size
=
layout
.size
.bytes
();
if
size
==
0
{
return
;
}
call_memcpy
(
bx
,
dst
,
src
,
C_usize
(
bx
.cx
,
size
),
align
,
volatile
);
call_memcpy
(
bx
,
dst
,
src
,
C_usize
(
bx
.cx
,
size
),
align
,
flags
);
}
pub
fn
call_memset
<
'a
,
'tcx
>
(
bx
:
&
Builder
<
'a
,
'tcx
>
,
...
...
src/librustc_trans/builder.rs
浏览文件 @
3ebe8679
...
...
@@ -50,6 +50,13 @@ fn noname() -> *const c_char {
&
CNULL
}
bitflags!
{
pub
struct
MemFlags
:
u8
{
const
VOLATILE
=
1
<<
0
;
const
NONTEMPORAL
=
1
<<
1
;
}
}
impl
<
'a
,
'tcx
>
Builder
<
'a
,
'tcx
>
{
pub
fn
new_block
<
'b
>
(
cx
:
&
'a
CodegenCx
<
'a
,
'tcx
>
,
llfn
:
ValueRef
,
name
:
&
'b
str
)
->
Self
{
let
bx
=
Builder
::
with_cx
(
cx
);
...
...
@@ -579,30 +586,39 @@ pub fn nonnull_metadata(&self, load: ValueRef) {
}
pub
fn
store
(
&
self
,
val
:
ValueRef
,
ptr
:
ValueRef
,
align
:
Align
)
->
ValueRef
{
debug!
(
"Store {:?} -> {:?}"
,
Value
(
val
),
Value
(
ptr
));
self
.store_with_flags
(
val
,
ptr
,
align
,
MemFlags
::
empty
())
}
pub
fn
store_with_flags
(
&
self
,
val
:
ValueRef
,
ptr
:
ValueRef
,
align
:
Align
,
flags
:
MemFlags
,
)
->
ValueRef
{
debug!
(
"Store {:?} -> {:?} ({:?})"
,
Value
(
val
),
Value
(
ptr
),
flags
);
assert
!
(
!
self
.llbuilder
.is_null
());
self
.count_insn
(
"store"
);
let
ptr
=
self
.check_store
(
val
,
ptr
);
unsafe
{
let
store
=
llvm
::
LLVMBuildStore
(
self
.llbuilder
,
val
,
ptr
);
llvm
::
LLVMSetAlignment
(
store
,
align
.abi
()
as
c_uint
);
if
flags
.contains
(
MemFlags
::
VOLATILE
)
{
llvm
::
LLVMSetVolatile
(
store
,
llvm
::
True
);
}
if
flags
.contains
(
MemFlags
::
NONTEMPORAL
)
{
// According to LLVM [1] building a nontemporal store must
// *always* point to a metadata value of the integer 1.
//
// [1]: http://llvm.org/docs/LangRef.html#store-instruction
let
one
=
C_i32
(
self
.cx
,
1
);
let
node
=
llvm
::
LLVMMDNodeInContext
(
self
.cx.llcx
,
&
one
,
1
);
llvm
::
LLVMSetMetadata
(
store
,
llvm
::
MD_nontemporal
as
c_uint
,
node
);
}
store
}
}
pub
fn
volatile_store
(
&
self
,
val
:
ValueRef
,
ptr
:
ValueRef
,
align
:
Align
)
->
ValueRef
{
debug!
(
"Store {:?} -> {:?}"
,
Value
(
val
),
Value
(
ptr
));
assert
!
(
!
self
.llbuilder
.is_null
());
self
.count_insn
(
"store.volatile"
);
let
ptr
=
self
.check_store
(
val
,
ptr
);
unsafe
{
let
insn
=
llvm
::
LLVMBuildStore
(
self
.llbuilder
,
val
,
ptr
);
llvm
::
LLVMSetAlignment
(
insn
,
align
.abi
()
as
c_uint
);
llvm
::
LLVMSetVolatile
(
insn
,
llvm
::
True
);
insn
}
}
pub
fn
atomic_store
(
&
self
,
val
:
ValueRef
,
ptr
:
ValueRef
,
order
:
AtomicOrdering
,
align
:
Align
)
{
debug!
(
"Store {:?} -> {:?}"
,
Value
(
val
),
Value
(
ptr
));
...
...
@@ -616,29 +632,6 @@ pub fn atomic_store(&self, val: ValueRef, ptr: ValueRef,
}
}
pub
fn
nontemporal_store
(
&
self
,
val
:
ValueRef
,
ptr
:
ValueRef
)
->
ValueRef
{
debug!
(
"Store {:?} -> {:?}"
,
Value
(
val
),
Value
(
ptr
));
assert
!
(
!
self
.llbuilder
.is_null
());
self
.count_insn
(
"store.nontemporal"
);
let
ptr
=
self
.check_store
(
val
,
ptr
);
unsafe
{
let
insn
=
llvm
::
LLVMBuildStore
(
self
.llbuilder
,
val
,
ptr
);
// According to LLVM [1] building a nontemporal store must *always*
// 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
.cx
,
1
);
let
node
=
llvm
::
LLVMMDNodeInContext
(
self
.cx.llcx
,
&
one
,
1
);
llvm
::
LLVMSetMetadata
(
insn
,
llvm
::
MD_nontemporal
as
c_uint
,
node
);
insn
}
}
pub
fn
gep
(
&
self
,
ptr
:
ValueRef
,
indices
:
&
[
ValueRef
])
->
ValueRef
{
self
.count_insn
(
"gep"
);
unsafe
{
...
...
src/librustc_trans/intrinsic.rs
浏览文件 @
3ebe8679
...
...
@@ -248,9 +248,6 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
},
"volatile_store"
=>
{
let
dst
=
args
[
0
]
.deref
(
bx
.cx
);
if
dst
.layout
.is_zst
()
{
return
;
}
args
[
1
]
.val
.volatile_store
(
bx
,
dst
);
return
;
},
...
...
@@ -536,19 +533,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
}
"nontemporal_store"
=>
{
let
tp_ty
=
substs
.type_at
(
0
);
let
dst
=
args
[
0
]
.deref
(
bx
.cx
);
let
val
=
if
let
OperandValue
::
Ref
(
ptr
,
align
)
=
args
[
1
]
.val
{
bx
.load
(
ptr
,
align
)
}
else
{
from_immediate
(
bx
,
args
[
1
]
.immediate
())
};
let
ptr
=
bx
.pointercast
(
dst
.llval
,
val_ty
(
val
)
.ptr_to
());
let
store
=
bx
.nontemporal_store
(
val
,
ptr
);
unsafe
{
llvm
::
LLVMSetAlignment
(
store
,
cx
.align_of
(
tp_ty
)
.abi
()
as
u32
);
}
return
args
[
1
]
.val
.nontemporal_store
(
bx
,
dst
);
return
;
}
_
=>
{
...
...
src/librustc_trans/lib.rs
浏览文件 @
3ebe8679
...
...
@@ -34,6 +34,7 @@
use
rustc
::
dep_graph
::
WorkProduct
;
use
syntax_pos
::
symbol
::
Symbol
;
#[macro_use]
extern
crate
bitflags
;
extern
crate
flate2
;
extern
crate
libc
;
#[macro_use]
extern
crate
rustc
;
...
...
src/librustc_trans/mir/block.rs
浏览文件 @
3ebe8679
...
...
@@ -17,7 +17,7 @@
use
abi
::{
Abi
,
ArgType
,
ArgTypeExt
,
FnType
,
FnTypeExt
,
LlvmType
,
PassMode
};
use
base
;
use
callee
;
use
builder
::
Builder
;
use
builder
::
{
Builder
,
MemFlags
}
;
use
common
::{
self
,
C_bool
,
C_str_slice
,
C_struct
,
C_u32
,
C_uint_big
,
C_undef
};
use
consts
;
use
meth
;
...
...
@@ -626,7 +626,7 @@ fn trans_argument(&mut self,
// have scary latent bugs around.
let
scratch
=
PlaceRef
::
alloca
(
bx
,
arg
.layout
,
"arg"
);
base
::
memcpy_ty
(
bx
,
scratch
.llval
,
llval
,
op
.layout
,
align
,
false
);
base
::
memcpy_ty
(
bx
,
scratch
.llval
,
llval
,
op
.layout
,
align
,
MemFlags
::
empty
()
);
(
scratch
.llval
,
scratch
.align
,
true
)
}
else
{
(
llval
,
align
,
true
)
...
...
src/librustc_trans/mir/operand.rs
浏览文件 @
3ebe8679
...
...
@@ -18,7 +18,7 @@
use
base
;
use
common
::{
self
,
CodegenCx
,
C_null
,
C_undef
,
C_usize
};
use
builder
::
Builder
;
use
builder
::
{
Builder
,
MemFlags
}
;
use
value
::
Value
;
use
type_of
::
LayoutLlvmExt
;
use
type_
::
Type
;
...
...
@@ -275,14 +275,18 @@ pub fn extract_field(&self, bx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tcx
impl
<
'a
,
'tcx
>
OperandValue
{
pub
fn
store
(
self
,
bx
:
&
Builder
<
'a
,
'tcx
>
,
dest
:
PlaceRef
<
'tcx
>
)
{
self
.store_
maybe_volatile
(
bx
,
dest
,
false
);
self
.store_
with_flags
(
bx
,
dest
,
MemFlags
::
empty
()
);
}
pub
fn
volatile_store
(
self
,
bx
:
&
Builder
<
'a
,
'tcx
>
,
dest
:
PlaceRef
<
'tcx
>
)
{
self
.store_
maybe_volatile
(
bx
,
dest
,
true
);
self
.store_
with_flags
(
bx
,
dest
,
MemFlags
::
VOLATILE
);
}
fn
store_maybe_volatile
(
self
,
bx
:
&
Builder
<
'a
,
'tcx
>
,
dest
:
PlaceRef
<
'tcx
>
,
volatile
:
bool
)
{
pub
fn
nontemporal_store
(
self
,
bx
:
&
Builder
<
'a
,
'tcx
>
,
dest
:
PlaceRef
<
'tcx
>
)
{
self
.store_with_flags
(
bx
,
dest
,
MemFlags
::
NONTEMPORAL
);
}
fn
store_with_flags
(
self
,
bx
:
&
Builder
<
'a
,
'tcx
>
,
dest
:
PlaceRef
<
'tcx
>
,
flags
:
MemFlags
)
{
debug!
(
"OperandRef::store: operand={:?}, dest={:?}"
,
self
,
dest
);
// Avoid generating stores of zero-sized values, because the only way to have a zero-sized
// value is through `undef`, and store itself is useless.
...
...
@@ -290,16 +294,13 @@ fn store_maybe_volatile(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, vola
return
;
}
match
self
{
OperandValue
::
Ref
(
r
,
source_align
)
=>
OperandValue
::
Ref
(
r
,
source_align
)
=>
{
base
::
memcpy_ty
(
bx
,
dest
.llval
,
r
,
dest
.layout
,
source_align
.min
(
dest
.align
),
volatile
),
source_align
.min
(
dest
.align
),
flags
)
}
OperandValue
::
Immediate
(
s
)
=>
{
let
val
=
base
::
from_immediate
(
bx
,
s
);
if
!
volatile
{
bx
.store
(
val
,
dest
.llval
,
dest
.align
);
}
else
{
bx
.volatile_store
(
val
,
dest
.llval
,
dest
.align
);
}
bx
.store_with_flags
(
val
,
dest
.llval
,
dest
.align
,
flags
);
}
OperandValue
::
Pair
(
a
,
b
)
=>
{
for
(
i
,
&
x
)
in
[
a
,
b
]
.iter
()
.enumerate
()
{
...
...
@@ -309,11 +310,7 @@ fn store_maybe_volatile(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, vola
llptr
=
bx
.pointercast
(
llptr
,
Type
::
i8p
(
bx
.cx
));
}
let
val
=
base
::
from_immediate
(
bx
,
x
);
if
!
volatile
{
bx
.store
(
val
,
llptr
,
dest
.align
);
}
else
{
bx
.volatile_store
(
val
,
llptr
,
dest
.align
);
}
bx
.store_with_flags
(
val
,
llptr
,
dest
.align
,
flags
);
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录