Skip to content

Commit bda083f

Browse files
committed
Avoid unnecessary temporaries when ref'ing a DST value
A DST value and a fat pointer to it have the same representation, all we have to do is to adjust the type of the datum holding the pointer.
1 parent e5ba127 commit bda083f

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

src/librustc_trans/trans/expr.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,29 +1691,20 @@ fn trans_uniq_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
16911691
immediate_rvalue_bcx(bcx, val, box_ty).to_expr_datumblock()
16921692
}
16931693

1694-
fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1695-
lval: Datum<'tcx, Lvalue>)
1696-
-> DatumBlock<'blk, 'tcx, Expr> {
1697-
let dest_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic), lval.ty);
1698-
let scratch = rvalue_scratch_datum(bcx, dest_ty, "__fat_ptr");
1699-
memcpy_ty(bcx, scratch.val, lval.val, scratch.ty);
1700-
1701-
DatumBlock::new(bcx, scratch.to_expr_datum())
1702-
}
1703-
17041694
fn trans_addr_of<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
17051695
expr: &hir::Expr,
17061696
subexpr: &hir::Expr)
17071697
-> DatumBlock<'blk, 'tcx, Expr> {
17081698
let _icx = push_ctxt("trans_addr_of");
17091699
let mut bcx = bcx;
17101700
let sub_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, subexpr, "addr_of"));
1701+
let ty = expr_ty(bcx, expr);
17111702
if !type_is_sized(bcx.tcx(), sub_datum.ty) {
1712-
// DST lvalue, close to a fat pointer
1713-
ref_fat_ptr(bcx, sub_datum)
1703+
// Always generate an lvalue datum, because this pointer doesn't own
1704+
// the data and cleanup is scheduled elsewhere.
1705+
DatumBlock::new(bcx, Datum::new(sub_datum.val, ty, LvalueExpr(sub_datum.kind)))
17141706
} else {
17151707
// Sized value, ref to a thin pointer
1716-
let ty = expr_ty(bcx, expr);
17171708
immediate_rvalue_bcx(bcx, sub_datum.val, ty).to_expr_datumblock()
17181709
}
17191710
}

src/test/codegen/refs.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -C no-prepopulate-passes
12+
13+
#![crate_type = "lib"]
14+
15+
// Hack to get the correct size for the length part in slices
16+
// CHECK: @helper([[USIZE:i[0-9]+]])
17+
#[no_mangle]
18+
fn helper(_: usize) {
19+
}
20+
21+
// CHECK-LABEL: @ref_dst
22+
#[no_mangle]
23+
pub fn ref_dst(s: &[u8]) {
24+
// We used to generate an extra alloca and memcpy to ref the dst, so check that we copy
25+
// directly to the alloca for "x"
26+
// CHECK: [[SRC:%[0-9]+]] = bitcast { i8*, [[USIZE]] }* %s to i8*
27+
// CHECK: [[DST:%[0-9]+]] = bitcast { i8*, [[USIZE]] }* %x to i8*
28+
// CHECK: call void @llvm.memcpy.{{.*}}(i8* [[DST]], i8* [[SRC]],
29+
let x = &*s;
30+
}

0 commit comments

Comments
 (0)