Disable generating split-stack code

Allows to compile for archs which do not have (or have limited)
segmented stack support like embedded.
This commit is contained in:
Valerii Hiora 2014-05-12 20:03:34 +03:00
parent d730ae2fb0
commit 0c10c68682
3 changed files with 29 additions and 14 deletions

View File

@ -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 // 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 { ty: Type, output: ty::t) -> ValueRef {
let llfn: ValueRef = name.with_c_str(|buf| { let llfn: ValueRef = name.with_c_str(|buf| {
unsafe { 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); lib::llvm::SetFunctionCallConv(llfn, cc);
// Function addresses in Rust are never significant, allowing functions to be merged. // Function addresses in Rust are never significant, allowing functions to be merged.
lib::llvm::SetUnnamedAddr(llfn, true); lib::llvm::SetUnnamedAddr(llfn, true);
set_split_stack(llfn);
if ccx.is_split_stack_supported() {
set_split_stack(llfn);
}
llfn llfn
} }
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions // 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, name: &str,
ty: Type, ty: Type,
output: ty::t) -> ValueRef { 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 // 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, Some(n) => return *n,
None => {} 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); externs.insert(name.to_string(), f);
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 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); let attrs = get_fn_llvm_attributes(ccx, fn_ty);
for &(idx, attr) in attrs.iter() { for &(idx, attr) in attrs.iter() {
unsafe { unsafe {
@ -1877,7 +1880,7 @@ pub fn register_fn_llvmty(ccx: &CrateContext,
llfty: Type) -> ValueRef { llfty: Type) -> ValueRef {
debug!("register_fn_llvmty id={} sym={}", node_id, sym); 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); finish_register_fn(ccx, sp, sym, node_id, llfn);
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()], let llfty = Type::func([ccx.int_type, Type::i8p(ccx).ptr_to()],
&ccx.int_type); &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| { let llbb = "top".with_c_str(|buf| {
unsafe { unsafe {
llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf) llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)

View File

@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use driver::config::NoDebugInfo; use driver::config::NoDebugInfo;
use driver::session::Session; use driver::session::Session;
use lib::llvm::{ContextRef, ModuleRef, ValueRef}; use lib::llvm::{ContextRef, ModuleRef, ValueRef};
@ -32,6 +31,7 @@ use std::c_str::ToCStr;
use std::ptr; use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use syntax::abi;
use syntax::ast; use syntax::ast;
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
@ -273,20 +273,32 @@ impl CrateContext {
None => fail!() 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<ValueRef> { fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef> {
macro_rules! ifn ( macro_rules! ifn (
($name:expr fn() -> $ret:expr) => ( ($name:expr fn() -> $ret:expr) => (
if *key == $name { 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()); ccx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f); return Some(f);
} }
); );
($name:expr fn($($arg:expr),*) -> $ret:expr) => ( ($name:expr fn($($arg:expr),*) -> $ret:expr) => (
if *key == $name { 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()); Type::func([$($arg),*], &$ret), ty::mk_nil());
ccx.intrinsics.borrow_mut().insert($name, f.clone()); ccx.intrinsics.borrow_mut().insert($name, f.clone());
return Some(f); return Some(f);
@ -418,7 +430,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
// The `if key == $name` is already in ifn! // The `if key == $name` is already in ifn!
ifn!($name fn($($arg),*) -> $ret); ifn!($name fn($($arg),*) -> $ret);
} else if *key == $name { } 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), Type::func([$($arg),*], &$ret),
ty::mk_nil()); ty::mk_nil());
ccx.intrinsics.borrow_mut().insert($name, f.clone()); ccx.intrinsics.borrow_mut().insert($name, f.clone());

View File

@ -462,7 +462,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
t, t,
format!("glue_{}", name).as_slice()); format!("glue_{}", name).as_slice());
debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx(), t)); 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); note_unique_llvm_symbol(ccx, fn_nm);
return llfn; return llfn;
} }