Skip to content

Commit 5b135aa

Browse files
committed
---
yaml --- r: 130519 b: refs/heads/try c: e09bef8 h: refs/heads/master i: 130517: e373cea 130515: 5317525 130511: 8f775a6 v: v3
1 parent 0947bb9 commit 5b135aa

File tree

6 files changed

+115
-32
lines changed

6 files changed

+115
-32
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: c964cb229bd342bdeb0b4506c3a6d32b03e575f6
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 67b97ab6d2b7de9b69fd97dc171fcf8feec932ff
5-
refs/heads/try: da9606247d5ddd0edebafaffd0367c541fbaee7e
5+
refs/heads/try: e09bef810a95c82fa5de08872fccffdd5e0fe1e7
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/librustc/middle/trans/base.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,11 +2124,24 @@ impl<'a> Visitor<()> for TransItemVisitor<'a> {
21242124
}
21252125
}
21262126

2127-
pub fn update_linkage(ccx: &CrateContext, llval: ValueRef, id: ast::NodeId) {
2128-
if ccx.reachable().contains(&id) || ccx.sess().opts.cg.codegen_units > 1 {
2129-
llvm::SetLinkage(llval, llvm::ExternalLinkage);
2130-
} else {
2131-
llvm::SetLinkage(llval, llvm::InternalLinkage);
2127+
/// Set the appropriate linkage for an LLVM `ValueRef` (function or global).
2128+
/// If the `llval` is the direct translation of a specific Rust item, `id`
2129+
/// should be set to the `NodeId` of that item. (This mapping should be
2130+
/// 1-to-1, so monomorphizations and drop/visit glue should have `id` set to
2131+
/// `None`.)
2132+
pub fn update_linkage(ccx: &CrateContext, llval: ValueRef, id: Option<ast::NodeId>) {
2133+
match id {
2134+
Some(id) if ccx.reachable().contains(&id) => {
2135+
llvm::SetLinkage(llval, llvm::ExternalLinkage);
2136+
},
2137+
_ => {
2138+
// `id` does not refer to an item in `ccx.reachable`.
2139+
if ccx.sess().opts.cg.codegen_units > 1 {
2140+
llvm::SetLinkage(llval, llvm::ExternalLinkage);
2141+
} else {
2142+
llvm::SetLinkage(llval, llvm::InternalLinkage);
2143+
}
2144+
},
21322145
}
21332146
}
21342147

@@ -2157,7 +2170,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
21572170
item.id,
21582171
item.attrs.as_slice());
21592172
}
2160-
update_linkage(ccx, llfn, item.id);
2173+
update_linkage(ccx, llfn, Some(item.id));
21612174
}
21622175

21632176
// Be sure to travel more than just one layer deep to catch nested
@@ -2185,7 +2198,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
21852198
consts::trans_const(ccx, m, item.id);
21862199

21872200
let g = get_item_val(ccx, item.id);
2188-
update_linkage(ccx, g, item.id);
2201+
update_linkage(ccx, g, Some(item.id));
21892202

21902203
// Do static_assert checking. It can't really be done much earlier
21912204
// because we need to get the value of the bool out of LLVM

branches/try/src/librustc/middle/trans/context.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ pub struct SharedCrateContext {
7272
symbol_hasher: RefCell<Sha256>,
7373
tcx: ty::ctxt,
7474
stats: Stats,
75+
76+
available_monomorphizations: RefCell<HashSet<String>>,
77+
available_drop_glues: RefCell<HashMap<ty::t, String>>,
78+
available_visit_glues: RefCell<HashMap<ty::t, String>>,
7579
}
7680

7781
/// The local portion of a `CrateContext`. There is one `LocalCrateContext`
@@ -233,6 +237,9 @@ impl SharedCrateContext {
233237
llvm_insns: RefCell::new(HashMap::new()),
234238
fn_stats: RefCell::new(Vec::new()),
235239
},
240+
available_monomorphizations: RefCell::new(HashSet::new()),
241+
available_drop_glues: RefCell::new(HashMap::new()),
242+
available_visit_glues: RefCell::new(HashMap::new()),
236243
};
237244

238245
for i in range(0, local_count) {
@@ -612,6 +619,18 @@ impl<'b> CrateContext<'b> {
612619
&self.shared.stats
613620
}
614621

622+
pub fn available_monomorphizations<'a>(&'a self) -> &'a RefCell<HashSet<String>> {
623+
&self.shared.available_monomorphizations
624+
}
625+
626+
pub fn available_drop_glues<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, String>> {
627+
&self.shared.available_drop_glues
628+
}
629+
630+
pub fn available_visit_glues<'a>(&'a self) -> &'a RefCell<HashMap<ty::t, String>> {
631+
&self.shared.available_visit_glues
632+
}
633+
615634
pub fn int_type(&self) -> Type {
616635
self.local.int_type
617636
}

branches/try/src/librustc/middle/trans/glue.rs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,11 +171,30 @@ pub fn get_drop_glue(ccx: &CrateContext, t: ty::t) -> ValueRef {
171171
};
172172

173173
let llfnty = Type::glue_fn(ccx, llty);
174-
let glue = declare_generic_glue(ccx, t, llfnty, "drop");
174+
175+
let (glue, new_sym) = match ccx.available_drop_glues().borrow().find(&t) {
176+
Some(old_sym) => {
177+
let glue = decl_cdecl_fn(ccx, old_sym.as_slice(), llfnty, ty::mk_nil());
178+
(glue, None)
179+
},
180+
None => {
181+
let (sym, glue) = declare_generic_glue(ccx, t, llfnty, "drop");
182+
(glue, Some(sym))
183+
},
184+
};
175185

176186
ccx.drop_glues().borrow_mut().insert(t, glue);
177187

178-
make_generic_glue(ccx, t, glue, make_drop_glue, "drop");
188+
// To avoid infinite recursion, don't `make_drop_glue` until after we've
189+
// added the entry to the `drop_glues` cache.
190+
match new_sym {
191+
Some(sym) => {
192+
ccx.available_drop_glues().borrow_mut().insert(t, sym);
193+
// We're creating a new drop glue, so also generate a body.
194+
make_generic_glue(ccx, t, glue, make_drop_glue, "drop");
195+
},
196+
None => {},
197+
}
179198

180199
glue
181200
}
@@ -189,9 +208,28 @@ pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: &tydesc_info) -> ValueRef
189208
Some(visit_glue) => visit_glue,
190209
None => {
191210
debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_string(ccx.tcx(), ti.ty));
192-
let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "visit");
211+
212+
let (glue_fn, new_sym) = match ccx.available_visit_glues().borrow().find(&ti.ty) {
213+
Some(old_sym) => {
214+
let glue_fn = decl_cdecl_fn(ccx, old_sym.as_slice(), llfnty, ty::mk_nil());
215+
(glue_fn, None)
216+
},
217+
None => {
218+
let (sym, glue_fn) = declare_generic_glue(ccx, ti.ty, llfnty, "visit");
219+
(glue_fn, Some(sym))
220+
},
221+
};
222+
193223
ti.visit_glue.set(Some(glue_fn));
194-
make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, "visit");
224+
225+
match new_sym {
226+
Some(sym) => {
227+
ccx.available_visit_glues().borrow_mut().insert(ti.ty, sym);
228+
make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, "visit");
229+
},
230+
None => {},
231+
}
232+
195233
debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_string(ccx.tcx(), ti.ty));
196234
glue_fn
197235
}
@@ -602,15 +640,15 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> tydesc_info {
602640
}
603641

604642
fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
605-
name: &str) -> ValueRef {
643+
name: &str) -> (String, ValueRef) {
606644
let _icx = push_ctxt("declare_generic_glue");
607645
let fn_nm = mangle_internal_name_by_type_and_seq(
608646
ccx,
609647
t,
610648
format!("glue_{}", name).as_slice());
611649
let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil());
612-
note_unique_llvm_symbol(ccx, fn_nm);
613-
return llfn;
650+
note_unique_llvm_symbol(ccx, fn_nm.clone());
651+
return (fn_nm, llfn);
614652
}
615653

616654
fn make_generic_glue(ccx: &CrateContext,
@@ -631,7 +669,8 @@ fn make_generic_glue(ccx: &CrateContext,
631669

632670
let bcx = init_function(&fcx, false, ty::mk_nil());
633671

634-
llvm::SetLinkage(llfn, llvm::InternalLinkage);
672+
update_linkage(ccx, llfn, None);
673+
635674
ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1u);
636675
// All glue functions take values passed *by alias*; this is a
637676
// requirement since in many contexts glue is invoked indirectly and

branches/try/src/librustc/middle/trans/meth.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub fn trans_impl(ccx: &CrateContext,
8585
&param_substs::empty(),
8686
method.id,
8787
[]);
88-
update_linkage(ccx, llfn, method.id);
88+
update_linkage(ccx, llfn, Some(method.id));
8989
}
9090
let mut v = TransItemVisitor {
9191
ccx: ccx,

branches/try/src/librustc/middle/trans/monomorphize.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,18 @@ pub fn monomorphic_fn(ccx: &CrateContext,
159159
..
160160
} => {
161161
let d = mk_lldecl(abi);
162+
base::update_linkage(ccx, d, None);
162163
set_llvm_fn_attrs(i.attrs.as_slice(), d);
163164

164-
if abi != abi::Rust {
165-
foreign::trans_rust_fn_with_foreign_abi(
166-
ccx, &**decl, &**body, [], d, &psubsts, fn_id.node,
167-
Some(hash.as_slice()));
168-
} else {
169-
trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, []);
165+
if !ccx.available_monomorphizations().borrow().contains(&s) {
166+
ccx.available_monomorphizations().borrow_mut().insert(s.clone());
167+
if abi != abi::Rust {
168+
foreign::trans_rust_fn_with_foreign_abi(
169+
ccx, &**decl, &**body, [], d, &psubsts, fn_id.node,
170+
Some(hash.as_slice()));
171+
} else {
172+
trans_fn(ccx, &**decl, &**body, d, &psubsts, fn_id.node, []);
173+
}
170174
}
171175

172176
d
@@ -201,14 +205,18 @@ pub fn monomorphic_fn(ccx: &CrateContext,
201205
match *ii {
202206
ast::MethodImplItem(mth) => {
203207
let d = mk_lldecl(abi::Rust);
208+
base::update_linkage(ccx, d, None);
204209
set_llvm_fn_attrs(mth.attrs.as_slice(), d);
205-
trans_fn(ccx,
206-
&*mth.pe_fn_decl(),
207-
&*mth.pe_body(),
208-
d,
209-
&psubsts,
210-
mth.id,
211-
[]);
210+
if !ccx.available_monomorphizations().borrow().contains(&s) {
211+
ccx.available_monomorphizations().borrow_mut().insert(s.clone());
212+
trans_fn(ccx,
213+
&*mth.pe_fn_decl(),
214+
&*mth.pe_body(),
215+
d,
216+
&psubsts,
217+
mth.id,
218+
[]);
219+
}
212220
d
213221
}
214222
}
@@ -217,9 +225,13 @@ pub fn monomorphic_fn(ccx: &CrateContext,
217225
match *method {
218226
ast::ProvidedMethod(mth) => {
219227
let d = mk_lldecl(abi::Rust);
228+
base::update_linkage(ccx, d, None);
220229
set_llvm_fn_attrs(mth.attrs.as_slice(), d);
221-
trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d,
222-
&psubsts, mth.id, []);
230+
if !ccx.available_monomorphizations().borrow().contains(&s) {
231+
ccx.available_monomorphizations().borrow_mut().insert(s.clone());
232+
trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d,
233+
&psubsts, mth.id, []);
234+
}
223235
d
224236
}
225237
_ => {

0 commit comments

Comments
 (0)