Skip to content

Commit 947a854

Browse files
committed
librustc: Classify newtype structs Foo(T) as immediates if T is an immediate.
1 parent 7ac831e commit 947a854

File tree

9 files changed

+47
-46
lines changed

9 files changed

+47
-46
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,13 +1036,13 @@ pub fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef {
10361036

10371037
pub fn spill_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef {
10381038
let _icx = cx.insn_ctxt("spill_if_immediate");
1039-
if ty::type_is_immediate(t) { return do_spill(cx, v, t); }
1039+
if ty::type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); }
10401040
return v;
10411041
}
10421042

10431043
pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef {
10441044
let _icx = cx.insn_ctxt("load_if_immediate");
1045-
if ty::type_is_immediate(t) { return Load(cx, v); }
1045+
if ty::type_is_immediate(cx.tcx(), t) { return Load(cx, v); }
10461046
return v;
10471047
}
10481048

@@ -1573,7 +1573,7 @@ pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks {
15731573
// slot where the return value of the function must go.
15741574
pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
15751575
unsafe {
1576-
if !ty::type_is_immediate(output_type) {
1576+
if !ty::type_is_immediate(fcx.ccx.tcx, output_type) {
15771577
llvm::LLVMGetParam(fcx.llfn, 0)
15781578
} else {
15791579
let lloutputtype = type_of::type_of(*fcx.ccx, output_type);
@@ -1614,7 +1614,7 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext,
16141614
ty::subst_tps(ccx.tcx, substs.tys, substs.self_ty, output_type)
16151615
}
16161616
};
1617-
let is_immediate = ty::type_is_immediate(substd_output_type);
1617+
let is_immediate = ty::type_is_immediate(ccx.tcx, substd_output_type);
16181618

16191619
let fcx = @mut fn_ctxt_ {
16201620
llfn: llfndecl,
@@ -1734,7 +1734,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
17341734
// This alloca should be optimized away by LLVM's mem-to-reg pass in
17351735
// the event it's not truly needed.
17361736
// only by value if immediate:
1737-
let llarg = if datum::appropriate_mode(arg_ty).is_by_value() {
1737+
let llarg = if datum::appropriate_mode(bcx.tcx(), arg_ty).is_by_value() {
17381738
let alloc = alloc_ty(bcx, arg_ty);
17391739
Store(bcx, raw_llarg, alloc);
17401740
alloc

src/librustc/middle/trans/callee.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ pub fn trans_call_inner(in_cx: block,
510510

511511
let mut llargs = ~[];
512512

513-
if ty::type_is_immediate(ret_ty) {
513+
if ty::type_is_immediate(bcx.tcx(), ret_ty) {
514514
unsafe {
515515
llargs.push(llvm::LLVMGetUndef(T_ptr(T_i8())));
516516
}
@@ -559,7 +559,7 @@ pub fn trans_call_inner(in_cx: block,
559559
// case to ignore instead of invoking the Store
560560
// below into a scratch pointer of a mismatched
561561
// type.
562-
} else if ty::type_is_immediate(ret_ty) {
562+
} else if ty::type_is_immediate(bcx.tcx(), ret_ty) {
563563
let llscratchptr = alloc_ty(bcx, ret_ty);
564564
Store(bcx, llresult, llscratchptr);
565565
bcx = glue::drop_ty(bcx, llscratchptr, ret_ty);
@@ -573,7 +573,7 @@ pub fn trans_call_inner(in_cx: block,
573573
// If this is an immediate, store into the result location.
574574
// (If this was not an immediate, the result will already be
575575
// directly written into the output slot.)
576-
if ty::type_is_immediate(ret_ty) {
576+
if ty::type_is_immediate(bcx.tcx(), ret_ty) {
577577
Store(bcx, llresult, lldest);
578578
}
579579
}
@@ -776,7 +776,7 @@ pub fn trans_arg_expr(bcx: block,
776776
scratch.add_clean(bcx);
777777
temp_cleanups.push(scratch.val);
778778

779-
match arg_datum.appropriate_mode() {
779+
match arg_datum.appropriate_mode(bcx.tcx()) {
780780
ByValue => val = Load(bcx, scratch.val),
781781
ByRef => val = scratch.val,
782782
}

src/librustc/middle/trans/datum.rs

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ pub fn scratch_datum(bcx: block, ty: ty::t, zero: bool) -> Datum {
197197
Datum { val: scratch, ty: ty, mode: ByRef, source: RevokeClean }
198198
}
199199

200-
pub fn appropriate_mode(ty: ty::t) -> DatumMode {
200+
pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode {
201201
/*!
202202
*
203203
* Indicates the "appropriate" mode for this value,
@@ -206,7 +206,7 @@ pub fn appropriate_mode(ty: ty::t) -> DatumMode {
206206

207207
if ty::type_is_nil(ty) || ty::type_is_bot(ty) {
208208
ByValue
209-
} else if ty::type_is_immediate(ty) {
209+
} else if ty::type_is_immediate(tcx, ty) {
210210
ByValue
211211
} else {
212212
ByRef
@@ -476,18 +476,18 @@ pub impl Datum {
476476
}
477477
}
478478

479-
fn appropriate_mode(&self) -> DatumMode {
479+
fn appropriate_mode(&self, tcx: ty::ctxt) -> DatumMode {
480480
/*! See the `appropriate_mode()` function */
481481

482-
appropriate_mode(self.ty)
482+
appropriate_mode(tcx, self.ty)
483483
}
484484

485485
fn to_appropriate_llval(&self, bcx: block) -> ValueRef {
486486
/*!
487487
*
488488
* Yields an llvalue with the `appropriate_mode()`. */
489489

490-
match self.appropriate_mode() {
490+
match self.appropriate_mode(bcx.tcx()) {
491491
ByValue => self.to_value_llval(bcx),
492492
ByRef => self.to_ref_llval(bcx)
493493
}
@@ -498,7 +498,7 @@ pub impl Datum {
498498
*
499499
* Yields a datum with the `appropriate_mode()`. */
500500

501-
match self.appropriate_mode() {
501+
match self.appropriate_mode(bcx.tcx()) {
502502
ByValue => self.to_value_datum(bcx),
503503
ByRef => self.to_ref_datum(bcx)
504504
}
@@ -622,13 +622,7 @@ pub impl Datum {
622622
ByValue => {
623623
// Actually, this case cannot happen right
624624
// now, because enums are never immediate.
625-
// But in principle newtype'd immediate
626-
// values should be immediate, and in that
627-
// case the * would be a no-op except for
628-
// changing the type, so I am putting this
629-
// code in place here to do the right
630-
// thing if this change ever goes through.
631-
assert!(ty::type_is_immediate(ty));
625+
assert!(ty::type_is_immediate(bcx.tcx(), ty));
632626
(Some(Datum {ty: ty, ..*self}), bcx)
633627
}
634628
};
@@ -661,14 +655,7 @@ pub impl Datum {
661655
)
662656
}
663657
ByValue => {
664-
// Actually, this case cannot happen right now,
665-
// because structs are never immediate. But in
666-
// principle, newtype'd immediate values should be
667-
// immediate, and in that case the * would be a no-op
668-
// except for changing the type, so I am putting this
669-
// code in place here to do the right thing if this
670-
// change ever goes through.
671-
assert!(ty::type_is_immediate(ty));
658+
assert!(ty::type_is_immediate(bcx.tcx(), ty));
672659
(Some(Datum {ty: ty, ..*self}), bcx)
673660
}
674661
}

src/librustc/middle/trans/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
289289
debug!("add_env(closure_ty=%s)", closure_ty.repr(tcx));
290290
let scratch = scratch_datum(bcx, closure_ty, false);
291291
let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]);
292-
assert_eq!(datum.appropriate_mode(), ByValue);
292+
assert_eq!(datum.appropriate_mode(tcx), ByValue);
293293
Store(bcx, datum.to_appropriate_llval(bcx), llfn);
294294
let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]);
295295
Store(bcx, base::null_env_ptr(bcx), llenv);

src/librustc/middle/trans/foreign.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ fn foreign_signature(ccx: @CrateContext, fn_sig: &ty::FnSig)
101101
LlvmSignature {
102102
llarg_tys: llarg_tys,
103103
llret_ty: llret_ty,
104-
sret: !ty::type_is_immediate(fn_sig.output),
104+
sret: !ty::type_is_immediate(ccx.tcx, fn_sig.output),
105105
}
106106
}
107107

@@ -193,7 +193,7 @@ fn build_wrap_fn_(ccx: @CrateContext,
193193

194194
// Patch up the return type if it's not immediate and we're returning via
195195
// the C ABI.
196-
if needs_c_return && !ty::type_is_immediate(tys.fn_sig.output) {
196+
if needs_c_return && !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) {
197197
let lloutputtype = type_of::type_of(*fcx.ccx, tys.fn_sig.output);
198198
fcx.llretptr = Some(alloca(raw_block(fcx, false, fcx.llstaticallocas),
199199
lloutputtype));
@@ -697,7 +697,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
697697
// is not necessary since, for intrinsics, there is no
698698
// cleanup to concern ourselves with.
699699
let tp_ty = substs.tys[0];
700-
let mode = appropriate_mode(tp_ty);
700+
let mode = appropriate_mode(ccx.tcx, tp_ty);
701701
let src = Datum {val: get_param(decl, first_real_arg + 1u),
702702
ty: tp_ty, mode: mode, source: RevokeClean};
703703
bcx = src.move_to(bcx, DROP_EXISTING,
@@ -706,7 +706,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
706706
~"move_val_init" => {
707707
// See comments for `"move_val"`.
708708
let tp_ty = substs.tys[0];
709-
let mode = appropriate_mode(tp_ty);
709+
let mode = appropriate_mode(ccx.tcx, tp_ty);
710710
let src = Datum {val: get_param(decl, first_real_arg + 1u),
711711
ty: tp_ty, mode: mode, source: RevokeClean};
712712
bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg));
@@ -777,7 +777,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
777777
let lldestptr = PointerCast(bcx, lldestptr, T_ptr(T_i8()));
778778

779779
let llsrcval = get_param(decl, first_real_arg);
780-
let llsrcptr = if ty::type_is_immediate(in_type) {
780+
let llsrcptr = if ty::type_is_immediate(ccx.tcx, in_type) {
781781
let llsrcptr = alloca(bcx, llintype);
782782
Store(bcx, llsrcval, llsrcptr);
783783
llsrcptr
@@ -1228,7 +1228,7 @@ pub fn trans_foreign_fn(ccx: @CrateContext,
12281228
let mut i = 0u;
12291229
let n = tys.fn_sig.inputs.len();
12301230

1231-
if !ty::type_is_immediate(tys.fn_sig.output) {
1231+
if !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) {
12321232
let llretptr = load_inbounds(bcx, llargbundle, [0u, n]);
12331233
llargvals.push(llretptr);
12341234
} else {
@@ -1256,7 +1256,7 @@ pub fn trans_foreign_fn(ccx: @CrateContext,
12561256
shim_types: &ShimTypes,
12571257
llargbundle: ValueRef,
12581258
llretval: ValueRef) {
1259-
if ty::type_is_immediate(shim_types.fn_sig.output) {
1259+
if ty::type_is_immediate(bcx.tcx(), shim_types.fn_sig.output) {
12601260
// Write the value into the argument bundle.
12611261
let arg_count = shim_types.fn_sig.inputs.len();
12621262
let llretptr = load_inbounds(bcx,

src/librustc/middle/trans/glue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) {
655655
pub fn declare_tydesc_addrspace(ccx: @CrateContext, t: ty::t) -> addrspace {
656656
if !ty::type_needs_drop(ccx.tcx, t) {
657657
return default_addrspace;
658-
} else if ty::type_is_immediate(t) {
658+
} else if ty::type_is_immediate(ccx.tcx, t) {
659659
// For immediate types, we don't actually need an addrspace, because
660660
// e.g. boxed types include pointers to their contents which are
661661
// already correctly tagged with addrspaces.

src/librustc/middle/trans/monomorphize.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ pub fn make_mono_id(ccx: @CrateContext,
379379
let llty = type_of::type_of(ccx, subst);
380380
let size = machine::llbitsize_of_real(ccx, llty);
381381
let align = machine::llalign_of_pref(ccx, llty);
382-
let mode = datum::appropriate_mode(subst);
382+
let mode = datum::appropriate_mode(ccx.tcx, subst);
383383
let data_class = mono_data_classify(subst);
384384

385385
// Special value for nil to prevent problems

src/librustc/middle/trans/type_of.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use util::ppaux;
2121

2222
use syntax::ast;
2323

24-
pub fn arg_is_indirect(_: @CrateContext, arg_ty: &ty::t) -> bool {
25-
!ty::type_is_immediate(*arg_ty)
24+
pub fn arg_is_indirect(ccx: @CrateContext, arg_ty: &ty::t) -> bool {
25+
!ty::type_is_immediate(ccx.tcx, *arg_ty)
2626
}
2727

2828
pub fn type_of_explicit_arg(ccx: @CrateContext, arg_ty: &ty::t) -> TypeRef {
@@ -42,7 +42,7 @@ pub fn type_of_fn(cx: @CrateContext, inputs: &[ty::t], output: ty::t)
4242

4343
// Arg 0: Output pointer.
4444
// (if the output type is non-immediate)
45-
let output_is_immediate = ty::type_is_immediate(output);
45+
let output_is_immediate = ty::type_is_immediate(cx.tcx, output);
4646
let lloutputtype = type_of(cx, output);
4747
if !output_is_immediate {
4848
atys.push(T_ptr(lloutputtype));

src/librustc/middle/ty.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,9 +1706,23 @@ pub fn type_is_scalar(ty: t) -> bool {
17061706
}
17071707
}
17081708

1709-
pub fn type_is_immediate(ty: t) -> bool {
1709+
pub fn type_is_newtype_immediate(cx: ctxt, ty: t) -> bool {
1710+
match get(ty).sty {
1711+
ty_struct(def_id, ref substs) => {
1712+
let fields = struct_fields(cx, def_id, substs);
1713+
1714+
// Is this an immediate newtype struct?
1715+
fields.len() == 1 && fields[0].ident == special_idents::unnamed_field
1716+
&& type_is_immediate(cx, fields[0].mt.ty)
1717+
}
1718+
_ => false
1719+
}
1720+
}
1721+
1722+
pub fn type_is_immediate(cx: ctxt, ty: t) -> bool {
17101723
return type_is_scalar(ty) || type_is_boxed(ty) ||
1711-
type_is_unique(ty) || type_is_region_ptr(ty);
1724+
type_is_unique(ty) || type_is_region_ptr(ty) ||
1725+
type_is_newtype_immediate(cx, ty);
17121726
}
17131727

17141728
pub fn type_needs_drop(cx: ctxt, ty: t) -> bool {
@@ -3228,7 +3242,7 @@ pub fn expr_kind(tcx: ctxt,
32283242
ast::expr_cast(*) => {
32293243
match tcx.node_types.find(&(expr.id as uint)) {
32303244
Some(&t) => {
3231-
if ty::type_is_immediate(t) {
3245+
if ty::type_is_immediate(tcx, t) {
32323246
RvalueDatumExpr
32333247
} else {
32343248
RvalueDpsExpr

0 commit comments

Comments
 (0)