Skip to content

make small (<= size_of::<int>()) tuples immediate #9656

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 2, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ pub fn decl_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
_ => ()
}

let uses_outptr = type_of::return_uses_outptr(ccx.tcx, output);
let uses_outptr = type_of::return_uses_outptr(ccx, output);
let offset = if uses_outptr { 2 } else { 1 };

for (i, &arg_ty) in inputs.iter().enumerate() {
Expand Down Expand Up @@ -1121,13 +1121,13 @@ pub fn do_spill_noroot(cx: @mut Block, v: ValueRef) -> ValueRef {

pub fn spill_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
let _icx = push_ctxt("spill_if_immediate");
if type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); }
if type_is_immediate(cx.ccx(), t) { return do_spill(cx, v, t); }
return v;
}

pub fn load_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
let _icx = push_ctxt("load_if_immediate");
if type_is_immediate(cx.tcx(), t) { return Load(cx, v); }
if type_is_immediate(cx.ccx(), t) { return Load(cx, v); }
return v;
}

Expand Down Expand Up @@ -1660,7 +1660,7 @@ pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef {
// slot where the return value of the function must go.
pub fn make_return_pointer(fcx: @mut FunctionContext, output_type: ty::t) -> ValueRef {
unsafe {
if type_of::return_uses_outptr(fcx.ccx.tcx, output_type) {
if type_of::return_uses_outptr(fcx.ccx, output_type) {
llvm::LLVMGetParam(fcx.llfn, 0)
} else {
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
Expand Down Expand Up @@ -1700,7 +1700,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
ty::subst_tps(ccx.tcx, substs.tys, substs.self_ty, output_type)
}
};
let uses_outptr = type_of::return_uses_outptr(ccx.tcx, substd_output_type);
let uses_outptr = type_of::return_uses_outptr(ccx, substd_output_type);
let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);

let fcx = @mut FunctionContext {
Expand Down Expand Up @@ -1812,7 +1812,7 @@ pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
match fcx.llself {
Some(slf) => {
let self_val = if slf.is_copy
&& datum::appropriate_mode(bcx.tcx(), slf.t).is_by_value() {
&& datum::appropriate_mode(bcx.ccx(), slf.t).is_by_value() {
let tmp = BitCast(bcx, slf.v, type_of(bcx.ccx(), slf.t));
let alloc = alloc_ty(bcx, slf.t, "__self");
Store(bcx, tmp, alloc);
Expand Down Expand Up @@ -1842,7 +1842,7 @@ pub fn copy_args_to_allocas(fcx: @mut FunctionContext,
// This alloca should be optimized away by LLVM's mem-to-reg pass in
// the event it's not truly needed.
// only by value if immediate:
let llarg = if datum::appropriate_mode(bcx.tcx(), arg_ty).is_by_value() {
let llarg = if datum::appropriate_mode(bcx.ccx(), arg_ty).is_by_value() {
let alloc = alloc_ty(bcx, arg_ty, "__arg");
Store(bcx, raw_llarg, alloc);
alloc
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/middle/trans/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ pub fn trans_call_inner(in_cx: @mut Block,
// not care about the result, just make a stack slot.
let opt_llretslot = match dest {
None => {
assert!(!type_of::return_uses_outptr(in_cx.tcx(), ret_ty));
assert!(!type_of::return_uses_outptr(in_cx.ccx(), ret_ty));
None
}
Some(expr::SaveIn(dst)) => Some(dst),
Expand Down Expand Up @@ -685,7 +685,7 @@ pub fn trans_call_inner(in_cx: @mut Block,

// Push the out-pointer if we use an out-pointer for this
// return type, otherwise push "undef".
if type_of::return_uses_outptr(in_cx.tcx(), ret_ty) {
if type_of::return_uses_outptr(in_cx.ccx(), ret_ty) {
llargs.push(opt_llretslot.unwrap());
}

Expand All @@ -711,7 +711,7 @@ pub fn trans_call_inner(in_cx: @mut Block,
// any attributes with ABI implications directly to the call instruction. Right now, the
// only attribute we need to worry about is `sret`.
let mut attrs = ~[];
if type_of::return_uses_outptr(in_cx.tcx(), ret_ty) {
if type_of::return_uses_outptr(in_cx.ccx(), ret_ty) {
attrs.push((1, StructRetAttribute));
}

Expand All @@ -734,7 +734,7 @@ pub fn trans_call_inner(in_cx: @mut Block,
// the return value, copy it into llretslot.
match opt_llretslot {
Some(llretslot) => {
if !type_of::return_uses_outptr(bcx.tcx(), ret_ty) &&
if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
!ty::type_is_voidish(ret_ty)
{
Store(bcx, llret, llretslot);
Expand All @@ -758,7 +758,7 @@ pub fn trans_call_inner(in_cx: @mut Block,
// drop the temporary slot we made.
match dest {
None => {
assert!(!type_of::return_uses_outptr(bcx.tcx(), ret_ty));
assert!(!type_of::return_uses_outptr(bcx.ccx(), ret_ty));
}
Some(expr::Ignore) => {
// drop the value if it is not being saved.
Expand Down Expand Up @@ -871,7 +871,7 @@ pub fn trans_arg_expr(bcx: @mut Block,
DontAutorefArg => {
let need_scratch = ty::type_needs_drop(bcx.tcx(), arg_datum.ty) ||
(bcx.expr_is_lval(arg_expr) &&
arg_datum.appropriate_mode(bcx.tcx()).is_by_ref());
arg_datum.appropriate_mode(bcx.ccx()).is_by_ref());

let arg_datum = if need_scratch {
let scratch = scratch_datum(bcx, arg_datum.ty, "__self", false);
Expand Down
28 changes: 21 additions & 7 deletions src/librustc/middle/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,37 @@ use syntax::{ast, ast_map};

pub use middle::trans::context::CrateContext;

fn type_is_newtype_immediate(cx: ty::ctxt, ty: ty::t) -> bool {
fn type_is_newtype_immediate(ccx: &mut CrateContext, ty: ty::t) -> bool {
match ty::get(ty).sty {
ty::ty_struct(def_id, ref substs) => {
let fields = ty::struct_fields(cx, def_id, substs);
let fields = ty::struct_fields(ccx.tcx, def_id, substs);
fields.len() == 1 &&
fields[0].ident.name == token::special_idents::unnamed_field.name &&
type_is_immediate(cx, fields[0].mt.ty)
type_is_immediate(ccx, fields[0].mt.ty)
}
_ => false
}
}

pub fn type_is_immediate(cx: ty::ctxt, ty: ty::t) -> bool {
ty::type_is_scalar(ty) || ty::type_is_boxed(ty) ||
pub fn type_is_immediate(ccx: &mut CrateContext, ty: ty::t) -> bool {
use middle::trans::machine::llsize_of_alloc;
use middle::trans::type_of::sizing_type_of;
let tcx = ccx.tcx;
let simple = ty::type_is_scalar(ty) || ty::type_is_boxed(ty) ||
ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
type_is_newtype_immediate(cx, ty) ||
ty::type_is_simd(cx, ty)
type_is_newtype_immediate(ccx, ty) ||
ty::type_is_simd(tcx, ty);
if simple {
return true;
}
match ty::get(ty).sty {
// FIXME: #9651: small `ty_struct` and `ty_enum` should also be immediate
ty::ty_tup(*) => {
let llty = sizing_type_of(ccx, ty);
llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
}
_ => false
}
}

pub fn gensym_name(name: &str) -> (Ident, path_elt) {
Expand Down
16 changes: 8 additions & 8 deletions src/librustc/middle/trans/datum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ pub fn scratch_datum(bcx: @mut Block, ty: ty::t, name: &str, zero: bool) -> Datu
Datum { val: scratch, ty: ty, mode: ByRef(RevokeClean) }
}

pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode {
pub fn appropriate_mode(ccx: &mut CrateContext, ty: ty::t) -> DatumMode {
/*!
* Indicates the "appropriate" mode for this value,
* which is either by ref or by value, depending
Expand All @@ -197,7 +197,7 @@ pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode {

if ty::type_is_voidish(ty) {
ByValue
} else if type_is_immediate(tcx, ty) {
} else if type_is_immediate(ccx, ty) {
ByValue
} else {
ByRef(RevokeClean)
Expand Down Expand Up @@ -505,18 +505,18 @@ impl Datum {
}
}

pub fn appropriate_mode(&self, tcx: ty::ctxt) -> DatumMode {
pub fn appropriate_mode(&self, ccx: &mut CrateContext) -> DatumMode {
/*! See the `appropriate_mode()` function */

appropriate_mode(tcx, self.ty)
appropriate_mode(ccx, self.ty)
}

pub fn to_appropriate_llval(&self, bcx: @mut Block) -> ValueRef {
/*!
*
* Yields an llvalue with the `appropriate_mode()`. */

match self.appropriate_mode(bcx.tcx()) {
match self.appropriate_mode(bcx.ccx()) {
ByValue => self.to_value_llval(bcx),
ByRef(_) => self.to_ref_llval(bcx)
}
Expand All @@ -527,7 +527,7 @@ impl Datum {
*
* Yields a datum with the `appropriate_mode()`. */

match self.appropriate_mode(bcx.tcx()) {
match self.appropriate_mode(bcx.ccx()) {
ByValue => self.to_value_datum(bcx),
ByRef(_) => self.to_ref_datum(bcx)
}
Expand Down Expand Up @@ -667,7 +667,7 @@ impl Datum {
ByValue => {
// Actually, this case cannot happen right
// now, because enums are never immediate.
assert!(type_is_immediate(bcx.tcx(), ty));
assert!(type_is_immediate(bcx.ccx(), ty));
(Some(Datum {ty: ty, ..*self}), bcx)
}
};
Expand Down Expand Up @@ -699,7 +699,7 @@ impl Datum {
)
}
ByValue => {
assert!(type_is_immediate(bcx.tcx(), ty));
assert!(type_is_immediate(bcx.ccx(), ty));
(
Some(Datum {
val: ExtractValue(bcx, self.val, 0),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ pub fn trans_to_datum(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
debug!("add_env(closure_ty=%s)", closure_ty.repr(tcx));
let scratch = scratch_datum(bcx, closure_ty, "__adjust", false);
let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]);
assert_eq!(datum.appropriate_mode(tcx), ByValue);
assert_eq!(datum.appropriate_mode(bcx.ccx()), ByValue);
Store(bcx, datum.to_appropriate_llval(bcx), llfn);
let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]);
Store(bcx, base::null_env_ptr(bcx.ccx()), llenv);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ pub fn trans_rust_fn_with_foreign_abi(ccx: @mut CrateContext,

// Push Rust return pointer, using null if it will be unused.
let rust_uses_outptr =
type_of::return_uses_outptr(tcx, tys.fn_sig.output);
type_of::return_uses_outptr(ccx, tys.fn_sig.output);
let return_alloca: Option<ValueRef>;
let llrust_ret_ty = tys.llsig.llret_ty;
let llrust_retptr_ty = llrust_ret_ty.ptr_to();
Expand Down Expand Up @@ -702,7 +702,7 @@ fn foreign_signature(ccx: &mut CrateContext, fn_sig: &ty::FnSig)
LlvmSignature {
llarg_tys: llarg_tys,
llret_ty: llret_ty,
sret: type_of::return_uses_outptr(ccx.tcx, fn_sig.output),
sret: type_of::return_uses_outptr(ccx, fn_sig.output),
}
}

Expand Down
Loading