diff --git a/.gitmodules b/.gitmodules index 39288a7ae490..02c06618a004 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "src/llvm"] path = src/llvm - url = https://github.com/rust-lang/llvm.git + url = https://github.com/bitshifter/llvm.git branch = master [submodule "src/compiler-rt"] path = src/compiler-rt diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 5ccc96210be7..107dc6a46517 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -165,6 +165,10 @@ pub enum PrintRequest { CrateName, Cfg, TargetList, + TargetCPUs, + TargetFeatures, + RelocationModels, + CodeModels, } pub enum Input { @@ -1197,6 +1201,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::::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)); @@ -1274,18 +1296,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::>(); + })); 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 c9569a63436f..afa6f87f84f0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -69,6 +69,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; use rustc::dep_graph::DepGraph; use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType}; @@ -657,6 +658,29 @@ 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:\n"); + println!(" pic"); + println!(" static"); + println!(" default"); + println!(" dynamic-no-pic\n"); + } + PrintRequest::CodeModels => { + println!("Available code models:\n"); + println!(" default"); + println!(" small"); + println!(" kernel"); + println!(" medium"); + println!(" large\n"); + } } } return Compilation::Stop; diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index e757201c8863..033342b81a4c 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -2040,6 +2040,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/llvm b/src/llvm index 7ca76af03bb0..31d7a4027469 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 7ca76af03bb04659562890d6b4f223fffe0d748f +Subproject commit 31d7a402746936d6a279d6e5bb7b1cfd88a66abd diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 3564f338a029..962e81b018b4 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -162,6 +162,44 @@ LLVMRustHasFeature(LLVMTargetMachineRef TM, return (Bits & FeatureEntry->Value) == FeatureEntry->Value; } +/// getLongestEntryLength - Return the length of the longest entry in the table. +/// +static size_t getLongestEntryLength(ArrayRef 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 CPUTable = MCInfo->getCPUTable(); + unsigned MaxCPULen = getLongestEntryLength(CPUTable); + + printf("Available CPUs for this target:\n\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 FeatTable = MCInfo->getFeatureTable(); + unsigned MaxFeatLen = getLongestEntryLength(FeatTable); + + printf("Available features for this target:\n\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"); +} + extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(const char *triple, const char *cpu,