Add support for specifying the TLS model
This commit is contained in:
parent
37b015fb91
commit
b233a6e096
|
@ -368,6 +368,7 @@ pub enum PrintRequest {
|
|||
TargetFeatures,
|
||||
RelocationModels,
|
||||
CodeModels,
|
||||
TlsModels,
|
||||
TargetSpec,
|
||||
NativeStaticLibs,
|
||||
}
|
||||
|
@ -910,6 +911,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
|
|||
"choose the relocation model to use (rustc --print relocation-models for details)"),
|
||||
code_model: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||
"choose the code model to use (rustc --print code-models for details)"),
|
||||
tls_model: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||
"choose the TLS model to use (rustc --print tls-models for details)"),
|
||||
metadata: Vec<String> = (Vec::new(), parse_list, [TRACKED],
|
||||
"metadata to mangle symbol names with"),
|
||||
extra_filename: String = ("".to_string(), parse_string, [UNTRACKED],
|
||||
|
@ -1330,7 +1333,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
|
|||
print on stdout",
|
||||
"[crate-name|file-names|sysroot|cfg|target-list|\
|
||||
target-cpus|target-features|relocation-models|\
|
||||
code-models|target-spec-json|native-static-libs]"),
|
||||
code-models|tls-models|target-spec-json|native-static-libs]"),
|
||||
opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
|
||||
opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
|
||||
opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
|
||||
|
@ -1573,6 +1576,10 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
|
|||
prints.push(PrintRequest::CodeModels);
|
||||
cg.code_model = None;
|
||||
}
|
||||
if cg.tls_model.as_ref().map_or(false, |s| s == "help") {
|
||||
prints.push(PrintRequest::TlsModels);
|
||||
cg.tls_model = None;
|
||||
}
|
||||
|
||||
let cg = cg;
|
||||
|
||||
|
@ -1672,6 +1679,7 @@ pub fn build_session_options_and_crate_config(matches: &getopts::Matches)
|
|||
"target-features" => PrintRequest::TargetFeatures,
|
||||
"relocation-models" => PrintRequest::RelocationModels,
|
||||
"code-models" => PrintRequest::CodeModels,
|
||||
"tls-models" => PrintRequest::TlsModels,
|
||||
"native-static-libs" => PrintRequest::NativeStaticLibs,
|
||||
"target-spec-json" => {
|
||||
if nightly_options::is_unstable_enabled(matches) {
|
||||
|
@ -2514,6 +2522,10 @@ mod tests {
|
|||
opts.cg.code_model = Some(String::from("code model"));
|
||||
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
|
||||
|
||||
opts = reference.clone();
|
||||
opts.cg.tls_model = Some(String::from("tls model"));
|
||||
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
|
||||
|
||||
opts = reference.clone();
|
||||
opts.cg.metadata = vec![String::from("A"), String::from("B")];
|
||||
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
|
||||
|
|
|
@ -177,6 +177,7 @@ mod rustc_trans {
|
|||
pub mod write {
|
||||
pub const RELOC_MODEL_ARGS: [(&'static str, ()); 0] = [];
|
||||
pub const CODE_GEN_MODEL_ARGS: [(&'static str, ()); 0] = [];
|
||||
pub const TLS_MODEL_ARGS: [(&'static str, ()); 0] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -797,6 +798,13 @@ impl RustcDefaultCalls {
|
|||
}
|
||||
println!("");
|
||||
}
|
||||
PrintRequest::TlsModels => {
|
||||
println!("Available TLS models:");
|
||||
for &(name, _) in rustc_trans::back::write::TLS_MODEL_ARGS.iter(){
|
||||
println!(" {}", name);
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
PrintRequest::TargetCPUs | PrintRequest::TargetFeatures => {
|
||||
rustc_trans::print(*req, sess);
|
||||
}
|
||||
|
|
|
@ -359,6 +359,17 @@ pub struct ThinLTOModule {
|
|||
pub len: usize,
|
||||
}
|
||||
|
||||
/// LLVMThreadLocalMode
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub enum ThreadLocalMode {
|
||||
NotThreadLocal,
|
||||
GeneralDynamic,
|
||||
LocalDynamic,
|
||||
InitialExec,
|
||||
LocalExec
|
||||
}
|
||||
|
||||
// Opaque pointer types
|
||||
#[allow(missing_copy_implementations)]
|
||||
pub enum Module_opaque {}
|
||||
|
@ -709,6 +720,7 @@ extern "C" {
|
|||
pub fn LLVMGetInitializer(GlobalVar: ValueRef) -> ValueRef;
|
||||
pub fn LLVMSetInitializer(GlobalVar: ValueRef, ConstantVal: ValueRef);
|
||||
pub fn LLVMSetThreadLocal(GlobalVar: ValueRef, IsThreadLocal: Bool);
|
||||
pub fn LLVMSetThreadLocalMode(GlobalVar: ValueRef, Mode: ThreadLocalMode);
|
||||
pub fn LLVMIsGlobalConstant(GlobalVar: ValueRef) -> Bool;
|
||||
pub fn LLVMSetGlobalConstant(GlobalVar: ValueRef, IsConstant: Bool);
|
||||
pub fn LLVMRustGetNamedValue(M: ModuleRef, Name: *const c_char) -> ValueRef;
|
||||
|
|
|
@ -172,6 +172,11 @@ pub fn set_thread_local(global: ValueRef, is_thread_local: bool) {
|
|||
LLVMSetThreadLocal(global, is_thread_local as Bool);
|
||||
}
|
||||
}
|
||||
pub fn set_thread_local_mode(global: ValueRef, mode: ThreadLocalMode) {
|
||||
unsafe {
|
||||
LLVMSetThreadLocalMode(global, mode);
|
||||
}
|
||||
}
|
||||
|
||||
impl Attribute {
|
||||
pub fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
|
||||
|
|
|
@ -76,6 +76,13 @@ pub const CODE_GEN_MODEL_ARGS : [(&'static str, llvm::CodeModel); 5] = [
|
|||
("large", llvm::CodeModel::Large),
|
||||
];
|
||||
|
||||
pub const TLS_MODEL_ARGS : [(&'static str, llvm::ThreadLocalMode); 4] = [
|
||||
("global-dynamic", llvm::ThreadLocalMode::GeneralDynamic),
|
||||
("local-dynamic", llvm::ThreadLocalMode::LocalDynamic),
|
||||
("initial-exec", llvm::ThreadLocalMode::InitialExec),
|
||||
("local-exec", llvm::ThreadLocalMode::LocalExec),
|
||||
];
|
||||
|
||||
pub fn llvm_err(handler: &errors::Handler, msg: String) -> FatalError {
|
||||
match llvm::last_error() {
|
||||
Some(err) => handler.fatal(&format!("{}: {}", msg, err)),
|
||||
|
|
|
@ -23,6 +23,7 @@ use monomorphize::Instance;
|
|||
use type_::Type;
|
||||
use type_of;
|
||||
use rustc::ty;
|
||||
use context::get_tls_model;
|
||||
|
||||
use rustc::hir;
|
||||
|
||||
|
@ -196,7 +197,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
|||
|
||||
for attr in attrs {
|
||||
if attr.check_name("thread_local") {
|
||||
llvm::set_thread_local(g, true);
|
||||
llvm::set_thread_local_mode(g, get_tls_model(ccx.sess()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +216,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
|
|||
// symbol and another one doesn't.
|
||||
for attr in ccx.tcx().get_attrs(def_id).iter() {
|
||||
if attr.check_name("thread_local") {
|
||||
llvm::set_thread_local(g, true);
|
||||
llvm::set_thread_local_mode(g, get_tls_model(ccx.sess()));
|
||||
}
|
||||
}
|
||||
if ccx.use_dll_storage_attrs() && !ccx.tcx().is_foreign_item(def_id) {
|
||||
|
@ -305,9 +306,8 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
|
||||
debuginfo::create_global_var_metadata(ccx, id, g);
|
||||
|
||||
if attr::contains_name(attrs,
|
||||
"thread_local") {
|
||||
llvm::set_thread_local(g, true);
|
||||
if attr::contains_name(attrs, "thread_local") {
|
||||
llvm::set_thread_local_mode(g, get_tls_model(ccx.sess()));
|
||||
}
|
||||
|
||||
base::set_link_section(ccx, g, attrs);
|
||||
|
|
|
@ -166,6 +166,24 @@ pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_tls_model(sess: &Session) -> llvm::ThreadLocalMode {
|
||||
let tls_model_arg = match sess.opts.cg.tls_model {
|
||||
Some(ref s) => &s[..],
|
||||
None => &sess.target.target.options.tls_model[..],
|
||||
};
|
||||
|
||||
match ::back::write::TLS_MODEL_ARGS.iter().find(
|
||||
|&&arg| arg.0 == tls_model_arg) {
|
||||
Some(x) => x.1,
|
||||
_ => {
|
||||
sess.err(&format!("{:?} is not a valid TLS model",
|
||||
tls_model_arg));
|
||||
sess.abort_if_errors();
|
||||
bug!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_any_library(sess: &Session) -> bool {
|
||||
sess.crate_types.borrow().iter().any(|ty| {
|
||||
*ty != config::CrateTypeExecutable
|
||||
|
|
Loading…
Reference in New Issue