Skip to content

Remove unused implicit argument for functions that return immediate values #6731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 29, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1612,10 +1612,11 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
}
};
let is_immediate = ty::type_is_immediate(substd_output_type);

let fcx = @mut fn_ctxt_ {
llfn: llfndecl,
llenv: unsafe { llvm::LLVMGetParam(llfndecl, 1u as c_uint) },
llenv: unsafe {
llvm::LLVMGetUndef(T_ptr(T_i8()))
},
llretptr: None,
llstaticallocas: llbbs.sa,
llloadenv: None,
Expand All @@ -1634,7 +1635,9 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
path: path,
ccx: @ccx
};

fcx.llenv = unsafe {
llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
};
fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type));
fcx
}
Expand Down Expand Up @@ -1690,7 +1693,7 @@ pub fn create_llargs_for_fn_args(cx: fn_ctxt,
// llvm::LLVMGetParam for each argument.
vec::from_fn(args.len(), |i| {
unsafe {
let arg_n = first_real_arg + i;
let arg_n = cx.arg_pos(i);
let arg = &args[i];
let llarg = llvm::LLVMGetParam(cx.llfn, arg_n as c_uint);

Expand Down Expand Up @@ -2293,19 +2296,26 @@ pub fn create_entry_wrapper(ccx: @CrateContext,

fn create_main(ccx: @CrateContext, main_llfn: ValueRef) -> ValueRef {
let nt = ty::mk_nil();

let llfty = type_of_fn(ccx, [], nt);
let llfdecl = decl_fn(ccx.llmod, "_rust_main",
lib::llvm::CCallConv, llfty);

let fcx = new_fn_ctxt(ccx, ~[], llfdecl, nt, None);

// the args vector built in create_entry_fn will need
// be updated if this assertion starts to fail.
assert!(fcx.has_immediate_return_value);

let bcx = top_scope_block(fcx, None);
let lltop = bcx.llbb;

// Call main.
let lloutputarg = C_null(T_ptr(T_i8()));
let llenvarg = unsafe { llvm::LLVMGetParam(llfdecl, 1 as c_uint) };
let args = ~[lloutputarg, llenvarg];
let llenvarg = unsafe {
let env_arg = fcx.env_arg_pos();
llvm::LLVMGetParam(llfdecl, env_arg as c_uint)
};
let args = ~[llenvarg];
let llresult = Call(bcx, main_llfn, args);
Store(bcx, llresult, fcx.llretptr.get());

Expand Down Expand Up @@ -2347,8 +2357,6 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
trans_external_path(ccx, start_def_id, start_fn_type);
}

let retptr = llvm::LLVMBuildAlloca(bld, T_i8(), noname());

let crate_map = ccx.crate_map;
let opaque_crate_map = llvm::LLVMBuildPointerCast(bld,
crate_map,
Expand All @@ -2371,7 +2379,6 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
bld, rust_main, T_ptr(T_i8()), noname());

~[
retptr,
C_null(T_opaque_box_ptr(ccx)),
opaque_rust_main,
llvm::LLVMGetParam(llfn, 0),
Expand All @@ -2384,7 +2391,6 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
debug!("using user-defined start fn");
let args = {
~[
retptr,
C_null(T_opaque_box_ptr(ccx)),
llvm::LLVMGetParam(llfn, 0 as c_uint),
llvm::LLVMGetParam(llfn, 1 as c_uint),
Expand Down
6 changes: 1 addition & 5 deletions src/librustc/middle/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,7 @@ pub fn trans_call_inner(in_cx: block,

let mut llargs = ~[];

if ty::type_is_immediate(ret_ty) {
unsafe {
llargs.push(llvm::LLVMGetUndef(T_ptr(T_i8())));
}
} else {
if !ty::type_is_immediate(ret_ty) {
llargs.push(llretslot);
}

Expand Down
30 changes: 25 additions & 5 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,30 @@ pub struct fn_ctxt_ {
ccx: @@CrateContext
}

pub impl fn_ctxt_ {
pub fn arg_pos(&self, arg: uint) -> uint {
if self.has_immediate_return_value {
arg + 1u
} else {
arg + 2u
}
}

pub fn out_arg_pos(&self) -> uint {
assert!(self.has_immediate_return_value);
0u
}

pub fn env_arg_pos(&self) -> uint {
if !self.has_immediate_return_value {
1u
} else {
0u
}
}

}

pub type fn_ctxt = @mut fn_ctxt_;

pub fn warn_not_to_commit(ccx: @CrateContext, msg: &str) {
Expand Down Expand Up @@ -660,9 +684,6 @@ pub fn mk_block(llbb: BasicBlockRef, parent: Option<block>, kind: block_kind,
@mut block_(llbb, parent, kind, is_lpad, node_info, fcx)
}

// First two args are retptr, env
pub static first_real_arg: uint = 2u;

pub struct Result {
bcx: block,
val: ValueRef
Expand Down Expand Up @@ -962,8 +983,7 @@ pub fn T_tydesc(targ_cfg: @session::config) -> TypeRef {
let tydescpp = T_ptr(T_ptr(tydesc));
let pvoid = T_ptr(T_i8());
let glue_fn_ty =
T_ptr(T_fn([T_ptr(T_nil()), T_ptr(T_nil()), tydescpp,
pvoid], T_void()));
T_ptr(T_fn([T_ptr(T_nil()), tydescpp, pvoid], T_void()));

let int_type = T_int(targ_cfg);
let elems =
Expand Down
16 changes: 8 additions & 8 deletions src/librustc/middle/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ fn build_shim_fn_(ccx: @CrateContext,
let fcx = new_fn_ctxt(ccx, ~[], llshimfn, tys.fn_sig.output, None);
let bcx = top_scope_block(fcx, None);
let lltop = bcx.llbb;

let llargbundle = get_param(llshimfn, 0u);
let llargvals = arg_builder(bcx, tys, llargbundle);

Expand Down Expand Up @@ -437,11 +438,11 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
let llbasefn = base_fn(ccx, *link_name(ccx, item), tys, cc);
let ty = ty::lookup_item_type(ccx.tcx,
ast_util::local_def(item.id)).ty;
let ret_ty = ty::ty_fn_ret(ty);
let args = vec::from_fn(ty::ty_fn_args(ty).len(), |i| {
get_param(decl, i + first_real_arg)
get_param(decl, fcx.arg_pos(i))
});
let retval = Call(bcx, llbasefn, args);
let ret_ty = ty::ty_fn_ret(ty);
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
Store(bcx, retval, fcx.llretptr.get());
}
Expand All @@ -465,11 +466,11 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
set_fixed_stack_segment(fcx.llfn);
let ty = ty::lookup_item_type(ccx.tcx,
ast_util::local_def(item.id)).ty;
let ret_ty = ty::ty_fn_ret(ty);
let args = vec::from_fn(ty::ty_fn_args(ty).len(), |i| {
get_param(decl, i + first_real_arg)
get_param(decl, fcx.arg_pos(i))
});
let retval = Call(bcx, llbasefn, args);
let ret_ty = ty::ty_fn_ret(ty);
if !ty::type_is_nil(ret_ty) && !ty::type_is_bot(ret_ty) {
Store(bcx, retval, fcx.llretptr.get());
}
Expand Down Expand Up @@ -512,9 +513,9 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
let _icx = bcx.insn_ctxt("foreign::wrap::build_args");
let ccx = bcx.ccx();
let n = tys.llsig.llarg_tys.len();
let implicit_args = first_real_arg; // return + env
for uint::range(0, n) |i| {
let mut llargval = get_param(llwrapfn, i + implicit_args);
let arg_i = bcx.fcx.arg_pos(i);
let mut llargval = get_param(llwrapfn, arg_i);

// In some cases, Rust will pass a pointer which the
// native C type doesn't have. In that case, just
Expand Down Expand Up @@ -568,6 +569,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,

let mut bcx = top_scope_block(fcx, None);
let lltop = bcx.llbb;
let first_real_arg = fcx.arg_pos(0u);
match *ccx.sess.str_of(item.ident) {
~"atomic_cxchg" => {
let old = AtomicCmpXchg(bcx,
Expand Down Expand Up @@ -1269,8 +1271,6 @@ pub fn trans_foreign_fn(ccx: @CrateContext,
if !ty::type_is_immediate(tys.fn_sig.output) {
let llretptr = load_inbounds(bcx, llargbundle, [0u, n]);
llargvals.push(llretptr);
} else {
llargvals.push(C_null(T_ptr(T_i8())));
}

let llenvptr = C_null(T_opaque_box_ptr(bcx.ccx()));
Expand Down
18 changes: 10 additions & 8 deletions src/librustc/middle/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use back::link::*;
use driver::session;
use lib;
use lib::llvm::{llvm, ValueRef, TypeRef, True};
use lib::llvm::type_to_str;
use middle::trans::adt;
use middle::trans::base::*;
use middle::trans::callee;
Expand Down Expand Up @@ -381,8 +382,9 @@ pub fn call_tydesc_glue_full(bcx: block,
}
};

Call(bcx, llfn, [C_null(T_ptr(T_nil())), C_null(T_ptr(T_nil())),
C_null(T_ptr(T_ptr(bcx.ccx().tydesc_type))), llrawptr]);
Call(bcx, llfn, [C_null(T_ptr(T_nil())),
C_null(T_ptr(T_ptr(bcx.ccx().tydesc_type))),
llrawptr]);
}

// See [Note-arg-mode]
Expand Down Expand Up @@ -483,17 +485,16 @@ pub fn trans_struct_drop(bcx: block,
};

// Class dtors have no explicit args, so the params should
// just consist of the output pointer and the environment
// (self)
assert_eq!(params.len(), 2);
// just consist of the environment (self)
assert_eq!(params.len(), 1);

// Take a reference to the class (because it's using the Drop trait),
// do so now.
let llval = alloca(bcx, val_ty(v0));
Store(bcx, v0, llval);

let self_arg = PointerCast(bcx, llval, params[1]);
let args = ~[C_null(T_ptr(T_i8())), self_arg];
let self_arg = PointerCast(bcx, llval, params[0]);
let args = ~[self_arg];

Call(bcx, dtor_addr, args);

Expand Down Expand Up @@ -739,7 +740,8 @@ pub fn make_generic_glue_inner(ccx: @CrateContext,

let bcx = top_scope_block(fcx, None);
let lltop = bcx.llbb;
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, 3u as c_uint) };
let rawptr0_arg = fcx.arg_pos(1u);
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
helper(bcx, llrawptr0, t);
finish_fn(fcx, lltop);
return llfn;
Expand Down
11 changes: 8 additions & 3 deletions src/librustc/middle/trans/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,19 @@ pub impl Reflector {

let llfty = type_of_fn(ccx, [opaqueptrty], ty::mk_int());
let llfdecl = decl_internal_cdecl_fn(ccx.llmod, sym, llfty);
let arg = unsafe {
llvm::LLVMGetParam(llfdecl, first_real_arg as c_uint)
};
let fcx = new_fn_ctxt(ccx,
~[],
llfdecl,
ty::mk_uint(),
None);
let arg = unsafe {
//
// we know the return type of llfdecl is an int here, so
// no need for a special check to see if the return type
// is immediate.
//
llvm::LLVMGetParam(llfdecl, fcx.arg_pos(0u) as c_uint)
};
let bcx = top_scope_block(fcx, None);
let arg = BitCast(bcx, arg, llptrty);
let ret = adt::trans_get_discr(bcx, repr, arg);
Expand Down
9 changes: 2 additions & 7 deletions src/librustc/middle/trans/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ pub fn type_of_fn(cx: @CrateContext, inputs: &[ty::t], output: ty::t)
let lloutputtype = type_of(cx, output);
if !output_is_immediate {
atys.push(T_ptr(lloutputtype));
} else {
// FIXME #6575: Eliminate this.
atys.push(T_ptr(T_i8()));
}

// Arg 1: Environment
Expand Down Expand Up @@ -334,9 +331,7 @@ pub fn llvm_type_name(cx: @CrateContext,
}

pub fn type_of_dtor(ccx: @CrateContext, self_ty: ty::t) -> TypeRef {
T_fn([T_ptr(T_i8()), // output pointer
T_ptr(type_of(ccx, self_ty))], // self arg
T_nil())
T_fn([T_ptr(type_of(ccx, self_ty))] /* self */, T_nil())
}

pub fn type_of_rooted(ccx: @CrateContext, t: ty::t) -> TypeRef {
Expand All @@ -349,5 +344,5 @@ pub fn type_of_rooted(ccx: @CrateContext, t: ty::t) -> TypeRef {
pub fn type_of_glue_fn(ccx: @CrateContext, t: ty::t) -> TypeRef {
let tydescpp = T_ptr(T_ptr(ccx.tydesc_type));
let llty = T_ptr(type_of(ccx, t));
return T_fn([T_ptr(T_nil()), T_ptr(T_nil()), tydescpp, llty], T_nil());
return T_fn([T_ptr(T_nil()), tydescpp, llty], T_nil());
}
11 changes: 11 additions & 0 deletions src/rt/rust_builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,10 +731,17 @@ rust_task_deref(rust_task *task) {
// Must call on rust stack.
extern "C" CDECL void
rust_call_tydesc_glue(void *root, size_t *tydesc, size_t glue_index) {
#ifdef _RUST_STAGE0
void (*glue_fn)(void *, void *, void *, void *) =
(void (*)(void *, void *, void *, void *))tydesc[glue_index];
if (glue_fn)
glue_fn(0, 0, 0, root);
#else
void (*glue_fn)(void *, void *, void *) =
(void (*)(void *, void *, void *))tydesc[glue_index];
if (glue_fn)
glue_fn(0, 0, root);
#endif
}

// Don't run on the Rust stack!
Expand All @@ -754,7 +761,11 @@ class raw_thread: public rust_thread {

virtual void run() {
record_sp_limit(0);
#ifdef _RUST_STAGE0
fn.f(NULL, fn.env, NULL);
#else
fn.f(fn.env, NULL);
#endif
}
};

Expand Down
12 changes: 9 additions & 3 deletions src/rt/rust_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,11 @@ void task_start_wrapper(spawn_args *a)

bool threw_exception = false;
try {
// The first argument is the return pointer; as the task fn
// must have void return type, we can safely pass 0.
a->f(0, a->envptr, a->argptr);
#ifdef _RUST_STAGE0
a->f(NULL, a->envptr, a->argptr);
#else
a->f(a->envptr, a->argptr);
#endif
} catch (rust_task *ex) {
assert(ex == task && "Expected this task to be thrown for unwinding");
threw_exception = true;
Expand All @@ -185,7 +187,11 @@ void task_start_wrapper(spawn_args *a)
if(env) {
// free the environment (which should be a unique closure).
const type_desc *td = env->td;
#ifdef _RUST_STAGE0
td->drop_glue(NULL, NULL, NULL, box_body(env));
#else
td->drop_glue(NULL, NULL, box_body(env));
#endif
task->kernel->region()->free(env);
}

Expand Down
10 changes: 9 additions & 1 deletion src/rt/rust_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,19 @@ struct rust_opaque_box;
// - the main function: has a NULL environment, but uses the void* arg
// - unique closures of type fn~(): have a non-NULL environment, but
// no arguments (and hence the final void*) is harmless
typedef void (*CDECL spawn_fn)(void*, rust_opaque_box*, void *);
#ifdef _RUST_STAGE0
typedef void (*CDECL spawn_fn)(void *, rust_opaque_box*, void *);
#else
typedef void (*CDECL spawn_fn)(rust_opaque_box*, void *);
#endif

struct type_desc;

#ifdef _RUST_STAGE0
typedef void CDECL (glue_fn)(void *, void *, const type_desc **, void *);
#else
typedef void CDECL (glue_fn)(void *, const type_desc **, void *);
#endif

// Corresponds to the boxed data in the @ region. The body follows the
// header; you can obtain a ptr via box_body() below.
Expand Down