Skip to content

Commit dbf472b

Browse files
committed
rustc: Switch to cdecl for all calls. This is needed to make stack growth efficient, as I need to use eax and ecx in the function prologue and can't afford to stomp on incoming arguments.
1 parent 512cfb4 commit dbf472b

File tree

3 files changed

+25
-36
lines changed

3 files changed

+25
-36
lines changed

src/comp/middle/trans.rs

+20-30
Original file line numberDiff line numberDiff line change
@@ -317,18 +317,12 @@ fn decl_cdecl_fn(llmod: ModuleRef, name: str, llty: TypeRef) -> ValueRef {
317317
ret decl_fn(llmod, name, lib::llvm::LLVMCCallConv, llty);
318318
}
319319

320-
fn decl_fastcall_fn(llmod: ModuleRef, name: str, llty: TypeRef) -> ValueRef {
321-
let llfn = decl_fn(llmod, name, lib::llvm::LLVMFastCallConv, llty);
322-
let _: () = str::as_buf("rust", {|buf| llvm::LLVMSetGC(llfn, buf) });
323-
ret llfn;
324-
}
325-
326320

327321
// Only use this if you are going to actually define the function. It's
328322
// not valid to simply declare a function as internal.
329-
fn decl_internal_fastcall_fn(llmod: ModuleRef, name: str, llty: TypeRef) ->
323+
fn decl_internal_cdecl_fn(llmod: ModuleRef, name: str, llty: TypeRef) ->
330324
ValueRef {
331-
let llfn = decl_fastcall_fn(llmod, name, llty);
325+
let llfn = decl_cdecl_fn(llmod, name, llty);
332326
llvm::LLVMSetLinkage(llfn,
333327
lib::llvm::LLVMInternalLinkage as llvm::Linkage);
334328
ret llfn;
@@ -1454,7 +1448,7 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id,
14541448
(llvm::LLVMGetElementType
14551449
(llvm::LLVMTypeOf(dtor_addr)))[std::vec::len(args)];
14561450
let val_cast = BitCast(cx, val.val, val_llty);
1457-
FastCall(cx, dtor_addr, args + [val_cast]);
1451+
Call(cx, dtor_addr, args + [val_cast]);
14581452

14591453
cx = drop_ty(cx, val.val, inner_t_s);
14601454
Store(cx, C_int(0), drop_flag.val);
@@ -2861,7 +2855,7 @@ fn trans_for_each(cx: @block_ctxt, local: @ast::local, seq: @ast::expr,
28612855
let iter_body_llty =
28622856
type_of_fn_from_ty(ccx, cx.sp, iter_body_fn, 0u);
28632857
let lliterbody: ValueRef =
2864-
decl_internal_fastcall_fn(ccx.llmod, s, iter_body_llty);
2858+
decl_internal_cdecl_fn(ccx.llmod, s, iter_body_llty);
28652859
let fcx = new_fn_ctxt_w_id(lcx, cx.sp, lliterbody, body.node.id,
28662860
ast::return_val);
28672861
fcx.iterbodyty = cx.fcx.iterbodyty;
@@ -3418,8 +3412,7 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
34183412
// Give the thunk a name, type, and value.
34193413
let s: str = mangle_internal_name_by_path_and_seq(ccx, cx.path, "thunk");
34203414
let llthunk_ty: TypeRef = get_pair_fn_ty(type_of(ccx, sp, incoming_fty));
3421-
let llthunk: ValueRef =
3422-
decl_internal_fastcall_fn(ccx.llmod, s, llthunk_ty);
3415+
let llthunk: ValueRef = decl_internal_cdecl_fn(ccx.llmod, s, llthunk_ty);
34233416

34243417
// Create a new function context and block context for the thunk, and hold
34253418
// onto a pointer to the first block in the function for later use.
@@ -3559,7 +3552,7 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
35593552
let lltargetty =
35603553
type_of_fn_from_ty(ccx, sp, outgoing_fty, ty_param_count);
35613554
lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty));
3562-
FastCall(bcx, lltargetfn, llargs);
3555+
Call(bcx, lltargetfn, llargs);
35633556
build_return(bcx);
35643557
finish_fn(fcx, lltop);
35653558
ret {val: llthunk, ty: llthunk_ty};
@@ -3869,8 +3862,8 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
38693862
type _|_. Since that means it diverges, the code
38703863
for the call itself is unreachable. */
38713864
let retval = C_nil();
3872-
bcx = invoke_fastcall(bcx, faddr, llargs,
3873-
args_res.to_zero, args_res.to_revoke);
3865+
bcx = invoke_full(bcx, faddr, llargs, args_res.to_zero,
3866+
args_res.to_revoke);
38743867
alt lliterbody {
38753868
none. {
38763869
if !ty::type_is_nil(tcx, ret_ty) {
@@ -3922,14 +3915,10 @@ fn invoke(bcx: @block_ctxt, llfn: ValueRef,
39223915
ret invoke_(bcx, llfn, llargs, [], [], Invoke);
39233916
}
39243917

3925-
fn invoke_fastcall(bcx: @block_ctxt, llfn: ValueRef,
3926-
llargs: [ValueRef],
3927-
to_zero: [{v: ValueRef, t: ty::t}],
3928-
to_revoke: [{v: ValueRef, t: ty::t}])
3929-
-> @block_ctxt {
3930-
ret invoke_(bcx, llfn, llargs,
3931-
to_zero, to_revoke,
3932-
FastInvoke);
3918+
fn invoke_full(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef],
3919+
to_zero: [{v: ValueRef, t: ty::t}],
3920+
to_revoke: [{v: ValueRef, t: ty::t}]) -> @block_ctxt {
3921+
ret invoke_(bcx, llfn, llargs, to_zero, to_revoke, Invoke);
39333922
}
39343923

39353924
fn invoke_(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef],
@@ -4129,7 +4118,7 @@ fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
41294118
type_of_fn_from_ty(ccx, e.span, fty, 0u);
41304119
let sub_cx = extend_path(cx.fcx.lcx, ccx.names.next("anon"));
41314120
let s = mangle_internal_name_by_path(ccx, sub_cx.path);
4132-
let llfn = decl_internal_fastcall_fn(ccx.llmod, s, llfnty);
4121+
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
41334122

41344123
let fn_res =
41354124
trans_closure(some(cx), some(llfnty), sub_cx, e.span, f, llfn,
@@ -4580,7 +4569,7 @@ fn trans_put(in_cx: @block_ctxt, e: option::t<@ast::expr>) -> @block_ctxt {
45804569
llargs += [r.val];
45814570
}
45824571
}
4583-
bcx = invoke_fastcall(bcx, llcallee, llargs, [], []);
4572+
bcx = invoke(bcx, llcallee, llargs);
45844573
bcx = trans_block_cleanups(bcx, cx);
45854574
let next_cx = new_sub_block_ctxt(in_cx, "next");
45864575
if bcx.unreachable { Unreachable(next_cx); }
@@ -5557,7 +5546,7 @@ fn register_fn_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
55575546
_ { ccx.sess.bug("register_fn(): fn item doesn't have fn type!"); }
55585547
}
55595548
let ps: str = mangle_exported_name(ccx, path, node_type);
5560-
let llfn: ValueRef = decl_fastcall_fn(ccx.llmod, ps, llfty);
5549+
let llfn: ValueRef = decl_cdecl_fn(ccx.llmod, ps, llfty);
55615550
ccx.item_ids.insert(node_id, llfn);
55625551
ccx.item_symbols.insert(node_id, ps);
55635552

@@ -5594,7 +5583,8 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
55945583

55955584
let llfty = type_of_fn(ccx, sp, ast::proto_fn, false, false,
55965585
[vecarg_ty], nt, 0u);
5597-
let llfdecl = decl_fastcall_fn(ccx.llmod, "_rust_main", llfty);
5586+
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
5587+
lib::llvm::LLVMFastCallConv, llfty);
55985588

55995589
let fcx = new_fn_ctxt(new_local_ctxt(ccx), sp, llfdecl);
56005590

@@ -5613,7 +5603,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
56135603
llargvarg = PointerCast(bcx, llargvarg, minus_ptr);
56145604
args += [do_spill_noroot(bcx, llargvarg)];
56155605
}
5616-
FastCall(bcx, main_llfn, args);
5606+
Call(bcx, main_llfn, args);
56175607
build_return(bcx);
56185608

