Rollup merge of #123237 - bjorn3:debuginfo_refactor, r=compiler-errors

Various rustc_codegen_ssa cleanups
This commit is contained in:
Matthias Krüger 2024-06-29 22:10:55 +02:00 committed by GitHub
commit 5b90824433
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 138 additions and 179 deletions

View File

@ -28,6 +28,19 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
global
// TODO(antoyo): set linkage.
}
pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
if value.get_type() == self.bool_type.make_pointer() {
if let Some(pointee) = typ.get_pointee() {
if pointee.dyncast_vector().is_some() {
panic!()
}
}
}
// NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some
// SIMD builtins require a constant value.
self.bitcast_if_needed(value, typ)
}
}
pub fn bytes_in_context<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, bytes: &[u8]) -> RValue<'gcc> {
@ -239,19 +252,6 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
const_alloc_to_gcc(self, alloc)
}
fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
if value.get_type() == self.bool_type.make_pointer() {
if let Some(pointee) = typ.get_pointee() {
if pointee.dyncast_vector().is_some() {
panic!()
}
}
}
// NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some
// SIMD builtins require a constant value.
self.bitcast_if_needed(value, typ)
}
fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
self.context
.new_array_access(None, base_addr, self.const_usize(offset.bytes()))

View File

@ -27,7 +27,6 @@ use crate::callee::get_fn;
use crate::common::SignType;
pub struct CodegenCx<'gcc, 'tcx> {
pub check_overflow: bool,
pub codegen_unit: &'tcx CodegenUnit<'tcx>,
pub context: &'gcc Context<'gcc>,
@ -134,8 +133,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
tcx: TyCtxt<'tcx>,
supports_128bit_integers: bool,
) -> Self {
let check_overflow = tcx.sess.overflow_checks();
let create_type = |ctype, rust_type| {
let layout = tcx.layout_of(ParamEnv::reveal_all().and(rust_type)).unwrap();
let align = layout.align.abi.bytes();
@ -271,7 +268,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
}
let mut cx = Self {
check_overflow,
codegen_unit,
context,
current_func: RefCell::new(None),
@ -511,10 +507,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
&self.tcx.sess
}
fn check_overflow(&self) -> bool {
self.check_overflow
}
fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> {
self.codegen_unit
}

View File

@ -89,13 +89,34 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
ty::FloatTy::F128 => self.type_f128(),
}
}
}
impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn type_i1(&self) -> Type<'gcc> {
pub fn type_i1(&self) -> Type<'gcc> {
self.bool_type
}
pub fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> {
let types = fields.to_vec();
if let Some(typ) = self.struct_types.borrow().get(fields) {
return *typ;
}
let fields: Vec<_> = fields
.iter()
.enumerate()
.map(|(index, field)| {
self.context.new_field(None, *field, format!("field{}_TODO", index))
})
.collect();
let typ = self.context.new_struct_type(None, "struct", &fields).as_type();
if packed {
#[cfg(feature = "master")]
typ.set_packed();
}
self.struct_types.borrow_mut().insert(types, typ);
typ
}
}
impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn type_i8(&self) -> Type<'gcc> {
self.i8_type
}
@ -131,7 +152,7 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn type_f64(&self) -> Type<'gcc> {
self.double_type
}
fn type_f128(&self) -> Type<'gcc> {
unimplemented!("f16_f128")
}
@ -140,27 +161,6 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.context.new_function_pointer_type(None, return_type, params, false)
}
fn type_struct(&self, fields: &[Type<'gcc>], packed: bool) -> Type<'gcc> {
let types = fields.to_vec();
if let Some(typ) = self.struct_types.borrow().get(fields) {
return *typ;
}
let fields: Vec<_> = fields
.iter()
.enumerate()
.map(|(index, field)| {
self.context.new_field(None, *field, format!("field{}_TODO", index))
})
.collect();
let typ = self.context.new_struct_type(None, "struct", &fields).as_type();
if packed {
#[cfg(feature = "master")]
typ.set_packed();
}
self.struct_types.borrow_mut().insert(types, typ);
typ
}
fn type_kind(&self, typ: Type<'gcc>) -> TypeKind {
if self.is_int_type_or_bool(typ) {
TypeKind::Integer

View File

@ -329,10 +329,6 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
const_alloc_to_llvm(self, alloc, /*static*/ false)
}
fn const_bitcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
self.const_bitcast(val, ty)
}
fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
unsafe {
llvm::LLVMConstInBoundsGEP2(

View File

@ -3,6 +3,7 @@ use crate::back::write::to_llvm_code_model;
use crate::callee::get_fn;
use crate::coverageinfo;
use crate::debuginfo;
use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
use crate::llvm;
use crate::llvm_util;
use crate::type_::Type;
@ -43,7 +44,6 @@ use std::str;
/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
pub struct CodegenCx<'ll, 'tcx> {
pub tcx: TyCtxt<'tcx>,
pub check_overflow: bool,
pub use_dll_storage_attrs: bool,
pub tls_model: llvm::ThreadLocalMode,
@ -441,8 +441,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
// start) and then strongly recommending static linkage on Windows!
let use_dll_storage_attrs = tcx.sess.target.is_like_windows;
let check_overflow = tcx.sess.overflow_checks();
let tls_model = to_llvm_tls_model(tcx.sess.tls_model());
let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod());
@ -466,7 +464,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
CodegenCx {
tcx,
check_overflow,
use_dll_storage_attrs,
tls_model,
llmod,
@ -522,6 +519,15 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
&self.vtables
}
fn apply_vcall_visibility_metadata(
&self,
ty: Ty<'tcx>,
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
vtable: &'ll Value,
) {
apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable);
}
fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
get_fn(self, instance)
}
@ -596,10 +602,6 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self.tcx.sess
}
fn check_overflow(&self) -> bool {
self.check_overflow
}
fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> {
self.codegen_unit
}

View File

@ -1449,12 +1449,18 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
.di_node
}
fn vcall_visibility_metadata<'ll, 'tcx>(
pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
ty: Ty<'tcx>,
trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
vtable: &'ll Value,
) {
// FIXME(flip1995): The virtual function elimination optimization only works with full LTO in
// LLVM at the moment.
if !cx.sess().opts.unstable_opts.virtual_function_elimination || cx.sess().lto() != Lto::Fat {
return;
}
enum VCallVisibility {
Public = 0,
LinkageUnit = 1,
@ -1531,12 +1537,6 @@ pub fn create_vtable_di_node<'ll, 'tcx>(
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
vtable: &'ll Value,
) {
// FIXME(flip1995): The virtual function elimination optimization only works with full LTO in
// LLVM at the moment.
if cx.sess().opts.unstable_opts.virtual_function_elimination && cx.sess().lto() == Lto::Fat {
vcall_visibility_metadata(cx, ty, poly_trait_ref, vtable);
}
if cx.dbg_cx.is_none() {
return;
}

View File

@ -274,10 +274,11 @@ impl CodegenBackend for LlvmCodegenBackend {
|tcx, ()| llvm_util::global_llvm_features(tcx.sess, true)
}
fn print(&self, req: &PrintRequest, out: &mut dyn PrintBackendInfo, sess: &Session) {
fn print(&self, req: &PrintRequest, out: &mut String, sess: &Session) {
use std::fmt::Write;
match req.kind {
PrintKind::RelocationModels => {
writeln!(out, "Available relocation models:");
writeln!(out, "Available relocation models:").unwrap();
for name in &[
"static",
"pic",
@ -288,25 +289,25 @@ impl CodegenBackend for LlvmCodegenBackend {
"ropi-rwpi",
"default",
] {
writeln!(out, " {name}");
writeln!(out, " {name}").unwrap();
}
writeln!(out);
writeln!(out).unwrap();
}
PrintKind::CodeModels => {
writeln!(out, "Available code models:");
writeln!(out, "Available code models:").unwrap();
for name in &["tiny", "small", "kernel", "medium", "large"] {
writeln!(out, " {name}");
writeln!(out, " {name}").unwrap();
}
writeln!(out);
writeln!(out).unwrap();
}
PrintKind::TlsModels => {
writeln!(out, "Available TLS models:");
writeln!(out, "Available TLS models:").unwrap();
for name in
&["global-dynamic", "local-dynamic", "initial-exec", "local-exec", "emulated"]
{
writeln!(out, " {name}");
writeln!(out, " {name}").unwrap();
}
writeln!(out);
writeln!(out).unwrap();
}
PrintKind::StackProtectorStrategies => {
writeln!(
@ -332,7 +333,8 @@ impl CodegenBackend for LlvmCodegenBackend {
none
Do not generate stack canaries.
"#
);
)
.unwrap();
}
_other => llvm_util::print(req, out, sess),
}

View File

@ -6,7 +6,6 @@ use crate::errors::{
use crate::llvm;
use libc::c_int;
use rustc_codegen_ssa::base::wants_wasm_eh;
use rustc_codegen_ssa::traits::PrintBackendInfo;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_fs_util::path_to_c_string;
@ -18,6 +17,7 @@ use rustc_target::spec::{MergeFunctions, PanicStrategy};
use rustc_target::target_features::RUSTC_SPECIFIC_FEATURES;
use std::ffi::{c_char, c_void, CStr, CString};
use std::fmt::Write;
use std::path::Path;
use std::ptr;
use std::slice;
@ -372,7 +372,7 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> {
ret
}
fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &llvm::TargetMachine) {
fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMachine) {
let mut llvm_target_features = llvm_target_features(tm);
let mut known_llvm_target_features = FxHashSet::<&'static str>::default();
let mut rustc_target_features = sess
@ -412,24 +412,26 @@ fn print_target_features(out: &mut dyn PrintBackendInfo, sess: &Session, tm: &ll
.max()
.unwrap_or(0);
writeln!(out, "Features supported by rustc for this target:");
writeln!(out, "Features supported by rustc for this target:").unwrap();
for (feature, desc) in &rustc_target_features {
writeln!(out, " {feature:max_feature_len$} - {desc}.");
writeln!(out, " {feature:max_feature_len$} - {desc}.").unwrap();
}
writeln!(out, "\nCode-generation features supported by LLVM for this target:");
writeln!(out, "\nCode-generation features supported by LLVM for this target:").unwrap();
for (feature, desc) in &llvm_target_features {
writeln!(out, " {feature:max_feature_len$} - {desc}.");
writeln!(out, " {feature:max_feature_len$} - {desc}.").unwrap();
}
if llvm_target_features.is_empty() {
writeln!(out, " Target features listing is not supported by this LLVM version.");
writeln!(out, " Target features listing is not supported by this LLVM version.")
.unwrap();
}
writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it.");
writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n");
writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],");
writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n");
writeln!(out, "\nUse +feature to enable a feature, or -feature to disable it.").unwrap();
writeln!(out, "For example, rustc -C target-cpu=mycpu -C target-feature=+feature1,-feature2\n")
.unwrap();
writeln!(out, "Code-generation features cannot be used in cfg or #[target_feature],").unwrap();
writeln!(out, "and may be renamed or removed in a future version of LLVM or rustc.\n").unwrap();
}
pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess: &Session) {
pub(crate) fn print(req: &PrintRequest, mut out: &mut String, sess: &Session) {
require_inited();
let tm = create_informational_target_machine(sess);
match req.kind {
@ -440,9 +442,9 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess
let cpu_cstring = CString::new(handle_native(sess.target.cpu.as_ref()))
.unwrap_or_else(|e| bug!("failed to convert to cstring: {}", e));
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 out = &mut *(out as *mut &mut String);
let bytes = slice::from_raw_parts(string as *const u8, len);
write!(out, "{}", String::from_utf8_lossy(bytes));
write!(out, "{}", String::from_utf8_lossy(bytes)).unwrap();
}
unsafe {
llvm::LLVMRustPrintTargetCPUs(

View File

@ -127,13 +127,24 @@ impl<'ll> CodegenCx<'ll, '_> {
pub(crate) fn type_variadic_func(&self, args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, True) }
}
}
impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn type_i1(&self) -> &'ll Type {
pub(crate) fn type_i1(&self) -> &'ll Type {
unsafe { llvm::LLVMInt1TypeInContext(self.llcx) }
}
pub(crate) fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type {
unsafe {
llvm::LLVMStructTypeInContext(
self.llcx,
els.as_ptr(),
els.len() as c_uint,
packed as Bool,
)
}
}
}
impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn type_i8(&self) -> &'ll Type {
unsafe { llvm::LLVMInt8TypeInContext(self.llcx) }
}
@ -178,17 +189,6 @@ impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
unsafe { llvm::LLVMFunctionType(ret, args.as_ptr(), args.len() as c_uint, False) }
}
fn type_struct(&self, els: &[&'ll Type], packed: bool) -> &'ll Type {
unsafe {
llvm::LLVMStructTypeInContext(
self.llcx,
els.as_ptr(),
els.len() as c_uint,
packed as Bool,
)
}
}
fn type_kind(&self, ty: &'ll Type) -> TypeKind {
unsafe { llvm::LLVMRustGetTypeKind(ty).to_generic() }
}

View File

@ -133,6 +133,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
let align = cx.data_layout().pointer_align.abi;
let vtable = cx.static_addr_of(vtable_const, align, Some("vtable"));
cx.apply_vcall_visibility_metadata(ty, trait_ref, vtable);
cx.create_vtable_debuginfo(ty, trait_ref, vtable);
cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
vtable

View File

@ -658,7 +658,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// with #[rustc_inherit_overflow_checks] and inlined from
// another crate (mostly core::num generic/#[inline] fns),
// while the current crate doesn't use overflow checks.
if !bx.cx().check_overflow() && msg.is_optional_overflow_check() {
if !bx.sess().overflow_checks() && msg.is_optional_overflow_check() {
const_cond = Some(expected);
}
@ -751,7 +751,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&mut self,
helper: &TerminatorCodegenHelper<'tcx>,
bx: &mut Bx,
intrinsic: Option<ty::IntrinsicDef>,
intrinsic: ty::IntrinsicDef,
instance: Option<Instance<'tcx>>,
source_info: mir::SourceInfo,
target: Option<mir::BasicBlock>,
@ -761,8 +761,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Emit a panic or a no-op for `assert_*` intrinsics.
// These are intrinsics that compile to panics so that we can get a message
// which mentions the offending type, even from a const context.
let panic_intrinsic = intrinsic.and_then(|i| ValidityRequirement::from_intrinsic(i.name));
if let Some(requirement) = panic_intrinsic {
if let Some(requirement) = ValidityRequirement::from_intrinsic(intrinsic.name) {
let ty = instance.unwrap().args.type_at(0);
let do_panic = !bx
@ -869,12 +868,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let sig = callee.layout.ty.fn_sig(bx.tcx());
let abi = sig.abi();
// Handle intrinsics old codegen wants Expr's for, ourselves.
let intrinsic = match def {
Some(ty::InstanceKind::Intrinsic(def_id)) => Some(bx.tcx().intrinsic(def_id).unwrap()),
_ => None,
};
let extra_args = &args[sig.inputs().skip_binder().len()..];
let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| {
let op_ty = op_arg.node.ty(self.mir, bx.tcx());
@ -886,50 +879,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
None => bx.fn_abi_of_fn_ptr(sig, extra_args),
};
if let Some(merging_succ) = self.codegen_panic_intrinsic(
&helper,
bx,
intrinsic,
instance,
source_info,
target,
unwind,
mergeable_succ,
) {
return merging_succ;
}
// The arguments we'll be passing. Plus one to account for outptr, if used.
let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
if matches!(intrinsic, Some(ty::IntrinsicDef { name: sym::caller_location, .. })) {
return if let Some(target) = target {
let location =
self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
let mut llargs = Vec::with_capacity(arg_count);
let ret_dest = self.make_return_dest(
let instance = match def {
Some(ty::InstanceKind::Intrinsic(def_id)) => {
let intrinsic = bx.tcx().intrinsic(def_id).unwrap();
if let Some(merging_succ) = self.codegen_panic_intrinsic(
&helper,
bx,
destination,
&fn_abi.ret,
&mut llargs,
intrinsic,
Some(target),
);
assert_eq!(llargs, []);
if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
location.val.store(bx, tmp);
instance,
source_info,
target,
unwind,
mergeable_succ,
) {
return merging_succ;
}
self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate());
helper.funclet_br(self, bx, target, mergeable_succ)
} else {
MergingSucc::False
};
}
let instance = match intrinsic {
None => instance,
Some(intrinsic) => {
let mut llargs = Vec::with_capacity(1);
let ret_dest = self.make_return_dest(
bx,
@ -971,6 +939,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
})
.collect();
if matches!(intrinsic, ty::IntrinsicDef { name: sym::caller_location, .. }) {
let location = self
.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
assert_eq!(llargs, []);
if let ReturnDest::IndirectOperand(tmp, _) = ret_dest {
location.val.store(bx, tmp);
}
self.store_return(bx, ret_dest, &fn_abi.ret, location.immediate());
return helper.funclet_br(self, bx, target.unwrap(), mergeable_succ);
}
let instance = *instance.as_ref().unwrap();
match Self::codegen_intrinsic_call(bx, instance, fn_abi, &args, dest, span) {
Ok(()) => {
@ -997,6 +977,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
_ => instance,
};
let mut llargs = Vec::with_capacity(arg_count);

View File

@ -22,8 +22,6 @@ use rustc_session::{
use rustc_span::symbol::Symbol;
use rustc_target::abi::call::FnAbi;
use std::fmt;
pub trait BackendTypes {
type Value: CodegenObject;
type Function: CodegenObject;
@ -62,7 +60,7 @@ pub trait CodegenBackend {
fn locale_resource(&self) -> &'static str;
fn init(&self, _sess: &Session) {}
fn print(&self, _req: &PrintRequest, _out: &mut dyn PrintBackendInfo, _sess: &Session) {}
fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
vec![]
}
@ -150,19 +148,3 @@ pub trait ExtraBackendMethods:
std::thread::Builder::new().name(name).spawn(f)
}
}
pub trait PrintBackendInfo {
fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>);
}
impl PrintBackendInfo for String {
fn infallible_write_fmt(&mut self, args: fmt::Arguments<'_>) {
fmt::Write::write_fmt(self, args).unwrap();
}
}
impl dyn PrintBackendInfo + '_ {
pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) {
self.infallible_write_fmt(args);
}
}

View File

@ -37,6 +37,5 @@ pub trait ConstMethods<'tcx>: BackendTypes {
fn scalar_to_backend(&self, cv: Scalar, layout: abi::Scalar, llty: Self::Type) -> Self::Value;
fn const_bitcast(&self, val: Self::Value, ty: Self::Type) -> Self::Value;
fn const_ptr_byte_offset(&self, val: Self::Value, offset: abi::Size) -> Self::Value;
}

View File

@ -9,7 +9,13 @@ pub trait MiscMethods<'tcx>: BackendTypes {
fn vtables(
&self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
fn check_overflow(&self) -> bool;
fn apply_vcall_visibility_metadata(
&self,
_ty: Ty<'tcx>,
_poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
_vtable: Self::Value,
) {
}
fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function;
fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value;
fn eh_personality(&self) -> Self::Value;

View File

@ -30,9 +30,7 @@ mod write;
pub use self::abi::AbiBuilderMethods;
pub use self::asm::{AsmBuilderMethods, AsmMethods, GlobalAsmOperandRef, InlineAsmOperandRef};
pub use self::backend::{
Backend, BackendTypes, CodegenBackend, ExtraBackendMethods, PrintBackendInfo,
};
pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods};
pub use self::builder::{BuilderMethods, OverflowOp};
pub use self::consts::ConstMethods;
pub use self::coverageinfo::CoverageInfoBuilderMethods;

View File

@ -12,7 +12,6 @@ use rustc_target::abi::{AddressSpace, Float, Integer};
// This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use
// `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves.
pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn type_i1(&self) -> Self::Type;
fn type_i8(&self) -> Self::Type;
fn type_i16(&self) -> Self::Type;
fn type_i32(&self) -> Self::Type;
@ -27,7 +26,6 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn type_array(&self, ty: Self::Type, len: u64) -> Self::Type;
fn type_func(&self, args: &[Self::Type], ret: Self::Type) -> Self::Type;
fn type_struct(&self, els: &[Self::Type], packed: bool) -> Self::Type;
fn type_kind(&self, ty: Self::Type) -> TypeKind;
fn type_ptr(&self) -> Self::Type;
fn type_ptr_ext(&self, address_space: AddressSpace) -> Self::Type;
@ -115,8 +113,8 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
/// The backend type used for a rust type when it's in an SSA register.
///
/// For nearly all types this is the same as the [`Self::backend_type`], however
/// `bool` (and other `0`-or-`1` values) are kept as [`BaseTypeMethods::type_i1`]
/// in registers but as [`BaseTypeMethods::type_i8`] in memory.
/// `bool` (and other `0`-or-`1` values) are kept as `i1` in registers but as
/// [`BaseTypeMethods::type_i8`] in memory.
///
/// Converting values between the two different backend types is done using
/// [`from_immediate`](super::BuilderMethods::from_immediate) and