Skip to content

Commit d5c9577

Browse files
Implement the translation item collector.
The purpose of the translation item collector is to find all monomorphic instances of functions, methods and statics that need to be translated into LLVM IR in order to compile the current crate. So far these instances have been discovered lazily during the trans path. For incremental compilation we want to know the set of these instances in advance, and that is what the trans::collect module provides. In the future, incremental and regular translation will be driven by the collector implemented here.
1 parent 5b3a75f commit d5c9577

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3405
-38
lines changed

configure

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,7 @@ do
13911391
make_dir $h/test/debuginfo-gdb
13921392
make_dir $h/test/debuginfo-lldb
13931393
make_dir $h/test/codegen
1394+
make_dir $h/test/codegen-units
13941395
make_dir $h/test/rustdoc
13951396
done
13961397

mk/tests.mk

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
321321
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-gdb-exec \
322322
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-lldb-exec \
323323
check-stage$(1)-T-$(2)-H-$(3)-codegen-exec \
324+
check-stage$(1)-T-$(2)-H-$(3)-codegen-units-exec \
324325
check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
325326
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec
326327

@@ -484,6 +485,7 @@ DEBUGINFO_GDB_RS := $(wildcard $(S)src/test/debuginfo/*.rs)
484485
DEBUGINFO_LLDB_RS := $(wildcard $(S)src/test/debuginfo/*.rs)
485486
CODEGEN_RS := $(wildcard $(S)src/test/codegen/*.rs)
486487
CODEGEN_CC := $(wildcard $(S)src/test/codegen/*.cc)
488+
CODEGEN_UNITS_RS := $(wildcard $(S)src/test/codegen-units/*.rs)
487489
RUSTDOCCK_RS := $(wildcard $(S)src/test/rustdoc/*.rs)
488490

489491
# perf tests are the same as bench tests only they run under
@@ -504,6 +506,7 @@ PRETTY_TESTS := $(PRETTY_RS)
504506
DEBUGINFO_GDB_TESTS := $(DEBUGINFO_GDB_RS)
505507
DEBUGINFO_LLDB_TESTS := $(DEBUGINFO_LLDB_RS)
506508
CODEGEN_TESTS := $(CODEGEN_RS) $(CODEGEN_CC)
509+
CODEGEN_UNITS_TESTS := $(CODEGEN_UNITS_RS)
507510
RUSTDOCCK_TESTS := $(RUSTDOCCK_RS)
508511

509512
CTEST_SRC_BASE_rpass = run-pass
@@ -571,6 +574,11 @@ CTEST_BUILD_BASE_codegen = codegen
571574
CTEST_MODE_codegen = codegen
572575
CTEST_RUNTOOL_codegen = $(CTEST_RUNTOOL)
573576

577+
CTEST_SRC_BASE_codegen-units = codegen-units
578+
CTEST_BUILD_BASE_codegen-units = codegen-units
579+
CTEST_MODE_codegen-units = codegen-units
580+
CTEST_RUNTOOL_codegen-units = $(CTEST_RUNTOOL)
581+
574582
CTEST_SRC_BASE_rustdocck = rustdoc
575583
CTEST_BUILD_BASE_rustdocck = rustdoc
576584
CTEST_MODE_rustdocck = rustdoc
@@ -695,6 +703,7 @@ CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS) \
695703
$(S)src/etc/lldb_batchmode.py \
696704
$(S)src/etc/lldb_rust_formatters.py
697705
CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS)
706+
CTEST_DEPS_codegen-units_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_UNITS_TESTS)
698707
CTEST_DEPS_rustdocck_$(1)-T-$(2)-H-$(3) = $$(RUSTDOCCK_TESTS) \
699708
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
700709
$(S)src/etc/htmldocck.py
@@ -761,7 +770,7 @@ endif
761770
endef
762771

763772
CTEST_NAMES = rpass rpass-valgrind rpass-full rfail-full cfail-full rfail cfail pfail \
764-
bench perf debuginfo-gdb debuginfo-lldb codegen rustdocck
773+
bench perf debuginfo-gdb debuginfo-lldb codegen codegen-units rustdocck
765774

766775
$(foreach host,$(CFG_HOST), \
767776
$(eval $(foreach target,$(CFG_TARGET), \
@@ -940,6 +949,7 @@ TEST_GROUPS = \
940949
debuginfo-gdb \
941950
debuginfo-lldb \
942951
codegen \
952+
codegen-units \
943953
doc \
944954
$(foreach docname,$(DOC_NAMES),doc-$(docname)) \
945955
pretty \

src/compiletest/common.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub enum Mode {
2525
DebugInfoLldb,
2626
Codegen,
2727
Rustdoc,
28+
CodegenUnits
2829
}
2930

3031
impl FromStr for Mode {
@@ -41,6 +42,7 @@ impl FromStr for Mode {
4142
"debuginfo-gdb" => Ok(DebugInfoGdb),
4243
"codegen" => Ok(Codegen),
4344
"rustdoc" => Ok(Rustdoc),
45+
"codegen-units" => Ok(CodegenUnits),
4446
_ => Err(()),
4547
}
4648
}
@@ -59,6 +61,7 @@ impl fmt::Display for Mode {
5961
DebugInfoLldb => "debuginfo-lldb",
6062
Codegen => "codegen",
6163
Rustdoc => "rustdoc",
64+
CodegenUnits => "codegen-units",
6265
}, f)
6366
}
6467
}

src/compiletest/runtest.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010

1111
use common::Config;
1212
use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
13-
use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc};
13+
use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits};
1414
use errors;
1515
use header::TestProps;
1616
use header;
1717
use procsrv;
1818
use util::logv;
1919

2020
use std::env;
21+
use std::collections::HashSet;
2122
use std::fmt;
2223
use std::fs::{self, File};
2324
use std::io::BufReader;
@@ -56,6 +57,7 @@ pub fn run(config: Config, testfile: &Path) {
5657
DebugInfoLldb => run_debuginfo_lldb_test(&config, &props, &testfile),
5758
Codegen => run_codegen_test(&config, &props, &testfile),
5859
Rustdoc => run_rustdoc_test(&config, &props, &testfile),
60+
CodegenUnits => run_codegen_units_test(&config, &props, &testfile),
5961
}
6062
}
6163

@@ -1747,3 +1749,44 @@ fn run_rustdoc_test(config: &Config, props: &TestProps, testfile: &Path) {
17471749
fatal_proc_rec("htmldocck failed!", &res);
17481750
}
17491751
}
1752+
1753+
fn run_codegen_units_test(config: &Config, props: &TestProps, testfile: &Path) {
1754+
let proc_res = compile_test(config, props, testfile);
1755+
1756+
if !proc_res.status.success() {
1757+
fatal_proc_rec("compilation failed!", &proc_res);
1758+
}
1759+
1760+
check_no_compiler_crash(&proc_res);
1761+
1762+
let prefix = "TRANS_ITEM ";
1763+
1764+
let actual: HashSet<String> = proc_res
1765+
.stdout
1766+
.lines()
1767+
.filter(|line| line.starts_with(prefix))
1768+
.map(|s| (&s[prefix.len()..]).to_string())
1769+
.collect();
1770+
1771+
let expected: HashSet<String> = errors::load_errors(testfile)
1772+
.iter()
1773+
.map(|e| e.msg.trim().to_string())
1774+
.collect();
1775+
1776+
if actual != expected {
1777+
let mut missing: Vec<_> = expected.difference(&actual).collect();
1778+
missing.sort();
1779+
1780+
let mut too_much: Vec<_> = actual.difference(&expected).collect();
1781+
too_much.sort();
1782+
1783+
println!("Expected and actual sets of codegen-items differ.\n\
1784+
These items should have been contained but were not:\n\n\
1785+
{}\n\n\
1786+
These items were contained but should not have been:\n\n\
1787+
{}\n\n",
1788+
missing.iter().fold("".to_string(), |s1, s2| s1 + "\n" + s2),
1789+
too_much.iter().fold("".to_string(), |s1, s2| s1 + "\n" + s2));
1790+
panic!();
1791+
}
1792+
}

src/librustc/front/map/definitions.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,33 +196,33 @@ impl DefPathData {
196196

197197
PositionalField |
198198
Field(hir::StructFieldKind::UnnamedField(_)) => {
199-
InternedString::new("<field>")
199+
InternedString::new("{{field}}")
200200
}
201201

202202
// note that this does not show up in user printouts
203203
CrateRoot => {
204-
InternedString::new("<root>")
204+
InternedString::new("{{root}}")
205205
}
206206

207207
// note that this does not show up in user printouts
208208
InlinedRoot(_) => {
209-
InternedString::new("<inlined-root>")
209+
InternedString::new("{{inlined-root}}")
210210
}
211211

212212
Misc => {
213-
InternedString::new("?")
213+
InternedString::new("{{?}}")
214214
}
215215

216216
ClosureExpr => {
217-
InternedString::new("<closure>")
217+
InternedString::new("{{closure}}")
218218
}
219219

220220
StructCtor => {
221-
InternedString::new("<constructor>")
221+
InternedString::new("{{constructor}}")
222222
}
223223

224224
Initializer => {
225-
InternedString::new("<initializer>")
225+
InternedString::new("{{initializer}}")
226226
}
227227
}
228228
}

src/librustc/middle/ty/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ pub struct ctxt<'tcx> {
408408
/// fragmented data to the set of unfragmented pieces that
409409
/// constitute it.
410410
pub fragment_infos: RefCell<DefIdMap<Vec<ty::FragmentInfo>>>,
411+
412+
/// Maps inlined closures from their original DefId to their local NodeId
413+
pub inlined_closures: RefCell<DepTrackingMap<maps::InlinedClosures<'tcx>>>,
411414
}
412415

413416
impl<'tcx> ctxt<'tcx> {
@@ -563,6 +566,7 @@ impl<'tcx> ctxt<'tcx> {
563566
custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
564567
cast_kinds: RefCell::new(NodeMap()),
565568
fragment_infos: RefCell::new(DefIdMap()),
569+
inlined_closures: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
566570
}, f)
567571
}
568572
}

src/librustc/middle/ty/maps.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use middle::def_id::DefId;
1313
use middle::ty;
1414
use std::marker::PhantomData;
1515
use std::rc::Rc;
16-
use syntax::attr;
16+
use syntax::{attr, ast};
1717

1818
macro_rules! dep_map_ty {
1919
($ty_name:ident : $node_name:ident ($key:ty) -> $value:ty) => {
@@ -42,3 +42,4 @@ dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Rc<Vec<DefId>> }
4242
dep_map_ty! { ImplItems: ImplItems(DefId) -> Vec<ty::ImplOrTraitItemId> }
4343
dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> }
4444
dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
45+
dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId }

src/librustc/mir/repr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ pub enum Rvalue<'tcx> {
720720
InlineAsm(InlineAsm),
721721
}
722722

723-
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
723+
#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
724724
pub enum CastKind {
725725
Misc,
726726

src/librustc/session/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
634634
"keep the AST after lowering it to HIR"),
635635
show_span: Option<String> = (None, parse_opt_string,
636636
"show spans for compiler debugging (expr|pat|ty)"),
637+
print_trans_items: Option<String> = (None, parse_opt_string,
638+
"print the result of the translation item collection pass"),
637639
}
638640

639641
pub fn default_lib_output() -> CrateType {

src/librustc_metadata/astencode.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414

1515
use rustc::front::map as ast_map;
1616
use rustc::session::Session;
17+
use rustc::util::common::MemoizationMap;
1718

1819
use rustc_front::hir;
1920
use rustc_front::fold;
2021
use rustc_front::fold::Folder;
22+
use rustc_front::intravisit;
2123

2224
use common as c;
2325
use cstore;
@@ -177,6 +179,8 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
177179
}
178180
_ => { }
179181
}
182+
register_inlined_closures(dcx.tcx, ii);
183+
180184
Ok(ii)
181185
}
182186
}
@@ -1274,6 +1278,41 @@ fn inlined_item_id_range(v: &InlinedItem) -> ast_util::IdRange {
12741278
visitor.result()
12751279
}
12761280

1281+
fn register_inlined_closures<'tcx, 'ii>(tcx: &ty::ctxt<'tcx>,
1282+
ii: &'ii InlinedItem)
1283+
where 'tcx: 'ii {
1284+
1285+
let mut visitor = ClosureVisitor { tcx: tcx };
1286+
ii.visit(&mut visitor);
1287+
1288+
struct ClosureVisitor<'a, 'tcx>
1289+
where 'tcx: 'a {
1290+
tcx: &'a ty::ctxt<'tcx>
1291+
}
1292+
1293+
impl<'a, 'tcx, 'v> intravisit::Visitor<'v> for ClosureVisitor<'a, 'tcx>
1294+
where 'tcx: 'a,
1295+
'tcx: 'v {
1296+
1297+
fn visit_fn(&mut self,
1298+
fk: intravisit::FnKind<'v>,
1299+
fd: &'v hir::FnDecl,
1300+
b: &'v hir::Block,
1301+
s: codemap::Span,
1302+
id: ast::NodeId) {
1303+
1304+
if let intravisit::FnKind::Closure = fk {
1305+
let ty = self.tcx.node_id_to_type(id);
1306+
if let ty::TyClosure(def_id, _) = ty.sty {
1307+
self.tcx.inlined_closures.memoize(def_id, || id );
1308+
}
1309+
}
1310+
1311+
intravisit::walk_fn(self, fk, fd, b, s)
1312+
}
1313+
}
1314+
}
1315+
12771316
// ______________________________________________________________________
12781317
// Testing of astencode_gen
12791318

src/librustc_metadata/decoder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,8 @@ pub fn maybe_get_item_mir<'tcx>(cdata: Cmd,
834834
})
835835
}).unwrap();
836836

837+
assert!(decoder.position() == mir_doc.end);
838+
837839
let mut def_id_and_span_translator = MirDefIdAndSpanTranslator {
838840
crate_metadata: cdata,
839841
codemap: tcx.sess.codemap(),

0 commit comments

Comments
 (0)