Skip to content

Commit 10ac685

Browse files
committed
---
yaml --- r: 81924 b: refs/heads/master c: 2835df2 h: refs/heads/master v: v3
1 parent 4b43c70 commit 10ac685

File tree

14 files changed

+633
-47
lines changed

14 files changed

+633
-47
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: c3e4e068416438e91e3e9809ee8553a764d8e26e
2+
refs/heads/master: 2835df2db65b1c03f3f21f553b8f31db0fb1b6c0
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 6c08cc2db4f98e9f07ae7d50338396c4123c2f0a
55
refs/heads/try: 70152ff55722878cde684ee6462c14c65f2c4729

trunk/Makefile.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,10 @@ config.stamp: $(S)configure $(S)Makefile.in $(S)src/snapshots.txt
608608
# Primary-target makefiles
609609
######################################################################
610610

611+
# Issue #9531: If you change the order of any of the following (or add
612+
# new definitions), make sure definitions always precede their uses,
613+
# especially for the dependency lists of recipes.
614+
611615
include $(CFG_SRC_DIR)mk/target.mk
612616
include $(CFG_SRC_DIR)mk/host.mk
613617
include $(CFG_SRC_DIR)mk/stage0.mk

trunk/mk/stage0.mk

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ $(HBIN0_H_$(CFG_BUILD_TRIPLE))/:
66
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/:
77
mkdir -p $@
88

9-
SNAPSHOT_RUSTC_POST_CLEANUP=$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
10-
119
$(SNAPSHOT_RUSTC_POST_CLEANUP): \
1210
$(S)src/snapshots.txt \
1311
$(S)src/etc/get-snapshot.py $(MKFILE_DEPS) \

trunk/mk/target.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ WFLAGS_ST2 = -D warnings
3636
# had its chance to clean it out; otherwise the other products will be
3737
# inadvertantly included in the clean out.
3838

39+
SNAPSHOT_RUSTC_POST_CLEANUP=$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
40+
3941
define TARGET_STAGE_N
4042

4143
$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \

trunk/src/etc/monodebug.pl

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/perl
2+
3+
#
4+
# This is a tool that helps with debugging incorrect monomorphic instance collapse.
5+
#
6+
# To use:
7+
# $ RUST_LOG=rustc::middle::trans::monomorphize rustc ARGS 2>&1 >log.txt
8+
# $ ./monodebug.pl log.txt
9+
#
10+
# This will show all generics that got collapsed. You can inspect this list to find the instances
11+
# that were mistakenly combined into one. Fixes will (most likely) be applied to type_use.rs.
12+
#
13+
# Questions about this tool go to pcwalton.
14+
#
15+
16+
use strict;
17+
use warnings;
18+
use Data::Dumper qw(Dumper);
19+
use Text::Balanced qw(extract_bracketed);
20+
21+
my %funcs;
22+
while (<>) {
23+
chomp;
24+
/^rust: ~"monomorphic_fn\((.*)"$/ or next;
25+
my $text = $1;
26+
$text =~ /fn_id=(\{ crate: \d+, node: \d+ \} \([^)]+\)), real_substs=(.*?), substs=(.*?), hash_id = \@\{ (.*) \}$/ or next;
27+
my ($fn_id, $real_substs, $substs, $hash_id) = ($1, $2, $3, $4);
28+
29+
#print "$hash_id\n";
30+
$hash_id =~ /^def: { crate: \d+, node: \d+ }, params: ~\[ (.*) \], impl_did_opt: (?:None|Some\({ crate: \d+, node: \d+ }\))$/ or next;
31+
my $params = $1;
32+
33+
my @real_substs;
34+
@real_substs = $real_substs =~ /\\"(.*?)\\"/g;
35+
36+
my @mono_params;
37+
while (1) {
38+
$params =~ s/^, //;
39+
if ($params =~ s/^mono_precise//) {
40+
extract_bracketed($params, '()');
41+
push @mono_params, 'precise';
42+
next;
43+
}
44+
if ($params =~ s/^mono_repr//) {
45+
my $sub = extract_bracketed($params, '()');
46+
push @mono_params, "repr($sub)";
47+
next;
48+
}
49+
if ($params =~ s/^mono_any//) {
50+
push @mono_params, "any";
51+
next;
52+
}
53+
last;
54+
}
55+
56+
my @key_params;
57+
for (my $i = 0; $i < @mono_params; ++$i) {
58+
if ($mono_params[$i] eq 'precise') {
59+
push @key_params, 'precise(' . $real_substs[$i] . ')';
60+
} else {
61+
push @key_params, $mono_params[$i];
62+
}
63+
}
64+
65+
my $key = "$fn_id with " . (join ', ', @key_params);
66+
$funcs{$key}{$real_substs} = 1;
67+
}
68+
69+
while (my ($key, $substs) = each %funcs) {
70+
my @params = keys %$substs;
71+
next if @params == 1;
72+
73+
print "$key\n";
74+
print(('-' x (length $key)), $/);
75+
for my $param (@params) {
76+
print "$param\n";
77+
}
78+
print "\n";
79+
}

