librustc: Fastisel dislikes memmove, switch to memcpy. Perf win, r=catamorphism.
Fastisel actually has a special case for memcpy, the intrinsic, by name. It has no such special case for memmove, so bails. Close #3987.
This commit is contained in:
parent
8b309e54c7
commit
2bf6663cf0
@ -1275,33 +1275,33 @@ fn with_cond(bcx: block, val: ValueRef, f: fn(block) -> block) -> block {
|
||||
next_cx
|
||||
}
|
||||
|
||||
fn call_memmove(cx: block, dst: ValueRef, src: ValueRef,
|
||||
fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef,
|
||||
n_bytes: ValueRef) {
|
||||
// FIXME (Related to #1645, I think?): Provide LLVM with better
|
||||
// alignment information when the alignment is statically known (it must
|
||||
// be nothing more than a constant int, or LLVM complains -- not even a
|
||||
// constant element of a tydesc works).
|
||||
let _icx = cx.insn_ctxt("call_memmove");
|
||||
let _icx = cx.insn_ctxt("call_memcpy");
|
||||
let ccx = cx.ccx();
|
||||
let key = match ccx.sess.targ_cfg.arch {
|
||||
session::arch_x86 | session::arch_arm => ~"llvm.memmove.p0i8.p0i8.i32",
|
||||
session::arch_x86_64 => ~"llvm.memmove.p0i8.p0i8.i64"
|
||||
session::arch_x86 | session::arch_arm => ~"llvm.memcpy.p0i8.p0i8.i32",
|
||||
session::arch_x86_64 => ~"llvm.memcpy.p0i8.p0i8.i64"
|
||||
};
|
||||
let memmove = ccx.intrinsics.get(key);
|
||||
let memcpy = ccx.intrinsics.get(key);
|
||||
let src_ptr = PointerCast(cx, src, T_ptr(T_i8()));
|
||||
let dst_ptr = PointerCast(cx, dst, T_ptr(T_i8()));
|
||||
let size = IntCast(cx, n_bytes, ccx.int_type);
|
||||
let align = C_i32(1i32);
|
||||
let volatile = C_bool(false);
|
||||
Call(cx, memmove, ~[dst_ptr, src_ptr, size, align, volatile]);
|
||||
Call(cx, memcpy, ~[dst_ptr, src_ptr, size, align, volatile]);
|
||||
}
|
||||
|
||||
fn memmove_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
|
||||
let _icx = bcx.insn_ctxt("memmove_ty");
|
||||
fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) {
|
||||
let _icx = bcx.insn_ctxt("memcpy_ty");
|
||||
let ccx = bcx.ccx();
|
||||
if ty::type_is_structural(t) {
|
||||
let llsz = llsize_of(ccx, type_of::type_of(ccx, t));
|
||||
call_memmove(bcx, dst, src, llsz);
|
||||
call_memcpy(bcx, dst, src, llsz);
|
||||
} else {
|
||||
Store(bcx, Load(bcx, src), dst);
|
||||
}
|
||||
@ -1711,7 +1711,7 @@ fn trans_enum_variant(ccx: @crate_ctxt,
|
||||
_ => fail ~"trans_enum_variant: how do we know this works?",
|
||||
};
|
||||
let arg_ty = arg_tys[i].ty;
|
||||
memmove_ty(bcx, lldestptr, llarg, arg_ty);
|
||||
memcpy_ty(bcx, lldestptr, llarg, arg_ty);
|
||||
}
|
||||
build_return(bcx);
|
||||
finish_fn(fcx, lltop);
|
||||
@ -1757,7 +1757,7 @@ fn trans_tuple_struct(ccx: @crate_ctxt,
|
||||
}
|
||||
};
|
||||
let arg_ty = arg_tys[i].ty;
|
||||
memmove_ty(bcx, lldestptr, llarg, arg_ty);
|
||||
memcpy_ty(bcx, lldestptr, llarg, arg_ty);
|
||||
}
|
||||
|
||||
build_return(bcx);
|
||||
@ -2333,9 +2333,9 @@ fn p2i(ccx: @crate_ctxt, v: ValueRef) -> ValueRef {
|
||||
}
|
||||
|
||||
fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
|
||||
let T_memmove32_args: ~[TypeRef] =
|
||||
let T_memcpy32_args: ~[TypeRef] =
|
||||
~[T_ptr(T_i8()), T_ptr(T_i8()), T_i32(), T_i32(), T_i1()];
|
||||
let T_memmove64_args: ~[TypeRef] =
|
||||
let T_memcpy64_args: ~[TypeRef] =
|
||||
~[T_ptr(T_i8()), T_ptr(T_i8()), T_i64(), T_i32(), T_i1()];
|
||||
let T_memset32_args: ~[TypeRef] =
|
||||
~[T_ptr(T_i8()), T_i8(), T_i32(), T_i32(), T_i1()];
|
||||
@ -2351,12 +2351,12 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
|
||||
decl_cdecl_fn(llmod, ~"llvm.gcread",
|
||||
T_fn(~[T_ptr(T_i8()), T_ptr(T_ptr(T_i8()))],
|
||||
T_void()));
|
||||
let memmove32 =
|
||||
decl_cdecl_fn(llmod, ~"llvm.memmove.p0i8.p0i8.i32",
|
||||
T_fn(T_memmove32_args, T_void()));
|
||||
let memmove64 =
|
||||
decl_cdecl_fn(llmod, ~"llvm.memmove.p0i8.p0i8.i64",
|
||||
T_fn(T_memmove64_args, T_void()));
|
||||
let memcpy32 =
|
||||
decl_cdecl_fn(llmod, ~"llvm.memcpy.p0i8.p0i8.i32",
|
||||
T_fn(T_memcpy32_args, T_void()));
|
||||
let memcpy64 =
|
||||
decl_cdecl_fn(llmod, ~"llvm.memcpy.p0i8.p0i8.i64",
|
||||
T_fn(T_memcpy64_args, T_void()));
|
||||
let memset32 =
|
||||
decl_cdecl_fn(llmod, ~"llvm.memset.p0i8.i32",
|
||||
T_fn(T_memset32_args, T_void()));
|
||||
@ -2371,8 +2371,8 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
|
||||
let intrinsics = HashMap();
|
||||
intrinsics.insert(~"llvm.gcroot", gcroot);
|
||||
intrinsics.insert(~"llvm.gcread", gcread);
|
||||
intrinsics.insert(~"llvm.memmove.p0i8.p0i8.i32", memmove32);
|
||||
intrinsics.insert(~"llvm.memmove.p0i8.p0i8.i64", memmove64);
|
||||
intrinsics.insert(~"llvm.memcpy.p0i8.p0i8.i32", memcpy32);
|
||||
intrinsics.insert(~"llvm.memcpy.p0i8.p0i8.i64", memcpy64);
|
||||
intrinsics.insert(~"llvm.memset.p0i8.i32", memset32);
|
||||
intrinsics.insert(~"llvm.memset.p0i8.i64", memset64);
|
||||
intrinsics.insert(~"llvm.trap", trap);
|
||||
|
@ -485,7 +485,7 @@ fn make_opaque_cbox_take_glue(
|
||||
let bcx = callee::trans_rtcall(bcx, malloc, ~[opaque_tydesc, sz],
|
||||
expr::SaveIn(rval));
|
||||
let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty);
|
||||
call_memmove(bcx, cbox_out, cbox_in, sz);
|
||||
call_memcpy(bcx, cbox_out, cbox_in, sz);
|
||||
Store(bcx, cbox_out, cboxptr);
|
||||
|
||||
// Take the (deeply cloned) type descriptor
|
||||
|
@ -326,7 +326,7 @@ impl Datum {
|
||||
Store(bcx, self.val, dst);
|
||||
}
|
||||
ByRef => {
|
||||
memmove_ty(bcx, dst, self.val, self.ty);
|
||||
memcpy_ty(bcx, dst, self.val, self.ty);
|
||||
}
|
||||
}
|
||||
|
||||
@ -353,7 +353,7 @@ impl Datum {
|
||||
|
||||
match self.mode {
|
||||
ByRef => {
|
||||
glue::memmove_ty(bcx, dst, self.val, self.ty);
|
||||
glue::memcpy_ty(bcx, dst, self.val, self.ty);
|
||||
}
|
||||
ByValue => {
|
||||
Store(bcx, self.val, dst);
|
||||
|
@ -971,7 +971,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
||||
let llretptr = PointerCast(bcx, fcx.llretptr, T_ptr(T_i8()));
|
||||
let llcast = get_param(decl, first_real_arg);
|
||||
let llcast = PointerCast(bcx, llcast, T_ptr(T_i8()));
|
||||
call_memmove(bcx, llretptr, llcast, llsize_of(ccx, lltp_ty));
|
||||
call_memcpy(bcx, llretptr, llcast, llsize_of(ccx, lltp_ty));
|
||||
}
|
||||
}
|
||||
~"addr_of" => {
|
||||
|
@ -99,7 +99,7 @@ fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result {
|
||||
|
||||
let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr));
|
||||
let new_data_ptr = get_dataptr(bcx, get_bodyptr(bcx, newptr));
|
||||
base::call_memmove(bcx, new_data_ptr, data_ptr, fill);
|
||||
base::call_memcpy(bcx, new_data_ptr, data_ptr, fill);
|
||||
|
||||
let bcx = if ty::type_needs_drop(bcx.tcx(), unit_ty) {
|
||||
iter_vec_raw(bcx, new_data_ptr, vec_ty, fill, glue::take_ty)
|
||||
@ -309,7 +309,7 @@ fn write_content(bcx: block,
|
||||
let bytes = s.len() + 1; // copy null-terminator too
|
||||
let llbytes = C_uint(bcx.ccx(), bytes);
|
||||
let llcstr = C_cstr(bcx.ccx(), *s);
|
||||
base::call_memmove(bcx, lldest, llcstr, llbytes);
|
||||
base::call_memcpy(bcx, lldest, llcstr, llbytes);
|
||||
return bcx;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user