]> git.lizzy.rs Git - rust.git/commitdiff
Add support for specifying the TLS model
authorAmanieu d'Antras <amanieu@gmail.com>
Tue, 31 Oct 2017 18:24:04 +0000 (18:24 +0000)
committerAmanieu d'Antras <amanieu@gmail.com>
Fri, 3 Nov 2017 00:29:54 +0000 (00:29 +0000)
src/librustc/session/config.rs
src/librustc_driver/lib.rs
src/librustc_llvm/ffi.rs
src/librustc_llvm/lib.rs
src/librustc_trans/back/write.rs
src/librustc_trans/consts.rs
src/librustc_trans/context.rs

index 0f8312abc3f9f10f7f75a0fe6d4df1dd16866ee3..d1d04e883b8fd0e7620eae2ddf1b3d89dac84c02 100644 (file)
@@ -368,6 +368,7 @@ pub enum PrintRequest {
     TargetFeatures,
     RelocationModels,
     CodeModels,
+    TlsModels,
     TargetSpec,
     NativeStaticLibs,
 }
@@ -910,6 +911,8 @@ fn parse_optimization_fuel(slot: &mut Option<(String, u64)>, v: Option<&str>) ->
          "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 @@ fn test_codegen_options_tracking_hash() {
         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());
index fc503f4eb4be16ac33422a19e07da7f61f76d358..c5cce70c945663393d38cdd27756c55bce9cda02 100644 (file)
@@ -177,6 +177,7 @@ pub mod back {
         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 @@ fn print_crate_info(sess: &Session,
                     }
                     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);
                 }
index 3399bf2acd8917c88bab7b3f4a337bc3a2a9ff7e..ac0e4dde0c1024e95bbc2f3c91ad49e96a1423c3 100644 (file)
@@ -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 @@ pub fn LLVMConstInlineAsm(Ty: TypeRef,
     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;
index 98172bca1778625da8ce88b02513b4788055a9b8..5ccce8de7063995ccb2e9378a83f7a96bae4234c 100644 (file)
@@ -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) {
index 6153d3dcdbba2da2d514671a2ca110623093eb6a..3d923922bb1cf76b6d1fb198513f03f4934b6c97 100644 (file)
     ("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)),
index eaf7392aab5b4f6d95a2ca635c4fb0bd8db8b3e6..0f5ede91c7d6ec012728965d1a081346bb90c7f0 100644 (file)
@@ -23,6 +23,7 @@
 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);
index cd9cb8c0df531aed9c99f7abb4c123887ee9f7bf..afdbc31c456bbd23c9e14f8bc4884bad03e280ad 100644 (file)
@@ -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