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:
parent
d730ae2fb0
commit
0c10c68682
@ -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)
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user