Implement printing to file in PassWrapper

This commit is contained in:
David Tolnay 2023-07-13 16:56:29 -07:00
parent 6e734fce63
commit 815a114974
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
3 changed files with 43 additions and 14 deletions

View File

@ -2280,7 +2280,12 @@ extern "C" {
pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool; pub fn LLVMRustHasFeature(T: &TargetMachine, s: *const c_char) -> bool;
pub fn LLVMRustPrintTargetCPUs(T: &TargetMachine, cpu: *const c_char); pub fn LLVMRustPrintTargetCPUs(
T: &TargetMachine,
cpu: *const c_char,
print: unsafe extern "C" fn(out: *mut c_void, string: *const c_char, len: usize),
out: *mut c_void,
);
pub fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t; pub fn LLVMRustGetTargetFeaturesCount(T: &TargetMachine) -> size_t;
pub fn LLVMRustGetTargetFeature( pub fn LLVMRustGetTargetFeature(
T: &TargetMachine, T: &TargetMachine,

View File

@ -17,8 +17,8 @@ use rustc_session::config::{PrintKind, PrintRequest};
use rustc_session::Session; use rustc_session::Session;
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_target::spec::{MergeFunctions, PanicStrategy}; use rustc_target::spec::{MergeFunctions, PanicStrategy};
use std::ffi::{CStr, CString};
use std::ffi::{c_char, c_void, CStr, CString};
use std::path::Path; use std::path::Path;
use std::ptr; use std::ptr;
use std::slice; use std::slice;
@ -401,7 +401,7 @@ fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &ll
writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n"); writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n");
} }
pub(crate) fn print(req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) { pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess: &Session) {
require_inited(); require_inited();
let tm = create_informational_target_machine(sess); let tm = create_informational_target_machine(sess);
match req.kind { match req.kind {
@ -411,7 +411,19 @@ pub(crate) fn print(req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &S
// at least as long as the C function // at least as long as the C function
let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref())) let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref()))
.unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e)); .unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e));
unsafe { llvm::LLVMRustPrintTargetCPUs(tm, cpu_cstring.as_ptr()) }; unsafe extern "C" fn callback(out: *mut c_void, string: *const c_char, len: usize) {
let out = &mut *(out as *mut &mut dyn PrintBackendInfo);
let bytes = slice::from_raw_parts(string as *const u8, len);
write!(out, "{}", String::from_utf8_lossy(bytes));
}
unsafe {
llvm::LLVMRustPrintTargetCPUs(
tm,
cpu_cstring.as_ptr(),
callback,
&mut out as *mut &mut dyn PrintBackendInfo as *mut c_void,
);
}
} }
PrintKind::TargetFeatures => print_target_features(out, sess, tm), PrintKind::TargetFeatures => print_target_features(out, sess, tm),
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req), _ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),

View File

@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <iomanip>
#include <vector> #include <vector>
#include <set> #include <set>
@ -306,44 +307,55 @@ static size_t getLongestEntryLength(ArrayRef<KV> Table) {
return MaxLen; return MaxLen;
} }
extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM, const char* TargetCPU) { using PrintBackendInfo = void(void*, const char* Data, size_t Len);
extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM,
const char* TargetCPU,
PrintBackendInfo Print,
void* Out) {
const TargetMachine *Target = unwrap(TM); const TargetMachine *Target = unwrap(TM);
const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch(); const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch();
const Triple::ArchType TargetArch = Target->getTargetTriple().getArch(); const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
std::ostringstream Buf;
#if LLVM_VERSION_GE(17, 0) #if LLVM_VERSION_GE(17, 0)
const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getAllProcessorDescriptions(); const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getAllProcessorDescriptions();
#elif defined(LLVM_RUSTLLVM) #elif defined(LLVM_RUSTLLVM)
const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable(); const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
#else #else
printf("Full target CPU help is not supported by this LLVM version.\n\n"); Buf << "Full target CPU help is not supported by this LLVM version.\n\n";
SubtargetSubTypeKV TargetCPUKV = { TargetCPU, {{}}, {{}} }; SubtargetSubTypeKV TargetCPUKV = { TargetCPU, {{}}, {{}} };
const ArrayRef<SubtargetSubTypeKV> CPUTable = TargetCPUKV; const ArrayRef<SubtargetSubTypeKV> CPUTable = TargetCPUKV;
#endif #endif
unsigned MaxCPULen = getLongestEntryLength(CPUTable); unsigned MaxCPULen = getLongestEntryLength(CPUTable);
printf("Available CPUs for this target:\n"); Buf << "Available CPUs for this target:\n";
// Don't print the "native" entry when the user specifies --target with a // Don't print the "native" entry when the user specifies --target with a
// different arch since that could be wrong or misleading. // different arch since that could be wrong or misleading.
if (HostArch == TargetArch) { if (HostArch == TargetArch) {
MaxCPULen = std::max(MaxCPULen, (unsigned) std::strlen("native")); MaxCPULen = std::max(MaxCPULen, (unsigned) std::strlen("native"));
const StringRef HostCPU = sys::getHostCPUName(); const StringRef HostCPU = sys::getHostCPUName();
printf(" %-*s - Select the CPU of the current host (currently %.*s).\n", Buf << " " << std::left << std::setw(MaxCPULen) << "native"
MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data()); << " - Select the CPU of the current host "
"(currently " << HostCPU.str() << ").\n";
} }
for (auto &CPU : CPUTable) { for (auto &CPU : CPUTable) {
// Compare cpu against current target to label the default // Compare cpu against current target to label the default
if (strcmp(CPU.Key, TargetCPU) == 0) { if (strcmp(CPU.Key, TargetCPU) == 0) {
printf(" %-*s - This is the default target CPU" Buf << " " << std::left << std::setw(MaxCPULen) << CPU.Key
" for the current build target (currently %s).", << " - This is the default target CPU for the current build target "
MaxCPULen, CPU.Key, Target->getTargetTriple().str().c_str()); "(currently " << Target->getTargetTriple().str() << ").";
} }
else { else {
printf(" %-*s", MaxCPULen, CPU.Key); Buf << " " << CPU.Key;
} }
printf("\n"); Buf << "\n";
} }
const auto &BufString = Buf.str();
Print(Out, BufString.data(), BufString.size());
} }
extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) { extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) {