diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 9cebc79171f..594a62ea9b2 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -172,12 +172,12 @@ 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()) } }); @@ -196,17 +196,20 @@ 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.is_split_stack_supported() { + 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 @@ -221,7 +224,7 @@ pub fn get_extern_fn(ccx: &CrateContext, Some(n) => return *n, None => {} } - let f = decl_fn(ccx.llmod, name, cc, ty, output); + let f = decl_fn(ccx, name, cc, ty, output); externs.insert(name.to_string(), f); f } @@ -250,7 +253,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str) -> ValueRef { }; let llfty = type_of_rust_fn(ccx, has_env, inputs.as_slice(), output); - let llfn = decl_fn(ccx.llmod, name, lib::llvm::CCallConv, llfty, output); + let llfn = decl_fn(ccx, name, lib::llvm::CCallConv, llfty, output); let attrs = get_fn_llvm_attributes(ccx, fn_ty); for &(idx, attr) in attrs.iter() { unsafe { @@ -1877,7 +1880,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext, llfty: Type) -> ValueRef { debug!("register_fn_llvmty id={} sym={}", node_id, sym); - let llfn = decl_fn(ccx.llmod, sym.as_slice(), cc, llfty, ty::mk_nil()); + let llfn = decl_fn(ccx, sym.as_slice(), cc, llfty, ty::mk_nil()); finish_register_fn(ccx, sp, sym, node_id, llfn); llfn } @@ -1909,7 +1912,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/context.rs b/src/librustc/middle/trans/context.rs index a80ae9e2596..68c6f1752bd 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - use driver::config::NoDebugInfo; use driver::session::Session; use lib::llvm::{ContextRef, ModuleRef, ValueRef}; @@ -32,6 +31,7 @@ use std::c_str::ToCStr; use std::ptr; use std::rc::Rc; use std::collections::{HashMap, HashSet}; +use syntax::abi; use syntax::ast; use syntax::parse::token::InternedString; @@ -273,20 +273,32 @@ impl CrateContext { None => fail!() } } + + // Although there is an experimental implementation of LLVM which + // supports SS on armv7 it wasn't approved by Apple, see: + // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216350.html + // It looks like it might be never accepted to upstream LLVM. + // + // So far the decision was to disable them in default builds + // but it could be enabled (with patched LLVM) + pub fn is_split_stack_supported(&self) -> bool { + let ref cfg = self.sess().targ_cfg; + cfg.os != abi::OsiOS || cfg.arch != abi::Arm + } } fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option { macro_rules! ifn ( ($name:expr fn() -> $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 +430,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/glue.rs b/src/librustc/middle/trans/glue.rs index 96aa7267d23..ef9bf4eebe2 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -462,7 +462,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, fn_nm.as_slice(), llfnty, ty::mk_nil()); + let llfn = decl_cdecl_fn(ccx, fn_nm.as_slice(), llfnty, ty::mk_nil()); note_unique_llvm_symbol(ccx, fn_nm); return llfn; }