diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index d80cf72bb466d..ba758b6811c7e 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -220,7 +220,7 @@ pub fn debugging_opts_map() -> Vec<(&'static str, &'static str, u64)> { /// its respective field in the struct. There are a few hand-written parsers for /// parsing specific types of values in this module. macro_rules! cgoptions( - ($($opt:ident : $t:ty = ($init:expr, $parse:ident, $desc:expr)),* ,) => + ($($opt:ident : $t:ty = ($init:expr, $parse:ident, $desc:expr, $is_public:expr)),* ,) => ( #[deriving(Clone)] pub struct CodegenOptions { $(pub $opt: $t),* } @@ -231,8 +231,8 @@ macro_rules! cgoptions( pub type CodegenSetter = fn(&mut CodegenOptions, v: Option<&str>) -> bool; pub static CG_OPTIONS: &'static [(&'static str, CodegenSetter, - &'static str)] = - &[ $( (stringify!($opt), cgsetters::$opt, $desc) ),* ]; + &'static str, bool)] = + &[ $( (stringify!($opt), cgsetters::$opt, $desc, $is_public) ),* ]; mod cgsetters { use super::CodegenOptions; @@ -282,37 +282,39 @@ macro_rules! cgoptions( cgoptions!( ar: Option = (None, parse_opt_string, - "tool to assemble archives with"), + "tool to assemble archives with", true), linker: Option = (None, parse_opt_string, - "system linker to link outputs with"), + "system linker to link outputs with", true), link_args: Vec = (Vec::new(), parse_list, - "extra arguments to pass to the linker (space separated)"), + "extra arguments to pass to the linker (space separated)", true), target_cpu: StrBuf = ("generic".to_strbuf(), parse_string, - "select target processor (llc -mcpu=help for details)"), + "select target processor (llc -mcpu=help for details)", true), target_feature: StrBuf = ("".to_strbuf(), parse_string, - "target specific attributes (llc -mattr=help for details)"), + "target specific attributes (llc -mattr=help for details)", true), passes: Vec = (Vec::new(), parse_list, - "a list of extra LLVM passes to run (space separated)"), + "a list of extra LLVM passes to run (space separated)", true), llvm_args: Vec = (Vec::new(), parse_list, - "a list of arguments to pass to llvm (space separated)"), + "a list of arguments to pass to llvm (space separated)", true), save_temps: bool = (false, parse_bool, - "save all temporary output files during compilation"), + "save all temporary output files during compilation", true), no_rpath: bool = (false, parse_bool, - "disables setting the rpath in libs/exes"), + "disables setting the rpath in libs/exes", true), no_prepopulate_passes: bool = (false, parse_bool, - "don't pre-populate the pass manager with a list of passes"), + "don't pre-populate the pass manager with a list of passes", true), no_vectorize_loops: bool = (false, parse_bool, - "don't run the loop vectorization optimization passes"), + "don't run the loop vectorization optimization passes", true), no_vectorize_slp: bool = (false, parse_bool, - "don't run LLVM's SLP vectorization pass"), + "don't run LLVM's SLP vectorization pass", true), soft_float: bool = (false, parse_bool, - "generate software floating point library calls"), + "generate software floating point library calls", true), prefer_dynamic: bool = (false, parse_bool, - "prefer dynamic linking to static linking"), + "prefer dynamic linking to static linking", true), no_integrated_as: bool = (false, parse_bool, - "use an external assembler rather than LLVM's integrated one"), + "use an external assembler rather than LLVM's integrated one", true), relocation_model: StrBuf = ("pic".to_strbuf(), parse_string, - "choose the relocation model to use (llc -relocation-model for details)"), + "choose the relocation model to use (llc -relocation-model for details)", true), + no_split_stack: bool = (false, parse_bool, + "disable segmented stack support", false), ) pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions @@ -324,8 +326,8 @@ pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions let value = iter.next(); let option_to_lookup = key.replace("-", "_"); let mut found = false; - for &(candidate, setter, _) in CG_OPTIONS.iter() { - if option_to_lookup.as_slice() != candidate { continue } + for &(candidate, setter, _, is_public) in CG_OPTIONS.iter() { + if option_to_lookup.as_slice() != candidate || !is_public { continue } if !setter(&mut cg, value) { match value { Some(..) => { diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs index c870ee5e8f7ac..953745f990b23 100644 --- a/src/librustc/driver/mod.rs +++ b/src/librustc/driver/mod.rs @@ -176,7 +176,8 @@ fn describe_debug_flags() { fn describe_codegen_flags() { println!("\nAvailable codegen options:\n"); let mut cg = config::basic_codegen_options(); - for &(name, parser, desc) in config::CG_OPTIONS.iter() { + for &(name, parser, desc, is_public) in config::CG_OPTIONS.iter() { + if !is_public { continue } // we invoke the parser function on `None` to see if this option needs // an argument or not. let (width, extra) = if parser(&mut cg, None) { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index e208097e99b33..b4c449cfba0c7 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -165,11 +165,11 @@ impl<'a> Drop for StatRecorder<'a> { } // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions -fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, +fn decl_fn(ccx: &CrateContext, name: &str, cc: lib::llvm::CallConv, ty: Type, output: ty::t) -> ValueRef { let llfn: ValueRef = name.with_c_str(|buf| { unsafe { - llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref()) + llvm::LLVMGetOrInsertFunction(ccx.llmod, buf, ty.to_ref()) } }); @@ -193,22 +193,25 @@ fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, lib::llvm::SetFunctionCallConv(llfn, cc); // Function addresses in Rust are never significant, allowing functions to be merged. lib::llvm::SetUnnamedAddr(llfn, true); - set_split_stack(llfn); + + if !ccx.sess().opts.cg.no_split_stack { + set_split_stack(llfn); + } llfn } // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions -pub fn decl_cdecl_fn(llmod: ModuleRef, +pub fn decl_cdecl_fn(ccx: &CrateContext, name: &str, ty: Type, output: ty::t) -> ValueRef { - decl_fn(llmod, name, lib::llvm::CCallConv, ty, output) + decl_fn(ccx, name, lib::llvm::CCallConv, ty, output) } // only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions pub fn get_extern_fn(externs: &mut ExternMap, - llmod: ModuleRef, + ccx: &CrateContext, name: &str, cc: lib::llvm::CallConv, ty: Type, @@ -218,7 +221,7 @@ pub fn get_extern_fn(externs: &mut ExternMap, Some(n) => return *n, None => {} } - let f = decl_fn(llmod, name, cc, ty, output); + let f = decl_fn(ccx, name, cc, ty, output); externs.insert(name.to_strbuf(), f); f } @@ -246,7 +249,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool, use middle::ty::{BrAnon, ReLateBound}; let llfty = type_of_rust_fn(ccx, has_env, inputs, output); - let llfn = decl_cdecl_fn(ccx.llmod, name, llfty, output); + let llfn = decl_cdecl_fn(ccx, name, llfty, output); let uses_outptr = type_of::return_uses_outptr(ccx, output); let offset = if uses_outptr { 1 } else { 0 }; @@ -512,7 +515,7 @@ pub fn get_res_dtor(ccx: &CrateContext, let llty = type_of_dtor(ccx, class_ty); get_extern_fn(&mut *ccx.externs.borrow_mut(), - ccx.llmod, + ccx, name.as_slice(), lib::llvm::CCallConv, llty, @@ -1735,7 +1738,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext, output: ty::t) -> ValueRef { debug!("register_fn_llvmty id={} sym={}", node_id, sym); - let llfn = decl_fn(ccx.llmod, sym.as_slice(), cc, fn_ty, output); + let llfn = decl_fn(ccx, sym.as_slice(), cc, fn_ty, output); finish_register_fn(ccx, sp, sym, node_id, llfn); llfn } @@ -1767,7 +1770,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext, let llfty = Type::func([ccx.int_type, Type::i8p(ccx).ptr_to()], &ccx.int_type); - let llfn = decl_cdecl_fn(ccx.llmod, "main", llfty, ty::mk_nil()); + let llfn = decl_cdecl_fn(ccx, "main", llfty, ty::mk_nil()); let llbb = "top".with_c_str(|buf| { unsafe { llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf) diff --git a/src/librustc/middle/trans/cleanup.rs b/src/librustc/middle/trans/cleanup.rs index 68e66724d0c26..6258909e0f1de 100644 --- a/src/librustc/middle/trans/cleanup.rs +++ b/src/librustc/middle/trans/cleanup.rs @@ -680,7 +680,7 @@ impl<'a> CleanupHelperMethods<'a> for FunctionContext<'a> { Some(llpersonality) => llpersonality, None => { let fty = Type::variadic_func(&[], &Type::i32(self.ccx)); - let f = base::decl_cdecl_fn(self.ccx.llmod, + let f = base::decl_cdecl_fn(self.ccx, "rust_eh_personality", fty, ty::mk_i32()); diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index a876c68d443db..2dc750f52df0d 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -279,14 +279,14 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option $ret:expr) => ( if *key == $name { - let f = base::decl_cdecl_fn(ccx.llmod, $name, Type::func([], &$ret), ty::mk_nil()); + let f = base::decl_cdecl_fn(ccx, $name, Type::func([], &$ret), ty::mk_nil()); ccx.intrinsics.borrow_mut().insert($name, f.clone()); return Some(f); } ); ($name:expr fn($($arg:expr),*) -> $ret:expr) => ( if *key == $name { - let f = base::decl_cdecl_fn(ccx.llmod, $name, + let f = base::decl_cdecl_fn(ccx, $name, Type::func([$($arg),*], &$ret), ty::mk_nil()); ccx.intrinsics.borrow_mut().insert($name, f.clone()); return Some(f); @@ -418,7 +418,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option $ret); } else if *key == $name { - let f = base::decl_cdecl_fn(ccx.llmod, stringify!($cname), + let f = base::decl_cdecl_fn(ccx, stringify!($cname), Type::func([$($arg),*], &$ret), ty::mk_nil()); ccx.intrinsics.borrow_mut().insert($name, f.clone()); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index e08ab33808ac9..47b532e5b2a5b 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -228,7 +228,7 @@ pub fn register_foreign_item_fn(ccx: &CrateContext, abi: Abi, fty: ty::t, let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys); let llfn = base::get_extern_fn(&mut *ccx.externs.borrow_mut(), - ccx.llmod, + ccx, name, cc, llfn_ty, diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index c103a44aa7543..409b0bdad434b 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -459,7 +459,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, t, format!("glue_{}", name).as_slice()); debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx(), t)); - let llfn = decl_cdecl_fn(ccx.llmod, + let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil());