Skip to content
Merged
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be updated once llvm PR is accepted.

branch = master
[submodule "src/compiler-rt"]
path = src/compiler-rt
Expand Down
30 changes: 28 additions & 2 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ pub enum PrintRequest {
CrateName,
Cfg,
TargetList,
TargetCPUs,
TargetFeatures,
RelocationModels,
CodeModels,
}

pub enum Input {
Expand Down Expand Up @@ -1195,6 +1199,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;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Push as print request and reset target-cpu vaule so LLVM doesn't print help several times when creating a target machine, we want to print ourselves from rustc.

};
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));
Expand Down Expand Up @@ -1272,18 +1294,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 \
Expand Down
24 changes: 24 additions & 0 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to make a list of available strings and their enum mappings instead of duplicating them, but not sure where to put it. This information is currently processed in librustc_trans/back/write.rs create_target_machine function.

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;
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/llvm
38 changes: 38 additions & 0 deletions src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<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\n");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seemed easier to print in C++ to avoid exposing ArrayRef to Rust.

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\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,
Expand Down