Skip to content

Commit

Permalink
librustc: Don't emit call for intrinsics instead just trans at callsite.
Browse files Browse the repository at this point in the history
  • Loading branch information
luqmana committed Jul 9, 2014
1 parent 8bb34a3 commit c6a148d
Show file tree
Hide file tree
Showing 2 changed files with 541 additions and 14 deletions.
52 changes: 38 additions & 14 deletions src/librustc/middle/trans/callee.rs
Expand Up @@ -40,6 +40,7 @@ use middle::trans::expr;
use middle::trans::glue;
use middle::trans::inline;
use middle::trans::foreign;
use middle::trans::intrinsic;
use middle::trans::meth;
use middle::trans::monomorphize;
use middle::trans::type_::Type;
Expand Down Expand Up @@ -68,6 +69,8 @@ pub enum CalleeData {
// value (which is a pair).
Fn(/* llfn */ ValueRef),

Intrinsic(ast::NodeId, subst::Substs),

TraitMethod(MethodData)
}

Expand Down Expand Up @@ -119,7 +122,21 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {

fn trans_def<'a>(bcx: &'a Block<'a>, def: def::Def, ref_expr: &ast::Expr)
-> Callee<'a> {
debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
let expr_ty = node_id_type(bcx, ref_expr.id);
match def {
def::DefFn(did, _) if match ty::get(expr_ty).sty {
ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
_ => false
} => {
let substs = node_id_substs(bcx, ExprId(ref_expr.id));
let def_id = if did.krate != ast::LOCAL_CRATE {
inline::maybe_instantiate_inline(bcx.ccx(), did)
} else {
did
};
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
}
def::DefFn(did, _) |
def::DefStaticMethod(did, def::FromImpl(_), _) => {
fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
Expand Down Expand Up @@ -662,6 +679,12 @@ pub fn trans_call_inner<'a>(
let callee = get_callee(bcx, cleanup::CustomScope(arg_cleanup_scope));
let mut bcx = callee.bcx;

let (abi, ret_ty) = match ty::get(callee_ty).sty {
ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
_ => fail!("expected bare rust fn or closure in trans_call_inner")
};

let (llfn, llenv, llself) = match callee.data {
Fn(llfn) => {
(llfn, None, None)
Expand All @@ -679,14 +702,15 @@ pub fn trans_call_inner<'a>(
let llenv = Load(bcx, llenv);
(llfn, Some(llenv), None)
}
};
Intrinsic(node, substs) => {
assert!(abi == synabi::RustIntrinsic);
assert!(dest.is_some());

let (abi, ret_ty) = match ty::get(callee_ty).sty {
ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
_ => fail!("expected bare rust fn or closure in trans_call_inner")
return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
arg_cleanup_scope, args,
dest.unwrap(), substs);
}
};
let is_rust_fn = abi == synabi::Rust || abi == synabi::RustIntrinsic;

// Generate a location to store the result. If the user does
// not care about the result, just make a stack slot.
Expand Down Expand Up @@ -716,7 +740,7 @@ pub fn trans_call_inner<'a>(
// and done, either the return value of the function will have been
// written in opt_llretslot (if it is Some) or `llresult` will be
// set appropriately (otherwise).
if is_rust_fn {
if abi == synabi::Rust {
let mut llargs = Vec::new();

// Push the out-pointer if we use an out-pointer for this
Expand Down Expand Up @@ -816,13 +840,13 @@ pub enum CallArgs<'a> {
ArgOverloadedOp(Datum<Expr>, Option<(Datum<Expr>, ast::NodeId)>),
}

fn trans_args<'a>(cx: &'a Block<'a>,
args: CallArgs,
fn_ty: ty::t,
llargs: &mut Vec<ValueRef> ,
arg_cleanup_scope: cleanup::ScopeId,
ignore_self: bool)
-> &'a Block<'a> {
pub fn trans_args<'a>(cx: &'a Block<'a>,
args: CallArgs,
fn_ty: ty::t,
llargs: &mut Vec<ValueRef> ,
arg_cleanup_scope: cleanup::ScopeId,
ignore_self: bool)
-> &'a Block<'a> {
let _icx = push_ctxt("trans_args");
let arg_tys = ty::ty_fn_args(fn_ty);
let variadic = ty::fn_is_variadic(fn_ty);
Expand Down

0 comments on commit c6a148d

Please sign in to comment.