remove a layer of indirection from most intrinsics

This commit is contained in:
Daniel Micay 2014-01-29 18:44:14 -05:00
parent 1e23c5c051
commit e532e8d55d
2 changed files with 137 additions and 136 deletions

View File

@ -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<ValueRef> {
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<ast::NodeId>) {
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),

View File

@ -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))
}
};
{