Skip to content

Commit b9b217f

Browse files
committed
---
yaml --- r: 227706 b: refs/heads/try c: f777562 h: refs/heads/master v: v3
1 parent e5e3e59 commit b9b217f

File tree

16 files changed

+231
-121
lines changed

16 files changed

+231
-121
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 02d74a4852f9138dbabdfeab8ac31298226620fd
4+
refs/heads/try: f777562eabdb676fafe738b4a652d33866292d7a
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc_trans/trans/_match.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -828,19 +828,11 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
828828
None,
829829
&format!("comparison of `{}`", rhs_t),
830830
StrEqFnLangItem);
831-
let t = ty::mk_str_slice(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), ast::MutImmutable);
832-
// The comparison function gets the slices by value, so we have to make copies here. Even
833-
// if the function doesn't write through the pointer, things like lifetime intrinsics
834-
// require that we do this properly
835-
let lhs_arg = alloc_ty(cx, t, "lhs");
836-
let rhs_arg = alloc_ty(cx, t, "rhs");
837-
memcpy_ty(cx, lhs_arg, lhs, t);
838-
memcpy_ty(cx, rhs_arg, rhs, t);
839-
let res = callee::trans_lang_call(cx, did, &[lhs_arg, rhs_arg], None, debug_loc);
840-
call_lifetime_end(res.bcx, lhs_arg);
841-
call_lifetime_end(res.bcx, rhs_arg);
842-
843-
res
831+
let lhs_data = Load(cx, expr::get_dataptr(cx, lhs));
832+
let lhs_len = Load(cx, expr::get_len(cx, lhs));
833+
let rhs_data = Load(cx, expr::get_dataptr(cx, rhs));
834+
let rhs_len = Load(cx, expr::get_len(cx, rhs));
835+
callee::trans_lang_call(cx, did, &[lhs_data, lhs_len, rhs_data, rhs_len], None, debug_loc)
844836
}
845837

846838
let _icx = push_ctxt("compare_values");

branches/try/src/librustc_trans/trans/attributes.rs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
188188
};
189189

190190
// Index 0 is the return value of the llvm func, so we start at 1
191-
let mut first_arg_offset = 1;
191+
let mut idx = 1;
192192
if let ty::FnConverging(ret_ty) = ret_ty {
193193
// A function pointer is called without the declaration
194194
// available, so we have to apply any attributes with ABI
@@ -206,7 +206,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
206206
.arg(1, llvm::DereferenceableAttribute(llret_sz));
207207

208208
// Add one more since there's an outptr
209-
first_arg_offset += 1;
209+
idx += 1;
210210
} else {
211211
// The `noalias` attribute on the return value is useful to a
212212
// function ptr caller.
@@ -236,10 +236,9 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
236236
}
237237
}
238238

239-
for (idx, &t) in input_tys.iter().enumerate().map(|(i, v)| (i + first_arg_offset, v)) {
239+
for &t in input_tys.iter() {
240240
match t.sty {
241-
// this needs to be first to prevent fat pointers from falling through
242-
_ if !common::type_is_immediate(ccx, t) => {
241+
_ if type_of::arg_is_indirect(ccx, t) => {
243242
let llarg_sz = machine::llsize_of_real(ccx, type_of::type_of(ccx, t));
244243

245244
// For non-immediate arguments the callee gets its own copy of
@@ -256,10 +255,17 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
256255

257256
// `Box` pointer parameters never alias because ownership is transferred
258257
ty::TyBox(inner) => {
259-
let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, inner));
260-
261-
attrs.arg(idx, llvm::Attribute::NoAlias)
262-
.arg(idx, llvm::DereferenceableAttribute(llsz));
258+
attrs.arg(idx, llvm::Attribute::NoAlias);
259+
260+
if common::type_is_sized(ccx.tcx(), inner) {
261+
let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, inner));
262+
attrs.arg(idx, llvm::DereferenceableAttribute(llsz));
263+
} else {
264+
attrs.arg(idx, llvm::NonNullAttribute);
265+
if ty::type_is_trait(inner) {
266+
attrs.arg(idx + 1, llvm::NonNullAttribute);
267+
}
268+
}
263269
}
264270

265271
ty::TyRef(b, mt) => {
@@ -278,10 +284,17 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
278284
attrs.arg(idx, llvm::Attribute::ReadOnly);
279285
}
280286

281-
// & pointer parameters are also never null and we know exactly
282-
// how many bytes we can dereference
283-
let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
284-
attrs.arg(idx, llvm::DereferenceableAttribute(llsz));
287+
// & pointer parameters are also never null and for sized types we also know
288+
// exactly how many bytes we can dereference
289+
if common::type_is_sized(ccx.tcx(), mt.ty) {
290+
let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
291+
attrs.arg(idx, llvm::DereferenceableAttribute(llsz));
292+
} else {
293+
attrs.arg(idx, llvm::NonNullAttribute);
294+
if ty::type_is_trait(mt.ty) {
295+
attrs.arg(idx + 1, llvm::NonNullAttribute);
296+
}
297+
}
285298

286299
// When a reference in an argument has no named lifetime, it's
287300
// impossible for that reference to escape this function
@@ -293,6 +306,12 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
293306

294307
_ => ()
295308
}
309+
310+
if common::type_is_fat_ptr(ccx.tcx(), t) {
311+
idx += 2;
312+
} else {
313+
idx += 1;
314+
}
296315
}
297316

298317
attrs

branches/try/src/librustc_trans/trans/base.rs

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,16 +1297,28 @@ pub type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
12971297
// create_datums_for_fn_args: creates rvalue datums for each of the
12981298
// incoming function arguments. These will later be stored into
12991299
// appropriate lvalue datums.
1300-
pub fn create_datums_for_fn_args<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
1300+
pub fn create_datums_for_fn_args<'a, 'tcx>(bcx: Block<'a, 'tcx>,
13011301
arg_tys: &[Ty<'tcx>])
13021302
-> Vec<RvalueDatum<'tcx>> {
13031303
let _icx = push_ctxt("create_datums_for_fn_args");
1304+
let fcx = bcx.fcx;
13041305

13051306
// Return an array wrapping the ValueRefs that we get from `get_param` for
13061307
// each argument into datums.
1307-
arg_tys.iter().enumerate().map(|(i, &arg_ty)| {
1308-
let llarg = get_param(fcx.llfn, fcx.arg_pos(i) as c_uint);
1309-
datum::Datum::new(llarg, arg_ty, arg_kind(fcx, arg_ty))
1308+
let mut i = fcx.arg_offset() as c_uint;
1309+
arg_tys.iter().map(|&arg_ty| {
1310+
if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
1311+
let llty = type_of::type_of(bcx.ccx(), arg_ty);
1312+
let data = get_param(fcx.llfn, i);
1313+
let extra = get_param(fcx.llfn, i + 1);
1314+
let fat_ptr = expr::make_fat_ptr(bcx, llty, data, extra);
1315+
i += 2;
1316+
datum::Datum::new(fat_ptr, arg_ty, datum::Rvalue { mode: datum::ByValue })
1317+
} else {
1318+
let llarg = get_param(fcx.llfn, i);
1319+
i += 1;
1320+
datum::Datum::new(llarg, arg_ty, arg_kind(fcx, arg_ty))
1321+
}
13101322
}).collect()
13111323
}
13121324

@@ -1321,12 +1333,23 @@ fn create_datums_for_fn_args_under_call_abi<'blk, 'tcx>(
13211333
arg_tys: &[Ty<'tcx>])
13221334
-> Vec<RvalueDatum<'tcx>> {
13231335
let mut result = Vec::new();
1336+
let mut idx = bcx.fcx.arg_offset() as c_uint;
13241337
for (i, &arg_ty) in arg_tys.iter().enumerate() {
13251338
if i < arg_tys.len() - 1 {
13261339
// Regular argument.
1327-
let llarg = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(i) as c_uint);
1328-
result.push(datum::Datum::new(llarg, arg_ty, arg_kind(bcx.fcx,
1329-
arg_ty)));
1340+
result.push(if common::type_is_fat_ptr(bcx.tcx(), arg_ty) {
1341+
let llty = type_of::type_of(bcx.ccx(), arg_ty);
1342+
let data = get_param(bcx.fcx.llfn, idx);
1343+
let extra = get_param(bcx.fcx.llfn, idx + 1);
1344+
idx += 2;
1345+
let fat_ptr = expr::make_fat_ptr(bcx, llty, data, extra);
1346+
datum::Datum::new(fat_ptr, arg_ty, datum::Rvalue { mode: datum::ByValue })
1347+
} else {
1348+
let val = get_param(bcx.fcx.llfn, idx);
1349+
idx += 1;
1350+
datum::Datum::new(val, arg_ty, arg_kind(bcx.fcx, arg_ty))
1351+
});
1352+
13301353
continue
13311354
}
13321355

@@ -1346,15 +1369,21 @@ fn create_datums_for_fn_args_under_call_abi<'blk, 'tcx>(
13461369
llval| {
13471370
for (j, &tupled_arg_ty) in
13481371
tupled_arg_tys.iter().enumerate() {
1349-
let llarg =
1350-
get_param(bcx.fcx.llfn,
1351-
bcx.fcx.arg_pos(i + j) as c_uint);
13521372
let lldest = GEPi(bcx, llval, &[0, j]);
1353-
let datum = datum::Datum::new(
1354-
llarg,
1355-
tupled_arg_ty,
1356-
arg_kind(bcx.fcx, tupled_arg_ty));
1357-
bcx = datum.store_to(bcx, lldest);
1373+
if common::type_is_fat_ptr(bcx.tcx(), tupled_arg_ty) {
1374+
let data = get_param(bcx.fcx.llfn, idx);
1375+
let extra = get_param(bcx.fcx.llfn, idx + 1);
1376+
Store(bcx, data, expr::get_dataptr(bcx, lldest));
1377+
Store(bcx, extra, expr::get_len(bcx, lldest));
1378+
idx += 2;
1379+
} else {
1380+
let datum = datum::Datum::new(
1381+
get_param(bcx.fcx.llfn, idx),
1382+
tupled_arg_ty,
1383+
arg_kind(bcx.fcx, tupled_arg_ty));
1384+
idx += 1;
1385+
bcx = datum.store_to(bcx, lldest);
1386+
};
13581387
}
13591388
bcx
13601389
}));
@@ -1566,7 +1595,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
15661595
}
15671596
_ => {
15681597
let arg_tys = untuple_arguments_if_necessary(ccx, &monomorphized_arg_types, abi);
1569-
create_datums_for_fn_args(&fcx, &arg_tys)
1598+
create_datums_for_fn_args(bcx, &arg_tys)
15701599
}
15711600
};
15721601

@@ -1773,7 +1802,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
17731802
ty::erase_late_bound_regions(
17741803
ccx.tcx(), &ty::ty_fn_args(ctor_ty));
17751804

1776-
let arg_datums = create_datums_for_fn_args(&fcx, &arg_tys[..]);
1805+
let arg_datums = create_datums_for_fn_args(bcx, &arg_tys[..]);
17771806

17781807
if !type_is_zero_size(fcx.ccx, result_ty.unwrap()) {
17791808
let dest = fcx.get_ret_slot(bcx, result_ty, "eret_slot");

branches/try/src/librustc_trans/trans/callee.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,12 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
343343

344344
let llargs = get_params(fcx.llfn);
345345

346+
let self_idx = fcx.arg_offset();
346347
// the first argument (`self`) will be ptr to the the fn pointer
347348
let llfnpointer = if is_by_ref {
348-
Load(bcx, llargs[fcx.arg_pos(0)])
349+
Load(bcx, llargs[self_idx])
349350
} else {
350-
llargs[fcx.arg_pos(0)]
351+
llargs[self_idx]
351352
};
352353

353354
assert!(!fcx.needs_ret_allocas);
@@ -360,7 +361,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
360361
DebugLoc::None,
361362
bare_fn_ty,
362363
|bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) },
363-
ArgVals(&llargs[fcx.arg_pos(1)..]),
364+
ArgVals(&llargs[(self_idx + 1)..]),
364365
dest).bcx;
365366

