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:
Graydon Hoare 2012-11-16 11:26:26 -08:00
parent 8b309e54c7
commit 2bf6663cf0
5 changed files with 27 additions and 27 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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" => {

View File

@ -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;
}
}