Skip to content

Commit 85b155f

Browse files
trans: Don't try to place declarations during codegen unit partitioning.
1 parent e3f19cb commit 85b155f

File tree

6 files changed

+75
-139
lines changed

6 files changed

+75
-139
lines changed

src/librustc_trans/base.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real};
8080
use meth;
8181
use mir;
8282
use monomorphize::{self, Instance};
83-
use partitioning::{self, PartitioningStrategy, InstantiationMode, CodegenUnit};
83+
use partitioning::{self, PartitioningStrategy, CodegenUnit};
8484
use symbol_names_test;
8585
use trans_item::TransItem;
8686
use tvec;
@@ -2942,8 +2942,8 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
29422942
None => TransItemCollectionMode::Lazy
29432943
};
29442944

2945-
let (items, reference_map) = time(time_passes, "translation item collection", || {
2946-
collector::collect_crate_translation_items(scx, collection_mode)
2945+
let (items, inlining_map) = time(time_passes, "translation item collection", || {
2946+
collector::collect_crate_translation_items(&scx, collection_mode)
29472947
});
29482948

29492949
let strategy = if scx.sess().opts.debugging_opts.incremental.is_some() {
@@ -2956,7 +2956,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
29562956
partitioning::partition(scx.tcx(),
29572957
items.iter().cloned(),
29582958
strategy,
2959-
&reference_map)
2959+
&inlining_map)
29602960
});
29612961

29622962
if scx.sess().opts.debugging_opts.print_trans_items.is_some() {
@@ -2984,18 +2984,17 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
29842984
output.push_str(&cgu_name[..]);
29852985

29862986
let linkage_abbrev = match linkage {
2987-
InstantiationMode::Def(llvm::ExternalLinkage) => "External",
2988-
InstantiationMode::Def(llvm::AvailableExternallyLinkage) => "Available",
2989-
InstantiationMode::Def(llvm::LinkOnceAnyLinkage) => "OnceAny",
2990-
InstantiationMode::Def(llvm::LinkOnceODRLinkage) => "OnceODR",
2991-
InstantiationMode::Def(llvm::WeakAnyLinkage) => "WeakAny",
2992-
InstantiationMode::Def(llvm::WeakODRLinkage) => "WeakODR",
2993-
InstantiationMode::Def(llvm::AppendingLinkage) => "Appending",
2994-
InstantiationMode::Def(llvm::InternalLinkage) => "Internal",
2995-
InstantiationMode::Def(llvm::PrivateLinkage) => "Private",
2996-
InstantiationMode::Def(llvm::ExternalWeakLinkage) => "ExternalWeak",
2997-
InstantiationMode::Def(llvm::CommonLinkage) => "Common",
2998-
InstantiationMode::Decl => "Declaration",
2987+
llvm::ExternalLinkage => "External",
2988+
llvm::AvailableExternallyLinkage => "Available",
2989+
llvm::LinkOnceAnyLinkage => "OnceAny",
2990+
llvm::LinkOnceODRLinkage => "OnceODR",
2991+
llvm::WeakAnyLinkage => "WeakAny",
2992+
llvm::WeakODRLinkage => "WeakODR",
2993+
llvm::AppendingLinkage => "Appending",
2994+
llvm::InternalLinkage => "Internal",
2995+
llvm::PrivateLinkage => "Private",
2996+
llvm::ExternalWeakLinkage => "ExternalWeak",
2997+
llvm::CommonLinkage => "Common",
29992998
};
30002999

30013000
output.push_str("[");

src/librustc_trans/collector.rs

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,6 @@
188188
//! this is not implemented however: a translation item will be produced
189189
//! regardless of whether it is actually needed or not.
190190
191-
use rustc_data_structures::bitvec::BitVector;
192-
193191
use rustc::hir;
194192
use rustc::hir::intravisit as hir_visit;
195193

@@ -226,42 +224,33 @@ pub enum TransItemCollectionMode {
226224

227225
/// Maps every translation item to all translation items it references in its
228226
/// body.
229-
pub struct ReferenceMap<'tcx> {
230-
// Maps a source translation item to a range of target translation items.
227+
pub struct InliningMap<'tcx> {
228+
// Maps a source translation item to a range of target translation items
229+
// that are potentially inlined by LLVM into the source.
231230
// The two numbers in the tuple are the start (inclusive) and
232-
// end index (exclusive) within the `targets` and the `inlined` vecs.
231+
// end index (exclusive) within the `targets` vecs.
233232
index: FnvHashMap<TransItem<'tcx>, (usize, usize)>,
234233
targets: Vec<TransItem<'tcx>>,
235-
inlined: BitVector
236234
}
237235

238-
impl<'tcx> ReferenceMap<'tcx> {
236+
impl<'tcx> InliningMap<'tcx> {
239237

240-
fn new() -> ReferenceMap<'tcx> {
241-
ReferenceMap {
238+
fn new() -> InliningMap<'tcx> {
239+
InliningMap {
242240
index: FnvHashMap(),
243241
targets: Vec::new(),
244-
inlined: BitVector::new(64 * 256),
245242
}
246243
}
247244

248-
fn record_references<I>(&mut self, source: TransItem<'tcx>, targets: I)
249-
where I: Iterator<Item=(TransItem<'tcx>, bool)>
245+
fn record_inlining_canditates<I>(&mut self,
246+
source: TransItem<'tcx>,
247+
targets: I)
248+
where I: Iterator<Item=TransItem<'tcx>>
250249
{
251250
assert!(!self.index.contains_key(&source));
252251

253252
let start_index = self.targets.len();
254-
255-
for (target, inlined) in targets {
256-
let index = self.targets.len();
257-
self.targets.push(target);
258-
self.inlined.grow(index + 1);
259-
260-
if inlined {
261-
self.inlined.insert(index);
262-
}
263-
}
264-
253+
self.targets.extend(targets);
265254
let end_index = self.targets.len();
266255
self.index.insert(source, (start_index, end_index));
267256
}
@@ -272,28 +261,17 @@ impl<'tcx> ReferenceMap<'tcx> {
272261
where F: FnMut(TransItem<'tcx>) {
273262
if let Some(&(start_index, end_index)) = self.index.get(&source)
274263
{
275-
for index in start_index .. end_index {
276-
if self.inlined.contains(index) {
277-
f(self.targets[index])
278-
}
264+
for candidate in &self.targets[start_index .. end_index] {
265+
f(*candidate)
279266
}
280267
}
281268
}
282-
283-
pub fn get_direct_references_from(&self, source: TransItem<'tcx>) -> &[TransItem<'tcx>]
284-
{
285-
if let Some(&(start_index, end_index)) = self.index.get(&source) {
286-
&self.targets[start_index .. end_index]
287-
} else {
288-
&self.targets[0 .. 0]
289-
}
290-
}
291269
}
292270

293271
pub fn collect_crate_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
294272
mode: TransItemCollectionMode)
295273
-> (FnvHashSet<TransItem<'tcx>>,
296-
ReferenceMap<'tcx>) {
274+
InliningMap<'tcx>) {
297275
// We are not tracking dependencies of this pass as it has to be re-executed
298276
// every time no matter what.
299277
scx.tcx().dep_graph.with_ignore(|| {
@@ -302,17 +280,17 @@ pub fn collect_crate_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a, 't
302280
debug!("Building translation item graph, beginning at roots");
303281
let mut visited = FnvHashSet();
304282
let mut recursion_depths = DefIdMap();
305-
let mut reference_map = ReferenceMap::new();
283+
let mut inlining_map = InliningMap::new();
306284

307285
for root in roots {
308286
collect_items_rec(scx,
309287
root,
310288
&mut visited,
311289
&mut recursion_depths,
312-
&mut reference_map);
290+
&mut inlining_map);
313291
}
314292

315-
(visited, reference_map)
293+
(visited, inlining_map)
316294
})
317295
}
318296

@@ -343,7 +321,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
343321
starting_point: TransItem<'tcx>,
344322
visited: &mut FnvHashSet<TransItem<'tcx>>,
345323
recursion_depths: &mut DefIdMap<usize>,
346-
reference_map: &mut ReferenceMap<'tcx>) {
324+
inlining_map: &mut InliningMap<'tcx>) {
347325
if !visited.insert(starting_point.clone()) {
348326
// We've been here already, no need to search again.
349327
return;
@@ -390,10 +368,10 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
390368
}
391369
}
392370

393-
record_references(scx.tcx(), starting_point, &neighbors[..], reference_map);
371+
record_inlining_canditates(scx.tcx(), starting_point, &neighbors[..], inlining_map);
394372

395373
for neighbour in neighbors {
396-
collect_items_rec(scx, neighbour, visited, recursion_depths, reference_map);
374+
collect_items_rec(scx, neighbour, visited, recursion_depths, inlining_map);
397375
}
398376

399377
if let Some((def_id, depth)) = recursion_depth_reset {
@@ -403,17 +381,19 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
403381
debug!("END collect_items_rec({})", starting_point.to_string(scx.tcx()));
404382
}
405383

406-
fn record_references<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
407-
caller: TransItem<'tcx>,
408-
callees: &[TransItem<'tcx>],
409-
reference_map: &mut ReferenceMap<'tcx>) {
410-
let iter = callees.into_iter()
411-
.map(|callee| {
412-
let is_inlining_candidate = callee.is_from_extern_crate() ||
413-
callee.requests_inline(tcx);
414-
(*callee, is_inlining_candidate)
415-
});
416-
reference_map.record_references(caller, iter);
384+
fn record_inlining_canditates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
385+
caller: TransItem<'tcx>,
386+
callees: &[TransItem<'tcx>],
387+
inlining_map: &mut InliningMap<'tcx>) {
388+
let is_inlining_candidate = |trans_item: &TransItem<'tcx>| {
389+
trans_item.is_from_extern_crate() || trans_item.requests_inline(tcx)
390+
};
391+
392+
let inlining_candidates = callees.into_iter()
393+
.map(|x| *x)
394+
.filter(is_inlining_candidate);
395+
396+
inlining_map.record_inlining_canditates(caller, inlining_candidates);
417397
}
418398

419399
fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

src/librustc_trans/partitioning.rs

Lines changed: 15 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116
//! source-level module, functions from the same module will be available for
117117
//! inlining, even when they are not marked #[inline].
118118
119-
use collector::ReferenceMap;
119+
use collector::InliningMap;
120120
use llvm;
121121
use monomorphize;
122122
use rustc::hir::def_id::DefId;
@@ -127,20 +127,9 @@ use syntax::parse::token::{self, InternedString};
127127
use trans_item::TransItem;
128128
use util::nodemap::{FnvHashMap, FnvHashSet};
129129

130-
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
131-
pub enum InstantiationMode {
132-
/// This variant indicates that a translation item should be placed in some
133-
/// codegen unit as a definition and with the given linkage.
134-
Def(llvm::Linkage),
135-
136-
/// This variant indicates that only a declaration of some translation item
137-
/// should be placed in a given codegen unit.
138-
Decl
139-
}
140-
141130
pub struct CodegenUnit<'tcx> {
142131
pub name: InternedString,
143-
pub items: FnvHashMap<TransItem<'tcx>, InstantiationMode>,
132+
pub items: FnvHashMap<TransItem<'tcx>, llvm::Linkage>,
144133
}
145134

146135
pub enum PartitioningStrategy {
@@ -157,7 +146,7 @@ const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";
157146
pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
158147
trans_items: I,
159148
strategy: PartitioningStrategy,
160-
reference_map: &ReferenceMap<'tcx>)
149+
inlining_map: &InliningMap<'tcx>)
161150
-> Vec<CodegenUnit<'tcx>>
162151
where I: Iterator<Item = TransItem<'tcx>>
163152
{
@@ -177,13 +166,8 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
177166
// translation items can be drop-glue, functions from external crates, and
178167
// local functions the definition of which is marked with #[inline].
179168
let post_inlining = place_inlined_translation_items(initial_partitioning,
180-
reference_map);
181-
182-
// Now we know all *definitions* within all codegen units, thus we can
183-
// easily determine which declarations need to be placed within each one.
184-
let post_declarations = place_declarations(post_inlining, reference_map);
185-
186-
post_declarations.0
169+
inlining_map);
170+
post_inlining.0
187171
}
188172

189173
struct PreInliningPartitioning<'tcx> {
@@ -192,7 +176,6 @@ struct PreInliningPartitioning<'tcx> {
192176
}
193177

194178
struct PostInliningPartitioning<'tcx>(Vec<CodegenUnit<'tcx>>);
195-
struct PostDeclarationsPartitioning<'tcx>(Vec<CodegenUnit<'tcx>>);
196179

197180
fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
198181
trans_items: I)
@@ -240,8 +223,7 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
240223
}
241224
};
242225

243-
codegen_unit.items.insert(trans_item,
244-
InstantiationMode::Def(linkage));
226+
codegen_unit.items.insert(trans_item, linkage);
245227
roots.insert(trans_item);
246228
}
247229
}
@@ -295,15 +277,15 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
295277
}
296278

297279
fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartitioning<'tcx>,
298-
reference_map: &ReferenceMap<'tcx>)
280+
inlining_map: &InliningMap<'tcx>)
299281
-> PostInliningPartitioning<'tcx> {
300282
let mut new_partitioning = Vec::new();
301283

302284
for codegen_unit in &initial_partitioning.codegen_units[..] {
303285
// Collect all items that need to be available in this codegen unit
304286
let mut reachable = FnvHashSet();
305287
for root in codegen_unit.items.keys() {
306-
follow_inlining(*root, reference_map, &mut reachable);
288+
follow_inlining(*root, inlining_map, &mut reachable);
307289
}
308290

309291
let mut new_codegen_unit = CodegenUnit {
@@ -313,22 +295,22 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit
313295

314296
// Add all translation items that are not already there
315297
for trans_item in reachable {
316-
if let Some(instantiation_mode) = codegen_unit.items.get(&trans_item) {
298+
if let Some(linkage) = codegen_unit.items.get(&trans_item) {
317299
// This is a root, just copy it over
318-
new_codegen_unit.items.insert(trans_item, *instantiation_mode);
300+
new_codegen_unit.items.insert(trans_item, *linkage);
319301
} else {
320302
if initial_partitioning.roots.contains(&trans_item) {
321303
// This item will be instantiated in some other codegen unit,
322304
// so we just add it here with AvailableExternallyLinkage
323305
new_codegen_unit.items.insert(trans_item,
324-
InstantiationMode::Def(llvm::AvailableExternallyLinkage));
306+
llvm::AvailableExternallyLinkage);
325307
} else {
326308
// We can't be sure if this will also be instantiated
327309
// somewhere else, so we add an instance here with
328310
// LinkOnceODRLinkage. That way the item can be discarded if
329311
// it's not needed (inlined) after all.
330312
new_codegen_unit.items.insert(trans_item,
331-
InstantiationMode::Def(llvm::LinkOnceODRLinkage));
313+
llvm::LinkOnceODRLinkage);
332314
}
333315
}
334316
}
@@ -339,43 +321,18 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit
339321
return PostInliningPartitioning(new_partitioning);
340322

341323
fn follow_inlining<'tcx>(trans_item: TransItem<'tcx>,
342-
reference_map: &ReferenceMap<'tcx>,
324+
inlining_map: &InliningMap<'tcx>,
343325
visited: &mut FnvHashSet<TransItem<'tcx>>) {
344326
if !visited.insert(trans_item) {
345327
return;
346328
}
347329

348-
reference_map.with_inlining_candidates(trans_item, |target| {
349-
follow_inlining(target, reference_map, visited);
330+
inlining_map.with_inlining_candidates(trans_item, |target| {
331+
follow_inlining(target, inlining_map, visited);
350332
});
351333
}
352334
}
353335

354-
fn place_declarations<'tcx>(codegen_units: PostInliningPartitioning<'tcx>,
355-
reference_map: &ReferenceMap<'tcx>)
356-
-> PostDeclarationsPartitioning<'tcx> {
357-
let PostInliningPartitioning(mut codegen_units) = codegen_units;
358-
359-
for codegen_unit in codegen_units.iter_mut() {
360-
let mut declarations = FnvHashSet();
361-
362-
for (trans_item, _) in &codegen_unit.items {
363-
for referenced_item in reference_map.get_direct_references_from(*trans_item) {
364-
if !codegen_unit.items.contains_key(referenced_item) {
365-
declarations.insert(*referenced_item);
366-
}
367-
}
368-
}
369-
370-
codegen_unit.items
371-
.extend(declarations.iter()
372-
.map(|trans_item| (*trans_item,
373-
InstantiationMode::Decl)));
374-
}
375-
376-
PostDeclarationsPartitioning(codegen_units)
377-
}
378-
379336
fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
380337
trans_item: TransItem<'tcx>)
381338
-> Option<DefId> {

0 commit comments

Comments
 (0)