Skip to content

Commit 0fc9f9a

Browse files
Make the codegen unit partitioner also emit item declarations.
1 parent 7f04d35 commit 0fc9f9a

15 files changed

+225
-113
lines changed

src/librustc_data_structures/bitvec.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ impl BitVector {
5252

5353
pub fn grow(&mut self, num_bits: usize) {
5454
let num_words = u64s(num_bits);
55-
let extra_words = self.data.len() - num_words;
56-
if extra_words > 0 {
57-
self.data.extend((0..extra_words).map(|_| 0));
55+
if self.data.len() < num_words {
56+
self.data.resize(num_words, 0)
5857
}
5958
}
6059

@@ -284,15 +283,27 @@ fn union_two_vecs() {
284283
#[test]
285284
fn grow() {
286285
let mut vec1 = BitVector::new(65);
287-
assert!(vec1.insert(3));
288-
assert!(!vec1.insert(3));
289-
assert!(vec1.insert(5));
290-
assert!(vec1.insert(64));
286+
for index in 0 .. 65 {
287+
assert!(vec1.insert(index));
288+
assert!(!vec1.insert(index));
289+
}
291290
vec1.grow(128);
292-
assert!(vec1.contains(3));
293-
assert!(vec1.contains(5));
294-
assert!(vec1.contains(64));
295-
assert!(!vec1.contains(126));
291+
292+
// Check if the bits set before growing are still set
293+
for index in 0 .. 65 {
294+
assert!(vec1.contains(index));
295+
}
296+
297+
// Check if the new bits are all un-set
298+
for index in 65 .. 128 {
299+
assert!(!vec1.contains(index));
300+
}
301+
302+
// Check that we can set all new bits without running out of bounds
303+
for index in 65 .. 128 {
304+
assert!(vec1.insert(index));
305+
assert!(!vec1.insert(index));
306+
}
296307
}
297308

298309
#[test]

src/librustc_llvm/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub enum Visibility {
9797
// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
9898
// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
9999
// they've been removed in upstream LLVM commit r203866.
100-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
100+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
101101
pub enum Linkage {
102102
ExternalLinkage = 0,
103103
AvailableExternallyLinkage = 1,

src/librustc_trans/base.rs

+15-14
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ use attributes;
5858
use build::*;
5959
use builder::{Builder, noname};
6060
use callee::{Callee, CallArgs, ArgExprs, ArgVals};
61-
use partitioning::{self, PartitioningStrategy};
6261
use cleanup::{self, CleanupMethods, DropHint};
6362
use closure;
6463
use common::{Block, C_bool, C_bytes_in_context, C_i32, C_int, C_uint, C_integral};
@@ -83,6 +82,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real};
8382
use meth;
8483
use mir;
8584
use monomorphize::{self, Instance};
85+
use partitioning::{self, PartitioningStrategy, InstantiationMode};
8686
use symbol_names_test;
8787
use tvec;
8888
use type_::Type;
@@ -2934,7 +2934,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29342934
None => TransItemCollectionMode::Lazy
29352935
};
29362936

2937-
let (items, inlining_map) = time(time_passes, "translation item collection", || {
2937+
let (items, reference_map) = time(time_passes, "translation item collection", || {
29382938
collector::collect_crate_translation_items(&ccx, collection_mode)
29392939
});
29402940

@@ -2948,7 +2948,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29482948
partitioning::partition(ccx.tcx(),
29492949
items.iter().cloned(),
29502950
strategy,
2951-
&inlining_map)
2951+
&reference_map)
29522952
});
29532953

29542954
if ccx.sess().opts.debugging_opts.print_trans_items.is_some() {
@@ -2976,17 +2976,18 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29762976
output.push_str(&cgu_name[..]);
29772977

29782978
let linkage_abbrev = match linkage {
2979-
llvm::ExternalLinkage => "External",
2980-
llvm::AvailableExternallyLinkage => "Available",
2981-
llvm::LinkOnceAnyLinkage => "OnceAny",
2982-
llvm::LinkOnceODRLinkage => "OnceODR",
2983-
llvm::WeakAnyLinkage => "WeakAny",
2984-
llvm::WeakODRLinkage => "WeakODR",
2985-
llvm::AppendingLinkage => "Appending",
2986-
llvm::InternalLinkage => "Internal",
2987-
llvm::PrivateLinkage => "Private",
2988-
llvm::ExternalWeakLinkage => "ExternalWeak",
2989-
llvm::CommonLinkage => "Common",
2979+
InstantiationMode::Def(llvm::ExternalLinkage) => "External",
2980+
InstantiationMode::Def(llvm::AvailableExternallyLinkage) => "Available",
2981+
InstantiationMode::Def(llvm::LinkOnceAnyLinkage) => "OnceAny",
2982+
InstantiationMode::Def(llvm::LinkOnceODRLinkage) => "OnceODR",
2983+
InstantiationMode::Def(llvm::WeakAnyLinkage) => "WeakAny",
2984+
InstantiationMode::Def(llvm::WeakODRLinkage) => "WeakODR",
2985+
InstantiationMode::Def(llvm::AppendingLinkage) => "Appending",
2986+
InstantiationMode::Def(llvm::InternalLinkage) => "Internal",
2987+
InstantiationMode::Def(llvm::PrivateLinkage) => "Private",
2988+
InstantiationMode::Def(llvm::ExternalWeakLinkage) => "ExternalWeak",
2989+
InstantiationMode::Def(llvm::CommonLinkage) => "Common",
2990+
InstantiationMode::Decl => "Declaration",
29902991
};
29912992

29922993
output.push_str("[");

src/librustc_trans/collector.rs

+86-18
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,8 @@
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+
191193
use rustc::hir;
192194
use rustc::hir::intravisit as hir_visit;
193195

@@ -252,12 +254,76 @@ impl<'tcx> Hash for TransItem<'tcx> {
252254
}
253255
}
254256

255-
pub type InliningMap<'tcx> = FnvHashMap<TransItem<'tcx>, FnvHashSet<TransItem<'tcx>>>;
257+
/// Maps every translation item to all translation items it references in its
258+
/// body.
259+
pub struct ReferenceMap<'tcx> {
260+
// Maps a source translation item to a range of target translation items.
261+
// The two numbers in the tuple are the start (inclusive) and
262+
// end index (exclusive) within the `targets` and the `inlined` vecs.
263+
index: FnvHashMap<TransItem<'tcx>, (usize, usize)>,
264+
targets: Vec<TransItem<'tcx>>,
265+
inlined: BitVector
266+
}
267+
268+
impl<'tcx> ReferenceMap<'tcx> {
269+
270+
fn new() -> ReferenceMap<'tcx> {
271+
ReferenceMap {
272+
index: FnvHashMap(),
273+
targets: Vec::new(),
274+
inlined: BitVector::new(64 * 256),
275+
}
276+
}
277+
278+
fn record_references<I>(&mut self, source: TransItem<'tcx>, targets: I)
279+
where I: Iterator<Item=(TransItem<'tcx>, bool)>
280+
{
281+
assert!(!self.index.contains_key(&source));
282+
283+
let start_index = self.targets.len();
284+
285+
for (target, inlined) in targets {
286+
let index = self.targets.len();
287+
self.targets.push(target);
288+
self.inlined.grow(index + 1);
289+
290+
if inlined {
291+
self.inlined.insert(index);
292+
}
293+
}
294+
295+
let end_index = self.targets.len();
296+
self.index.insert(source, (start_index, end_index));
297+
}
298+
299+
// Internally iterate over all items referenced by `source` which will be
300+
// made available for inlining.
301+
pub fn with_inlining_candidates<F>(&self, source: TransItem<'tcx>, mut f: F)
302+
where F: FnMut(TransItem<'tcx>) {
303+
if let Some(&(start_index, end_index)) = self.index.get(&source)
304+
{
305+
for index in start_index .. end_index {
306+
if self.inlined.contains(index) {
307+
f(self.targets[index])
308+
}
309+
}
310+
}
311+
}
312+
313+
pub fn get_direct_references_from(&self, source: TransItem<'tcx>) -> &[TransItem<'tcx>]
314+
{
315+
if let Some(&(start_index, end_index)) = self.index.get(&source) {
316+
&self.targets[start_index .. end_index]
317+
} else {
318+
&self.targets[0 .. 0]
319+
}
320+
}
321+
}
256322

257323
pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
258324
mode: TransItemCollectionMode)
259325
-> (FnvHashSet<TransItem<'tcx>>,
260-
InliningMap<'tcx>) {
326+
ReferenceMap<'tcx>) {
261327
// We are not tracking dependencies of this pass as it has to be re-executed
262328
// every time no matter what.
263329
ccx.tcx().dep_graph.with_ignore(|| {
@@ -266,17 +332,17 @@ pub fn collect_crate_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
266332
debug!("Building translation item graph, beginning at roots");
267333
let mut visited = FnvHashSet();
268334
let mut recursion_depths = DefIdMap();
269-
let mut inlining_map = FnvHashMap();
335+
let mut reference_map = ReferenceMap::new();
270336

271337
for root in roots {
272338
collect_items_rec(ccx,
273339
root,
274340
&mut visited,
275341
&mut recursion_depths,
276-
&mut inlining_map);
342+
&mut reference_map);
277343
}
278344

279-
(visited, inlining_map)
345+
(visited, reference_map)
280346
})
281347
}
282348

@@ -307,7 +373,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
307373
starting_point: TransItem<'tcx>,
308374
visited: &mut FnvHashSet<TransItem<'tcx>>,
309375
recursion_depths: &mut DefIdMap<usize>,
310-
inlining_map: &mut InliningMap<'tcx>) {
376+
reference_map: &mut ReferenceMap<'tcx>) {
311377
if !visited.insert(starting_point.clone()) {
312378
// We've been here already, no need to search again.
313379
return;
@@ -351,9 +417,10 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
351417
}
352418
}
353419

420+
record_references(ccx, starting_point, &neighbors[..], reference_map);
421+
354422
for neighbour in neighbors {
355-
record_inlined_use(ccx, starting_point, neighbour, inlining_map);
356-
collect_items_rec(ccx, neighbour, visited, recursion_depths, inlining_map);
423+
collect_items_rec(ccx, neighbour, visited, recursion_depths, reference_map);
357424
}
358425

359426
if let Some((def_id, depth)) = recursion_depth_reset {
@@ -363,16 +430,17 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
363430
debug!("END collect_items_rec({})", starting_point.to_string(ccx));
364431
}
365432

366-
fn record_inlined_use<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
367-
caller: TransItem<'tcx>,
368-
callee: TransItem<'tcx>,
369-
inlining_map: &mut InliningMap<'tcx>) {
370-
if callee.is_from_extern_crate() ||
371-
callee.requests_inline(ccx.tcx()) {
372-
inlining_map.entry(caller)
373-
.or_insert_with(|| FnvHashSet())
374-
.insert(callee);
375-
}
433+
fn record_references<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
434+
caller: TransItem<'tcx>,
435+
callees: &[TransItem<'tcx>],
436+
reference_map: &mut ReferenceMap<'tcx>) {
437+
let iter = callees.into_iter()
438+
.map(|callee| {
439+
let is_inlining_candidate = callee.is_from_extern_crate() ||
440+
callee.requests_inline(ccx.tcx());
441+
(*callee, is_inlining_candidate)
442+
});
443+
reference_map.record_references(caller, iter);
376444
}
377445

378446
fn check_recursion_limit<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,

0 commit comments

Comments
 (0)