librustc: Only emit constructor functions as necessary.
This commit is contained in:
parent
06bf73a646
commit
27748b09d8
3 changed files with 27 additions and 62 deletions
|
@ -314,8 +314,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
|
||||||
ebml_w: &mut Encoder,
|
ebml_w: &mut Encoder,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
variants: &[P<Variant>],
|
variants: &[P<Variant>],
|
||||||
index: &mut Vec<entry<i64>>,
|
index: &mut Vec<entry<i64>>) {
|
||||||
generics: &ast::Generics) {
|
|
||||||
debug!("encode_enum_variant_info(id={:?})", id);
|
debug!("encode_enum_variant_info(id={:?})", id);
|
||||||
|
|
||||||
let mut disr_val = 0;
|
let mut disr_val = 0;
|
||||||
|
@ -343,10 +342,6 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
|
||||||
encode_stability(ebml_w, stab);
|
encode_stability(ebml_w, stab);
|
||||||
|
|
||||||
match variant.node.kind {
|
match variant.node.kind {
|
||||||
ast::TupleVariantKind(ref args)
|
|
||||||
if args.len() > 0 && generics.ty_params.len() == 0 => {
|
|
||||||
encode_symbol(ecx, ebml_w, variant.node.id);
|
|
||||||
}
|
|
||||||
ast::TupleVariantKind(_) => {},
|
ast::TupleVariantKind(_) => {},
|
||||||
ast::StructVariantKind(_) => {
|
ast::StructVariantKind(_) => {
|
||||||
let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
|
let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
|
||||||
|
@ -1019,7 +1014,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
encode_stability(ebml_w, stab);
|
encode_stability(ebml_w, stab);
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
ItemEnum(ref enum_definition, ref generics) => {
|
ItemEnum(ref enum_definition, _) => {
|
||||||
add_to_index(item, ebml_w, index);
|
add_to_index(item, ebml_w, index);
|
||||||
|
|
||||||
ebml_w.start_tag(tag_items_data_item);
|
ebml_w.start_tag(tag_items_data_item);
|
||||||
|
@ -1046,8 +1041,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
ebml_w,
|
ebml_w,
|
||||||
item.id,
|
item.id,
|
||||||
(*enum_definition).variants.as_slice(),
|
(*enum_definition).variants.as_slice(),
|
||||||
index,
|
index);
|
||||||
generics);
|
|
||||||
}
|
}
|
||||||
ItemStruct(struct_def, _) => {
|
ItemStruct(struct_def, _) => {
|
||||||
let fields = ty::lookup_struct_fields(tcx, def_id);
|
let fields = ty::lookup_struct_fields(tcx, def_id);
|
||||||
|
|
|
@ -80,7 +80,6 @@ use std::c_str::ToCStr;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::{i8, i16, i32, i64};
|
use std::{i8, i16, i32, i64};
|
||||||
use std::gc::Gc;
|
|
||||||
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel, Rust, RustCall};
|
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel, Rust, RustCall};
|
||||||
use syntax::abi::{RustIntrinsic, Abi};
|
use syntax::abi::{RustIntrinsic, Abi};
|
||||||
use syntax::ast_util::{local_def, is_local};
|
use syntax::ast_util::{local_def, is_local};
|
||||||
|
@ -1815,31 +1814,6 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
|
||||||
finish_fn(&fcx, bcx, result_ty);
|
finish_fn(&fcx, bcx, result_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
|
|
||||||
sp: Span, id: ast::NodeId, vi: &[Rc<ty::VariantInfo>],
|
|
||||||
i: &mut uint) {
|
|
||||||
for variant in enum_definition.variants.iter() {
|
|
||||||
let disr_val = vi[*i].disr_val;
|
|
||||||
*i += 1;
|
|
||||||
|
|
||||||
match variant.node.kind {
|
|
||||||
ast::TupleVariantKind(ref args) if args.len() > 0 => {
|
|
||||||
let llfn = get_item_val(ccx, variant.node.id);
|
|
||||||
trans_enum_variant(ccx, id, &**variant, args.as_slice(),
|
|
||||||
disr_val, ¶m_substs::empty(), llfn);
|
|
||||||
}
|
|
||||||
ast::TupleVariantKind(_) => {
|
|
||||||
// Nothing to do.
|
|
||||||
}
|
|
||||||
ast::StructVariantKind(struct_def) => {
|
|
||||||
trans_struct_def(ccx, struct_def);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum_variant_size_lint(ccx, enum_definition, sp, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, id: ast::NodeId) {
|
fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, id: ast::NodeId) {
|
||||||
let mut sizes = Vec::new(); // does no allocation if no pushes, thankfully
|
let mut sizes = Vec::new(); // does no allocation if no pushes, thankfully
|
||||||
|
|
||||||
|
@ -1932,12 +1906,8 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
||||||
ast::ItemMod(ref m) => {
|
ast::ItemMod(ref m) => {
|
||||||
trans_mod(ccx, m);
|
trans_mod(ccx, m);
|
||||||
}
|
}
|
||||||
ast::ItemEnum(ref enum_definition, ref generics) => {
|
ast::ItemEnum(ref enum_definition, _) => {
|
||||||
if !generics.is_type_parameterized() {
|
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
|
||||||
let vi = ty::enum_variants(ccx.tcx(), local_def(item.id));
|
|
||||||
let mut i = 0;
|
|
||||||
trans_enum_def(ccx, enum_definition, item.span, item.id, vi.as_slice(), &mut i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast::ItemStatic(_, m, ref expr) => {
|
ast::ItemStatic(_, m, ref expr) => {
|
||||||
// Recurse on the expression to catch items in blocks
|
// Recurse on the expression to catch items in blocks
|
||||||
|
@ -1964,11 +1934,6 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
||||||
ast::ItemForeignMod(ref foreign_mod) => {
|
ast::ItemForeignMod(ref foreign_mod) => {
|
||||||
foreign::trans_foreign_mod(ccx, foreign_mod);
|
foreign::trans_foreign_mod(ccx, foreign_mod);
|
||||||
}
|
}
|
||||||
ast::ItemStruct(struct_def, ref generics) => {
|
|
||||||
if !generics.is_type_parameterized() {
|
|
||||||
trans_struct_def(ccx, struct_def);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::ItemTrait(..) => {
|
ast::ItemTrait(..) => {
|
||||||
// Inside of this trait definition, we won't be actually translating any
|
// Inside of this trait definition, we won't be actually translating any
|
||||||
// functions, but the trait still needs to be walked. Otherwise default
|
// functions, but the trait still needs to be walked. Otherwise default
|
||||||
|
@ -1981,20 +1946,6 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trans_struct_def(ccx: &CrateContext, struct_def: Gc<ast::StructDef>) {
|
|
||||||
// If this is a tuple-like struct, translate the constructor.
|
|
||||||
match struct_def.ctor_id {
|
|
||||||
// We only need to translate a constructor if there are fields;
|
|
||||||
// otherwise this is a unit-like struct.
|
|
||||||
Some(ctor_id) if struct_def.fields.len() > 0 => {
|
|
||||||
let llfndecl = get_item_val(ccx, ctor_id);
|
|
||||||
trans_tuple_struct(ccx, struct_def.fields.as_slice(),
|
|
||||||
ctor_id, ¶m_substs::empty(), llfndecl);
|
|
||||||
}
|
|
||||||
Some(_) | None => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate a module. Doing this amounts to translating the items in the
|
// Translate a module. Doing this amounts to translating the items in the
|
||||||
// module; there ends up being no artifact (aside from linkage names) of
|
// module; there ends up being no artifact (aside from linkage names) of
|
||||||
// separate modules in the compiled program. That's because modules exist
|
// separate modules in the compiled program. That's because modules exist
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
use arena::TypedArena;
|
use arena::TypedArena;
|
||||||
use back::abi;
|
use back::abi;
|
||||||
use back::link;
|
use back::link;
|
||||||
|
use driver::session;
|
||||||
use llvm::{ValueRef, get_param};
|
use llvm::{ValueRef, get_param};
|
||||||
use llvm;
|
use llvm;
|
||||||
use metadata::csearch;
|
use metadata::csearch;
|
||||||
|
@ -521,8 +522,27 @@ pub fn trans_fn_ref_with_vtables(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// We must monomorphise if the fn has type parameters or is a default method.
|
// We must monomorphise if the fn has type parameters, is a default method,
|
||||||
let must_monomorphise = !substs.types.is_empty() || is_default;
|
// or is a named tuple constructor.
|
||||||
|
let must_monomorphise = if !substs.types.is_empty() || is_default {
|
||||||
|
true
|
||||||
|
} else if def_id.krate == ast::LOCAL_CRATE {
|
||||||
|
let map_node = session::expect(
|
||||||
|
ccx.sess(),
|
||||||
|
tcx.map.find(def_id.node),
|
||||||
|
|| "local item should be in ast map".to_string());
|
||||||
|
|
||||||
|
match map_node {
|
||||||
|
ast_map::NodeVariant(v) => match v.node.kind {
|
||||||
|
ast::TupleVariantKind(ref args) => args.len() > 0,
|
||||||
|
_ => false
|
||||||
|
},
|
||||||
|
ast_map::NodeStructCtor(_) => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
// Create a monomorphic version of generic functions
|
// Create a monomorphic version of generic functions
|
||||||
if must_monomorphise {
|
if must_monomorphise {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue