about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-08-10 21:42:48 -0700
committerGitHub <noreply@github.com>2016-08-10 21:42:48 -0700
commit1222f5d52ba0586d67c32a5bc4a3097eb9574aae (patch)
tree436580873936f5699d607ff9bf84ef6f05d816ae
parent0ef24eed2fe3bfdd050e246327332fadb5985a6a (diff)
parent05045da9fdab511f39e88335b1bc7f92ea7973ba (diff)
downloadrust-1222f5d52ba0586d67c32a5bc4a3097eb9574aae.tar.gz
rust-1222f5d52ba0586d67c32a5bc4a3097eb9574aae.zip
Auto merge of #34845 - bitshifter:issue-30961, r=alexcrichton
Add help for target CPUs, features, relocation and code models.

Fix for https://github.com/rust-lang/rust/issues/30961. Requires PR https://github.com/rust-lang/llvm/pull/45 to be accepted first, and the .gitmodules for llvm to be updated before this can be merged.
-rw-r--r--mk/rustllvm.mk6
-rw-r--r--src/bootstrap/compile.rs4
-rw-r--r--src/bootstrap/lib.rs10
-rw-r--r--src/librustc/session/config.rs41
-rw-r--r--src/librustc_driver/lib.rs23
-rw-r--r--src/librustc_llvm/build.rs4
-rw-r--r--src/librustc_llvm/ffi.rs3
-rw-r--r--src/librustc_trans/back/write.rs24
-rw-r--r--src/librustc_trans/context.rs10
m---------src/llvm0
-rw-r--r--src/rustllvm/PassWrapper.cpp52
-rw-r--r--src/rustllvm/llvm-auto-clean-trigger2
12 files changed, 159 insertions, 20 deletions
diff --git a/mk/rustllvm.mk b/mk/rustllvm.mk
index b50dbd01ad0..2d63f69960f 100644
--- a/mk/rustllvm.mk
+++ b/mk/rustllvm.mk
@@ -32,6 +32,11 @@ RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
                      $$(call CFG_CC_INCLUDE_$(1),$$(S)src/rustllvm/include)
 RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=$(1)/rustllvm/%.o)
 
+# Flag that we are building with Rust's llvm fork
+ifeq ($(CFG_LLVM_ROOT),)
+RUSTLLVM_CXXFLAGS_$(1) := -DLLVM_RUSTLLVM
+endif
+
 # Note that we appease `cl.exe` and its need for some sort of exception
 # handling flag with the `EHsc` argument here as well.
 ifeq ($$(findstring msvc,$(1)),msvc)
@@ -55,6 +60,7 @@ $(1)/rustllvm/%.o: $(S)src/rustllvm/%.cpp $$(MKFILE_DEPS) $$(LLVM_CONFIG_$(1))
 	$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@,) \
 		$$(subst  /,//,$$(LLVM_CXXFLAGS_$(1))) \
 		$$(RUSTLLVM_COMPONENTS_$(1)) \
+		$$(RUSTLLVM_CXXFLAGS_$(1)) \
 		$$(EXTRA_RUSTLLVM_CXXFLAGS_$(1)) \
 		$$(RUSTLLVM_INCS_$(1)) \
 		$$<
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 061192ebd13..155848901cd 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -198,6 +198,10 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
     if !build.unstable_features {
         cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
     }
+    // Flag that rust llvm is in use
+    if build.is_rust_llvm(target) {
+        cargo.env("LLVM_RUSTLLVM", "1");
+    }
     cargo.env("LLVM_CONFIG", build.llvm_config(target));
     if build.config.llvm_static_stdcpp {
         cargo.env("LLVM_STATIC_STDCPP",
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index acb7e0fadd9..5d61abe5e08 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -727,6 +727,16 @@ impl Build {
         self.out.join(target).join("llvm")
     }
 
+    /// Returns true if no custom `llvm-config` is set for the specified target.
+    ///
+    /// If no custom `llvm-config` was specified then Rust's llvm will be used.
+    fn is_rust_llvm(&self, target: &str) -> bool {
+        match self.config.target_config.get(target) {
+            Some(ref c) => c.llvm_config.is_none(),
+            None => true
+        }
+    }
+
     /// Returns the path to `llvm-config` for the specified target.
     ///
     /// If a custom `llvm-config` was specified for target then that's returned
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 3984d2b3d00..0fb4d0f8fea 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -176,6 +176,10 @@ pub enum PrintRequest {
     CrateName,
     Cfg,
     TargetList,
+    TargetCPUs,
+    TargetFeatures,
+    RelocationModels,
+    CodeModels,
 }
 
 pub enum Input {
@@ -629,9 +633,9 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
     lto: bool = (false, parse_bool,
         "perform LLVM link-time optimizations"),
     target_cpu: Option<String> = (None, parse_opt_string,
-        "select target processor (llc -mcpu=help for details)"),
+        "select target processor (rustc --print target-cpus for details)"),
     target_feature: String = ("".to_string(), parse_string,
-        "target specific attributes (llc -mattr=help for details)"),
+        "target specific attributes (rustc --print target-features for details)"),
     passes: Vec<String> = (Vec::new(), parse_list,
         "a list of extra LLVM passes to run (space separated)"),
     llvm_args: Vec<String> = (Vec::new(), parse_list,
@@ -655,9 +659,9 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
     no_redzone: Option<bool> = (None, parse_opt_bool,
         "disable the use of the redzone"),
     relocation_model: Option<String> = (None, parse_opt_string,
-         "choose the relocation model to use (llc -relocation-model for details)"),
+         "choose the relocation model to use (rustc --print relocation-models for details)"),
     code_model: Option<String> = (None, parse_opt_string,
-         "choose the code model to use (llc -code-model for details)"),
+         "choose the code model to use (rustc --print code-models for details)"),
     metadata: Vec<String> = (Vec::new(), parse_list,
          "metadata to mangle symbol names with"),
     extra_filename: String = ("".to_string(), parse_string,
@@ -1024,7 +1028,8 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
                  "[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
         opt::multi_s("", "print", "Comma separated list of compiler information to \
                                print on stdout",
-                 "[crate-name|file-names|sysroot|cfg|target-list]"),
+                 "[crate-name|file-names|sysroot|cfg|target-list|target-cpus|\
+                   target-features|relocation-models|code-models]"),
         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"),
@@ -1238,6 +1243,24 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         early_error(error_format, "Value for codegen units must be a positive nonzero integer");
     }
 
+    let mut prints = Vec::<PrintRequest>::new();
+    if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
+        prints.push(PrintRequest::TargetCPUs);
+        cg.target_cpu = None;
+    };
+    if cg.target_feature == "help" {
+        prints.push(PrintRequest::TargetFeatures);
+        cg.target_feature = "".to_string();
+    }
+    if cg.relocation_model.as_ref().map_or(false, |s| s == "help") {
+        prints.push(PrintRequest::RelocationModels);
+        cg.relocation_model = None;
+    }
+    if cg.code_model.as_ref().map_or(false, |s| s == "help") {
+        prints.push(PrintRequest::CodeModels);
+        cg.code_model = None;
+    }
+
     let cg = cg;
 
     let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
@@ -1315,18 +1338,22 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
     let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
     let test = matches.opt_present("test");
 
