Skip to content

Commit 27617a1

Browse files
committed
librustc_trans: Get rid of unnecessary allocation in finding discriminant field.
1 parent c15df8e commit 27617a1

File tree

1 file changed

+38
-47
lines changed
  • src/librustc_trans/trans

1 file changed

+38
-47
lines changed

src/librustc_trans/trans/adt.rs

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -228,24 +228,24 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
228228
let st = mk_struct(cx, cases[discr].tys[],
229229
false, t);
230230
match cases[discr].find_ptr(cx) {
231-
Some(ref pf) if pf.len() == 1 && st.fields.len() == 1 => {
231+
Some(ref df) if df.len() == 1 && st.fields.len() == 1 => {
232232
return RawNullablePointer {
233233
nndiscr: discr as Disr,
234234
nnty: st.fields[0],
235235
nullfields: cases[1 - discr].tys.clone()
236236
};
237237
}
238-
Some(pf) => {
239-
let mut discrfield = vec![0];
240-
discrfield.extend(pf.into_iter());
238+
Some(mut discrfield) => {
239+
discrfield.push(0);
240+
discrfield.reverse();
241241
return StructWrappedNullablePointer {
242242
nndiscr: discr as Disr,
243243
nonnull: st,
244244
discrfield: discrfield,
245245
nullfields: cases[1 - discr].tys.clone()
246246
};
247247
}
248-
None => { }
248+
None => {}
249249
}
250250
}
251251
discr += 1;
@@ -338,33 +338,38 @@ struct Case<'tcx> {
338338
/// This represents the (GEP) indices to follow to get to the discriminant field
339339
pub type DiscrField = Vec<uint>;
340340

341-
fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Option<DiscrField> {
341+
fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>,
342+
ty: Ty<'tcx>,
343+
mut path: DiscrField) -> Option<DiscrField> {
342344
match ty.sty {
343-
// &T/&mut T/Box<T> could either be a thin or fat pointer depending on T
344-
ty::ty_rptr(_, ty::mt { ty, .. }) | ty::ty_uniq(ty) => match ty.sty {
345-
// &[T] and &str are a pointer and length pair
346-
ty::ty_vec(_, None) | ty::ty_str => Some(vec![FAT_PTR_ADDR]),
347-
348-
ty::ty_struct(..) if !ty::type_is_sized(tcx, ty) => Some(vec![FAT_PTR_ADDR]),
349-
350-
// Any other &T is just a pointer
351-
_ => Some(vec![])
345+
// Fat &T/&mut T/Box<T> i.e. T is [T], str, or Trait
346+
ty::ty_rptr(_, ty::mt { ty, .. }) | ty::ty_uniq(ty) if !ty::type_is_sized(tcx, ty) => {
347+
path.push(FAT_PTR_ADDR);
348+
Some(path)
352349
},
353350

351+
// Regular thin pointer: &T/&mut T/Box<T>
352+
ty::ty_rptr(..) | ty::ty_uniq(..) => Some(path),
353+
354354
// Functions are just pointers
355-
ty::ty_bare_fn(..) => Some(vec![]),
355+
ty::ty_bare_fn(..) => Some(path),
356356

357357
// Closures are a pair of pointers: the code and environment
358-
ty::ty_closure(..) => Some(vec![FAT_PTR_ADDR]),
358+
ty::ty_closure(..) => {
359+
path.push(FAT_PTR_ADDR);
360+
Some(path)
361+
},
359362

360363
// Is this the NonZero lang item wrapping a pointer or integer type?
361364
ty::ty_struct(did, ref substs) if Some(did) == tcx.lang_items.non_zero() => {
362365
let nonzero_fields = ty::lookup_struct_fields(tcx, did);
363366
assert_eq!(nonzero_fields.len(), 1);
364367
let nonzero_field = ty::lookup_field_type(tcx, did, nonzero_fields[0].id, substs);
365368
match nonzero_field.sty {
366-
ty::ty_ptr(..) | ty::ty_int(..) |
367-
ty::ty_uint(..) => Some(vec![0]),
369+
ty::ty_ptr(..) | ty::ty_int(..) | ty::ty_uint(..) => {
370+
path.push(0);
371+
Some(path)
372+
},
368373
_ => None
369374
}
370375
},
@@ -375,13 +380,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
375380
let fields = ty::lookup_struct_fields(tcx, def_id);
376381
for (j, field) in fields.iter().enumerate() {
377382
let field_ty = ty::lookup_field_type(tcx, def_id, field.id, substs);
378-
match find_discr_field_candidate(tcx, field_ty) {
379-
Some(v) => {
380-
let mut discrfield = vec![j];
381-
discrfield.extend(v.into_iter());
382-
return Some(discrfield);
383-
}
384-
None => continue
383+
if let Some(mut fpath) = find_discr_field_candidate(tcx, field_ty, path.clone()) {
384+
fpath.push(j);
385+
return Some(fpath);
385386
}
386387
}
387388
None
@@ -390,13 +391,9 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
390391
// Can we use one of the fields in this tuple?
391392
ty::ty_tup(ref tys) => {
392393
for (j, &ty) in tys.iter().enumerate() {
393-
match find_discr_field_candidate(tcx, ty) {
394-
Some(v) => {
395-
let mut discrfield = vec![j];
396-
discrfield.extend(v.into_iter());
397-
return Some(discrfield);
398-
}
399-
None => continue
394+
if let Some(mut fpath) = find_discr_field_candidate(tcx, ty, path.clone()) {
395+
fpath.push(j);
396+
return Some(fpath);
400397
}
401398
}
402399
None
@@ -405,13 +402,11 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
405402
// Is this a fixed-size array of something non-zero
406403
// with at least one element?
407404
ty::ty_vec(ety, Some(d)) if d > 0 => {
408-
match find_discr_field_candidate(tcx, ety) {
409-
Some(v) => {
410-
let mut discrfield = vec![0];
411-
discrfield.extend(v.into_iter());
412-
return Some(discrfield);
413-
}
414-
None => None
405+
if let Some(mut vpath) = find_discr_field_candidate(tcx, ety, path) {
406+
vpath.push(0);
407+
Some(vpath)
408+
} else {
409+
None
415410
}
416411
},
417412

@@ -427,13 +422,9 @@ impl<'tcx> Case<'tcx> {
427422

428423
fn find_ptr<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> Option<DiscrField> {
429424
for (i, &ty) in self.tys.iter().enumerate() {
430-
match find_discr_field_candidate(cx.tcx(), ty) {
431-
Some(v) => {
432-
let mut discrfield = vec![i];
433-
discrfield.extend(v.into_iter());
434-
return Some(discrfield);
435-
}
436-
None => continue
425+
if let Some(mut path) = find_discr_field_candidate(cx.tcx(), ty, vec![]) {
426+
path.push(i);
427+
return Some(path);
437428
}
438429
}
439430
None

0 commit comments

Comments
 (0)