Skip to content

Commit

Permalink
librustc: Translate input for transmute directly into dest.
Browse files Browse the repository at this point in the history
  • Loading branch information
luqmana committed Jul 10, 2014
1 parent 8fa3006 commit 83122af
Showing 1 changed file with 42 additions and 58 deletions.
100 changes: 42 additions & 58 deletions src/librustc/middle/trans/intrinsic.rs
Expand Up @@ -10,8 +10,7 @@

#![allow(non_uppercase_pattern_statics)]

use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
use lib::llvm::{ValueRef, Pointer, Array, Struct};
use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg, ValueRef};
use lib;
use middle::subst;
use middle::subst::FnSpace;
Expand Down Expand Up @@ -137,6 +136,47 @@ pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
_ => fail!("expected bare_fn in trans_intrinsic_call")
};
let llret_ty = type_of::type_of(ccx, ret_ty);
let foreign_item = tcx.map.expect_foreign_item(node);
let name = token::get_ident(foreign_item.ident);

// For `transmute` we can just trans the input expr directly into dest
if name.get() == "transmute" {
match args {
callee::ArgExprs(arg_exprs) => {
assert_eq!(arg_exprs.len(), 1);

let (in_type, out_type) = (*substs.types.get(FnSpace, 0),
*substs.types.get(FnSpace, 1));
let llintype = type_of::type_of(ccx, in_type);
let llouttype = type_of::type_of(ccx, out_type);

let in_type_size = machine::llbitsize_of_real(ccx, llintype);
let out_type_size = machine::llbitsize_of_real(ccx, llouttype);

// This should be caught by the intrinsicck pass
assert_eq!(in_type_size, out_type_size);

// We need to cast the dest so the types work out
let dest = match dest {
expr::SaveIn(d) => expr::SaveIn(PointerCast(bcx, d, llintype.ptr_to())),
expr::Ignore => expr::Ignore
};
bcx = expr::trans_into(bcx, &*arg_exprs[0], dest);

fcx.pop_custom_cleanup_scope(cleanup_scope);

return match dest {
expr::SaveIn(d) => Result::new(bcx, d),
expr::Ignore => Result::new(bcx, C_undef(llret_ty.ptr_to()))
};

}

_ => {
ccx.sess().bug("expected expr as argument for transmute");
}
}
}

// Get location to store the result. If the user does
// not care about the result, just make a stack slot
Expand All @@ -158,8 +198,6 @@ pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,

fcx.pop_custom_cleanup_scope(cleanup_scope);

let foreign_item = tcx.map.expect_foreign_item(node);
let name = token::get_ident(foreign_item.ident);
let simple = get_simple_intrinsic(ccx, &*foreign_item);

let llval = match (simple, name.get()) {
Expand Down Expand Up @@ -240,60 +278,6 @@ pub fn trans_intrinsic_call<'a>(mut bcx: &'a Block<'a>, node: ast::NodeId,
(_, "uninit") | (_, "forget") => {
C_nil(ccx)
}
(_, "transmute") => {
let (in_type, out_type) = (*substs.types.get(FnSpace, 0),
*substs.types.get(FnSpace, 1));
let llintype = type_of::type_of(ccx, in_type);
let llouttype = type_of::type_of(ccx, out_type);

let in_type_size = machine::llbitsize_of_real(ccx, llintype);
let out_type_size = machine::llbitsize_of_real(ccx, llouttype);

// This should be caught by the intrinsicck pass
assert_eq!(in_type_size, out_type_size);

if !return_type_is_void(ccx, out_type) {
let llsrcval = *llargs.get(0);
if type_is_immediate(ccx, in_type) {
if type_is_immediate(ccx, out_type) {
Store(bcx, llsrcval, PointerCast(bcx, llresult, llintype.ptr_to()));
C_nil(ccx)
} else {
match (llintype.kind(), llouttype.kind()) {
(Pointer, other) | (other, Pointer) if other != Pointer => {
let tmp = Alloca(bcx, llouttype, "");
Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
Load(bcx, tmp)
}
(Array, _) | (_, Array) | (Struct, _) | (_, Struct) => {
let tmp = Alloca(bcx, llouttype, "");
Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to()));
Load(bcx, tmp)
}
_ => {
BitCast(bcx, llsrcval, llouttype)
}
}
}
} else if type_is_immediate(ccx, out_type) {
Load(bcx, PointerCast(bcx, llsrcval, llouttype.ptr_to()))
} else {
// NB: Do not use a Load and Store here. This causes massive
// code bloat when `transmute` is used on large structural
// types.
let lldestptr = llresult;
let lldestptr = PointerCast(bcx, lldestptr, Type::i8p(ccx));
let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p(ccx));

let llsize = llsize_of(ccx, llintype);
call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1);

C_nil(ccx)
}
} else {
C_nil(ccx)
}
}
(_, "needs_drop") => {
let tp_ty = *substs.types.get(FnSpace, 0);
C_bool(ccx, ty::type_needs_drop(ccx.tcx(), tp_ty))
Expand Down

9 comments on commit 83122af

@bors
Copy link
Contributor

@bors bors commented on 83122af Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from pcwalton
at luqmana@83122af

@bors
Copy link
Contributor

@bors bors commented on 83122af Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging luqmana/rust/nif = 83122af into auto

@bors
Copy link
Contributor

@bors bors commented on 83122af Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

luqmana/rust/nif = 83122af merged ok, testing candidate = 75d09482

@bors
Copy link
Contributor

@bors bors commented on 83122af Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from pcwalton
at luqmana@83122af

@bors
Copy link
Contributor

@bors bors commented on 83122af Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging luqmana/rust/nif = 83122af into auto

@bors
Copy link
Contributor

@bors bors commented on 83122af Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

luqmana/rust/nif = 83122af merged ok, testing candidate = a1bd5d3

@bors
Copy link
Contributor

@bors bors commented on 83122af Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = a1bd5d3

Please sign in to comment.