-    let prints = matches.opt_strs("print").into_iter().map(|s| {
+    prints.extend(matches.opt_strs("print").into_iter().map(|s| {
         match &*s {
             "crate-name" => PrintRequest::CrateName,
             "file-names" => PrintRequest::FileNames,
             "sysroot" => PrintRequest::Sysroot,
             "cfg" => PrintRequest::Cfg,
             "target-list" => PrintRequest::TargetList,
+            "target-cpus" => PrintRequest::TargetCPUs,
+            "target-features" => PrintRequest::TargetFeatures,
+            "relocation-models" => PrintRequest::RelocationModels,
+            "code-models" => PrintRequest::CodeModels,
             req => {
                 early_error(error_format, &format!("unknown print request `{}`", req))
             }
         }
-    }).collect::<Vec<_>>();
+    }));
 
     if !cg.remark.is_empty() && debuginfo == NoDebugInfo {
         early_warn(error_format, "-C remark will not show source locations without \
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 80f1910906b..98860c8f900 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -68,6 +68,7 @@ use pretty::{PpMode, UserIdentifiedItem};
 use rustc_resolve as resolve;
 use rustc_save_analysis as save;
 use rustc_trans::back::link;
+use rustc_trans::back::write::{create_target_machine, RELOC_MODEL_ARGS, CODE_GEN_MODEL_ARGS};
 use rustc::dep_graph::DepGraph;
 use rustc::session::{self, config, Session, build_session, CompileResult};
 use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
@@ -654,6 +655,28 @@ impl RustcDefaultCalls {
                         }
                     }
                 }
+                PrintRequest::TargetCPUs => {
+                    let tm = create_target_machine(sess);
+                    unsafe { llvm::LLVMRustPrintTargetCPUs(tm); }
+                }
+                PrintRequest::TargetFeatures => {
+                    let tm = create_target_machine(sess);
+                    unsafe { llvm::LLVMRustPrintTargetFeatures(tm); }
+                }
+                PrintRequest::RelocationModels => {
+                    println!("Available relocation models:");
+                    for &(name, _) in RELOC_MODEL_ARGS.iter() {
+                        println!("    {}", name);
+                    }
+                    println!("");
+                }
+                PrintRequest::CodeModels => {
+                    println!("Available code models:");
+                    for &(name, _) in CODE_GEN_MODEL_ARGS.iter(){
+                        println!("    {}", name);
+                    }
+                    println!("");
+                }
             }
         }
         return Compilation::Stop;
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index b8548aaec5b..5f7a0f788ca 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -112,6 +112,10 @@ fn main() {
         cfg.flag(&flag);
     }
 