56195609
finish_fn(fcx, lltop);
@@ -5676,7 +5666,7 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
56765666
let t = node_id_type(ccx, id);
56775667
let wrapper_type = native_fn_wrapper_type(ccx, sp, num_ty_param, t);
56785668
let ps: str = mangle_exported_name(ccx, path, node_id_type(ccx, id));
5679-
let wrapper_fn = decl_fastcall_fn(ccx.llmod, ps, wrapper_type);
5669+
let wrapper_fn = decl_cdecl_fn(ccx.llmod, ps, wrapper_type);
56805670
ccx.item_ids.insert(id, wrapper_fn);
56815671
ccx.item_symbols.insert(id, ps);
56825672

@@ -6048,7 +6038,7 @@ fn trap(bcx: @block_ctxt) {
60486038

60496039
fn decl_no_op_type_glue(llmod: ModuleRef, taskptr_type: TypeRef) -> ValueRef {
60506040
let ty = T_fn([taskptr_type, T_ptr(T_i8())], T_void());
6051-
ret decl_fastcall_fn(llmod, abi::no_op_type_glue_name(), ty);
6041+
ret decl_cdecl_fn(llmod, abi::no_op_type_glue_name(), ty);
60526042
}
60536043

60546044
fn make_glues(llmod: ModuleRef, taskptr_type: TypeRef) -> @glue_fns {

src/comp/middle/trans_objects.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -604,8 +604,7 @@ fn begin_fn(cx: @local_ctxt, sp: span, m: @ty::method,
604604

605605
// Get the function's type and declare it.
606606
let llfn_ty: TypeRef = type_of_meth(cx.ccx, sp, m, ty_params);
607-
let llfn: ValueRef =
608-
decl_internal_fastcall_fn(cx.ccx.llmod, s, llfn_ty);
607+
let llfn: ValueRef = decl_internal_cdecl_fn(cx.ccx.llmod, s, llfn_ty);
609608

610609
ret llfn;
611610
}
@@ -706,7 +705,7 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
706705
}
707706

708707
// And, finally, call the outer method.
709-
FastCall(bcx, llouter_mthd, llouter_mthd_args);
708+
Call(bcx, llouter_mthd, llouter_mthd_args);
710709

711710
build_return(bcx);
712711
finish_fn(fcx, lltop);
@@ -858,7 +857,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
858857
}
859858

