Skip to content

Commit 237885c

Browse files
committed
auto merge of #11917 : thestinger/rust/intrinsic, r=alexcrichton
2 parents bec01ad + e532e8d commit 237885c

File tree

2 files changed

+137
-136
lines changed

2 files changed

+137
-136
lines changed

src/librustc/middle/trans/intrinsic.rs

+54-58
Original file line numberDiff line numberDiff line change
@@ -29,27 +29,68 @@ use util::ppaux::ty_to_str;
2929
use middle::trans::machine::llsize_of;
3030
use middle::trans::type_::Type;
3131

32+
pub fn get_simple_intrinsic(ccx: @CrateContext, item: &ast::ForeignItem) -> Option<ValueRef> {
33+
let nm = ccx.sess.str_of(item.ident);
34+
let name = nm.as_slice();
35+
36+
match name {
37+
"sqrtf32" => Some(ccx.intrinsics.get_copy(&("llvm.sqrt.f32"))),
38+
"sqrtf64" => Some(ccx.intrinsics.get_copy(&("llvm.sqrt.f64"))),
39+
"powif32" => Some(ccx.intrinsics.get_copy(&("llvm.powi.f32"))),
40+
"powif64" => Some(ccx.intrinsics.get_copy(&("llvm.powi.f64"))),
41+
"sinf32" => Some(ccx.intrinsics.get_copy(&("llvm.sin.f32"))),
42+
"sinf64" => Some(ccx.intrinsics.get_copy(&("llvm.sin.f64"))),
43+
"cosf32" => Some(ccx.intrinsics.get_copy(&("llvm.cos.f32"))),
44+
"cosf64" => Some(ccx.intrinsics.get_copy(&("llvm.cos.f64"))),
45+
"powf32" => Some(ccx.intrinsics.get_copy(&("llvm.pow.f32"))),
46+
"powf64" => Some(ccx.intrinsics.get_copy(&("llvm.pow.f64"))),
47+
"expf32" => Some(ccx.intrinsics.get_copy(&("llvm.exp.f32"))),
48+
"expf64" => Some(ccx.intrinsics.get_copy(&("llvm.exp.f64"))),
49+
"exp2f32" => Some(ccx.intrinsics.get_copy(&("llvm.exp2.f32"))),
50+
"exp2f64" => Some(ccx.intrinsics.get_copy(&("llvm.exp2.f64"))),
51+
"logf32" => Some(ccx.intrinsics.get_copy(&("llvm.log.f32"))),
52+
"logf64" => Some(ccx.intrinsics.get_copy(&("llvm.log.f64"))),
53+
"log10f32" => Some(ccx.intrinsics.get_copy(&("llvm.log10.f32"))),
54+
"log10f64" => Some(ccx.intrinsics.get_copy(&("llvm.log10.f64"))),
55+
"log2f32" => Some(ccx.intrinsics.get_copy(&("llvm.log2.f32"))),
56+
"log2f64" => Some(ccx.intrinsics.get_copy(&("llvm.log2.f64"))),
57+
"fmaf32" => Some(ccx.intrinsics.get_copy(&("llvm.fma.f32"))),
58+
"fmaf64" => Some(ccx.intrinsics.get_copy(&("llvm.fma.f64"))),
59+
"fabsf32" => Some(ccx.intrinsics.get_copy(&("llvm.fabs.f32"))),
60+
"fabsf64" => Some(ccx.intrinsics.get_copy(&("llvm.fabs.f64"))),
61+
"copysignf32" => Some(ccx.intrinsics.get_copy(&("llvm.copysign.f32"))),
62+
"copysignf64" => Some(ccx.intrinsics.get_copy(&("llvm.copysign.f64"))),
63+
"floorf32" => Some(ccx.intrinsics.get_copy(&("llvm.floor.f32"))),
64+
"floorf64" => Some(ccx.intrinsics.get_copy(&("llvm.floor.f64"))),
65+
"ceilf32" => Some(ccx.intrinsics.get_copy(&("llvm.ceil.f32"))),
66+
"ceilf64" => Some(ccx.intrinsics.get_copy(&("llvm.ceil.f64"))),
67+
"truncf32" => Some(ccx.intrinsics.get_copy(&("llvm.trunc.f32"))),
68+
"truncf64" => Some(ccx.intrinsics.get_copy(&("llvm.trunc.f64"))),
69+
"rintf32" => Some(ccx.intrinsics.get_copy(&("llvm.rint.f32"))),
70+
"rintf64" => Some(ccx.intrinsics.get_copy(&("llvm.rint.f64"))),
71+
"nearbyintf32" => Some(ccx.intrinsics.get_copy(&("llvm.nearbyint.f32"))),
72+
"nearbyintf64" => Some(ccx.intrinsics.get_copy(&("llvm.nearbyint.f64"))),
73+
"roundf32" => Some(ccx.intrinsics.get_copy(&("llvm.round.f32"))),
74+
"roundf64" => Some(ccx.intrinsics.get_copy(&("llvm.round.f64"))),
75+
"ctpop8" => Some(ccx.intrinsics.get_copy(&("llvm.ctpop.i8"))),
76+
"ctpop16" => Some(ccx.intrinsics.get_copy(&("llvm.ctpop.i16"))),
77+
"ctpop32" => Some(ccx.intrinsics.get_copy(&("llvm.ctpop.i32"))),
78+
"ctpop64" => Some(ccx.intrinsics.get_copy(&("llvm.ctpop.i64"))),
79+
"bswap16" => Some(ccx.intrinsics.get_copy(&("llvm.bswap.i16"))),
80+
"bswap32" => Some(ccx.intrinsics.get_copy(&("llvm.bswap.i32"))),
81+
"bswap64" => Some(ccx.intrinsics.get_copy(&("llvm.bswap.i64"))),
82+
_ => None
83+
}
84+
}
85+
3286
pub fn trans_intrinsic(ccx: @CrateContext,
3387
decl: ValueRef,
3488
item: &ast::ForeignItem,
3589
path: ast_map::Path,
3690
substs: @param_substs,
37-
_attributes: &[ast::Attribute],
3891
ref_id: Option<ast::NodeId>) {
3992
debug!("trans_intrinsic(item.ident={})", ccx.sess.str_of(item.ident));
4093

41-
fn simple_llvm_intrinsic(bcx: &Block, name: &'static str, num_args: uint) {
42-
assert!(num_args <= 4);
43-
let mut args = [0 as ValueRef, ..4];
44-
let first_real_arg = bcx.fcx.arg_pos(0u);
45-
for i in range(0u, num_args) {
46-
args[i] = get_param(bcx.fcx.llfn, first_real_arg + i);
47-
}
48-
let llfn = bcx.ccx().intrinsics.get_copy(&name);
49-
let llcall = Call(bcx, llfn, args.slice(0, num_args), []);
50-
Ret(bcx, llcall);
51-
}
52-
5394
fn with_overflow_instrinsic(bcx: &Block, name: &'static str, t: ty::t) {
5495
let first_real_arg = bcx.fcx.arg_pos(0u);
5596
let a = get_param(bcx.fcx.llfn, first_real_arg);
@@ -431,48 +472,6 @@ pub fn trans_intrinsic(ccx: @CrateContext,
431472
"copy_nonoverlapping_memory" => copy_intrinsic(bcx, false, substs.tys[0]),
432473
"copy_memory" => copy_intrinsic(bcx, true, substs.tys[0]),
433474
"set_memory" => memset_intrinsic(bcx, substs.tys[0]),
434-
"sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1),
435-
"sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1),
436-
"powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2),
437-
"powif64" => simple_llvm_intrinsic(bcx, "llvm.powi.f64", 2),
438-
"sinf32" => simple_llvm_intrinsic(bcx, "llvm.sin.f32", 1),
439-
"sinf64" => simple_llvm_intrinsic(bcx, "llvm.sin.f64", 1),
440-
"cosf32" => simple_llvm_intrinsic(bcx, "llvm.cos.f32", 1),
441-
"cosf64" => simple_llvm_intrinsic(bcx, "llvm.cos.f64", 1),
442-
"powf32" => simple_llvm_intrinsic(bcx, "llvm.pow.f32", 2),
443-
"powf64" => simple_llvm_intrinsic(bcx, "llvm.pow.f64", 2),
444-
"expf32" => simple_llvm_intrinsic(bcx, "llvm.exp.f32", 1),
445-
"expf64" => simple_llvm_intrinsic(bcx, "llvm.exp.f64", 1),
446-
"exp2f32" => simple_llvm_intrinsic(bcx, "llvm.exp2.f32", 1),
447-
"exp2f64" => simple_llvm_intrinsic(bcx, "llvm.exp2.f64", 1),
448-
"logf32" => simple_llvm_intrinsic(bcx, "llvm.log.f32", 1),
449-
"logf64" => simple_llvm_intrinsic(bcx, "llvm.log.f64", 1),
450-
"log10f32" => simple_llvm_intrinsic(bcx, "llvm.log10.f32", 1),
451-
"log10f64" => simple_llvm_intrinsic(bcx, "llvm.log10.f64", 1),
452-
"log2f32" => simple_llvm_intrinsic(bcx, "llvm.log2.f32", 1),
453-
"log2f64" => simple_llvm_intrinsic(bcx, "llvm.log2.f64", 1),
454-
"fmaf32" => simple_llvm_intrinsic(bcx, "llvm.fma.f32", 3),
455-
"fmaf64" => simple_llvm_intrinsic(bcx, "llvm.fma.f64", 3),
456-
"fabsf32" => simple_llvm_intrinsic(bcx, "llvm.fabs.f32", 1),
457-
"fabsf64" => simple_llvm_intrinsic(bcx, "llvm.fabs.f64", 1),
458-
"copysignf32" => simple_llvm_intrinsic(bcx, "llvm.copysign.f32", 2),
459-
"copysignf64" => simple_llvm_intrinsic(bcx, "llvm.copysign.f64", 2),
460-
"floorf32" => simple_llvm_intrinsic(bcx, "llvm.floor.f32", 1),
461-
"floorf64" => simple_llvm_intrinsic(bcx, "llvm.floor.f64", 1),
462-
"ceilf32" => simple_llvm_intrinsic(bcx, "llvm.ceil.f32", 1),
463-
"ceilf64" => simple_llvm_intrinsic(bcx, "llvm.ceil.f64", 1),
464-
"truncf32" => simple_llvm_intrinsic(bcx, "llvm.trunc.f32", 1),
465-
"truncf64" => simple_llvm_intrinsic(bcx, "llvm.trunc.f64", 1),
466-
"rintf32" => simple_llvm_intrinsic(bcx, "llvm.rint.f32", 1),
467-
"rintf64" => simple_llvm_intrinsic(bcx, "llvm.rint.f64", 1),
468-
"nearbyintf32" => simple_llvm_intrinsic(bcx, "llvm.nearbyint.f32", 1),
469-
"nearbyintf64" => simple_llvm_intrinsic(bcx, "llvm.nearbyint.f64", 1),
470-
"roundf32" => simple_llvm_intrinsic(bcx, "llvm.round.f32", 1),
471-
"roundf64" => simple_llvm_intrinsic(bcx, "llvm.round.f64", 1),
472-
"ctpop8" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i8", 1),
473-
"ctpop16" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i16", 1),
474-
"ctpop32" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i32", 1),
475-
"ctpop64" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i64", 1),
476475
"ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"),
477476
"ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"),
478477
"ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"),
@@ -481,9 +480,6 @@ pub fn trans_intrinsic(ccx: @CrateContext,
481480
"cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"),
482481
"cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"),
483482
"cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"),
484-
"bswap16" => simple_llvm_intrinsic(bcx, "llvm.bswap.i16", 1),
485-
"bswap32" => simple_llvm_intrinsic(bcx, "llvm.bswap.i32", 1),
486-
"bswap64" => simple_llvm_intrinsic(bcx, "llvm.bswap.i64", 1),
487483

488484
"volatile_load" => volatile_load_intrinsic(bcx),
489485
"volatile_store" => volatile_store_intrinsic(bcx),

src/librustc/middle/trans/monomorphize.rs

+83-78
Original file line numberDiff line numberDiff line change
@@ -223,90 +223,95 @@ pub fn monomorphic_fn(ccx: @CrateContext,
223223
};
224224

225225
let lldecl = match map_node {
226-
ast_map::NodeItem(i, _) => {
227-
match *i {
228-
ast::Item {
229-
node: ast::ItemFn(decl, _, _, _, body),
230-
..
231-
} => {
232-
let d = mk_lldecl();
233-
set_llvm_fn_attrs(i.attrs, d);
234-
trans_fn(ccx, pt, decl, body, d, Some(psubsts), fn_id.node, []);
235-
d
236-
}
237-
_ => {
238-
ccx.tcx.sess.bug("Can't monomorphize this kind of item")
239-
}
240-
}
241-
}
242-
ast_map::NodeForeignItem(i, _, _, _) => {
243-
let d = mk_lldecl();
244-
intrinsic::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs,
245-
ref_id);
246-
d
247-
}
248-
ast_map::NodeVariant(v, enum_item, _) => {
249-
let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id));
250-
let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
251-
let d = mk_lldecl();
252-
set_inline_hint(d);
253-
match v.node.kind {
254-
ast::TupleVariantKind(ref args) => {
255-
trans_enum_variant(ccx,
256-
enum_item.id,
257-
v,
258-
(*args).clone(),
259-
this_tv.disr_val,
260-
Some(psubsts),
261-
d);
262-
}
263-
ast::StructVariantKind(_) =>
264-
ccx.tcx.sess.bug("can't monomorphize struct variants"),
265-
}
266-
d
267-
}
268-
ast_map::NodeMethod(mth, _, _) => {
269-
let d = mk_lldecl();
270-
set_llvm_fn_attrs(mth.attrs, d);
271-
trans_fn(ccx, pt, mth.decl, mth.body, d, Some(psubsts), mth.id, []);
272-
d
273-
}
274-
ast_map::NodeTraitMethod(method, _, pt) => {
275-
match *method {
276-
ast::Provided(mth) => {
226+
ast_map::NodeItem(i, _) => {
227+
match *i {
228+
ast::Item {
229+
node: ast::ItemFn(decl, _, _, _, body),
230+
..
231+
} => {
277232
let d = mk_lldecl();
278-
set_llvm_fn_attrs(mth.attrs, d);
279-
trans_fn(ccx, (*pt).clone(), mth.decl, mth.body,
280-
d, Some(psubsts), mth.id, []);
233+
set_llvm_fn_attrs(i.attrs, d);
234+
trans_fn(ccx, pt, decl, body, d, Some(psubsts), fn_id.node, []);
281235
d
282236
}
283237
_ => {
284-
ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}",
285-
map_node))
238+
ccx.tcx.sess.bug("Can't monomorphize this kind of item")
286239
}
287-
}
288-
}
289-
ast_map::NodeStructCtor(struct_def, _, _) => {
290-
let d = mk_lldecl();
291-
set_inline_hint(d);
292-
base::trans_tuple_struct(ccx,
293-
struct_def.fields,
294-
struct_def.ctor_id.expect("ast-mapped tuple struct \
295-
didn't have a ctor id"),
296-
Some(psubsts),
297-
d);
298-
d
299-
}
240+
}
241+
}
242+
ast_map::NodeForeignItem(i, _, _, _) => {
243+
let simple = intrinsic::get_simple_intrinsic(ccx, i);
244+
match simple {
245+
Some(decl) => decl,
246+
None => {
247+
let d = mk_lldecl();
248+
intrinsic::trans_intrinsic(ccx, d, i, pt, psubsts, ref_id);
249+
d
250+
}
251+
}
252+
}
253+
ast_map::NodeVariant(v, enum_item, _) => {
254+
let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id));
255+
let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
256+
let d = mk_lldecl();
257+
set_inline_hint(d);
258+
match v.node.kind {
259+
ast::TupleVariantKind(ref args) => {
260+
trans_enum_variant(ccx,
261+
enum_item.id,
262+
v,
263+
(*args).clone(),
264+
this_tv.disr_val,
265+
Some(psubsts),
266+
d);
267+
}
268+
ast::StructVariantKind(_) =>
269+
ccx.tcx.sess.bug("can't monomorphize struct variants"),
270+
}
271+
d
272+
}
273+
ast_map::NodeMethod(mth, _, _) => {
274+
let d = mk_lldecl();
275+
set_llvm_fn_attrs(mth.attrs, d);
276+
trans_fn(ccx, pt, mth.decl, mth.body, d, Some(psubsts), mth.id, []);
277+
d
278+
}
279+
ast_map::NodeTraitMethod(method, _, pt) => {
280+
match *method {
281+
ast::Provided(mth) => {
282+
let d = mk_lldecl();
283+
set_llvm_fn_attrs(mth.attrs, d);
284+
trans_fn(ccx, (*pt).clone(), mth.decl, mth.body,
285+
d, Some(psubsts), mth.id, []);
286+
d
287+
}
288+
_ => {
289+
ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}",
290+
map_node))
291+
}
292+
}
293+
}
294+
ast_map::NodeStructCtor(struct_def, _, _) => {
295+
let d = mk_lldecl();
296+
set_inline_hint(d);
297+
base::trans_tuple_struct(ccx,
298+
struct_def.fields,
299+
struct_def.ctor_id.expect("ast-mapped tuple struct \
300+
didn't have a ctor id"),
301+
Some(psubsts),
302+
d);
303+
d
304+
}
300305

301-
// Ugh -- but this ensures any new variants won't be forgotten
302-
ast_map::NodeExpr(..) |
303-
ast_map::NodeStmt(..) |
304-
ast_map::NodeArg(..) |
305-
ast_map::NodeBlock(..) |
306-
ast_map::NodeCalleeScope(..) |
307-
ast_map::NodeLocal(..) => {
308-
ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}", map_node))
309-
}
306+
// Ugh -- but this ensures any new variants won't be forgotten
307+
ast_map::NodeExpr(..) |
308+
ast_map::NodeStmt(..) |
309+
ast_map::NodeArg(..) |
310+
ast_map::NodeBlock(..) |
311+
ast_map::NodeCalleeScope(..) |
312+
ast_map::NodeLocal(..) => {
313+
ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}", map_node))
314+
}
310315
};
311316

312317
{

0 commit comments

Comments
 (0)