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.
This commit is contained in:
parent
512cfb4b83
commit
dbf472b0df
|
@ -317,18 +317,12 @@ fn decl_cdecl_fn(llmod: ModuleRef, name: str, llty: TypeRef) -> ValueRef {
|
|||
ret decl_fn(llmod, name, lib::llvm::LLVMCCallConv, llty);
|
||||
}
|
||||
|
||||
fn decl_fastcall_fn(llmod: ModuleRef, name: str, llty: TypeRef) -> ValueRef {
|
||||
let llfn = decl_fn(llmod, name, lib::llvm::LLVMFastCallConv, llty);
|
||||
let _: () = str::as_buf("rust", {|buf| llvm::LLVMSetGC(llfn, buf) });
|
||||
ret llfn;
|
||||
}
|
||||
|
||||
|
||||
// Only use this if you are going to actually define the function. It's
|
||||
// not valid to simply declare a function as internal.
|
||||
fn decl_internal_fastcall_fn(llmod: ModuleRef, name: str, llty: TypeRef) ->
|
||||
fn decl_internal_cdecl_fn(llmod: ModuleRef, name: str, llty: TypeRef) ->
|
||||
ValueRef {
|
||||
let llfn = decl_fastcall_fn(llmod, name, llty);
|
||||
let llfn = decl_cdecl_fn(llmod, name, llty);
|
||||
llvm::LLVMSetLinkage(llfn,
|
||||
lib::llvm::LLVMInternalLinkage as llvm::Linkage);
|
||||
ret llfn;
|
||||
|
@ -1454,7 +1448,7 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id,
|
|||
(llvm::LLVMGetElementType
|
||||
(llvm::LLVMTypeOf(dtor_addr)))[std::vec::len(args)];
|
||||
let val_cast = BitCast(cx, val.val, val_llty);
|
||||
FastCall(cx, dtor_addr, args + [val_cast]);
|
||||
Call(cx, dtor_addr, args + [val_cast]);
|
||||
|
||||
cx = drop_ty(cx, val.val, inner_t_s);
|
||||
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,
|
|||
let iter_body_llty =
|
||||
type_of_fn_from_ty(ccx, cx.sp, iter_body_fn, 0u);
|
||||
let lliterbody: ValueRef =
|
||||
decl_internal_fastcall_fn(ccx.llmod, s, iter_body_llty);
|
||||
decl_internal_cdecl_fn(ccx.llmod, s, iter_body_llty);
|
||||
let fcx = new_fn_ctxt_w_id(lcx, cx.sp, lliterbody, body.node.id,
|
||||
ast::return_val);
|
||||
fcx.iterbodyty = cx.fcx.iterbodyty;
|
||||
|
@ -3418,8 +3412,7 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
|
|||
// Give the thunk a name, type, and value.
|
||||
let s: str = mangle_internal_name_by_path_and_seq(ccx, cx.path, "thunk");
|
||||
let llthunk_ty: TypeRef = get_pair_fn_ty(type_of(ccx, sp, incoming_fty));
|
||||
let llthunk: ValueRef =
|
||||
decl_internal_fastcall_fn(ccx.llmod, s, llthunk_ty);
|
||||
let llthunk: ValueRef = decl_internal_cdecl_fn(ccx.llmod, s, llthunk_ty);
|
||||
|
||||
// Create a new function context and block context for the thunk, and hold
|
||||
// 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,
|
|||
let lltargetty =
|
||||
type_of_fn_from_ty(ccx, sp, outgoing_fty, ty_param_count);
|
||||
lltargetfn = PointerCast(bcx, lltargetfn, T_ptr(lltargetty));
|
||||
FastCall(bcx, lltargetfn, llargs);
|
||||
Call(bcx, lltargetfn, llargs);
|
||||
build_return(bcx);
|
||||
finish_fn(fcx, lltop);
|
||||
ret {val: llthunk, ty: llthunk_ty};
|
||||
|
@ -3869,8 +3862,8 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
|
|||
type _|_. Since that means it diverges, the code
|
||||
for the call itself is unreachable. */
|
||||
let retval = C_nil();
|
||||
bcx = invoke_fastcall(bcx, faddr, llargs,
|
||||
args_res.to_zero, args_res.to_revoke);
|
||||
bcx = invoke_full(bcx, faddr, llargs, args_res.to_zero,
|
||||
args_res.to_revoke);
|
||||
alt lliterbody {
|
||||
none. {
|
||||
if !ty::type_is_nil(tcx, ret_ty) {
|
||||
|
@ -3922,14 +3915,10 @@ fn invoke(bcx: @block_ctxt, llfn: ValueRef,
|
|||
ret invoke_(bcx, llfn, llargs, [], [], Invoke);
|
||||
}
|
||||
|
||||
fn invoke_fastcall(bcx: @block_ctxt, llfn: ValueRef,
|
||||
llargs: [ValueRef],
|
||||
to_zero: [{v: ValueRef, t: ty::t}],
|
||||
to_revoke: [{v: ValueRef, t: ty::t}])
|
||||
-> @block_ctxt {
|
||||
ret invoke_(bcx, llfn, llargs,
|
||||
to_zero, to_revoke,
|
||||
FastInvoke);
|
||||
fn invoke_full(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef],
|
||||
to_zero: [{v: ValueRef, t: ty::t}],
|
||||
to_revoke: [{v: ValueRef, t: ty::t}]) -> @block_ctxt {
|
||||
ret invoke_(bcx, llfn, llargs, to_zero, to_revoke, Invoke);
|
||||
}
|
||||
|
||||
fn invoke_(bcx: @block_ctxt, llfn: ValueRef, llargs: [ValueRef],
|
||||
|
@ -4129,7 +4118,7 @@ fn trans_expr(cx: @block_ctxt, e: @ast::expr) -> result {
|
|||
type_of_fn_from_ty(ccx, e.span, fty, 0u);
|
||||
let sub_cx = extend_path(cx.fcx.lcx, ccx.names.next("anon"));
|
||||
let s = mangle_internal_name_by_path(ccx, sub_cx.path);
|
||||
let llfn = decl_internal_fastcall_fn(ccx.llmod, s, llfnty);
|
||||
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
|
||||
|
||||
let fn_res =
|
||||
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 {
|
|||
llargs += [r.val];
|
||||
}
|
||||
}
|
||||
bcx = invoke_fastcall(bcx, llcallee, llargs, [], []);
|
||||
bcx = invoke(bcx, llcallee, llargs);
|
||||
bcx = trans_block_cleanups(bcx, cx);
|
||||
let next_cx = new_sub_block_ctxt(in_cx, "next");
|
||||
if bcx.unreachable { Unreachable(next_cx); }
|
||||
|
@ -5557,7 +5546,7 @@ fn register_fn_full(ccx: @crate_ctxt, sp: span, path: [str], _flav: str,
|
|||
_ { ccx.sess.bug("register_fn(): fn item doesn't have fn type!"); }
|
||||
}
|
||||
let ps: str = mangle_exported_name(ccx, path, node_type);
|
||||
let llfn: ValueRef = decl_fastcall_fn(ccx.llmod, ps, llfty);
|
||||
let llfn: ValueRef = decl_cdecl_fn(ccx.llmod, ps, llfty);
|
||||
ccx.item_ids.insert(node_id, llfn);
|
||||
ccx.item_symbols.insert(node_id, ps);
|
||||
|
||||
|
@ -5594,7 +5583,8 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
|
|||
|
||||
let llfty = type_of_fn(ccx, sp, ast::proto_fn, false, false,
|
||||
[vecarg_ty], nt, 0u);
|
||||
let llfdecl = decl_fastcall_fn(ccx.llmod, "_rust_main", llfty);
|
||||
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
|
||||
lib::llvm::LLVMFastCallConv, llfty);
|
||||
|
||||
let fcx = new_fn_ctxt(new_local_ctxt(ccx), sp, llfdecl);
|
||||
|
||||
|
@ -5613,7 +5603,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
|
|||
llargvarg = PointerCast(bcx, llargvarg, minus_ptr);
|
||||
args += [do_spill_noroot(bcx, llargvarg)];
|
||||
}
|
||||
FastCall(bcx, main_llfn, args);
|
||||
Call(bcx, main_llfn, args);
|
||||
build_return(bcx);
|
||||
|
||||
finish_fn(fcx, lltop);
|
||||
|
@ -5676,7 +5666,7 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
|
|||
let t = node_id_type(ccx, id);
|
||||
let wrapper_type = native_fn_wrapper_type(ccx, sp, num_ty_param, t);
|
||||
let ps: str = mangle_exported_name(ccx, path, node_id_type(ccx, id));
|
||||
let wrapper_fn = decl_fastcall_fn(ccx.llmod, ps, wrapper_type);
|
||||
let wrapper_fn = decl_cdecl_fn(ccx.llmod, ps, wrapper_type);
|
||||
ccx.item_ids.insert(id, wrapper_fn);
|
||||
ccx.item_symbols.insert(id, ps);
|
||||
|
||||
|
@ -6048,7 +6038,7 @@ fn trap(bcx: @block_ctxt) {
|
|||
|
||||
fn decl_no_op_type_glue(llmod: ModuleRef, taskptr_type: TypeRef) -> ValueRef {
|
||||
let ty = T_fn([taskptr_type, T_ptr(T_i8())], T_void());
|
||||
ret decl_fastcall_fn(llmod, abi::no_op_type_glue_name(), ty);
|
||||
ret decl_cdecl_fn(llmod, abi::no_op_type_glue_name(), ty);
|
||||
}
|
||||
|
||||
fn make_glues(llmod: ModuleRef, taskptr_type: TypeRef) -> @glue_fns {
|
||||
|
|
|
@ -604,8 +604,7 @@ fn begin_fn(cx: @local_ctxt, sp: span, m: @ty::method,
|
|||
|
||||
// Get the function's type and declare it.
|
||||
let llfn_ty: TypeRef = type_of_meth(cx.ccx, sp, m, ty_params);
|
||||
let llfn: ValueRef =
|
||||
decl_internal_fastcall_fn(cx.ccx.llmod, s, llfn_ty);
|
||||
let llfn: ValueRef = decl_internal_cdecl_fn(cx.ccx.llmod, s, llfn_ty);
|
||||
|
||||
ret llfn;
|
||||
}
|
||||
|
@ -706,7 +705,7 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
|
|||
}
|
||||
|
||||
// And, finally, call the outer method.
|
||||
FastCall(bcx, llouter_mthd, llouter_mthd_args);
|
||||
Call(bcx, llouter_mthd, llouter_mthd_args);
|
||||
|
||||
build_return(bcx);
|
||||
finish_fn(fcx, lltop);
|
||||
|
@ -858,7 +857,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
|
|||
}
|
||||
|
||||
// And, finally, call the original (inner) method.
|
||||
FastCall(bcx, llorig_mthd, llorig_mthd_args);
|
||||
Call(bcx, llorig_mthd, llorig_mthd_args);
|
||||
|
||||
build_return(bcx);
|
||||
finish_fn(fcx, lltop);
|
||||
|
@ -911,7 +910,7 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
|
|||
let mcx: @local_ctxt =
|
||||
@{path: cx.path + ["method", m.node.ident] with *cx};
|
||||
let s: str = mangle_internal_name_by_path(mcx.ccx, mcx.path);
|
||||
let llfn: ValueRef = decl_internal_fastcall_fn(ccx.llmod, s, llfnty);
|
||||
let llfn: ValueRef = decl_internal_cdecl_fn(ccx.llmod, s, llfnty);
|
||||
|
||||
// Every method on an object gets its node_id inserted into the crate-wide
|
||||
// item_ids map, together with the ValueRef that points to where that
|
||||
|
|
|
@ -29,7 +29,7 @@ define void @_rust_main_wrap(i1* nocapture, %task *, %2* nocapture, %vec *)
|
|||
define void @_rust_spawn_wrap(
|
||||
i1* nocapture, %task*, %2* nocapture, %nullary_fn* %f)
|
||||
{
|
||||
call fastcc void %f(i1* %0, %task *%1, %2* nocapture %2)
|
||||
call void %f(i1* %0, %task *%1, %2* nocapture %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue