Skip to content

Commit

Permalink
Implement the translation item collector.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
michaelwoerister committed Jan 26, 2016
1 parent b279c5b commit 862911d
Show file tree
Hide file tree
Showing 46 changed files with 3,296 additions and 61 deletions.
1 change: 1 addition & 0 deletions configure
Expand Up @@ -1409,6 +1409,7 @@ do
make_dir $h/test/debuginfo-gdb
make_dir $h/test/debuginfo-lldb
make_dir $h/test/codegen
make_dir $h/test/codegen-units
make_dir $h/test/rustdoc
done

Expand Down
12 changes: 11 additions & 1 deletion mk/tests.mk
Expand Up @@ -310,6 +310,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-gdb-exec \
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-lldb-exec \
check-stage$(1)-T-$(2)-H-$(3)-codegen-exec \
check-stage$(1)-T-$(2)-H-$(3)-codegen-units-exec \
check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec

Expand Down Expand Up @@ -473,6 +474,7 @@ DEBUGINFO_GDB_RS := $(wildcard $(S)src/test/debuginfo/*.rs)
DEBUGINFO_LLDB_RS := $(wildcard $(S)src/test/debuginfo/*.rs)
CODEGEN_RS := $(wildcard $(S)src/test/codegen/*.rs)
CODEGEN_CC := $(wildcard $(S)src/test/codegen/*.cc)
CODEGEN_UNITS_RS := $(wildcard $(S)src/test/codegen-units/*.rs)
RUSTDOCCK_RS := $(wildcard $(S)src/test/rustdoc/*.rs)

RPASS_TESTS := $(RPASS_RS)
Expand All @@ -488,6 +490,7 @@ PRETTY_TESTS := $(PRETTY_RS)
DEBUGINFO_GDB_TESTS := $(DEBUGINFO_GDB_RS)
DEBUGINFO_LLDB_TESTS := $(DEBUGINFO_LLDB_RS)
CODEGEN_TESTS := $(CODEGEN_RS) $(CODEGEN_CC)
CODEGEN_UNITS_TESTS := $(CODEGEN_UNITS_RS)
RUSTDOCCK_TESTS := $(RUSTDOCCK_RS)

CTEST_SRC_BASE_rpass = run-pass
Expand Down Expand Up @@ -550,6 +553,11 @@ CTEST_BUILD_BASE_codegen = codegen
CTEST_MODE_codegen = codegen
CTEST_RUNTOOL_codegen = $(CTEST_RUNTOOL)

CTEST_SRC_BASE_codegen-units = codegen-units
CTEST_BUILD_BASE_codegen-units = codegen-units
CTEST_MODE_codegen-units = codegen-units
CTEST_RUNTOOL_codegen-units = $(CTEST_RUNTOOL)

CTEST_SRC_BASE_rustdocck = rustdoc
CTEST_BUILD_BASE_rustdocck = rustdoc
CTEST_MODE_rustdocck = rustdoc
Expand Down Expand Up @@ -673,6 +681,7 @@ CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS) \
$(S)src/etc/lldb_batchmode.py \
$(S)src/etc/lldb_rust_formatters.py
CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS)
CTEST_DEPS_codegen-units_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_UNITS_TESTS)
CTEST_DEPS_rustdocck_$(1)-T-$(2)-H-$(3) = $$(RUSTDOCCK_TESTS) \
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
$(S)src/etc/htmldocck.py
Expand Down Expand Up @@ -739,7 +748,7 @@ endif
endef

CTEST_NAMES = rpass rpass-valgrind rpass-full rfail-full cfail-full rfail cfail pfail \
bench debuginfo-gdb debuginfo-lldb codegen rustdocck
bench debuginfo-gdb debuginfo-lldb codegen codegen-units rustdocck

$(foreach host,$(CFG_HOST), \
$(eval $(foreach target,$(CFG_TARGET), \
Expand Down Expand Up @@ -917,6 +926,7 @@ TEST_GROUPS = \
debuginfo-gdb \
debuginfo-lldb \
codegen \
codegen-units \
doc \
$(foreach docname,$(DOC_NAMES),doc-$(docname)) \
pretty \
Expand Down
3 changes: 3 additions & 0 deletions src/compiletest/common.rs
Expand Up @@ -25,6 +25,7 @@ pub enum Mode {
DebugInfoLldb,
Codegen,
Rustdoc,
CodegenUnits
}

impl FromStr for Mode {
Expand All @@ -41,6 +42,7 @@ impl FromStr for Mode {
"debuginfo-gdb" => Ok(DebugInfoGdb),
"codegen" => Ok(Codegen),
"rustdoc" => Ok(Rustdoc),
"codegen-units" => Ok(CodegenUnits),
_ => Err(()),
}
}
Expand All @@ -59,6 +61,7 @@ impl fmt::Display for Mode {
DebugInfoLldb => "debuginfo-lldb",
Codegen => "codegen",
Rustdoc => "rustdoc",
CodegenUnits => "codegen-units",
}, f)
}
}
Expand Down
45 changes: 44 additions & 1 deletion src/compiletest/runtest.rs
Expand Up @@ -10,14 +10,15 @@

use common::Config;
use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc};
use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits};
use errors;
use header::TestProps;
use header;
use procsrv;
use util::logv;

use std::env;
use std::collections::HashSet;
use std::fmt;
use std::fs::{self, File};
use std::io::BufReader;
Expand Down Expand Up @@ -56,6 +57,7 @@ pub fn run(config: Config, testfile: &Path) {
DebugInfoLldb => run_debuginfo_lldb_test(&config, &props, &testfile),
Codegen => run_codegen_test(&config, &props, &testfile),
Rustdoc => run_rustdoc_test(&config, &props, &testfile),
CodegenUnits => run_codegen_units_test(&config, &props, &testfile),
}
}

Expand Down Expand Up @@ -1747,3 +1749,44 @@ fn run_rustdoc_test(config: &Config, props: &TestProps, testfile: &Path) {
fatal_proc_rec("htmldocck failed!", &res);
}
}

fn run_codegen_units_test(config: &Config, props: &TestProps, testfile: &Path) {
let proc_res = compile_test(config, props, testfile);

if !proc_res.status.success() {
fatal_proc_rec("compilation failed!", &proc_res);
}

check_no_compiler_crash(&proc_res);

let prefix = "TRANS_ITEM ";

let actual: HashSet<String> = proc_res
.stdout
.lines()
.filter(|line| line.starts_with(prefix))
.map(|s| (&s[prefix.len()..]).to_string())
.collect();

let expected: HashSet<String> = errors::load_errors(testfile)
.iter()
.map(|e| e.msg.trim().to_string())
.collect();

if actual != expected {
let mut missing: Vec<_> = expected.difference(&actual).collect();
missing.sort();

let mut too_much: Vec<_> = actual.difference(&expected).collect();
too_much.sort();

println!("Expected and actual sets of codegen-items differ.\n\
These items should have been contained but were not:\n\n\
{}\n\n\
These items were contained but should not have been:\n\n\
{}\n\n",
missing.iter().fold("".to_string(), |s1, s2| s1 + "\n" + s2),
too_much.iter().fold("".to_string(), |s1, s2| s1 + "\n" + s2));
panic!();
}
}
14 changes: 7 additions & 7 deletions src/librustc/front/map/definitions.rs
Expand Up @@ -196,33 +196,33 @@ impl DefPathData {

PositionalField |
Field(hir::StructFieldKind::UnnamedField(_)) => {
InternedString::new("<field>")
InternedString::new("{{field}}")
}

// note that this does not show up in user printouts
CrateRoot => {
InternedString::new("<root>")
InternedString::new("{{root}}")
}

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

Misc => {
InternedString::new("?")
InternedString::new("{{?}}")
}

ClosureExpr => {
InternedString::new("<closure>")
InternedString::new("{{closure}}")
}

StructCtor => {
InternedString::new("<constructor>")
InternedString::new("{{constructor}}")
}

Initializer => {
InternedString::new("<initializer>")
InternedString::new("{{initializer}}")
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/middle/cstore.rs
Expand Up @@ -223,6 +223,8 @@ pub trait CrateStore<'tcx> : Any {
-> FoundAst<'tcx>;
fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
-> Option<Mir<'tcx>>;
fn is_item_mir_available(&self, def: DefId) -> bool;

// This is basically a 1-based range of ints, which is a little
// silly - I may fix that.
fn crates(&self) -> Vec<ast::CrateNum>;
Expand Down Expand Up @@ -397,6 +399,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
-> FoundAst<'tcx> { unimplemented!() }
fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
-> Option<Mir<'tcx>> { unimplemented!() }
fn is_item_mir_available(&self, def: DefId) -> bool {
unimplemented!()
}

// This is basically a 1-based range of ints, which is a little
// silly - I may fix that.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty/context.rs
Expand Up @@ -563,7 +563,7 @@ impl<'tcx> ctxt<'tcx> {
const_qualif_map: RefCell::new(NodeMap()),
custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
cast_kinds: RefCell::new(NodeMap()),
fragment_infos: RefCell::new(DefIdMap()),
fragment_infos: RefCell::new(DefIdMap())
}, f)
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/ty/maps.rs
Expand Up @@ -13,7 +13,7 @@ use middle::def_id::DefId;
use middle::ty;
use std::marker::PhantomData;
use std::rc::Rc;
use syntax::attr;
use syntax::{attr, ast};

macro_rules! dep_map_ty {
($ty_name:ident : $node_name:ident ($key:ty) -> $value:ty) => {
Expand Down Expand Up @@ -42,3 +42,4 @@ dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Rc<Vec<DefId>> }
dep_map_ty! { ImplItems: ImplItems(DefId) -> Vec<ty::ImplOrTraitItemId> }
dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> }
dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId }
2 changes: 1 addition & 1 deletion src/librustc/mir/repr.rs
Expand Up @@ -721,7 +721,7 @@ pub enum Rvalue<'tcx> {
InlineAsm(InlineAsm),
}

#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum CastKind {
Misc,

Expand Down
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Expand Up @@ -643,6 +643,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"keep the AST after lowering it to HIR"),
show_span: Option<String> = (None, parse_opt_string,
"show spans for compiler debugging (expr|pat|ty)"),
print_trans_items: Option<String> = (None, parse_opt_string,
"print the result of the translation item collection pass"),
}

pub fn default_lib_output() -> CrateType {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_metadata/astencode.rs
Expand Up @@ -177,6 +177,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
}
_ => { }
}

Ok(ii)
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/librustc_metadata/csearch.rs
Expand Up @@ -445,6 +445,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
decoder::maybe_get_item_mir(&*cdata, tcx, def.index)
}

fn is_item_mir_available(&self, def: DefId) -> bool {
let cdata = self.get_crate_data(def.krate);
decoder::is_item_mir_available(&*cdata, def.index)
}

fn crates(&self) -> Vec<ast::CrateNum>
{
let mut result = vec![];
Expand Down
10 changes: 10 additions & 0 deletions src/librustc_metadata/decoder.rs
Expand Up @@ -830,6 +830,14 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd,
}
}

pub fn is_item_mir_available<'tcx>(cdata: Cmd, id: DefIndex) -> bool {
if let Some(item_doc) = cdata.get_item(id) {
return reader::maybe_get_doc(item_doc, tag_mir as usize).is_some();
}

false
}

pub fn maybe_get_item_mir<'tcx>(cdata: Cmd,
tcx: &ty::ctxt<'tcx>,
id: DefIndex)
Expand All @@ -849,6 +857,8 @@ pub fn maybe_get_item_mir<'tcx>(cdata: Cmd,
})
}).unwrap();

assert!(decoder.position() == mir_doc.end);

let mut def_id_and_span_translator = MirDefIdAndSpanTranslator {
crate_metadata: cdata,
codemap: tcx.sess.codemap(),
Expand Down

0 comments on commit 862911d

Please sign in to comment.