mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Categorize and explain target features support
This commit is contained in:
parent
361bfce305
commit
e258a5ba6e
@ -2128,7 +2128,13 @@ extern "C" {
|
||||
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
|
||||
|
||||
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine);
|
||||
pub fn LLVMRustPrintTargetFeatures(T: &TargetMachine);
|
||||
pub fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t;
|
||||
pub fn LLVMRustGetTargetFeature(
|
||||
T: &TargetMachine,
|
||||
Index: size_t,
|
||||
Feature: &mut *const c_char,
|
||||
Desc: &mut *const c_char,
|
||||
);
|
||||
|
||||
pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char;
|
||||
pub fn LLVMRustCreateTargetMachine(
|
||||
|
@ -10,6 +10,7 @@ use rustc_span::symbol::Symbol;
|
||||
use rustc_target::spec::{MergeFunctions, PanicStrategy};
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
@ -192,15 +193,77 @@ pub fn print_passes() {
|
||||
}
|
||||
}
|
||||
|
||||
fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> {
|
||||
let len = unsafe { llvm::LLVMRustGetTargetFeaturesCount(tm) };
|
||||
let mut ret = Vec::with_capacity(len);
|
||||
for i in 0..len {
|
||||
unsafe {
|
||||
let mut feature = ptr::null();
|
||||
let mut desc = ptr::null();
|
||||
llvm::LLVMRustGetTargetFeature(tm, i, &mut feature, &mut desc);
|
||||
if feature.is_null() || desc.is_null() {
|
||||
bug!("LLVM returned a `null` target feature string");
|
||||
}
|
||||
let feature = CStr::from_ptr(feature).to_str().unwrap_or_else(|e| {
|
||||
bug!("LLVM returned a non-utf8 feature string: {}", e);
|
||||
});
|
||||
let desc = CStr::from_ptr(desc).to_str().unwrap_or_else(|e| {
|
||||
bug!("LLVM returned a non-utf8 feature string: {}", e);
|
||||
});
|
||||
ret.push((feature, desc));
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) {
|
||||
let mut target_features = llvm_target_features(tm);
|
||||
let mut rustc_target_features = supported_target_features(sess)
|
||||
.iter()
|
||||
.filter_map(|(feature, _gate)| {
|
||||
let llvm_feature = to_llvm_feature(sess, *feature);
|
||||
// LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
|
||||
target_features.binary_search_by_key(&llvm_feature, |(f, _d)| *f).ok().map(|index| {
|
||||
let (_f, desc) = target_features.remove(index);
|
||||
(*feature, desc)
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
rustc_target_features.extend_from_slice(&[(
|
||||
"crt-static",
|
||||
"Enables C Run-time Libraries to be statically linked",
|
||||
)]);
|
||||
let max_feature_len = target_features
|
||||
.iter()
|
||||
.chain(rustc_target_features.iter())
|
||||
.map(|(feature, _desc)| feature.len())
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
|
||||
println!("Features supported by rustc for this target:");
|
||||
for (feature, desc) in &rustc_target_features {
|
||||
println!(" {1:0$} - {2}.", max_feature_len, feature, desc);
|
||||
}
|
||||
println!("\nCode-generation features supported by LLVM for this target:");
|
||||
for (feature, desc) in &target_features {
|
||||
println!(" {1:0$} - {2}.", max_feature_len, feature, desc);
|
||||
}
|
||||
if target_features.len() == 0 {
|
||||
println!(" Target features listing is not supported by this LLVM version.");
|
||||
}
|
||||
println!("\nUse +feature to enable a feature, or -feature to disable it.");
|
||||
println!("For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n");
|
||||
println!("Code-generation features cannot be used in cfg or #[target_feature],");
|
||||
println!("and may be renamed or removed in a future version of LLVM or rustc.\n");
|
||||
}
|
||||
|
||||
pub(crate) fn print(req: PrintRequest, sess: &Session) {
|
||||
require_inited();
|
||||
let tm = create_informational_target_machine(sess);
|
||||
unsafe {
|
||||
match req {
|
||||
PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
|
||||
PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
|
||||
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
|
||||
}
|
||||
match req {
|
||||
PrintRequest::TargetCPUs => unsafe { llvm::LLVMRustPrintTargetCPUs(tm) },
|
||||
PrintRequest::TargetFeatures => print_target_features(sess, tm),
|
||||
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,26 +404,21 @@ extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
|
||||
extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) {
|
||||
const TargetMachine *Target = unwrap(TM);
|
||||
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
|
||||
const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
|
||||
unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
|
||||
return FeatTable.size();
|
||||
}
|
||||
|
||||
printf("Available features for this target:\n");
|
||||
for (auto &Feature : FeatTable)
|
||||
printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
|
||||
printf("\nRust-specific features:\n");
|
||||
printf(" %-*s - %s.\n",
|
||||
MaxFeatLen,
|
||||
"crt-static",
|
||||
"Enables libraries with C Run-time Libraries(CRT) to be statically linked"
|
||||
);
|
||||
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");
|
||||
extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
|
||||
const char** Feature, const char** Desc) {
|
||||
const TargetMachine *Target = unwrap(TM);
|
||||
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
|
||||
const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
|
||||
const SubtargetFeatureKV Feat = FeatTable[Index];
|
||||
*Feature = Feat.Key;
|
||||
*Desc = Feat.Desc;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -432,9 +427,11 @@ 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");
|
||||
extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef, const char**, const char**) {}
|
||||
#endif
|
||||
|
||||
extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
|
||||
|
Loading…
Reference in New Issue
Block a user