366367
finish_fn(&fcx, bcx, sig.output, DebugLoc::None);
@@ -1129,6 +1130,10 @@ pub fn trans_arg_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
11291130
bcx, arg_datum.to_lvalue_datum(bcx, "arg", arg_id));
11301131
val = arg_datum.val;
11311132
}
1133+
DontAutorefArg if common::type_is_fat_ptr(bcx.tcx(), arg_datum_ty) &&
1134+
!bcx.fcx.type_needs_drop(arg_datum_ty) => {
1135+
val = arg_datum.val
1136+
}
11321137
DontAutorefArg => {
11331138
// Make this an rvalue, since we are going to be
11341139
// passing ownership.
@@ -1147,7 +1152,7 @@ pub fn trans_arg_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
11471152
}
11481153
}
11491154

1150-
if formal_arg_ty != arg_datum_ty {
1155+
if type_of::arg_is_indirect(ccx, formal_arg_ty) && formal_arg_ty != arg_datum_ty {
11511156
// this could happen due to e.g. subtyping
11521157
let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, formal_arg_ty);
11531158
debug!("casting actual type ({}) to match formal ({})",
@@ -1159,7 +1164,12 @@ pub fn trans_arg_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
11591164

11601165
debug!("--- trans_arg_datum passing {}", bcx.val_to_string(val));
11611166

1162-
llargs.push(val);
1167+
if common::type_is_fat_ptr(bcx.tcx(), formal_arg_ty) {
1168+
llargs.push(Load(bcx, expr::get_dataptr(bcx, val)));
1169+
llargs.push(Load(bcx, expr::get_len(bcx, val)));
1170+
} else {
1171+
llargs.push(val);
1172+
}
11631173

11641174
bcx
11651175
}

branches/try/src/librustc_trans/trans/closure.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
411411
let self_scope = fcx.push_custom_cleanup_scope();
412412
let self_scope_id = CustomScope(self_scope);
413413
let rvalue_mode = datum::appropriate_rvalue_mode(ccx, closure_ty);
414-
let llself = llargs[fcx.arg_pos(0)];
414+
let self_idx = fcx.arg_offset();
415+
let llself = llargs[self_idx];
415416
let env_datum = Datum::new(llself, closure_ty, Rvalue::new(rvalue_mode));
416417
let env_datum = unpack_datum!(bcx,
417418
env_datum.to_lvalue_datum_in_scope(bcx, "self",
@@ -431,7 +432,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
431432
DebugLoc::None,
432433
llref_fn_ty,
433434
|bcx, _| Callee { bcx: bcx, data: callee_data },
434-
ArgVals(&llargs[fcx.arg_pos(1)..]),
435+
ArgVals(&llargs[(self_idx + 1)..]),
435436
dest).bcx;
436437

437438
fcx.pop_custom_cleanup_scope(self_scope);

branches/try/src/librustc_trans/trans/common.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -421,13 +421,8 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
421421
}
422422

423423
impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
424-
pub fn arg_pos(&self, arg: usize) -> usize {
425-
let arg = self.env_arg_pos() + arg;
426-
if self.llenv.is_some() {
427-
arg + 1
428-
} else {
429-
arg
430-
}
424+
pub fn arg_offset(&self) -> usize {
425+
self.env_arg_pos() + if self.llenv.is_some() { 1 } else { 0 }
431426
}
432427

433428
pub fn env_arg_pos(&self) -> usize {

branches/try/src/librustc_trans/trans/expr.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
293293
GEPi(bcx, fat_ptr, &[0, abi::FAT_PTR_ADDR])
294294
}
295295

296+
pub fn make_fat_ptr(bcx: Block, ty: Type, data: ValueRef, extra: ValueRef) -> ValueRef {
297+
InsertValue(bcx, InsertValue(bcx, C_undef(ty), data, 0), extra, 1)
298+
}
296299
pub fn copy_fat_ptr(bcx: Block, src_ptr: ValueRef, dst_ptr: ValueRef) {
297300
Store(bcx, Load(bcx, get_dataptr(bcx, src_ptr)), get_dataptr(bcx, dst_ptr));
298301
Store(bcx, Load(bcx, get_len(bcx, src_ptr)), get_len(bcx, dst_ptr));

0 commit comments

Comments
 (0)