Skip to content

Commit 8cffddd

Browse files
committed
---
yaml --- r: 2435 b: refs/heads/master c: 55f0f79 h: refs/heads/master i: 2433: 1cd158e 2431: 7cafa35 v: v3
1 parent 6648e5e commit 8cffddd

File tree

2 files changed

+78
-107
lines changed

2 files changed

+78
-107
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 1abb7a868e41003bd618b5bec75c39f90eee5ce1
2+
refs/heads/master: 55f0f79a46c230767c35a2b0d35718f71ae6fd11

trunk/src/comp/middle/trans.rs

Lines changed: 77 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ type glue_fns = rec(ValueRef activate_glue,
5858
vec[ValueRef] native_glues_pure_rust,
5959
vec[ValueRef] native_glues_cdecl,
6060
ValueRef no_op_type_glue,
61-
ValueRef memcpy_glue,
62-
ValueRef bzero_glue,
6361
ValueRef vec_append_glue);
6462

6563
type tydesc_info = rec(ValueRef tydesc,
@@ -2921,31 +2919,58 @@ fn drop_ty(@block_ctxt cx,
29212919
fn call_memcpy(@block_ctxt cx,
29222920
ValueRef dst,
29232921
ValueRef src,
2924-
ValueRef n_bytes) -> result {
2922+
ValueRef n_bytes,
2923+
ValueRef align_bytes) -> result {
2924+
// FIXME: switch to the 64-bit variant when on such a platform.
2925+
auto i = cx.fcx.lcx.ccx.intrinsics;
2926+
assert (i.contains_key("llvm.memcpy.p0i8.p0i8.i32"));
2927+
auto memcpy = i.get("llvm.memcpy.p0i8.p0i8.i32");
29252928
auto src_ptr = cx.build.PointerCast(src, T_ptr(T_i8()));
29262929
auto dst_ptr = cx.build.PointerCast(dst, T_ptr(T_i8()));
2927-
auto size = cx.build.IntCast(n_bytes, T_int());
2928-
ret res(cx, cx.build.FastCall(cx.fcx.lcx.ccx.glues.memcpy_glue,
2929-
vec(dst_ptr, src_ptr, size)));
2930+
auto size = cx.build.IntCast(n_bytes, T_i32());
2931+
auto align =
2932+
if (lib.llvm.llvm.LLVMIsConstant(align_bytes) == True)
2933+
{ cx.build.IntCast(align_bytes, T_i32()) }
2934+
else
2935+
{ cx.build.IntCast(C_int(0), T_i32()) };
2936+
2937+
auto volatile = C_bool(false);
2938+
ret res(cx, cx.build.Call(memcpy,
2939+
vec(dst_ptr, src_ptr,
2940+
size, align, volatile)));
29302941
}
29312942

29322943
fn call_bzero(@block_ctxt cx,
29332944
ValueRef dst,
2934-
ValueRef n_bytes) -> result {
2945+
ValueRef n_bytes,
2946+
ValueRef align_bytes) -> result {
2947+
2948+
// FIXME: switch to the 64-bit variant when on such a platform.
2949+
auto i = cx.fcx.lcx.ccx.intrinsics;
2950+
assert (i.contains_key("llvm.memset.p0i8.i32"));
2951+
auto memset = i.get("llvm.memset.p0i8.i32");
29352952
auto dst_ptr = cx.build.PointerCast(dst, T_ptr(T_i8()));
2936-
auto size = cx.build.IntCast(n_bytes, T_int());
2937-
ret res(cx, cx.build.FastCall(cx.fcx.lcx.ccx.glues.bzero_glue,
2938-
vec(dst_ptr, size)));
2953+
auto size = cx.build.IntCast(n_bytes, T_i32());
2954+
auto align =
2955+
if (lib.llvm.llvm.LLVMIsConstant(align_bytes) == True)
2956+
{ cx.build.IntCast(align_bytes, T_i32()) }
2957+
else
2958+
{ cx.build.IntCast(C_int(0), T_i32()) };
2959+
2960+
auto volatile = C_bool(false);
2961+
ret res(cx, cx.build.Call(memset,
2962+
vec(dst_ptr, C_u8(0u),
2963+
size, align, volatile)));
29392964
}
29402965

29412966
fn memcpy_ty(@block_ctxt cx,
29422967
ValueRef dst,
29432968
ValueRef src,
29442969
ty.t t) -> result {
29452970
if (ty.type_has_dynamic_size(cx.fcx.lcx.ccx.tcx, t)) {
2946-
auto llszptr = field_of_tydesc(cx, t, false, abi.tydesc_field_size);
2947-
auto llsz = llszptr.bcx.build.Load(llszptr.val);
2948-
ret call_memcpy(llszptr.bcx, dst, src, llsz);
2971+
auto llsz = size_of(cx, t);
2972+
auto llalign = align_of(llsz.bcx, t);
2973+
ret call_memcpy(llalign.bcx, dst, src, llsz.val, llalign.val);
29492974

29502975
} else {
29512976
ret res(cx, cx.build.Store(cx.build.Load(src), dst));
@@ -5553,7 +5578,8 @@ fn trans_break_cont(@block_ctxt cx, bool to_end) -> result {
55535578
}
55545579
}
55555580
}
5556-
ret res(new_sub_block_ctxt(bcx, "unreachable"), C_nil());
5581+
ret res(new_sub_block_ctxt(bcx, "break_cont.unreachable"),
5582+
C_nil());
55575583
}
55585584
case (_) {
55595585
alt (cleanup_cx.parent) {
@@ -5609,7 +5635,7 @@ fn trans_ret(@block_ctxt cx, &Option.t[@ast.expr] e) -> result {
56095635
}
56105636

56115637
bcx.build.RetVoid();
5612-
ret res(new_sub_block_ctxt(bcx, "unreachable"), C_nil());
5638+
ret res(new_sub_block_ctxt(bcx, "ret.unreachable"), C_nil());
56135639
}
56145640

56155641
fn trans_be(@block_ctxt cx, @ast.expr e) -> result {
@@ -5773,7 +5799,9 @@ fn zero_alloca(@block_ctxt cx, ValueRef llptr, ty.t t) -> result {
57735799
auto bcx = cx;
57745800
if (ty.type_has_dynamic_size(cx.fcx.lcx.ccx.tcx, t)) {
57755801
auto llsz = size_of(bcx, t);
5776-
bcx = call_bzero(llsz.bcx, llptr, llsz.val).bcx;
5802+
auto llalign = align_of(llsz.bcx, t);
5803+
bcx = call_bzero(llalign.bcx, llptr,
5804+
llsz.val, llalign.val).bcx;
57775805
} else {
57785806
auto llty = type_of(bcx.fcx.lcx.ccx, t);
57795807
auto null = lib.llvm.llvm.LLVMConstNull(llty);
@@ -7285,11 +7313,36 @@ fn trans_main_fn(@local_ctxt cx, ValueRef llcrate, ValueRef crate_map) {
72857313

72867314
fn declare_intrinsics(ModuleRef llmod) -> hashmap[str,ValueRef] {
72877315

7316+
let vec[TypeRef] T_memcpy32_args = vec(T_ptr(T_i8()), T_ptr(T_i8()),
7317+
T_i32(), T_i32(), T_i1());
7318+
let vec[TypeRef] T_memcpy64_args = vec(T_ptr(T_i8()), T_ptr(T_i8()),
7319+
T_i64(), T_i32(), T_i1());
7320+
7321+
let vec[TypeRef] T_memset32_args = vec(T_ptr(T_i8()), T_i8(),
7322+
T_i32(), T_i32(), T_i1());
7323+
let vec[TypeRef] T_memset64_args = vec(T_ptr(T_i8()), T_i8(),
7324+
T_i64(), T_i32(), T_i1());
7325+
72887326
let vec[TypeRef] T_trap_args = vec();
7327+
7328+
auto memcpy32 = decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i32",
7329+
T_fn(T_memcpy32_args, T_void()));
7330+
auto memcpy64 = decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i64",
7331+
T_fn(T_memcpy64_args, T_void()));
7332+
7333+
auto memset32 = decl_cdecl_fn(llmod, "llvm.memset.p0i8.i32",
7334+
T_fn(T_memset32_args, T_void()));
7335+
auto memset64 = decl_cdecl_fn(llmod, "llvm.memset.p0i8.i64",
7336+
T_fn(T_memset64_args, T_void()));
7337+
72897338
auto trap = decl_cdecl_fn(llmod, "llvm.trap",
72907339
T_fn(T_trap_args, T_void()));
72917340

72927341
auto intrinsics = new_str_hash[ValueRef]();
7342+
intrinsics.insert("llvm.memcpy.p0i8.p0i8.i32", memcpy32);
7343+
intrinsics.insert("llvm.memcpy.p0i8.p0i8.i64", memcpy64);
7344+
intrinsics.insert("llvm.memset.p0i8.i32", memset32);
7345+
intrinsics.insert("llvm.memset.p0i8.i64", memset64);
72937346
intrinsics.insert("llvm.trap", trap);
72947347
ret intrinsics;
72957348
}
@@ -7324,91 +7377,6 @@ fn make_no_op_type_glue(ValueRef fun) {
73247377
new_builder(llbb).RetVoid();
73257378
}
73267379

7327-
fn decl_memcpy_glue(ModuleRef llmod) -> ValueRef {
7328-
auto p8 = T_ptr(T_i8());
7329-
7330-
auto ty = T_fn(vec(p8, p8, T_int()), T_void());
7331-
ret decl_fastcall_fn(llmod, abi.memcpy_glue_name(), ty);
7332-
}
7333-
7334-
fn make_memcpy_glue(ValueRef fun) {
7335-
// We're not using the LLVM memcpy intrinsic. It appears to call through
7336-
// to the platform memcpy in some cases, which is not terribly safe to run
7337-
// on a rust stack.
7338-
auto initbb = llvm.LLVMAppendBasicBlock(fun, Str.buf("init"));
7339-
auto hdrbb = llvm.LLVMAppendBasicBlock(fun, Str.buf("hdr"));
7340-
auto loopbb = llvm.LLVMAppendBasicBlock(fun, Str.buf("loop"));
7341-
auto endbb = llvm.LLVMAppendBasicBlock(fun, Str.buf("end"));
7342-
7343-
auto dst = llvm.LLVMGetParam(fun, 0u);
7344-
auto src = llvm.LLVMGetParam(fun, 1u);
7345-
auto count = llvm.LLVMGetParam(fun, 2u);
7346-
7347-
// Init block.
7348-
auto ib = new_builder(initbb);
7349-
auto ip = ib.Alloca(T_int());
7350-
ib.Store(C_int(0), ip);
7351-
ib.Br(hdrbb);
7352-
7353-
// Loop-header block
7354-
auto hb = new_builder(hdrbb);
7355-
auto i = hb.Load(ip);
7356-
hb.CondBr(hb.ICmp(lib.llvm.LLVMIntEQ, count, i), endbb, loopbb);
7357-
7358-
// Loop-body block
7359-
auto lb = new_builder(loopbb);
7360-
i = lb.Load(ip);
7361-
lb.Store(lb.Load(lb.GEP(src, vec(i))),
7362-
lb.GEP(dst, vec(i)));
7363-
lb.Store(lb.Add(i, C_int(1)), ip);
7364-
lb.Br(hdrbb);
7365-
7366-
// End block
7367-
auto eb = new_builder(endbb);
7368-
eb.RetVoid();
7369-
}
7370-
7371-
fn decl_bzero_glue(ModuleRef llmod) -> ValueRef {
7372-
auto p8 = T_ptr(T_i8());
7373-
7374-
auto ty = T_fn(vec(p8, T_int()), T_void());
7375-
ret decl_fastcall_fn(llmod, abi.bzero_glue_name(), ty);
7376-
}
7377-
7378-
fn make_bzero_glue(ValueRef fun) -> ValueRef {
7379-
// We're not using the LLVM memset intrinsic. Same as with memcpy.
7380-
auto initbb = llvm.LLVMAppendBasicBlock(fun, Str.buf("init"));
7381-
auto hdrbb = llvm.LLVMAppendBasicBlock(fun, Str.buf("hdr"));
7382-
auto loopbb = llvm.LLVMAppendBasicBlock(fun, Str.buf("loop"));
7383-
auto endbb = llvm.LLVMAppendBasicBlock(fun, Str.buf("end"));
7384-
7385-
auto dst = llvm.LLVMGetParam(fun, 0u);
7386-
auto count = llvm.LLVMGetParam(fun, 1u);
7387-
7388-
// Init block.
7389-
auto ib = new_builder(initbb);
7390-
auto ip = ib.Alloca(T_int());
7391-
ib.Store(C_int(0), ip);
7392-
ib.Br(hdrbb);
7393-
7394-
// Loop-header block
7395-
auto hb = new_builder(hdrbb);
7396-
auto i = hb.Load(ip);
7397-
hb.CondBr(hb.ICmp(lib.llvm.LLVMIntEQ, count, i), endbb, loopbb);
7398-
7399-
// Loop-body block
7400-
auto lb = new_builder(loopbb);
7401-
i = lb.Load(ip);
7402-
lb.Store(C_u8(0u), lb.GEP(dst, vec(i)));
7403-
lb.Store(lb.Add(i, C_int(1)), ip);
7404-
lb.Br(hdrbb);
7405-
7406-
// End block
7407-
auto eb = new_builder(endbb);
7408-
eb.RetVoid();
7409-
ret fun;
7410-
}
7411-
74127380
fn make_vec_append_glue(ModuleRef llmod, type_names tn) -> ValueRef {
74137381
/*
74147382
* Args to vec_append_glue:
@@ -7559,6 +7527,13 @@ fn trans_vec_append_glue(@local_ctxt cx) {
75597527
C_int(abi.tydesc_field_size))));
75607528
llvm.LLVMSetValueName(elt_llsz, Str.buf("elt_llsz"));
75617529

7530+
auto elt_llalign =
7531+
cx.build.Load(cx.build.GEP(elt_tydesc,
7532+
vec(C_int(0),
7533+
C_int(abi.tydesc_field_align))));
7534+
llvm.LLVMSetValueName(elt_llsz, Str.buf("elt_llalign"));
7535+
7536+
75627537
fn take_one(ValueRef elt_tydesc,
75637538
@block_ctxt cx,
75647539
ValueRef dst, ValueRef src) -> result {
@@ -7572,7 +7547,7 @@ fn trans_vec_append_glue(@local_ctxt cx) {
75727547
elt_llsz, bind take_one(elt_tydesc,
75737548
_, _, _)).bcx;
75747549

7575-
ret call_memcpy(bcx, dst, src, n_bytes);
7550+
ret call_memcpy(bcx, dst, src, n_bytes, elt_llalign);
75767551
}
75777552

75787553
// Copy any dst elements in, omitting null if doing str.
@@ -7637,8 +7612,6 @@ fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
76377612
Vec.init_fn[ValueRef](bind decl_native_glue(llmod, tn,
76387613
abi.ngt_cdecl, _), abi.n_native_glues + 1 as uint),
76397614
no_op_type_glue = decl_no_op_type_glue(llmod, tn),
7640-
memcpy_glue = decl_memcpy_glue(llmod),
7641-
bzero_glue = decl_bzero_glue(llmod),
76427615
vec_append_glue = make_vec_append_glue(llmod, tn));
76437616
}
76447617

@@ -7663,8 +7636,6 @@ fn make_common_glue(session.session sess, str output) {
76637636

76647637
auto glues = make_glues(llmod, tn);
76657638
create_crate_constant(crate_ptr, glues);
7666-
make_memcpy_glue(glues.memcpy_glue);
7667-
make_bzero_glue(glues.bzero_glue);
76687639

76697640
trans.trans_exit_task_glue(glues, new_str_hash[ValueRef](), tn,
76707641
llmod);

0 commit comments

Comments
 (0)