860859
// And, finally, call the original (inner) method.
861-
FastCall(bcx, llorig_mthd, llorig_mthd_args);
860+
Call(bcx, llorig_mthd, llorig_mthd_args);
862861

863862
build_return(bcx);
864863
finish_fn(fcx, lltop);
@@ -911,7 +910,7 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
911910
let mcx: @local_ctxt =
912911
@{path: cx.path + ["method", m.node.ident] with *cx};
913912
let s: str = mangle_internal_name_by_path(mcx.ccx, mcx.path);
914-
let llfn: ValueRef = decl_internal_fastcall_fn(ccx.llmod, s, llfnty);
913+
let llfn: ValueRef = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
915914

916915
// Every method on an object gets its node_id inserted into the crate-wide
917916
// item_ids map, together with the ValueRef that points to where that

src/rt/main.ll.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ define void @_rust_main_wrap(i1* nocapture, %task *, %2* nocapture, %vec *)
2929
define void @_rust_spawn_wrap(
3030
i1* nocapture, %task*, %2* nocapture, %nullary_fn* %f)
3131
{
32-
call fastcc void %f(i1* %0, %task *%1, %2* nocapture %2)
32+
call void %f(i1* %0, %task *%1, %2* nocapture %2)
3333
ret void
3434
}
3535

0 commit comments

Comments
 (0)