+    if env::var_os("LLVM_RUSTLLVM").is_some() {
+        cfg.flag("-DLLVM_RUSTLLVM");
+    }
+
     cfg.file("../rustllvm/PassWrapper.cpp")
        .file("../rustllvm/RustWrapper.cpp")
        .file("../rustllvm/ArchiveWrapper.cpp")
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index 6301c57c555..b2ffcac365b 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -1940,6 +1940,9 @@ extern {
     pub fn LLVMRustHasFeature(T: TargetMachineRef,
                               s: *const c_char) -> bool;
 
+    pub fn LLVMRustPrintTargetCPUs(T: TargetMachineRef);
+    pub fn LLVMRustPrintTargetFeatures(T: TargetMachineRef);
+
     pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
                                        CPU: *const c_char,
                                        Features: *const c_char,
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 7025de523c3..b5c993b86ec 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -36,6 +36,21 @@ use std::sync::mpsc::channel;
 use std::thread;
 use libc::{c_uint, c_void};
 
+pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 4] = [
+    ("pic", llvm::RelocMode::PIC),
+    ("static", llvm::RelocMode::Static),
+    ("default", llvm::RelocMode::Default),
+    ("dynamic-no-pic", llvm::RelocMode::DynamicNoPic),
+];
+
+pub const CODE_GEN_MODEL_ARGS : [(&'static str, llvm::CodeModel); 5] = [
+    ("default", llvm::CodeModel::Default),
+    ("small", llvm::CodeModel::Small),
+    ("kernel", llvm::CodeModel::Kernel),
+    ("medium", llvm::CodeModel::Medium),
+    ("large", llvm::CodeModel::Large),
+];
+
 pub fn llvm_err(handler: &errors::Handler, msg: String) -> ! {
     match llvm::last_error() {
         Some(err) => panic!(handler.fatal(&format!("{}: {}", msg, err))),
@@ -168,12 +183,9 @@ pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
         None => &sess.target.target.options.code_model[..],
     };
 
-    let code_model = match code_model_arg {
-        "default" => llvm::CodeModel::Default,
-        "small" => llvm::CodeModel::Small,
-        "kernel" => llvm::CodeModel::Kernel,
-        "medium" => llvm::CodeModel::Medium,
-        "large" => llvm::CodeModel::Large,
+    let code_model = match CODE_GEN_MODEL_ARGS.iter().find(
+        |&&arg| arg.0 == code_model_arg) {
+        Some(x) => x.1,
         _ => {
             sess.err(&format!("{:?} is not a valid code model",
                              sess.opts
diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs
index 97b03312d79..65eea1bbb63 100644
--- a/src/librustc_trans/context.rs
+++ b/src/librustc_trans/context.rs
@@ -337,16 +337,14 @@ pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
         None => &sess.target.target.options.relocation_model[..],
     };
 
-    match reloc_model_arg {
-        "pic" => llvm::RelocMode::PIC,
-        "static" => llvm::RelocMode::Static,
-        "default" => llvm::RelocMode::Default,
-        "dynamic-no-pic" => llvm::RelocMode::DynamicNoPic,
+    match ::back::write::RELOC_MODEL_ARGS.iter().find(
+        |&&arg| arg.0 == reloc_model_arg) {
+        Some(x) => x.1,
         _ => {
             sess.err(&format!("{:?} is not a valid relocation mode",
                              sess.opts
                                  .cg
-                                 .relocation_model));
+                                 .code_model));
             sess.abort_if_errors();
             bug!();
         }
diff --git a/src/llvm b/src/llvm
-Subproject d1cc48989b13780f21c408fef17dceb104a09c9
+Subproject 786aad117be48547f4ca50fae84c4879fa992d4
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 3a20bb2714e..0555a96ff24 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -226,6 +226,58 @@ from_rust(LLVMRustCodeGenOptLevel level)
   }
 }
 
+#if LLVM_RUSTLLVM
+/// getLongestEntryLength - Return the length of the longest entry in the table.
+///
+static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
+  size_t MaxLen = 0;
+  for (auto &I : Table)
+    MaxLen = std::max(MaxLen, std::strlen(I.Key));
+  return MaxLen;
+}
+
+extern "C" void
+LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
+    const TargetMachine *Target = unwrap(TM);
+    const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
+    const ArrayRef<SubtargetFeatureKV> CPUTable = MCInfo->getCPUTable();
+    unsigned MaxCPULen = getLongestEntryLength(CPUTable);
+
+    printf("Available CPUs for this target:\n");
+    for (auto &CPU : CPUTable)
+        printf("    %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
+    printf("\n");
+}
+
+extern "C" void
+LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
+    const TargetMachine *Target = unwrap(TM);
+    const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
+    const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
+    unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
+
+    printf("Available features for this target:\n");
+    for (auto &Feature : FeatTable)
+        printf("    %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
+    printf("\n");
+
+    printf("Use +feature to enable a feature, or -feature to disable it.\n"
+            "For example, rustc -C -target-cpu=mycpu -C target-feature=+feature1,-feature2\n\n");
+}
+
+#else
+
+extern "C" void
+LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
+    printf("Target CPU help is not supported by this LLVM version.\n\n");
+}
+
+extern "C" void
+LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
+    printf("Target features help is not supported by this LLVM version.\n\n");
+}
+#endif
+
 extern "C" LLVMTargetMachineRef
 LLVMRustCreateTargetMachine(const char *triple,
                             const char *cpu,
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index e871763a48d..378810a8b89 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2016-07-25b
+2016-08-07