trunk/src/etc/zsh/_rust

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ _rustc_opts_debug=(
7171
'count-type-sizes:count the sizes of aggregate types'
7272
'meta-stats:gather metadata statistics'
7373
'no-opt:do not optimize, even if -O is passed'
74+
'no-monomorphic-collapse:do not collapse template instantiations'
7475
'print-link-args:Print the arguments passed to the linker'
7576
'gc:Garbage collect shared data (experimental)'
7677
'jit:Execute using JIT (experimental)'

trunk/src/librustc/driver/driver.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,13 @@ pub fn build_session_options(binary: @str,
748748
let debuginfo = debugging_opts & session::debug_info != 0 ||
749749
extra_debuginfo;
750750

751+
// If debugging info is generated, do not collapse monomorphized function instances.
752+
// Functions with equivalent llvm code still need separate debugging descriptions because names
753+
// might differ.
754+
if debuginfo {
755+
debugging_opts |= session::no_monomorphic_collapse;
756+
}
757+
751758
let statik = debugging_opts & session::statik != 0;
752759

753760
let addl_lib_search_paths = matches.opt_strs("L").map(|s| Path(*s));

trunk/src/librustc/driver/session.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,20 @@ pub static debug_llvm: uint = 1 << 13;
6767
pub static count_type_sizes: uint = 1 << 14;
6868
pub static meta_stats: uint = 1 << 15;
6969
pub static no_opt: uint = 1 << 16;
70-
pub static gc: uint = 1 << 17;
71-
pub static jit: uint = 1 << 18;
72-
pub static debug_info: uint = 1 << 19;
73-
pub static extra_debug_info: uint = 1 << 20;
74-
pub static statik: uint = 1 << 21;
75-
pub static print_link_args: uint = 1 << 22;
76-
pub static no_debug_borrows: uint = 1 << 23;
77-
pub static lint_llvm: uint = 1 << 24;
78-
pub static once_fns: uint = 1 << 25;
79-
pub static print_llvm_passes: uint = 1 << 26;
80-
pub static no_vectorize_loops: uint = 1 << 27;
81-
pub static no_vectorize_slp: uint = 1 << 28;
82-
pub static no_prepopulate_passes: uint = 1 << 29;
70+
pub static no_monomorphic_collapse: uint = 1 << 17;
71+
pub static gc: uint = 1 << 18;
72+
pub static jit: uint = 1 << 19;
73+
pub static debug_info: uint = 1 << 20;
74+
pub static extra_debug_info: uint = 1 << 21;
75+
pub static statik: uint = 1 << 22;
76+
pub static print_link_args: uint = 1 << 23;
77+
pub static no_debug_borrows: uint = 1 << 24;
78+
pub static lint_llvm: uint = 1 << 25;
79+
pub static once_fns: uint = 1 << 26;
80+
pub static print_llvm_passes: uint = 1 << 27;
81+
pub static no_vectorize_loops: uint = 1 << 28;
82+
pub static no_vectorize_slp: uint = 1 << 29;
83+
pub static no_prepopulate_passes: uint = 1 << 30;
8384

8485
pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
8586
~[(~"verbose", ~"in general, enable more debug printouts", verbose),
@@ -105,6 +106,8 @@ pub fn debugging_opts_map() -> ~[(~str, ~str, uint)] {
105106
count_type_sizes),
106107
(~"meta-stats", ~"gather metadata statistics", meta_stats),
107108
(~"no-opt", ~"do not optimize, even if -O is passed", no_opt),
109+
(~"no-monomorphic-collapse", ~"do not collapse template instantiations",
110+
no_monomorphic_collapse),
108111
(~"print-link-args", ~"Print the arguments passed to the linker", print_link_args),
109112
(~"gc", ~"Garbage collect shared data (experimental)", gc),
110113
(~"jit", ~"Execute using JIT (experimental)", jit),
@@ -323,6 +326,9 @@ impl Session_ {
323326
pub fn borrowck_note_loan(&self) -> bool {
324327
self.debugging_opt(borrowck_note_loan)
325328
}
329+
pub fn no_monomorphic_collapse(&self) -> bool {
330+
self.debugging_opt(no_monomorphic_collapse)
331+
}
326332
pub fn debug_borrows(&self) -> bool {
327333
self.opts.optimize == No && !self.debugging_opt(no_debug_borrows)
328334
}

trunk/src/librustc/middle/trans/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use middle::trans::adt;
2222
use middle::trans::base;
2323
use middle::trans::builder::Builder;
2424
use middle::trans::debuginfo;
25+
use middle::trans::type_use;
2526
use middle::trans::common::{C_i32, C_null};
2627
use middle::ty;
2728

@@ -72,6 +73,8 @@ pub struct CrateContext {
7273
// Cache instances of monomorphized functions
7374
monomorphized: HashMap<mono_id, ValueRef>,
7475
monomorphizing: HashMap<ast::DefId, uint>,
76+
// Cache computed type parameter uses (see type_use.rs)
77+
type_use_cache: HashMap<ast::DefId, @~[type_use::type_uses]>,
7578
// Cache generated vtables
7679
vtables: HashMap<(ty::t, mono_id), ValueRef>,
7780
// Cache of constant strings,
@@ -201,6 +204,7 @@ impl CrateContext {
201204
non_inlineable_statics: HashSet::new(),
202205
monomorphized: HashMap::new(),
203206
monomorphizing: HashMap::new(),
207+
type_use_cache: HashMap::new(),
204208
vtables: HashMap::new(),
205209
const_cstr_cache: HashMap::new(),
206210
const_globals: HashMap::new(),

trunk/src/librustc/middle/trans/meth.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,8 @@ pub fn vtable_id(ccx: @mut CrateContext,
520520
monomorphize::make_mono_id(
521521
ccx,
522522
impl_id,
523-
&psubsts)
523+
&psubsts,
524+
None)
524525
}
525526

526527
// can't this be checked at the callee?

trunk/src/librustc/middle/trans/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub mod foreign;
3838
pub mod intrinsic;
3939
pub mod reflect;
4040
pub mod debuginfo;
41+
pub mod type_use;
4142
pub mod machine;
4243
pub mod adt;
4344
pub mod asm;

trunk/src/librustc/middle/trans/monomorphize.rs

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@ use middle::trans::base::{trans_fn, decl_internal_rust_fn};
1818
use middle::trans::base::{get_item_val, no_self};
1919
use middle::trans::base;
2020
use middle::trans::common::*;
21+
use middle::trans::datum;
22+
use middle::trans::machine;
2123
use middle::trans::meth;
24+
use middle::trans::type_of;
25+
use middle::trans::type_use;
2226
use middle::trans::intrinsic;
2327
use middle::ty;
2428
use middle::typeck;
25-
use util::ppaux::Repr;
29+
use util::ppaux::{Repr,ty_to_str};
2630

2731
use syntax::ast;
2832
use syntax::ast_map;
@@ -61,8 +65,10 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
6165

6266
for s in real_substs.tps.iter() { assert!(!ty::type_has_params(*s)); }
6367
for s in psubsts.tys.iter() { assert!(!ty::type_has_params(*s)); }
68+
let param_uses = type_use::type_uses_for(ccx, fn_id, psubsts.tys.len());
6469

65-
let hash_id = make_mono_id(ccx, fn_id, &*psubsts);
70+
71+
let hash_id = make_mono_id(ccx, fn_id, &*psubsts, Some(param_uses));
6672
if hash_id.params.iter().any(
6773
|p| match *p { mono_precise(_, _) => false, _ => true }) {
6874
must_cast = true;
@@ -296,7 +302,8 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
296302

297303
pub fn make_mono_id(ccx: @mut CrateContext,
298304
item: ast::DefId,
299-
substs: &param_substs) -> mono_id {
305+
substs: &param_substs,
306+
param_uses: Option<@~[type_use::type_uses]>) -> mono_id {
300307
// FIXME (possibly #5801): Need a lot of type hints to get
301308
// .collect() to work.
302309
let substs_iter = substs.self_ty.iter().chain(substs.tys.iter());
@@ -314,9 +321,59 @@ pub fn make_mono_id(ccx: @mut CrateContext,
314321
};
315322

316323

317-
let param_ids = precise_param_ids.iter().map(|x| {
318-
let (a, b) = *x;
319-
mono_precise(a, b)
320-
}).collect();
324+
let param_ids = match param_uses {
325+
Some(ref uses) => {
326+
// param_uses doesn't include a use for the self type.
327+
// We just say it is fully used.
328+
let self_use =
329+
substs.self_ty.map(|_| type_use::use_repr|type_use::use_tydesc);
330+
let uses_iter = self_use.iter().chain(uses.iter());
331+
332+
precise_param_ids.iter().zip(uses_iter).map(|(id, uses)| {
333+
if ccx.sess.no_monomorphic_collapse() {
334+
match *id {
335+
(a, b) => mono_precise(a, b)
336+
}
337+
} else {
338+
match *id {
339+
(a, b@Some(_)) => mono_precise(a, b),
340+
(subst, None) => {
341+
if *uses == 0 {
342+
mono_any
343+
} else if *uses == type_use::use_repr &&
344+
!ty::type_needs_drop(ccx.tcx, subst)
345+
{
346+
let llty = type_of::type_of(ccx, subst);
347+
let size = machine::llbitsize_of_real(ccx, llty);
348+
let align = machine::llalign_of_min(ccx, llty);
349+
let mode = datum::appropriate_mode(ccx.tcx, subst);
350+
let data_class = mono_data_classify(subst);
351+
352+
debug!("make_mono_id: type %s -> size %u align %u mode %? class %?",
353+
ty_to_str(ccx.tcx, subst),
354+
size, align, mode, data_class);
355+
356+
// Special value for nil to prevent problems
357+
// with undef return pointers.
358+
if size <= 8u && ty::type_is_nil(subst) {
359+
mono_repr(0u, 0u, data_class, mode)
360+
} else {
361+
mono_repr(size, align, data_class, mode)
362+
}
363+
} else {
364+
mono_precise(subst, None)
365+
}
366+
}
367+
}
368+
}
369+
}).collect()
370+
}
371+
None => {
372+
precise_param_ids.iter().map(|x| {
373+
let (a, b) = *x;
374+
mono_precise(a, b)
375+
}).collect()
376+
}
377+
};
321378
@mono_id_ {def: item, params: param_ids}
322379
}

0 commit comments

Comments
 (0)