From e532e8d55d4f8a327b7163606c537fe3e358b03a Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 29 Jan 2014 18:44:14 -0500 Subject: [PATCH] remove a layer of indirection from most intrinsics --- src/librustc/middle/trans/intrinsic.rs | 112 ++++++++------- src/librustc/middle/trans/monomorphize.rs | 161 +++++++++++----------- 2 files changed, 137 insertions(+), 136 deletions(-) diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index eb71f6b8f198d..1ff21ce1a7cc3 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -29,27 +29,68 @@ use util::ppaux::ty_to_str; use middle::trans::machine::llsize_of; use middle::trans::type_::Type; +pub fn get_simple_intrinsic(ccx: @CrateContext, item: &ast::ForeignItem) -> Option { + let nm = ccx.sess.str_of(item.ident); + let name = nm.as_slice(); + + match name { + "sqrtf32" => Some(ccx.intrinsics.get_copy(&("llvm.sqrt.f32"))), + "sqrtf64" => Some(ccx.intrinsics.get_copy(&("llvm.sqrt.f64"))), + "powif32" => Some(ccx.intrinsics.get_copy(&("llvm.powi.f32"))), + "powif64" => Some(ccx.intrinsics.get_copy(&("llvm.powi.f64"))), + "sinf32" => Some(ccx.intrinsics.get_copy(&("llvm.sin.f32"))), + "sinf64" => Some(ccx.intrinsics.get_copy(&("llvm.sin.f64"))), + "cosf32" => Some(ccx.intrinsics.get_copy(&("llvm.cos.f32"))), + "cosf64" => Some(ccx.intrinsics.get_copy(&("llvm.cos.f64"))), + "powf32" => Some(ccx.intrinsics.get_copy(&("llvm.pow.f32"))), + "powf64" => Some(ccx.intrinsics.get_copy(&("llvm.pow.f64"))), + "expf32" => Some(ccx.intrinsics.get_copy(&("llvm.exp.f32"))), + "expf64" => Some(ccx.intrinsics.get_copy(&("llvm.exp.f64"))), + "exp2f32" => Some(ccx.intrinsics.get_copy(&("llvm.exp2.f32"))), + "exp2f64" => Some(ccx.intrinsics.get_copy(&("llvm.exp2.f64"))), + "logf32" => Some(ccx.intrinsics.get_copy(&("llvm.log.f32"))), + "logf64" => Some(ccx.intrinsics.get_copy(&("llvm.log.f64"))), + "log10f32" => Some(ccx.intrinsics.get_copy(&("llvm.log10.f32"))), + "log10f64" => Some(ccx.intrinsics.get_copy(&("llvm.log10.f64"))), + "log2f32" => Some(ccx.intrinsics.get_copy(&("llvm.log2.f32"))), + "log2f64" => Some(ccx.intrinsics.get_copy(&("llvm.log2.f64"))), + "fmaf32" => Some(ccx.intrinsics.get_copy(&("llvm.fma.f32"))), + "fmaf64" => Some(ccx.intrinsics.get_copy(&("llvm.fma.f64"))), + "fabsf32" => Some(ccx.intrinsics.get_copy(&("llvm.fabs.f32"))), + "fabsf64" => Some(ccx.intrinsics.get_copy(&("llvm.fabs.f64"))), + "copysignf32" => Some(ccx.intrinsics.get_copy(&("llvm.copysign.f32"))), + "copysignf64" => Some(ccx.intrinsics.get_copy(&("llvm.copysign.f64"))), + "floorf32" => Some(ccx.intrinsics.get_copy(&("llvm.floor.f32"))), + "floorf64" => Some(ccx.intrinsics.get_copy(&("llvm.floor.f64"))), + "ceilf32" => Some(ccx.intrinsics.get_copy(&("llvm.ceil.f32"))), + "ceilf64" => Some(ccx.intrinsics.get_copy(&("llvm.ceil.f64"))), + "truncf32" => Some(ccx.intrinsics.get_copy(&("llvm.trunc.f32"))), + "truncf64" => Some(ccx.intrinsics.get_copy(&("llvm.trunc.f64"))), + "rintf32" => Some(ccx.intrinsics.get_copy(&("llvm.rint.f32"))), + "rintf64" => Some(ccx.intrinsics.get_copy(&("llvm.rint.f64"))), + "nearbyintf32" => Some(ccx.intrinsics.get_copy(&("llvm.nearbyint.f32"))), + "nearbyintf64" => Some(ccx.intrinsics.get_copy(&("llvm.nearbyint.f64"))), + "roundf32" => Some(ccx.intrinsics.get_copy(&("llvm.round.f32"))), + "roundf64" => Some(ccx.intrinsics.get_copy(&("llvm.round.f64"))), + "ctpop8" => Some(ccx.intrinsics.get_copy(&("llvm.ctpop.i8"))), + "ctpop16" => Some(ccx.intrinsics.get_copy(&("llvm.ctpop.i16"))), + "ctpop32" => Some(ccx.intrinsics.get_copy(&("llvm.ctpop.i32"))), + "ctpop64" => Some(ccx.intrinsics.get_copy(&("llvm.ctpop.i64"))), + "bswap16" => Some(ccx.intrinsics.get_copy(&("llvm.bswap.i16"))), + "bswap32" => Some(ccx.intrinsics.get_copy(&("llvm.bswap.i32"))), + "bswap64" => Some(ccx.intrinsics.get_copy(&("llvm.bswap.i64"))), + _ => None + } +} + pub fn trans_intrinsic(ccx: @CrateContext, decl: ValueRef, item: &ast::ForeignItem, path: ast_map::Path, substs: @param_substs, - _attributes: &[ast::Attribute], ref_id: Option) { debug!("trans_intrinsic(item.ident={})", ccx.sess.str_of(item.ident)); - fn simple_llvm_intrinsic(bcx: &Block, name: &'static str, num_args: uint) { - assert!(num_args <= 4); - let mut args = [0 as ValueRef, ..4]; - let first_real_arg = bcx.fcx.arg_pos(0u); - for i in range(0u, num_args) { - args[i] = get_param(bcx.fcx.llfn, first_real_arg + i); - } - let llfn = bcx.ccx().intrinsics.get_copy(&name); - let llcall = Call(bcx, llfn, args.slice(0, num_args), []); - Ret(bcx, llcall); - } - fn with_overflow_instrinsic(bcx: &Block, name: &'static str, t: ty::t) { let first_real_arg = bcx.fcx.arg_pos(0u); let a = get_param(bcx.fcx.llfn, first_real_arg); @@ -431,48 +472,6 @@ pub fn trans_intrinsic(ccx: @CrateContext, "copy_nonoverlapping_memory" => copy_intrinsic(bcx, false, substs.tys[0]), "copy_memory" => copy_intrinsic(bcx, true, substs.tys[0]), "set_memory" => memset_intrinsic(bcx, substs.tys[0]), - "sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1), - "sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1), - "powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2), - "powif64" => simple_llvm_intrinsic(bcx, "llvm.powi.f64", 2), - "sinf32" => simple_llvm_intrinsic(bcx, "llvm.sin.f32", 1), - "sinf64" => simple_llvm_intrinsic(bcx, "llvm.sin.f64", 1), - "cosf32" => simple_llvm_intrinsic(bcx, "llvm.cos.f32", 1), - "cosf64" => simple_llvm_intrinsic(bcx, "llvm.cos.f64", 1), - "powf32" => simple_llvm_intrinsic(bcx, "llvm.pow.f32", 2), - "powf64" => simple_llvm_intrinsic(bcx, "llvm.pow.f64", 2), - "expf32" => simple_llvm_intrinsic(bcx, "llvm.exp.f32", 1), - "expf64" => simple_llvm_intrinsic(bcx, "llvm.exp.f64", 1), - "exp2f32" => simple_llvm_intrinsic(bcx, "llvm.exp2.f32", 1), - "exp2f64" => simple_llvm_intrinsic(bcx, "llvm.exp2.f64", 1), - "logf32" => simple_llvm_intrinsic(bcx, "llvm.log.f32", 1), - "logf64" => simple_llvm_intrinsic(bcx, "llvm.log.f64", 1), - "log10f32" => simple_llvm_intrinsic(bcx, "llvm.log10.f32", 1), - "log10f64" => simple_llvm_intrinsic(bcx, "llvm.log10.f64", 1), - "log2f32" => simple_llvm_intrinsic(bcx, "llvm.log2.f32", 1), - "log2f64" => simple_llvm_intrinsic(bcx, "llvm.log2.f64", 1), - "fmaf32" => simple_llvm_intrinsic(bcx, "llvm.fma.f32", 3), - "fmaf64" => simple_llvm_intrinsic(bcx, "llvm.fma.f64", 3), - "fabsf32" => simple_llvm_intrinsic(bcx, "llvm.fabs.f32", 1), - "fabsf64" => simple_llvm_intrinsic(bcx, "llvm.fabs.f64", 1), - "copysignf32" => simple_llvm_intrinsic(bcx, "llvm.copysign.f32", 2), - "copysignf64" => simple_llvm_intrinsic(bcx, "llvm.copysign.f64", 2), - "floorf32" => simple_llvm_intrinsic(bcx, "llvm.floor.f32", 1), - "floorf64" => simple_llvm_intrinsic(bcx, "llvm.floor.f64", 1), - "ceilf32" => simple_llvm_intrinsic(bcx, "llvm.ceil.f32", 1), - "ceilf64" => simple_llvm_intrinsic(bcx, "llvm.ceil.f64", 1), - "truncf32" => simple_llvm_intrinsic(bcx, "llvm.trunc.f32", 1), - "truncf64" => simple_llvm_intrinsic(bcx, "llvm.trunc.f64", 1), - "rintf32" => simple_llvm_intrinsic(bcx, "llvm.rint.f32", 1), - "rintf64" => simple_llvm_intrinsic(bcx, "llvm.rint.f64", 1), - "nearbyintf32" => simple_llvm_intrinsic(bcx, "llvm.nearbyint.f32", 1), - "nearbyintf64" => simple_llvm_intrinsic(bcx, "llvm.nearbyint.f64", 1), - "roundf32" => simple_llvm_intrinsic(bcx, "llvm.round.f32", 1), - "roundf64" => simple_llvm_intrinsic(bcx, "llvm.round.f64", 1), - "ctpop8" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i8", 1), - "ctpop16" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i16", 1), - "ctpop32" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i32", 1), - "ctpop64" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i64", 1), "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"), "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"), "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"), @@ -481,9 +480,6 @@ pub fn trans_intrinsic(ccx: @CrateContext, "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"), "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"), "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"), - "bswap16" => simple_llvm_intrinsic(bcx, "llvm.bswap.i16", 1), - "bswap32" => simple_llvm_intrinsic(bcx, "llvm.bswap.i32", 1), - "bswap64" => simple_llvm_intrinsic(bcx, "llvm.bswap.i64", 1), "volatile_load" => volatile_load_intrinsic(bcx), "volatile_store" => volatile_store_intrinsic(bcx), diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 678d23c0e1931..25c536f2a6db2 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -223,90 +223,95 @@ pub fn monomorphic_fn(ccx: @CrateContext, }; let lldecl = match map_node { - ast_map::NodeItem(i, _) => { - match *i { - ast::Item { - node: ast::ItemFn(decl, _, _, _, body), - .. - } => { - let d = mk_lldecl(); - set_llvm_fn_attrs(i.attrs, d); - trans_fn(ccx, pt, decl, body, d, Some(psubsts), fn_id.node, []); - d - } - _ => { - ccx.tcx.sess.bug("Can't monomorphize this kind of item") - } - } - } - ast_map::NodeForeignItem(i, _, _, _) => { - let d = mk_lldecl(); - intrinsic::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs, - ref_id); - d - } - ast_map::NodeVariant(v, enum_item, _) => { - let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id)); - let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap(); - let d = mk_lldecl(); - set_inline_hint(d); - match v.node.kind { - ast::TupleVariantKind(ref args) => { - trans_enum_variant(ccx, - enum_item.id, - v, - (*args).clone(), - this_tv.disr_val, - Some(psubsts), - d); - } - ast::StructVariantKind(_) => - ccx.tcx.sess.bug("can't monomorphize struct variants"), - } - d - } - ast_map::NodeMethod(mth, _, _) => { - let d = mk_lldecl(); - set_llvm_fn_attrs(mth.attrs, d); - trans_fn(ccx, pt, mth.decl, mth.body, d, Some(psubsts), mth.id, []); - d - } - ast_map::NodeTraitMethod(method, _, pt) => { - match *method { - ast::Provided(mth) => { + ast_map::NodeItem(i, _) => { + match *i { + ast::Item { + node: ast::ItemFn(decl, _, _, _, body), + .. + } => { let d = mk_lldecl(); - set_llvm_fn_attrs(mth.attrs, d); - trans_fn(ccx, (*pt).clone(), mth.decl, mth.body, - d, Some(psubsts), mth.id, []); + set_llvm_fn_attrs(i.attrs, d); + trans_fn(ccx, pt, decl, body, d, Some(psubsts), fn_id.node, []); d } _ => { - ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}", - map_node)) + ccx.tcx.sess.bug("Can't monomorphize this kind of item") } - } - } - ast_map::NodeStructCtor(struct_def, _, _) => { - let d = mk_lldecl(); - set_inline_hint(d); - base::trans_tuple_struct(ccx, - struct_def.fields, - struct_def.ctor_id.expect("ast-mapped tuple struct \ - didn't have a ctor id"), - Some(psubsts), - d); - d - } + } + } + ast_map::NodeForeignItem(i, _, _, _) => { + let simple = intrinsic::get_simple_intrinsic(ccx, i); + match simple { + Some(decl) => decl, + None => { + let d = mk_lldecl(); + intrinsic::trans_intrinsic(ccx, d, i, pt, psubsts, ref_id); + d + } + } + } + ast_map::NodeVariant(v, enum_item, _) => { + let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id)); + let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap(); + let d = mk_lldecl(); + set_inline_hint(d); + match v.node.kind { + ast::TupleVariantKind(ref args) => { + trans_enum_variant(ccx, + enum_item.id, + v, + (*args).clone(), + this_tv.disr_val, + Some(psubsts), + d); + } + ast::StructVariantKind(_) => + ccx.tcx.sess.bug("can't monomorphize struct variants"), + } + d + } + ast_map::NodeMethod(mth, _, _) => { + let d = mk_lldecl(); + set_llvm_fn_attrs(mth.attrs, d); + trans_fn(ccx, pt, mth.decl, mth.body, d, Some(psubsts), mth.id, []); + d + } + ast_map::NodeTraitMethod(method, _, pt) => { + match *method { + ast::Provided(mth) => { + let d = mk_lldecl(); + set_llvm_fn_attrs(mth.attrs, d); + trans_fn(ccx, (*pt).clone(), mth.decl, mth.body, + d, Some(psubsts), mth.id, []); + d + } + _ => { + ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}", + map_node)) + } + } + } + ast_map::NodeStructCtor(struct_def, _, _) => { + let d = mk_lldecl(); + set_inline_hint(d); + base::trans_tuple_struct(ccx, + struct_def.fields, + struct_def.ctor_id.expect("ast-mapped tuple struct \ + didn't have a ctor id"), + Some(psubsts), + d); + d + } - // Ugh -- but this ensures any new variants won't be forgotten - ast_map::NodeExpr(..) | - ast_map::NodeStmt(..) | - ast_map::NodeArg(..) | - ast_map::NodeBlock(..) | - ast_map::NodeCalleeScope(..) | - ast_map::NodeLocal(..) => { - ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}", map_node)) - } + // Ugh -- but this ensures any new variants won't be forgotten + ast_map::NodeExpr(..) | + ast_map::NodeStmt(..) | + ast_map::NodeArg(..) | + ast_map::NodeBlock(..) | + ast_map::NodeCalleeScope(..) | + ast_map::NodeLocal(..) => { + ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}", map_node)) + } }; {