Auto merge of #3901 - RalfJung:rustup, r=RalfJung

Rustup

This has a larger large "fmt" diff, probably there was a bug rustfmt update. For some reason the automatic `./miri fmt` on CI failed so this PR had to be created by hand -- it is unclear to me why this occurred.
This commit is contained in:
bors 2024-09-21 07:44:18 +00:00
commit a3fea24971
879 changed files with 15460 additions and 8559 deletions

View File

@ -4630,7 +4630,7 @@ dependencies = [
[[package]]
name = "rustfmt-nightly"
version = "1.7.1"
version = "1.8.0"
dependencies = [
"annotate-snippets 0.9.2",
"anyhow",

View File

@ -527,15 +527,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
let count =
(niche_variants.end().index() as u128 - niche_variants.start().index() as u128) + 1;
// Find the field with the largest niche
let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index]
.iter()
.enumerate()
.filter_map(|(j, field)| Some((j, field.largest_niche?)))
.max_by_key(|(_, niche)| niche.available(dl))
.and_then(|(j, niche)| Some((j, niche, niche.reserve(dl, count)?)))?;
let niche_offset =
niche.offset + variant_layouts[largest_variant_index].fields.offset(field_index);
// Use the largest niche in the largest variant.
let niche = variant_layouts[largest_variant_index].largest_niche?;
let (niche_start, niche_scalar) = niche.reserve(dl, count)?;
let niche_offset = niche.offset;
let niche_size = niche.value.size(dl);
let size = variant_layouts[largest_variant_index].size.align_to(align.abi);

View File

@ -833,6 +833,28 @@ pub enum Integer {
}
impl Integer {
pub fn int_ty_str(self) -> &'static str {
use Integer::*;
match self {
I8 => "i8",
I16 => "i16",
I32 => "i32",
I64 => "i64",
I128 => "i128",
}
}
pub fn uint_ty_str(self) -> &'static str {
use Integer::*;
match self {
I8 => "u8",
I16 => "u16",
I32 => "u32",
I64 => "u64",
I128 => "u128",
}
}
#[inline]
pub fn size(self) -> Size {
use Integer::*;

View File

@ -1293,7 +1293,7 @@ impl Expr {
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
ExprKind::Unary(..) => ExprPrecedence::Unary,
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
ExprKind::Cast(..) => ExprPrecedence::Cast,
ExprKind::Let(..) => ExprPrecedence::Let,
ExprKind::If(..) => ExprPrecedence::If,
ExprKind::While(..) => ExprPrecedence::While,
@ -1317,17 +1317,18 @@ impl Expr {
ExprKind::Break(..) => ExprPrecedence::Break,
ExprKind::Continue(..) => ExprPrecedence::Continue,
ExprKind::Ret(..) => ExprPrecedence::Ret,
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf,
ExprKind::MacCall(..) => ExprPrecedence::Mac,
ExprKind::Struct(..) => ExprPrecedence::Struct,
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
ExprKind::Paren(..) => ExprPrecedence::Paren,
ExprKind::Try(..) => ExprPrecedence::Try,
ExprKind::Yield(..) => ExprPrecedence::Yield,
ExprKind::Yeet(..) => ExprPrecedence::Yeet,
ExprKind::FormatArgs(..) => ExprPrecedence::FormatArgs,
ExprKind::Become(..) => ExprPrecedence::Become,
ExprKind::InlineAsm(..)
| ExprKind::Type(..)
| ExprKind::OffsetOf(..)
| ExprKind::FormatArgs(..)
| ExprKind::MacCall(..) => ExprPrecedence::Mac,
ExprKind::Err(_) | ExprKind::Dummy => ExprPrecedence::Err,
}
}

View File

@ -265,10 +265,7 @@ pub enum ExprPrecedence {
Field,
Index,
Try,
InlineAsm,
OffsetOf,
Mac,
FormatArgs,
Array,
Repeat,
@ -333,17 +330,14 @@ impl ExprPrecedence {
| ExprPrecedence::ConstBlock
| ExprPrecedence::Field
| ExprPrecedence::ForLoop
| ExprPrecedence::FormatArgs
| ExprPrecedence::Gen
| ExprPrecedence::If
| ExprPrecedence::Index
| ExprPrecedence::InlineAsm
| ExprPrecedence::Lit
| ExprPrecedence::Loop
| ExprPrecedence::Mac
| ExprPrecedence::Match
| ExprPrecedence::MethodCall
| ExprPrecedence::OffsetOf
| ExprPrecedence::Paren
| ExprPrecedence::Path
| ExprPrecedence::PostfixMatch

View File

@ -207,7 +207,7 @@ borrowck_simd_intrinsic_arg_const =
*[other] {$arg}th
} argument of `{$intrinsic}` is required to be a `const` item
borrowck_suggest_create_freash_reborrow =
borrowck_suggest_create_fresh_reborrow =
consider reborrowing the `Pin` instead of moving it
borrowck_suggest_iterate_over_slice =

View File

@ -415,7 +415,7 @@ pub(crate) enum CaptureReasonSuggest<'tcx> {
span: Span,
},
#[suggestion(
borrowck_suggest_create_freash_reborrow,
borrowck_suggest_create_fresh_reborrow,
applicability = "maybe-incorrect",
code = ".as_mut()",
style = "verbose"

View File

@ -785,8 +785,10 @@ fn codegen_stmt<'tcx>(
}
Rvalue::Repeat(ref operand, times) => {
let operand = codegen_operand(fx, operand);
let times =
fx.monomorphize(times).eval_target_usize(fx.tcx, ParamEnv::reveal_all());
let times = fx
.monomorphize(times)
.try_to_target_usize(fx.tcx)
.expect("expected monomorphic const in codegen");
if operand.layout().size.bytes() == 0 {
// Do nothing for ZST's
} else if fx.clif_type(operand.layout().ty) == Some(types::I8) {
@ -944,7 +946,10 @@ fn codegen_stmt<'tcx>(
fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value {
match *place.layout().ty.kind() {
ty::Array(_elem_ty, len) => {
let len = fx.monomorphize(len).eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64;
let len = fx
.monomorphize(len)
.try_to_target_usize(fx.tcx)
.expect("expected monomorphic const in codegen") as i64;
fx.bcx.ins().iconst(fx.pointer_type, len)
}
ty::Slice(_elem_ty) => place.to_ptr_unsized().1,

View File

@ -309,8 +309,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
}
impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
RevealAllLayoutCx(self.tcx).handle_layout_err(err, span, ty)
@ -318,8 +316,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
}
impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
#[inline]
fn handle_fn_abi_err(
&self,
@ -450,8 +446,6 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
pub(crate) struct RevealAllLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
@ -466,8 +460,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
}
impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
#[inline]
fn handle_fn_abi_err(
&self,

View File

@ -44,7 +44,7 @@ impl DebugContext {
type_dbg,
ty,
*elem_ty,
len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()),
len.try_to_target_usize(tcx).expect("expected monomorphic const in codegen"),
),
// ty::Slice(_) | ty::Str
// ty::Dynamic

View File

@ -131,9 +131,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
let idx = generic_args[2]
.expect_const()
.eval(fx.tcx, ty::ParamEnv::reveal_all(), span)
.unwrap()
.1
.try_to_valtree()
.expect("expected monomorphic const in codegen")
.unwrap_branch();
assert_eq!(x.layout(), y.layout());

View File

@ -24,10 +24,10 @@ pub(crate) fn unsized_info<'tcx>(
let (source, target) =
fx.tcx.struct_lockstep_tails_for_codegen(source, target, ParamEnv::reveal_all());
match (&source.kind(), &target.kind()) {
(&ty::Array(_, len), &ty::Slice(_)) => fx
.bcx
.ins()
.iconst(fx.pointer_type, len.eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
(&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst(
fx.pointer_type,
len.try_to_target_usize(fx.tcx).expect("expected monomorphic const in codegen") as i64,
),
(&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind))
if src_dyn_kind == target_dyn_kind =>
{

View File

@ -1,7 +1,7 @@
#[cfg(feature = "master")]
use gccjit::FnAttribute;
use gccjit::{ToLValue, ToRValue, Type};
use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeMethods};
use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeCodegenMethods};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::bug;
use rustc_middle::ty::layout::LayoutOf;

View File

@ -5,8 +5,8 @@ use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_codegen_ssa::mir::operand::OperandValue;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{
AsmBuilderMethods, AsmMethods, BaseTypeMethods, BuilderMethods, GlobalAsmOperandRef,
InlineAsmOperandRef,
AsmBuilderMethods, AsmCodegenMethods, BaseTypeCodegenMethods, BuilderMethods,
GlobalAsmOperandRef, InlineAsmOperandRef,
};
use rustc_middle::bug;
use rustc_middle::ty::Instance;
@ -770,7 +770,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
}
}
impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn codegen_global_asm(
&self,
template: &[InlineAsmTemplatePiece],

View File

@ -6,7 +6,7 @@ use std::time::Instant;
use gccjit::{CType, FunctionType, GlobalKind};
use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
use rustc_codegen_ssa::mono_item::MonoItemExt;
use rustc_codegen_ssa::traits::DebugInfoMethods;
use rustc_codegen_ssa::traits::DebugInfoCodegenMethods;
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind};
use rustc_middle::dep_graph;
use rustc_middle::mir::mono::Linkage;

View File

@ -14,8 +14,8 @@ use rustc_codegen_ssa::common::{
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{
BackendTypes, BaseTypeMethods, BuilderMethods, ConstMethods, HasCodegen, LayoutTypeMethods,
OverflowOp, StaticBuilderMethods,
BackendTypes, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods,
LayoutTypeCodegenMethods, OverflowOp, StaticBuilderMethods,
};
use rustc_codegen_ssa::MemFlags;
use rustc_data_structures::fx::FxHashSet;
@ -23,7 +23,6 @@ use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
TyAndLayout,
};
use rustc_middle::ty::{Instance, ParamEnv, Ty, TyCtxt};
use rustc_span::def_id::DefId;
@ -460,10 +459,6 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
}
}
impl<'gcc, 'tcx> HasCodegen<'tcx> for Builder<'_, 'gcc, 'tcx> {
type CodegenCx = CodegenCx<'gcc, 'tcx>;
}
impl<'tcx> HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.cx.tcx()
@ -477,8 +472,6 @@ impl HasDataLayout for Builder<'_, '_, '_> {
}
impl<'tcx> LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
self.cx.handle_layout_err(err, span, ty)
@ -486,8 +479,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
}
impl<'tcx> FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
#[inline]
fn handle_fn_abi_err(
&self,
@ -531,6 +522,8 @@ fn set_rvalue_location<'a, 'gcc, 'tcx>(
}
impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
type CodegenCx = CodegenCx<'gcc, 'tcx>;
fn build(cx: &'a CodegenCx<'gcc, 'tcx>, block: Block<'gcc>) -> Builder<'a, 'gcc, 'tcx> {
Builder::with_cx(cx, block)
}

View File

@ -1,5 +1,7 @@
use gccjit::{LValue, RValue, ToRValue, Type};
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, MiscMethods, StaticMethods};
use rustc_codegen_ssa::traits::{
BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
};
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
use rustc_middle::mir::Mutability;
use rustc_middle::ty::layout::LayoutOf;
@ -55,7 +57,7 @@ pub fn type_is_pointer(typ: Type<'_>) -> bool {
typ.get_pointee().is_some()
}
impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> {
if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) }
}
@ -78,22 +80,14 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.const_undef(typ)
}
fn const_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> {
self.gcc_int(typ, int)
}
fn const_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
self.gcc_uint(typ, int)
}
fn const_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
self.gcc_uint_big(typ, num)
}
fn const_bool(&self, val: bool) -> RValue<'gcc> {
self.const_uint(self.type_i1(), val as u64)
}
fn const_i8(&self, i: i8) -> RValue<'gcc> {
self.const_int(self.type_i8(), i as i64)
}
fn const_i16(&self, i: i16) -> RValue<'gcc> {
self.const_int(self.type_i16(), i as i64)
}
@ -102,8 +96,12 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.const_int(self.type_i32(), i as i64)
}
fn const_i8(&self, i: i8) -> RValue<'gcc> {
self.const_int(self.type_i8(), i as i64)
fn const_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> {
self.gcc_int(typ, int)
}
fn const_u8(&self, i: u8) -> RValue<'gcc> {
self.const_uint(self.type_u8(), i as u64)
}
fn const_u32(&self, i: u32) -> RValue<'gcc> {
@ -128,8 +126,12 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.const_uint(self.usize_type, i)
}
fn const_u8(&self, i: u8) -> RValue<'gcc> {
self.const_uint(self.type_u8(), i as u64)
fn const_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
self.gcc_uint(typ, int)
}
fn const_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
self.gcc_uint_big(typ, num)
}
fn const_real(&self, typ: Type<'gcc>, val: f64) -> RValue<'gcc> {

View File

@ -1,7 +1,9 @@
#[cfg(feature = "master")]
use gccjit::{FnAttribute, VarAttribute, Visibility};
use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type};
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, StaticMethods};
use rustc_codegen_ssa::traits::{
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
};
use rustc_hir::def::DefKind;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::interpret::{
@ -37,7 +39,7 @@ fn set_global_alignment<'gcc, 'tcx>(
gv.set_alignment(align.bytes() as i32);
}
impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
fn static_addr_of(&self, cv: RValue<'gcc>, align: Align, kind: Option<&str>) -> RValue<'gcc> {
// TODO(antoyo): implement a proper rvalue comparison in libgccjit instead of doing the
// following:

View File

@ -5,20 +5,19 @@ use gccjit::{
};
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::errors as ssa_errors;
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, MiscMethods};
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods};
use rustc_data_structures::base_n::{ToBaseN, ALPHANUMERIC_ONLY};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError,
LayoutOfHelpers, TyAndLayout,
LayoutOfHelpers,
};
use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
use rustc_session::Session;
use rustc_span::source_map::respan;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, TlsModel, WasmCAbi};
@ -426,7 +425,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
type DIVariable = (); // TODO(antoyo)
}
impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn vtables(
&self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
@ -572,8 +571,6 @@ impl<'gcc, 'tcx> HasWasmCAbiOpt for CodegenCx<'gcc, 'tcx> {
}
impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
@ -585,8 +582,6 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
}
impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
#[inline]
fn handle_fn_abi_err(
&self,

View File

@ -2,7 +2,7 @@ use std::ops::Range;
use gccjit::{Location, RValue};
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoMethods};
use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoCodegenMethods};
use rustc_data_structures::sync::Lrc;
use rustc_index::bit_set::BitSet;
use rustc_index::{Idx, IndexVec};
@ -206,7 +206,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
}
}
impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn create_vtable_debuginfo(
&self,
_ty: Ty<'tcx>,

View File

@ -1,7 +1,7 @@
#[cfg(feature = "master")]
use gccjit::{FnAttribute, ToRValue};
use gccjit::{Function, FunctionType, GlobalKind, LValue, RValue, Type};
use rustc_codegen_ssa::traits::BaseTypeMethods;
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::abi::call::FnAbi;

View File

@ -4,7 +4,7 @@
use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp};
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, BuilderMethods, OverflowOp};
use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp};
use rustc_middle::ty::{ParamEnv, Ty};
use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode};
use rustc_target::abi::Endian;

View File

@ -13,10 +13,10 @@ use rustc_codegen_ssa::errors::InvalidMonomorphization;
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
use rustc_codegen_ssa::traits::{
ArgAbiMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods,
ArgAbiBuilderMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods,
};
#[cfg(feature = "master")]
use rustc_codegen_ssa::traits::{BaseTypeMethods, MiscMethods};
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, MiscCodegenMethods};
use rustc_codegen_ssa::MemFlags;
use rustc_middle::bug;
use rustc_middle::ty::layout::LayoutOf;
@ -94,7 +94,7 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
Some(cx.context.get_builtin_function(gcc_name))
}
impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
fn codegen_intrinsic_call(
&mut self,
instance: Instance<'tcx>,
@ -448,7 +448,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
}
}
impl<'a, 'gcc, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
fn store_fn_arg(
&mut self,
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,

View File

@ -10,7 +10,7 @@ use rustc_codegen_ssa::errors::ExpectedPointerMutability;
use rustc_codegen_ssa::errors::InvalidMonomorphization;
use rustc_codegen_ssa::mir::operand::OperandRef;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods};
#[cfg(feature = "master")]
use rustc_hir as hir;
use rustc_middle::mir::BinOp;

View File

@ -1,6 +1,6 @@
#[cfg(feature = "master")]
use gccjit::{FnAttribute, VarAttribute};
use rustc_codegen_ssa::traits::PreDefineMethods;
use rustc_codegen_ssa::traits::PreDefineCodegenMethods;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::bug;
@ -13,7 +13,7 @@ use crate::context::CodegenCx;
use crate::type_of::LayoutGccExt;
use crate::{attributes, base};
impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
#[cfg_attr(not(feature = "master"), allow(unused_variables))]
fn predefine_static(
&self,

View File

@ -5,7 +5,9 @@ use std::convert::TryInto;
use gccjit::CType;
use gccjit::{RValue, Struct, Type};
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods};
use rustc_codegen_ssa::traits::{
BaseTypeCodegenMethods, DerivedTypeCodegenMethods, TypeMembershipCodegenMethods,
};
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::{bug, ty};
use rustc_target::abi::{AddressSpace, Align, Integer, Size};
@ -121,7 +123,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
}
}
impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn type_i8(&self) -> Type<'gcc> {
self.i8_type
}
@ -381,4 +383,4 @@ pub fn struct_fields<'gcc, 'tcx>(
(result, packed)
}
impl<'gcc, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'gcc, 'tcx> {}
impl<'gcc, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {}

View File

@ -1,7 +1,9 @@
use std::fmt::Write;
use gccjit::{Struct, Type};
use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods};
use rustc_codegen_ssa::traits::{
BaseTypeCodegenMethods, DerivedTypeCodegenMethods, LayoutTypeCodegenMethods,
};
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
@ -330,7 +332,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
}
}
impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
impl<'gcc, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Type<'gcc> {
layout.gcc_type(self)
}

View File

@ -285,7 +285,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
}
}
impl<'ll, 'tcx> ArgAbiMethods<'tcx> for Builder<'_, 'll, 'tcx> {
impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
fn store_fn_arg(
&mut self,
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
@ -465,9 +465,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
cx.type_array(cx.type_i8(), self.ret.layout.size.bytes()),
);
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]);
if cx.sess().opts.optimize != config::OptLevel::No
&& llvm_util::get_version() >= (18, 0, 0)
{
if cx.sess().opts.optimize != config::OptLevel::No {
attributes::apply_to_llfn(
llfn,
llvm::AttributePlace::Argument(i),

View File

@ -356,7 +356,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
}
impl<'tcx> AsmMethods<'tcx> for CodegenCx<'_, 'tcx> {
impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
fn codegen_global_asm(
&self,
template: &[InlineAsmTemplatePiece],
@ -520,24 +520,16 @@ pub(crate) fn inline_asm_call<'ll>(
/// If the register is an xmm/ymm/zmm register then return its index.
fn xmm_reg_index(reg: InlineAsmReg) -> Option<u32> {
use X86InlineAsmReg::*;
match reg {
InlineAsmReg::X86(reg)
if reg as u32 >= X86InlineAsmReg::xmm0 as u32
&& reg as u32 <= X86InlineAsmReg::xmm15 as u32 =>
{
Some(reg as u32 - X86InlineAsmReg::xmm0 as u32)
InlineAsmReg::X86(reg) if reg as u32 >= xmm0 as u32 && reg as u32 <= xmm15 as u32 => {
Some(reg as u32 - xmm0 as u32)
}
InlineAsmReg::X86(reg)
if reg as u32 >= X86InlineAsmReg::ymm0 as u32
&& reg as u32 <= X86InlineAsmReg::ymm15 as u32 =>
{
Some(reg as u32 - X86InlineAsmReg::ymm0 as u32)
InlineAsmReg::X86(reg) if reg as u32 >= ymm0 as u32 && reg as u32 <= ymm15 as u32 => {
Some(reg as u32 - ymm0 as u32)
}
InlineAsmReg::X86(reg)
if reg as u32 >= X86InlineAsmReg::zmm0 as u32
&& reg as u32 <= X86InlineAsmReg::zmm31 as u32 =>
{
Some(reg as u32 - X86InlineAsmReg::zmm0 as u32)
InlineAsmReg::X86(reg) if reg as u32 >= zmm0 as u32 && reg as u32 <= zmm31 as u32 => {
Some(reg as u32 - zmm0 as u32)
}
_ => None,
}
@ -545,50 +537,56 @@ fn xmm_reg_index(reg: InlineAsmReg) -> Option<u32> {
/// If the register is an AArch64 integer register then return its index.
fn a64_reg_index(reg: InlineAsmReg) -> Option<u32> {
match reg {
InlineAsmReg::AArch64(AArch64InlineAsmReg::x0) => Some(0),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x1) => Some(1),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x2) => Some(2),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x3) => Some(3),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x4) => Some(4),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x5) => Some(5),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x6) => Some(6),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x7) => Some(7),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x8) => Some(8),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x9) => Some(9),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x10) => Some(10),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x11) => Some(11),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x12) => Some(12),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x13) => Some(13),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x14) => Some(14),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x15) => Some(15),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x16) => Some(16),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x17) => Some(17),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x18) => Some(18),
// x19 is reserved
InlineAsmReg::AArch64(AArch64InlineAsmReg::x20) => Some(20),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x21) => Some(21),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x22) => Some(22),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x23) => Some(23),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x24) => Some(24),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x25) => Some(25),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x26) => Some(26),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x27) => Some(27),
InlineAsmReg::AArch64(AArch64InlineAsmReg::x28) => Some(28),
// x29 is reserved
InlineAsmReg::AArch64(AArch64InlineAsmReg::x30) => Some(30),
_ => None,
}
use AArch64InlineAsmReg::*;
// Unlike `a64_vreg_index`, we can't subtract `x0` to get the u32 because
// `x19` and `x29` are missing and the integer constants for the
// `x0`..`x30` enum variants don't all match the register number. E.g. the
// integer constant for `x18` is 18, but the constant for `x20` is 19.
Some(match reg {
InlineAsmReg::AArch64(r) => match r {
x0 => 0,
x1 => 1,
x2 => 2,
x3 => 3,
x4 => 4,
x5 => 5,
x6 => 6,
x7 => 7,
x8 => 8,
x9 => 9,
x10 => 10,
x11 => 11,
x12 => 12,
x13 => 13,
x14 => 14,
x15 => 15,
x16 => 16,
x17 => 17,
x18 => 18,
// x19 is reserved
x20 => 20,
x21 => 21,
x22 => 22,
x23 => 23,
x24 => 24,
x25 => 25,
x26 => 26,
x27 => 27,
x28 => 28,
// x29 is reserved
x30 => 30,
_ => return None,
},
_ => return None,
})
}
/// If the register is an AArch64 vector register then return its index.
fn a64_vreg_index(reg: InlineAsmReg) -> Option<u32> {
use AArch64InlineAsmReg::*;
match reg {
InlineAsmReg::AArch64(reg)
if reg as u32 >= AArch64InlineAsmReg::v0 as u32
&& reg as u32 <= AArch64InlineAsmReg::v31 as u32 =>
{
Some(reg as u32 - AArch64InlineAsmReg::v0 as u32)
InlineAsmReg::AArch64(reg) if reg as u32 >= v0 as u32 && reg as u32 <= v31 as u32 => {
Some(reg as u32 - v0 as u32)
}
_ => None,
}
@ -596,6 +594,7 @@ fn a64_vreg_index(reg: InlineAsmReg) -> Option<u32> {
/// Converts a register class to an LLVM constraint code.
fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> String {
use InlineAsmRegClass::*;
match reg {
// For vector registers LLVM wants the register name to match the type size.
InlineAsmRegOrRegClass::Reg(reg) => {
@ -652,75 +651,66 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
// The constraints can be retrieved from
// https://llvm.org/docs/LangRef.html#supported-constraint-code-list
InlineAsmRegOrRegClass::RegClass(reg) => match reg {
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r",
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w",
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
AArch64(AArch64InlineAsmRegClass::reg) => "r",
AArch64(AArch64InlineAsmRegClass::vreg) => "w",
AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
Arm(ArmInlineAsmRegClass::reg) => "r",
Arm(ArmInlineAsmRegClass::sreg)
| Arm(ArmInlineAsmRegClass::dreg_low16)
| Arm(ArmInlineAsmRegClass::qreg_low8) => "t",
Arm(ArmInlineAsmRegClass::sreg_low16)
| Arm(ArmInlineAsmRegClass::dreg_low8)
| Arm(ArmInlineAsmRegClass::qreg_low4) => "x",
Arm(ArmInlineAsmRegClass::dreg) | Arm(ArmInlineAsmRegClass::qreg) => "w",
Hexagon(HexagonInlineAsmRegClass::reg) => "r",
LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
Mips(MipsInlineAsmRegClass::reg) => "r",
Mips(MipsInlineAsmRegClass::freg) => "f",
Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => "t",
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) => "x",
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "w",
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) => "r",
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => "Q",
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => "q",
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg)
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x",
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk",
InlineAsmRegClass::X86(
RiscV(RiscVInlineAsmRegClass::reg) => "r",
RiscV(RiscVInlineAsmRegClass::freg) => "f",
RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
X86(X86InlineAsmRegClass::reg) => "r",
X86(X86InlineAsmRegClass::reg_abcd) => "Q",
X86(X86InlineAsmRegClass::reg_byte) => "q",
X86(X86InlineAsmRegClass::xmm_reg) | X86(X86InlineAsmRegClass::ymm_reg) => "x",
X86(X86InlineAsmRegClass::zmm_reg) => "v",
X86(X86InlineAsmRegClass::kreg) => "^Yk",
X86(
X86InlineAsmRegClass::x87_reg
| X86InlineAsmRegClass::mmx_reg
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => "d",
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => "r",
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w",
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e",
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r",
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
InlineAsmRegClass::Err => unreachable!(),
Wasm(WasmInlineAsmRegClass::local) => "r",
Bpf(BpfInlineAsmRegClass::reg) => "r",
Bpf(BpfInlineAsmRegClass::wreg) => "w",
Avr(AvrInlineAsmRegClass::reg) => "r",
Avr(AvrInlineAsmRegClass::reg_upper) => "d",
Avr(AvrInlineAsmRegClass::reg_pair) => "r",
Avr(AvrInlineAsmRegClass::reg_iw) => "w",
Avr(AvrInlineAsmRegClass::reg_ptr) => "e",
S390x(S390xInlineAsmRegClass::reg) => "r",
S390x(S390xInlineAsmRegClass::reg_addr) => "a",
S390x(S390xInlineAsmRegClass::freg) => "f",
Msp430(Msp430InlineAsmRegClass::reg) => "r",
M68k(M68kInlineAsmRegClass::reg) => "r",
M68k(M68kInlineAsmRegClass::reg_addr) => "a",
M68k(M68kInlineAsmRegClass::reg_data) => "d",
CSKY(CSKYInlineAsmRegClass::reg) => "r",
CSKY(CSKYInlineAsmRegClass::freg) => "f",
SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
Err => unreachable!(),
}
.to_string(),
}
@ -732,44 +722,41 @@ fn modifier_to_llvm(
reg: InlineAsmRegClass,
modifier: Option<char>,
) -> Option<char> {
use InlineAsmRegClass::*;
// The modifiers can be retrieved from
// https://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
match reg {
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => modifier,
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg)
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
if modifier == Some('v') { None } else { modifier }
AArch64(AArch64InlineAsmRegClass::reg) => modifier,
AArch64(AArch64InlineAsmRegClass::vreg) | AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
if modifier == Some('v') {
None
} else {
modifier
}
}
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => None,
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => None,
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8) => Some('P'),
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) => {
AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
Arm(ArmInlineAsmRegClass::reg) => None,
Arm(ArmInlineAsmRegClass::sreg) | Arm(ArmInlineAsmRegClass::sreg_low16) => None,
Arm(ArmInlineAsmRegClass::dreg)
| Arm(ArmInlineAsmRegClass::dreg_low16)
| Arm(ArmInlineAsmRegClass::dreg_low8) => Some('P'),
Arm(ArmInlineAsmRegClass::qreg)
| Arm(ArmInlineAsmRegClass::qreg_low8)
| Arm(ArmInlineAsmRegClass::qreg_low4) => {
if modifier.is_none() {
Some('q')
} else {
modifier
}
}
InlineAsmRegClass::Hexagon(_) => None,
InlineAsmRegClass::LoongArch(_) => None,
InlineAsmRegClass::Mips(_) => None,
InlineAsmRegClass::Nvptx(_) => None,
InlineAsmRegClass::PowerPC(_) => None,
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg)
| InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None,
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg)
| InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => match modifier {
Hexagon(_) => None,
LoongArch(_) => None,
Mips(_) => None,
Nvptx(_) => None,
PowerPC(_) => None,
RiscV(RiscVInlineAsmRegClass::reg) | RiscV(RiscVInlineAsmRegClass::freg) => None,
RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
X86(X86InlineAsmRegClass::reg) | X86(X86InlineAsmRegClass::reg_abcd) => match modifier {
None if arch == InlineAsmArch::X86_64 => Some('q'),
None => Some('k'),
Some('l') => Some('b'),
@ -779,10 +766,10 @@ fn modifier_to_llvm(
Some('r') => Some('q'),
_ => unreachable!(),
},
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => None,
InlineAsmRegClass::X86(reg @ X86InlineAsmRegClass::xmm_reg)
| InlineAsmRegClass::X86(reg @ X86InlineAsmRegClass::ymm_reg)
| InlineAsmRegClass::X86(reg @ X86InlineAsmRegClass::zmm_reg) => match (reg, modifier) {
X86(X86InlineAsmRegClass::reg_byte) => None,
X86(reg @ X86InlineAsmRegClass::xmm_reg)
| X86(reg @ X86InlineAsmRegClass::ymm_reg)
| X86(reg @ X86InlineAsmRegClass::zmm_reg) => match (reg, modifier) {
(X86InlineAsmRegClass::xmm_reg, None) => Some('x'),
(X86InlineAsmRegClass::ymm_reg, None) => Some('t'),
(X86InlineAsmRegClass::zmm_reg, None) => Some('g'),
@ -791,116 +778,97 @@ fn modifier_to_llvm(
(_, Some('z')) => Some('g'),
_ => unreachable!(),
},
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
InlineAsmRegClass::X86(
X86(X86InlineAsmRegClass::kreg) => None,
X86(
X86InlineAsmRegClass::x87_reg
| X86InlineAsmRegClass::mmx_reg
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
InlineAsmRegClass::Bpf(_) => None,
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair)
| InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw)
| InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => match modifier {
) => unreachable!("clobber-only"),
Wasm(WasmInlineAsmRegClass::local) => None,
Bpf(_) => None,
Avr(AvrInlineAsmRegClass::reg_pair)
| Avr(AvrInlineAsmRegClass::reg_iw)
| Avr(AvrInlineAsmRegClass::reg_ptr) => match modifier {
Some('h') => Some('B'),
Some('l') => Some('A'),
_ => None,
},
InlineAsmRegClass::Avr(_) => None,
InlineAsmRegClass::S390x(_) => None,
InlineAsmRegClass::Msp430(_) => None,
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
InlineAsmRegClass::M68k(_) => None,
InlineAsmRegClass::CSKY(_) => None,
InlineAsmRegClass::Err => unreachable!(),
Avr(_) => None,
S390x(_) => None,
Msp430(_) => None,
SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
M68k(_) => None,
CSKY(_) => None,
Err => unreachable!(),
}
}
/// Type to use for outputs that are discarded. It doesn't really matter what
/// the type is, as long as it is valid for the constraint code.
fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'ll Type {
use InlineAsmRegClass::*;
match reg {
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg)
| InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(),
AArch64(AArch64InlineAsmRegClass::vreg) | AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
cx.type_vector(cx.type_i64(), 2)
}
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
Arm(ArmInlineAsmRegClass::sreg) | Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
Arm(ArmInlineAsmRegClass::dreg)
| Arm(ArmInlineAsmRegClass::dreg_low16)
| Arm(ArmInlineAsmRegClass::dreg_low8) => cx.type_f64(),
Arm(ArmInlineAsmRegClass::qreg)
| Arm(ArmInlineAsmRegClass::qreg_low8)
| Arm(ArmInlineAsmRegClass::qreg_low4) => cx.type_vector(cx.type_i64(), 2),
Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(),
Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(),
PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8) => cx.type_f64(),
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8)
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) => {
cx.type_vector(cx.type_i64(), 2)
}
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(),
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg)
| InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => cx.type_i32(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => cx.type_i8(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg)
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg)
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
InlineAsmRegClass::X86(
RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
RiscV(RiscVInlineAsmRegClass::freg) => cx.type_f32(),
RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
X86(X86InlineAsmRegClass::reg) | X86(X86InlineAsmRegClass::reg_abcd) => cx.type_i32(),
X86(X86InlineAsmRegClass::reg_byte) => cx.type_i8(),
X86(X86InlineAsmRegClass::xmm_reg)
| X86(X86InlineAsmRegClass::ymm_reg)
| X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
X86(
X86InlineAsmRegClass::x87_reg
| X86InlineAsmRegClass::mmx_reg
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => cx.type_i8(),
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => cx.type_i8(),
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => cx.type_i16(),
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => cx.type_i16(),
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
InlineAsmRegClass::S390x(
S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr,
) => cx.type_i32(),
InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
InlineAsmRegClass::Err => unreachable!(),
) => unreachable!("clobber-only"),
Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
Avr(AvrInlineAsmRegClass::reg) => cx.type_i8(),
Avr(AvrInlineAsmRegClass::reg_upper) => cx.type_i8(),
Avr(AvrInlineAsmRegClass::reg_pair) => cx.type_i16(),
Avr(AvrInlineAsmRegClass::reg_iw) => cx.type_i16(),
Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(),
CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(),
SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
Err => unreachable!(),
}
}
@ -940,9 +908,10 @@ fn llvm_fixup_input<'ll, 'tcx>(
layout: &TyAndLayout<'tcx>,
instance: Instance<'_>,
) -> &'ll Value {
use InlineAsmRegClass::*;
let dl = &bx.tcx.data_layout;
match (reg, layout.abi) {
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
(AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
if let Primitive::Int(Integer::I8, _) = s.primitive() {
let vec_ty = bx.cx.type_vector(bx.cx.type_i8(), 8);
bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
@ -950,7 +919,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
value
}
}
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
if s.primitive() != Primitive::Float(Float::F128) =>
{
let elem_ty = llvm_asm_scalar_type(bx.cx, s);
@ -963,26 +932,25 @@ fn llvm_fixup_input<'ll, 'tcx>(
}
bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
}
(
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16),
Abi::Vector { element, count },
) if layout.size.bytes() == 8 => {
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
if layout.size.bytes() == 8 =>
{
let elem_ty = llvm_asm_scalar_type(bx.cx, element);
let vec_ty = bx.cx.type_vector(elem_ty, count);
let indices: Vec<_> = (0..count * 2).map(|x| bx.const_i32(x as i32)).collect();
bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
}
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
(X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
if s.primitive() == Primitive::Float(Float::F64) =>
{
bx.bitcast(value, bx.cx.type_i64())
}
(
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
Abi::Vector { .. },
) if layout.size.bytes() == 64 => bx.bitcast(value, bx.cx.type_vector(bx.cx.type_f64(), 8)),
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -994,7 +962,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
bx.bitcast(value, bx.type_vector(bx.type_i32(), 4))
}
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -1009,7 +977,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
bx.bitcast(value, bx.type_vector(bx.type_i16(), 8))
}
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -1018,10 +986,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
) if element.primitive() == Primitive::Float(Float::F16) => {
bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
}
(
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
Abi::Scalar(s),
) => {
(Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16), Abi::Scalar(s)) => {
if let Primitive::Int(Integer::I32, _) = s.primitive() {
bx.bitcast(value, bx.cx.type_f32())
} else {
@ -1029,7 +994,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
}
}
(
InlineAsmRegClass::Arm(
Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16,
@ -1043,7 +1008,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
}
}
(
InlineAsmRegClass::Arm(
Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16
@ -1055,7 +1020,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
) if element.primitive() == Primitive::Float(Float::F16) => {
bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
}
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
(Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
match s.primitive() {
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
@ -1064,7 +1029,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
_ => value,
}
}
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
(RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
if s.primitive() == Primitive::Float(Float::F16)
&& !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
{
@ -1086,15 +1051,16 @@ fn llvm_fixup_output<'ll, 'tcx>(
layout: &TyAndLayout<'tcx>,
instance: Instance<'_>,
) -> &'ll Value {
use InlineAsmRegClass::*;
match (reg, layout.abi) {
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
(AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
if let Primitive::Int(Integer::I8, _) = s.primitive() {
bx.extract_element(value, bx.const_i32(0))
} else {
value
}
}
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
if s.primitive() != Primitive::Float(Float::F128) =>
{
value = bx.extract_element(value, bx.const_i32(0));
@ -1103,26 +1069,25 @@ fn llvm_fixup_output<'ll, 'tcx>(
}
value
}
(
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16),
Abi::Vector { element, count },
) if layout.size.bytes() == 8 => {
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
if layout.size.bytes() == 8 =>
{
let elem_ty = llvm_asm_scalar_type(bx.cx, element);
let vec_ty = bx.cx.type_vector(elem_ty, count * 2);
let indices: Vec<_> = (0..count).map(|x| bx.const_i32(x as i32)).collect();
bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
}
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
(X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
if s.primitive() == Primitive::Float(Float::F64) =>
{
bx.bitcast(value, bx.cx.type_f64())
}
(
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
Abi::Vector { .. },
) if layout.size.bytes() == 64 => bx.bitcast(value, layout.llvm_type(bx.cx)),
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -1134,7 +1099,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
bx.bitcast(value, bx.type_f128())
}
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -1145,7 +1110,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
bx.extract_element(value, bx.const_usize(0))
}
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -1154,10 +1119,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
) if element.primitive() == Primitive::Float(Float::F16) => {
bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
}
(
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
Abi::Scalar(s),
) => {
(Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16), Abi::Scalar(s)) => {
if let Primitive::Int(Integer::I32, _) = s.primitive() {
bx.bitcast(value, bx.cx.type_i32())
} else {
@ -1165,7 +1127,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
}
}
(
InlineAsmRegClass::Arm(
Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16,
@ -1179,7 +1141,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
}
}
(
InlineAsmRegClass::Arm(
Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16
@ -1191,7 +1153,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
) if element.primitive() == Primitive::Float(Float::F16) => {
bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
}
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
(Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
match s.primitive() {
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
@ -1201,7 +1163,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
_ => value,
}
}
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
(RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
if s.primitive() == Primitive::Float(Float::F16)
&& !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
{
@ -1220,39 +1182,39 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
layout: &TyAndLayout<'tcx>,
instance: Instance<'_>,
) -> &'ll Type {
use InlineAsmRegClass::*;
match (reg, layout.abi) {
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
(AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
if let Primitive::Int(Integer::I8, _) = s.primitive() {
cx.type_vector(cx.type_i8(), 8)
} else {
layout.llvm_type(cx)
}
}
(InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
if s.primitive() != Primitive::Float(Float::F128) =>
{
let elem_ty = llvm_asm_scalar_type(cx, s);
let count = 16 / layout.size.bytes();
cx.type_vector(elem_ty, count)
}
(
InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16),
Abi::Vector { element, count },
) if layout.size.bytes() == 8 => {
(AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
if layout.size.bytes() == 8 =>
{
let elem_ty = llvm_asm_scalar_type(cx, element);
cx.type_vector(elem_ty, count * 2)
}
(InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
(X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
if s.primitive() == Primitive::Float(Float::F64) =>
{
cx.type_i64()
}
(
InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
Abi::Vector { .. },
) if layout.size.bytes() == 64 => cx.type_vector(cx.type_f64(), 8),
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -1264,7 +1226,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
cx.type_vector(cx.type_i32(), 4)
}
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -1272,7 +1234,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
Abi::Scalar(s),
) if s.primitive() == Primitive::Float(Float::F16) => cx.type_vector(cx.type_i16(), 8),
(
InlineAsmRegClass::X86(
X86(
X86InlineAsmRegClass::xmm_reg
| X86InlineAsmRegClass::ymm_reg
| X86InlineAsmRegClass::zmm_reg,
@ -1281,10 +1243,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
) if element.primitive() == Primitive::Float(Float::F16) => {
cx.type_vector(cx.type_i16(), count)
}
(
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
Abi::Scalar(s),
) => {
(Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16), Abi::Scalar(s)) => {
if let Primitive::Int(Integer::I32, _) = s.primitive() {
cx.type_f32()
} else {
@ -1292,7 +1251,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
}
}
(
InlineAsmRegClass::Arm(
Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16,
@ -1306,7 +1265,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
}
}
(
InlineAsmRegClass::Arm(
Arm(
ArmInlineAsmRegClass::dreg
| ArmInlineAsmRegClass::dreg_low8
| ArmInlineAsmRegClass::dreg_low16
@ -1318,7 +1277,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
) if element.primitive() == Primitive::Float(Float::F16) => {
cx.type_vector(cx.type_i16(), count)
}
(InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
(Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
match s.primitive() {
// MIPS only supports register-length arithmetics.
Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
@ -1327,7 +1286,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
_ => layout.llvm_type(cx),
}
}
(InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
(RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
if s.primitive() == Primitive::Float(Float::F16)
&& !any_target_feature_enabled(cx, instance, &[sym::zfhmin, sym::zfh]) =>
{

View File

@ -403,8 +403,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
// HACK(jubilee): "indirect branch tracking" works by attaching prologues to functions.
// And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules.
// Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768
// And it is a module-level attribute, so the alternative is pulling naked functions into
// new LLVM modules. Otherwise LLVM's "naked" functions come with endbr prefixes per
// https://github.com/rust-lang/rust/issues/98768
to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
if llvm_util::get_version() < (19, 0, 0) {
// Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to
@ -454,7 +455,8 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
flags |= AllocKindFlags::Zeroed;
}
to_add.push(llvm::CreateAllocKindAttr(cx.llcx, flags));
// apply to return place instead of function (unlike all other attributes applied in this function)
// apply to return place instead of function (unlike all other attributes applied in this
// function)
let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
}

View File

@ -156,15 +156,15 @@ fn get_bitcode_slice_from_object_data<'a>(
obj: &'a [u8],
cgcx: &CodegenContext<LlvmCodegenBackend>,
) -> Result<&'a [u8], LtoBitcodeFromRlib> {
// We're about to assume the data here is an object file with sections, but if it's raw LLVM IR that
// won't work. Fortunately, if that's what we have we can just return the object directly, so we sniff
// the relevant magic strings here and return.
// We're about to assume the data here is an object file with sections, but if it's raw LLVM IR
// that won't work. Fortunately, if that's what we have we can just return the object directly,
// so we sniff the relevant magic strings here and return.
if obj.starts_with(b"\xDE\xC0\x17\x0B") || obj.starts_with(b"BC\xC0\xDE") {
return Ok(obj);
}
// We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment name"
// which in the public API for sections gets treated as part of the section name, but internally
// in MachOObjectFile.cpp gets treated separately.
// We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment
// name" which in the public API for sections gets treated as part of the section name, but
// internally in MachOObjectFile.cpp gets treated separately.
let section_name = bitcode_section_name(cgcx).trim_start_matches("__LLVM,");
let mut len = 0;
let data = unsafe {

View File

@ -30,7 +30,7 @@ impl OwnedTargetMachine {
data_sections: bool,
unique_section_names: bool,
trap_unreachable: bool,
singletree: bool,
singlethread: bool,
verbose_asm: bool,
emit_stack_size_section: bool,
relax_elf_relocations: bool,
@ -62,7 +62,7 @@ impl OwnedTargetMachine {
data_sections,
unique_section_names,
trap_unreachable,
singletree,
singlethread,
verbose_asm,
emit_stack_size_section,
relax_elf_relocations,
@ -86,15 +86,17 @@ impl Deref for OwnedTargetMachine {
type Target = llvm::TargetMachine;
fn deref(&self) -> &Self::Target {
// SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
// SAFETY: constructing ensures we have a valid pointer created by
// llvm::LLVMRustCreateTargetMachine.
unsafe { self.tm_unique.as_ref() }
}
}
impl Drop for OwnedTargetMachine {
fn drop(&mut self) {
// SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
// OwnedTargetMachine is not copyable so there is no double free or use after free
// SAFETY: constructing ensures we have a valid pointer created by
// llvm::LLVMRustCreateTargetMachine OwnedTargetMachine is not copyable so there is no
// double free or use after free.
unsafe {
llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut());
}

View File

@ -38,7 +38,7 @@ use crate::errors::{
CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, UnknownCompression,
WithLlvmError, WriteBytecode,
};
use crate::llvm::diagnostic::OptimizationDiagnosticKind;
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
use crate::llvm::{self, DiagnosticInfo, PassManager};
use crate::type_::Type;
use crate::{base, common, llvm_util, LlvmCodegenBackend, ModuleLlvm};
@ -157,7 +157,8 @@ fn to_pass_builder_opt_level(cfg: config::OptLevel) -> llvm::PassBuilderOptLevel
fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
match relocation_model {
RelocModel::Static => llvm::RelocModel::Static,
// LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra attribute.
// LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra
// attribute.
RelocModel::Pic | RelocModel::Pie => llvm::RelocModel::PIC,
RelocModel::DynamicNoPic => llvm::RelocModel::DynamicNoPic,
RelocModel::Ropi => llvm::RelocModel::ROPI,
@ -188,8 +189,8 @@ pub(crate) fn target_machine_factory(
let use_softfp = if sess.target.arch == "arm" && sess.target.abi == "eabihf" {
sess.opts.cg.soft_float
} else {
// `validate_commandline_args_with_session_available` has already warned about this being ignored.
// Let's make sure LLVM doesn't suddenly start using this flag on more targets.
// `validate_commandline_args_with_session_available` has already warned about this being
// ignored. Let's make sure LLVM doesn't suddenly start using this flag on more targets.
false
};
@ -446,13 +447,12 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
column: opt.column,
pass_name: &opt.pass_name,
kind: match opt.kind {
OptimizationDiagnosticKind::OptimizationRemark => "success",
OptimizationDiagnosticKind::OptimizationMissed
| OptimizationDiagnosticKind::OptimizationFailure => "missed",
OptimizationDiagnosticKind::OptimizationAnalysis
| OptimizationDiagnosticKind::OptimizationAnalysisFPCommute
| OptimizationDiagnosticKind::OptimizationAnalysisAliasing => "analysis",
OptimizationDiagnosticKind::OptimizationRemarkOther => "other",
OptimizationRemark => "success",
OptimizationMissed | OptimizationFailure => "missed",
OptimizationAnalysis
| OptimizationAnalysisFPCommute
| OptimizationAnalysisAliasing => "analysis",
OptimizationRemarkOther => "other",
},
message: &opt.message,
});
@ -945,11 +945,12 @@ fn create_section_with_flags_asm(section_name: &str, section_flags: &str, data:
}
fn target_is_apple(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
cgcx.opts.target_triple.triple().contains("-ios")
|| cgcx.opts.target_triple.triple().contains("-darwin")
|| cgcx.opts.target_triple.triple().contains("-tvos")
|| cgcx.opts.target_triple.triple().contains("-watchos")
|| cgcx.opts.target_triple.triple().contains("-visionos")
let triple = cgcx.opts.target_triple.triple();
triple.contains("-ios")
|| triple.contains("-darwin")
|| triple.contains("-tvos")
|| triple.contains("-watchos")
|| triple.contains("-visionos")
}
fn target_is_aix(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {

View File

@ -26,13 +26,13 @@ use smallvec::SmallVec;
use tracing::{debug, instrument};
use crate::abi::FnAbiLlvmExt;
use crate::attributes;
use crate::common::Funclet;
use crate::context::CodegenCx;
use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;
use crate::value::Value;
use crate::{attributes, llvm_util};
// All Builders must have an llfn associated with them
#[must_use]
@ -93,8 +93,6 @@ impl HasTargetSpec for Builder<'_, '_, '_> {
}
impl<'tcx> LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
self.cx.handle_layout_err(err, span, ty)
@ -102,8 +100,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
}
impl<'tcx> FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
#[inline]
fn handle_fn_abi_err(
&self,
@ -124,11 +120,7 @@ impl<'ll, 'tcx> Deref for Builder<'_, 'll, 'tcx> {
}
}
impl<'ll, 'tcx> HasCodegen<'tcx> for Builder<'_, 'll, 'tcx> {
type CodegenCx = CodegenCx<'ll, 'tcx>;
}
macro_rules! builder_methods_for_value_instructions {
macro_rules! math_builder_methods {
($($name:ident($($arg:ident),*) => $llvm_capi:ident),+ $(,)?) => {
$(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
unsafe {
@ -138,7 +130,21 @@ macro_rules! builder_methods_for_value_instructions {
}
}
macro_rules! set_math_builder_methods {
($($name:ident($($arg:ident),*) => ($llvm_capi:ident, $llvm_set_math:ident)),+ $(,)?) => {
$(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
unsafe {
let instr = llvm::$llvm_capi(self.llbuilder, $($arg,)* UNNAMED);
llvm::$llvm_set_math(instr);
instr
}
})+
}
}
impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
type CodegenCx = CodegenCx<'ll, 'tcx>;
fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Self {
let bx = Builder::with_cx(cx);
unsafe {
@ -273,7 +279,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}
builder_methods_for_value_instructions! {
math_builder_methods! {
add(a, b) => LLVMBuildAdd,
fadd(a, b) => LLVMBuildFAdd,
sub(a, b) => LLVMBuildSub,
@ -305,84 +311,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
unchecked_umul(x, y) => LLVMBuildNUWMul,
}
fn fadd_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn fsub_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn fmul_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn fdiv_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn frem_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetFastMath(instr);
instr
}
}
fn fadd_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
}
fn fsub_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
}
fn fmul_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
}
fn fdiv_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
}
fn frem_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
unsafe {
let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
llvm::LLVMRustSetAlgebraicMath(instr);
instr
}
set_math_builder_methods! {
fadd_fast(x, y) => (LLVMBuildFAdd, LLVMRustSetFastMath),
fsub_fast(x, y) => (LLVMBuildFSub, LLVMRustSetFastMath),
fmul_fast(x, y) => (LLVMBuildFMul, LLVMRustSetFastMath),
fdiv_fast(x, y) => (LLVMBuildFDiv, LLVMRustSetFastMath),
frem_fast(x, y) => (LLVMBuildFRem, LLVMRustSetFastMath),
fadd_algebraic(x, y) => (LLVMBuildFAdd, LLVMRustSetAlgebraicMath),
fsub_algebraic(x, y) => (LLVMBuildFSub, LLVMRustSetAlgebraicMath),
fmul_algebraic(x, y) => (LLVMBuildFMul, LLVMRustSetAlgebraicMath),
fdiv_algebraic(x, y) => (LLVMBuildFDiv, LLVMRustSetAlgebraicMath),
frem_algebraic(x, y) => (LLVMBuildFRem, LLVMRustSetAlgebraicMath),
}
fn checked_binop(
@ -465,6 +404,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
val
}
}
fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value {
if scalar.is_bool() {
return self.trunc(val, self.cx().type_i1());
@ -733,11 +673,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
// for performance. LLVM doesn't seem to care about this, and will happily treat
// `!nontemporal` stores as-if they were normal stores (for reordering optimizations
// etc) even on x86, despite later lowering them to MOVNT which do *not* behave like
// regular stores but require special fences.
// So we keep a list of architectures where `!nontemporal` is known to be truly just
// a hint, and use regular stores everywhere else.
// (In the future, we could alternatively ensure that an sfence gets emitted after a sequence of movnt
// before any kind of synchronizing operation. But it's not clear how to do that with LLVM.)
// regular stores but require special fences. So we keep a list of architectures
// where `!nontemporal` is known to be truly just a hint, and use regular stores
// everywhere else. (In the future, we could alternatively ensure that an sfence
// gets emitted after a sequence of movnt before any kind of synchronizing
// operation. But it's not clear how to do that with LLVM.)
// For more context, see <https://github.com/rust-lang/rust/issues/114582> and
// <https://github.com/llvm/llvm-project/issues/64521>.
const WELL_BEHAVED_NONTEMPORAL_ARCHS: &[&str] =
@ -1166,6 +1106,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
(val, success)
}
}
fn atomic_rmw(
&mut self,
op: rustc_codegen_ssa::common::AtomicRmwBinOp,
@ -1317,15 +1258,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
fn apply_attrs_to_cleanup_callsite(&mut self, llret: &'ll Value) {
if llvm_util::get_version() < (17, 0, 2) {
// Work around https://github.com/llvm/llvm-project/issues/66984.
let noinline = llvm::AttributeKind::NoInline.create_attr(self.llcx);
attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[noinline]);
} else {
// Cleanup is always the cold path.
let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);
attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
}
// Cleanup is always the cold path.
let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);
attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
}
}
@ -1767,8 +1702,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
) {
debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bytes);
assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCParametersIntrinsic(self.cx().llmod) };
let llty = self.cx.type_func(
&[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32()],
@ -1802,7 +1735,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
"mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
fn_name, hash, bitmap_bytes, bitmap_index, mcdc_temp
);
assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
let llfn =
unsafe { llvm::LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(self.cx().llmod) };
@ -1844,7 +1776,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
"mcdc_condbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
fn_name, hash, cond_loc, mcdc_temp, bool_value
);
assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(self.cx().llmod) };
let llty = self.cx.type_func(
&[

View File

@ -15,11 +15,6 @@ use crate::value::Value;
/// Codegens a reference to a fn/method item, monomorphizing and
/// inlining as it goes.
///
/// # Parameters
///
/// - `cx`: the crate context
/// - `instance`: the instance to be instantiated
pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value {
let tcx = cx.tcx();
@ -106,62 +101,42 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
let is_generic =
instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some();
if is_generic {
// This is a monomorphization. Its expected visibility depends
// on whether we are in share-generics mode.
if cx.tcx.sess.opts.share_generics() {
// We are in share_generics mode.
let is_hidden = if is_generic {
// This is a monomorphization of a generic function.
if !cx.tcx.sess.opts.share_generics() {
// When not sharing generics, all instances are in the same
// crate and have hidden visibility.
true
} else {
if let Some(instance_def_id) = instance_def_id.as_local() {
// This is a definition from the current crate. If the
// definition is unreachable for downstream crates or
// the current crate does not re-export generics, the
// definition of the instance will have been declared
// as `hidden`.
if cx.tcx.is_unreachable_local_definition(instance_def_id)
// This is a monomorphization of a generic function
// defined in the current crate. It is hidden if:
// - the definition is unreachable for downstream
// crates, or
// - the current crate does not re-export generics
// (because the crate is a C library or executable)
cx.tcx.is_unreachable_local_definition(instance_def_id)
|| !cx.tcx.local_crate_exports_generics()
{
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
} else {
// This is a monomorphization of a generic function
// defined in an upstream crate.
if instance.upstream_monomorphization(tcx).is_some() {
// This is instantiated in another crate. It cannot
// be `hidden`.
} else {
// This is a local instantiation of an upstream definition.
// If the current crate does not re-export it
// (because it is a C library or an executable), it
// will have been declared `hidden`.
if !cx.tcx.local_crate_exports_generics() {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
}
// defined in an upstream crate. It is hidden if:
// - it is instantiated in this crate, and
// - the current crate does not re-export generics
instance.upstream_monomorphization(tcx).is_none()
&& !cx.tcx.local_crate_exports_generics()
}
} else {
// When not sharing generics, all instances are in the same
// crate and have hidden visibility
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
} else {
// This is a non-generic function
if cx.tcx.is_codegened_item(instance_def_id) {
// This is a function that is instantiated in the local crate
if instance_def_id.is_local() {
// This is function that is defined in the local crate.
// If it is not reachable, it is hidden.
if !cx.tcx.is_reachable_non_generic(instance_def_id) {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
} else {
// This is a function from an upstream crate that has
// been instantiated here. These are always hidden.
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
}
// This is a non-generic function. It is hidden if:
// - it is instantiated in the local crate, and
// - it is defined an upstream crate (non-local), or
// - it is not reachable
cx.tcx.is_codegened_item(instance_def_id)
&& (!instance_def_id.is_local()
|| !cx.tcx.is_reachable_non_generic(instance_def_id))
};
if is_hidden {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
// MinGW: For backward compatibility we rely on the linker to decide whether it

View File

@ -113,7 +113,7 @@ impl<'ll> CodegenCx<'ll, '_> {
}
}
impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn const_null(&self, t: &'ll Type) -> &'ll Value {
unsafe { llvm::LLVMConstNull(t) }
}
@ -126,25 +126,14 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
unsafe { llvm::LLVMGetPoison(t) }
}
fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value {
unsafe { llvm::LLVMConstInt(t, i as u64, True) }
}
fn const_uint(&self, t: &'ll Type, i: u64) -> &'ll Value {
unsafe { llvm::LLVMConstInt(t, i, False) }
}
fn const_uint_big(&self, t: &'ll Type, u: u128) -> &'ll Value {
unsafe {
let words = [u as u64, (u >> 64) as u64];
llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
}
}
fn const_bool(&self, val: bool) -> &'ll Value {
self.const_uint(self.type_i1(), val as u64)
}
fn const_i8(&self, i: i8) -> &'ll Value {
self.const_int(self.type_i8(), i as i64)
}
fn const_i16(&self, i: i16) -> &'ll Value {
self.const_int(self.type_i16(), i as i64)
}
@ -153,8 +142,12 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self.const_int(self.type_i32(), i as i64)
}
fn const_i8(&self, i: i8) -> &'ll Value {
self.const_int(self.type_i8(), i as i64)
fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value {
unsafe { llvm::LLVMConstInt(t, i as u64, True) }
}
fn const_u8(&self, i: u8) -> &'ll Value {
self.const_uint(self.type_i8(), i as u64)
}
fn const_u32(&self, i: u32) -> &'ll Value {
@ -179,8 +172,15 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self.const_uint(self.isize_ty, i)
}
fn const_u8(&self, i: u8) -> &'ll Value {
self.const_uint(self.type_i8(), i as u64)
fn const_uint(&self, t: &'ll Type, i: u64) -> &'ll Value {
unsafe { llvm::LLVMConstInt(t, i, False) }
}
fn const_uint_big(&self, t: &'ll Type, u: u128) -> &'ll Value {
unsafe {
let words = [u as u64, (u >> 64) as u64];
llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
}
}
fn const_real(&self, t: &'ll Type, val: f64) -> &'ll Value {

View File

@ -73,8 +73,8 @@ pub(crate) fn const_alloc_to_llvm<'ll>(
// Generating partially-uninit consts is limited to small numbers of chunks,
// to avoid the cost of generating large complex const expressions.
// For example, `[(u32, u8); 1024 * 1024]` contains uninit padding in each element,
// and would result in `{ [5 x i8] zeroinitializer, [3 x i8] undef, ...repeat 1M times... }`.
// For example, `[(u32, u8); 1024 * 1024]` contains uninit padding in each element, and
// would result in `{ [5 x i8] zeroinitializer, [3 x i8] undef, ...repeat 1M times... }`.
let max = cx.sess().opts.unstable_opts.uninit_const_chunk_threshold;
let allow_uninit_chunks = chunks.clone().take(max.saturating_add(1)).count() <= max;
@ -249,8 +249,8 @@ impl<'ll> CodegenCx<'ll, '_> {
trace!(?instance);
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out
// the llvm type from the actual evaluated initializer.
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure
// out the llvm type from the actual evaluated initializer.
let llty = if nested {
self.type_i8()
} else {
@ -262,7 +262,7 @@ impl<'ll> CodegenCx<'ll, '_> {
}
#[instrument(level = "debug", skip(self, llty))]
pub(crate) fn get_static_inner(&self, def_id: DefId, llty: &'ll Type) -> &'ll Value {
fn get_static_inner(&self, def_id: DefId, llty: &'ll Type) -> &'ll Value {
let instance = Instance::mono(self.tcx, def_id);
if let Some(&g) = self.instances.borrow().get(&instance) {
trace!("used cached value");
@ -320,15 +320,16 @@ impl<'ll> CodegenCx<'ll, '_> {
}
if !def_id.is_local() {
let needs_dll_storage_attr = self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) &&
let needs_dll_storage_attr = self.use_dll_storage_attrs
&& !self.tcx.is_foreign_item(def_id)
// Local definitions can never be imported, so we must not apply
// the DLLImport annotation.
!dso_local &&
&& !dso_local
// ThinLTO can't handle this workaround in all cases, so we don't
// emit the attrs. Instead we make them unnecessary by disallowing
// dynamic linking when linker plugin based LTO is enabled.
!self.tcx.sess.opts.cg.linker_plugin_lto.enabled() &&
self.tcx.sess.lto() != Lto::Thin;
&& !self.tcx.sess.opts.cg.linker_plugin_lto.enabled()
&& self.tcx.sess.lto() != Lto::Thin;
// If this assertion triggers, there's something wrong with commandline
// argument validation.
@ -442,58 +443,6 @@ impl<'ll> CodegenCx<'ll, '_> {
if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
llvm::set_thread_local_mode(g, self.tls_model);
// Do not allow LLVM to change the alignment of a TLS on macOS.
//
// By default a global's alignment can be freely increased.
// This allows LLVM to generate more performant instructions
// e.g., using load-aligned into a SIMD register.
//
// However, on macOS 10.10 or below, the dynamic linker does not
// respect any alignment given on the TLS (radar 24221680).
// This will violate the alignment assumption, and causing segfault at runtime.
//
// This bug is very easy to trigger. In `println!` and `panic!`,
// the `LOCAL_STDOUT`/`LOCAL_STDERR` handles are stored in a TLS,
// which the values would be `mem::replace`d on initialization.
// The implementation of `mem::replace` will use SIMD
// whenever the size is 32 bytes or higher. LLVM notices SIMD is used
// and tries to align `LOCAL_STDOUT`/`LOCAL_STDERR` to a 32-byte boundary,
// which macOS's dyld disregarded and causing crashes
// (see issues #51794, #51758, #50867, #48866 and #44056).
//
// To workaround the bug, we trick LLVM into not increasing
// the global's alignment by explicitly assigning a section to it
// (equivalent to automatically generating a `#[link_section]` attribute).
// See the comment in the `GlobalValue::canIncreaseAlignment()` function
// of `lib/IR/Globals.cpp` for why this works.
//
// When the alignment is not increased, the optimized `mem::replace`
// will use load-unaligned instructions instead, and thus avoiding the crash.
//
// We could remove this hack whenever we decide to drop macOS 10.10 support.
if self.tcx.sess.target.is_like_osx {
// The `inspect` method is okay here because we checked for provenance, and
// because we are doing this access to inspect the final interpreter state
// (not as part of the interpreter execution).
//
// FIXME: This check requires that the (arbitrary) value of undefined bytes
// happens to be zero. Instead, we should only check the value of defined bytes
// and set all undefined bytes to zero if this allocation is headed for the
// BSS.
let all_bytes_are_zero = alloc.provenance().ptrs().is_empty()
&& alloc
.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
.iter()
.all(|&byte| byte == 0);
let sect_name = if all_bytes_are_zero {
c"__DATA,__thread_bss"
} else {
c"__DATA,__thread_data"
};
llvm::LLVMSetSection(g, sect_name.as_ptr());
}
}
// Wasm statics with custom link sections get special treatment as they
@ -551,8 +500,8 @@ impl<'ll> CodegenCx<'ll, '_> {
// `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
// on other targets, in particular MachO targets have *their* static constructor
// lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However,
// that check happens when assigning the `CodegenFnAttrFlags` in `rustc_hir_analysis`,
// so we don't need to take care of it here.
// that check happens when assigning the `CodegenFnAttrFlags` in
// `rustc_hir_analysis`, so we don't need to take care of it here.
self.add_compiler_used_global(g);
}
if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) {
@ -565,7 +514,7 @@ impl<'ll> CodegenCx<'ll, '_> {
}
}
impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> {
fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value {
if let Some(&gv) = self.const_globals.borrow().get(&cv) {
unsafe {

View File

@ -15,7 +15,6 @@ use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
TyAndLayout,
};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
@ -25,7 +24,6 @@ use rustc_session::config::{
use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{HasDataLayout, TargetDataLayout, VariantIdx};
use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel};
use smallvec::SmallVec;
@ -37,8 +35,8 @@ use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util};
/// There is one `CodegenCx` per compilation unit. Each one has its own LLVM
/// `llvm::Context` so that several compilation units may be optimized in parallel.
/// There is one `CodegenCx` per codegen unit. Each one has its own LLVM
/// `llvm::Context` so that several codegen units may be processed in parallel.
/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
pub(crate) struct CodegenCx<'ll, 'tcx> {
pub tcx: TyCtxt<'tcx>,
@ -122,14 +120,6 @@ pub(crate) unsafe fn create_module<'ll>(
let mut target_data_layout = sess.target.data_layout.to_string();
let llvm_version = llvm_util::get_version();
if llvm_version < (18, 0, 0) {
if sess.target.arch == "x86" || sess.target.arch == "x86_64" {
// LLVM 18 adjusts i128 to be 128-bit aligned on x86 variants.
// Earlier LLVMs leave this as default alignment, so remove it.
// See https://reviews.llvm.org/D86310
target_data_layout = target_data_layout.replace("-i128:128", "");
}
}
if llvm_version < (19, 0, 0) {
if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") {
@ -241,7 +231,8 @@ pub(crate) unsafe fn create_module<'ll>(
}
}
// Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
// Enable LTO unit splitting if specified or if CFI is enabled. (See
// https://reviews.llvm.org/D53891.)
if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr();
unsafe {
@ -598,7 +589,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
}
}
impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn vtables(
&self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>
@ -1158,8 +1149,6 @@ impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> {
}
impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
@ -1171,8 +1160,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
}
impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
#[inline]
fn handle_fn_abi_err(
&self,

View File

@ -121,7 +121,8 @@ mod mcdc {
num_conditions: u16,
}
// ConditionId in llvm is `unsigned int` at 18 while `int16_t` at [19](https://github.com/llvm/llvm-project/pull/81257)
// ConditionId in llvm is `unsigned int` at 18 while `int16_t` at
// [19](https://github.com/llvm/llvm-project/pull/81257).
type LLVMConditionId = i16;
/// Must match the layout of `LLVMRustMCDCBranchParameters`.

View File

@ -1,5 +1,5 @@
use itertools::Itertools as _;
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods};
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_index::IndexVec;

View File

@ -2,8 +2,8 @@ use std::cell::RefCell;
use libc::c_uint;
use rustc_codegen_ssa::traits::{
BaseTypeMethods, BuilderMethods, ConstMethods, CoverageInfoBuilderMethods, MiscMethods,
StaticMethods,
BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, CoverageInfoBuilderMethods,
MiscCodegenMethods, StaticCodegenMethods,
};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_llvm::RustString;
@ -48,11 +48,10 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
self.function_coverage_map.replace(FxIndexMap::default())
}
/// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is called condition bitmap.
/// In order to handle nested decisions, several condition bitmaps can be
/// allocated for a function body.
/// These values are named `mcdc.addr.{i}` and are a 32-bit integers.
/// They respectively hold the condition bitmaps for decisions with a depth of `i`.
/// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is
/// called condition bitmap. In order to handle nested decisions, several condition bitmaps can
/// be allocated for a function body. These values are named `mcdc.addr.{i}` and are a 32-bit
/// integers. They respectively hold the condition bitmaps for decisions with a depth of `i`.
fn try_get_mcdc_condition_bitmap(
&self,
instance: &Instance<'tcx>,
@ -157,8 +156,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
),
CoverageKind::CounterIncrement { id } => {
func_coverage.mark_counter_id_seen(id);
// We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,
// as that needs an exclusive borrow.
// We need to explicitly drop the `RefMut` before calling into
// `instrprof_increment`, as that needs an exclusive borrow.
drop(coverage_map);
// The number of counters passed to `llvm.instrprof.increment` might

View File

@ -44,7 +44,8 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
// Add the pretty printers for the standard library first.
section_contents.extend_from_slice(b"\x01gdb_load_rust_pretty_printers.py\0");
// Next, add the pretty printers that were specified via the `#[debugger_visualizer]` attribute.
// Next, add the pretty printers that were specified via the `#[debugger_visualizer]`
// attribute.
let visualizers = collect_debugger_visualizers_transitive(
cx.tcx,
DebuggerVisualizerType::GdbPrettyPrinter,

View File

@ -125,7 +125,9 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>(
let (size, align) = cx.size_and_align_of(array_type);
let upper_bound = len.eval_target_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong;
let upper_bound = len
.try_to_target_usize(cx.tcx)
.expect("expected monomorphic const in codegen") as c_longlong;
let subrange =
unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) };
@ -216,8 +218,9 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
// need to make sure that we don't break existing debuginfo consumers
// by doing that (at least not without a warning period).
let layout_type = if ptr_type.is_box() {
// The assertion at the start of this function ensures we have a ZST allocator.
// We'll make debuginfo "skip" all ZST allocators, not just the default allocator.
// The assertion at the start of this function ensures we have a ZST
// allocator. We'll make debuginfo "skip" all ZST allocators, not just the
// default allocator.
Ty::new_mut_ptr(cx.tcx, pointee_type)
} else {
ptr_type
@ -280,8 +283,7 @@ fn build_subroutine_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>,
unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> {
// It's possible to create a self-referential
// type in Rust by using 'impl trait':
// It's possible to create a self-referential type in Rust by using 'impl trait':
//
// fn foo() -> impl Copy { foo }
//
@ -573,14 +575,14 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi
{
// If the compiler's working directory (which also is the DW_AT_comp_dir of
// the compilation unit) is a prefix of the path we are about to emit, then
// only emit the part relative to the working directory.
// Because of path remapping we sometimes see strange things here: `abs_path`
// might actually look like a relative path
// (e.g. `<crate-name-and-version>/src/lib.rs`), so if we emit it without
// taking the working directory into account, downstream tooling will
// interpret it as `<working-directory>/<crate-name-and-version>/src/lib.rs`,
// which makes no sense. Usually in such cases the working directory will also
// be remapped to `<crate-name-and-version>` or some other prefix of the path
// only emit the part relative to the working directory. Because of path
// remapping we sometimes see strange things here: `abs_path` might
// actually look like a relative path (e.g.
// `<crate-name-and-version>/src/lib.rs`), so if we emit it without taking
// the working directory into account, downstream tooling will interpret it
// as `<working-directory>/<crate-name-and-version>/src/lib.rs`, which
// makes no sense. Usually in such cases the working directory will also be
// remapped to `<crate-name-and-version>` or some other prefix of the path
// we are remapping, so we end up with
// `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`.
// By moving the working directory portion into the `directory` part of the

View File

@ -3,7 +3,7 @@ use std::borrow::Cow;
use libc::c_uint;
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
use rustc_codegen_ssa::traits::ConstMethods;
use rustc_codegen_ssa::traits::ConstCodegenMethods;
use rustc_index::IndexVec;
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};

View File

@ -3,7 +3,7 @@ use std::borrow::Cow;
use libc::c_uint;
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
use rustc_codegen_ssa::traits::ConstMethods;
use rustc_codegen_ssa::traits::ConstCodegenMethods;
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
use rustc_middle::ty::{self};

View File

@ -286,7 +286,7 @@ impl CodegenCx<'_, '_> {
}
}
impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn create_function_debug_context(
&self,
instance: Instance<'tcx>,

View File

@ -13,8 +13,7 @@ pub(crate) fn mangled_name_of_instance<'a, 'tcx>(
cx: &CodegenCx<'a, 'tcx>,
instance: Instance<'tcx>,
) -> ty::SymbolName<'tcx> {
let tcx = cx.tcx;
tcx.symbol_name(instance)
cx.tcx.symbol_name(instance)
}
pub(crate) fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {

View File

@ -12,7 +12,7 @@
//! * When in doubt, define.
use itertools::Itertools;
use rustc_codegen_ssa::traits::TypeMembershipMethods;
use rustc_codegen_ssa::traits::TypeMembershipCodegenMethods;
use rustc_data_structures::fx::FxIndexSet;
use rustc_middle::ty::{Instance, Ty};
use rustc_sanitizers::{cfi, kcfi};

View File

@ -148,7 +148,7 @@ fn get_simple_intrinsic<'ll>(
Some(cx.get_intrinsic(llvm_name))
}
impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
fn codegen_intrinsic_call(
&mut self,
instance: ty::Instance<'tcx>,
@ -404,7 +404,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
let llvm_name =
&format!("llvm.fsh{}.i{}", if is_left { 'l' } else { 'r' }, width);
// llvm expects shift to be the same type as the values, but rust always uses `u32`
// llvm expects shift to be the same type as the values, but rust
// always uses `u32`.
let raw_shift = self.intcast(raw_shift, self.val_ty(val), false);
self.call_intrinsic(llvm_name, &[val, val, raw_shift])
@ -573,8 +574,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
span,
) {
Ok(llval) => llval,
// If there was an error, just skip this invocation... we'll abort compilation anyway,
// but we can keep codegen'ing to find more errors.
// If there was an error, just skip this invocation... we'll abort compilation
// anyway, but we can keep codegen'ing to find more errors.
Err(()) => return Ok(()),
}
}
@ -1847,7 +1848,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
require!(
matches!(
*pointer_ty.kind(),
ty::RawPtr(p_ty, p_mutbl) if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut()
ty::RawPtr(p_ty, p_mutbl)
if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut()
),
InvalidMonomorphization::ExpectedElementType {
span,

View File

@ -220,17 +220,18 @@ pub enum IntPredicate {
impl IntPredicate {
pub fn from_generic(intpre: rustc_codegen_ssa::common::IntPredicate) -> Self {
use rustc_codegen_ssa::common::IntPredicate as Common;
match intpre {
rustc_codegen_ssa::common::IntPredicate::IntEQ => IntPredicate::IntEQ,
rustc_codegen_ssa::common::IntPredicate::IntNE => IntPredicate::IntNE,
rustc_codegen_ssa::common::IntPredicate::IntUGT => IntPredicate::IntUGT,
rustc_codegen_ssa::common::IntPredicate::IntUGE => IntPredicate::IntUGE,
rustc_codegen_ssa::common::IntPredicate::IntULT => IntPredicate::IntULT,
rustc_codegen_ssa::common::IntPredicate::IntULE => IntPredicate::IntULE,
rustc_codegen_ssa::common::IntPredicate::IntSGT => IntPredicate::IntSGT,
rustc_codegen_ssa::common::IntPredicate::IntSGE => IntPredicate::IntSGE,
rustc_codegen_ssa::common::IntPredicate::IntSLT => IntPredicate::IntSLT,
rustc_codegen_ssa::common::IntPredicate::IntSLE => IntPredicate::IntSLE,
Common::IntEQ => Self::IntEQ,
Common::IntNE => Self::IntNE,
Common::IntUGT => Self::IntUGT,
Common::IntUGE => Self::IntUGE,
Common::IntULT => Self::IntULT,
Common::IntULE => Self::IntULE,
Common::IntSGT => Self::IntSGT,
Common::IntSGE => Self::IntSGE,
Common::IntSLT => Self::IntSLT,
Common::IntSLE => Self::IntSLE,
}
}
}
@ -259,27 +260,24 @@ pub enum RealPredicate {
impl RealPredicate {
pub fn from_generic(realp: rustc_codegen_ssa::common::RealPredicate) -> Self {
use rustc_codegen_ssa::common::RealPredicate as Common;
match realp {
rustc_codegen_ssa::common::RealPredicate::RealPredicateFalse => {
RealPredicate::RealPredicateFalse
}
rustc_codegen_ssa::common::RealPredicate::RealOEQ => RealPredicate::RealOEQ,
rustc_codegen_ssa::common::RealPredicate::RealOGT => RealPredicate::RealOGT,
rustc_codegen_ssa::common::RealPredicate::RealOGE => RealPredicate::RealOGE,
rustc_codegen_ssa::common::RealPredicate::RealOLT => RealPredicate::RealOLT,
rustc_codegen_ssa::common::RealPredicate::RealOLE => RealPredicate::RealOLE,
rustc_codegen_ssa::common::RealPredicate::RealONE => RealPredicate::RealONE,
rustc_codegen_ssa::common::RealPredicate::RealORD => RealPredicate::RealORD,
rustc_codegen_ssa::common::RealPredicate::RealUNO => RealPredicate::RealUNO,
rustc_codegen_ssa::common::RealPredicate::RealUEQ => RealPredicate::RealUEQ,
rustc_codegen_ssa::common::RealPredicate::RealUGT => RealPredicate::RealUGT,
rustc_codegen_ssa::common::RealPredicate::RealUGE => RealPredicate::RealUGE,
rustc_codegen_ssa::common::RealPredicate::RealULT => RealPredicate::RealULT,
rustc_codegen_ssa::common::RealPredicate::RealULE => RealPredicate::RealULE,
rustc_codegen_ssa::common::RealPredicate::RealUNE => RealPredicate::RealUNE,
rustc_codegen_ssa::common::RealPredicate::RealPredicateTrue => {
RealPredicate::RealPredicateTrue
}
Common::RealPredicateFalse => Self::RealPredicateFalse,
Common::RealOEQ => Self::RealOEQ,
Common::RealOGT => Self::RealOGT,
Common::RealOGE => Self::RealOGE,
Common::RealOLT => Self::RealOLT,
Common::RealOLE => Self::RealOLE,
Common::RealONE => Self::RealONE,
Common::RealORD => Self::RealORD,
Common::RealUNO => Self::RealUNO,
Common::RealUEQ => Self::RealUEQ,
Common::RealUGT => Self::RealUGT,
Common::RealUGE => Self::RealUGE,
Common::RealULT => Self::RealULT,
Common::RealULE => Self::RealULE,
Common::RealUNE => Self::RealUNE,
Common::RealPredicateTrue => Self::RealPredicateTrue,
}
}
}
@ -311,26 +309,27 @@ pub enum TypeKind {
impl TypeKind {
pub fn to_generic(self) -> rustc_codegen_ssa::common::TypeKind {
use rustc_codegen_ssa::common::TypeKind as Common;
match self {
TypeKind::Void => rustc_codegen_ssa::common::TypeKind::Void,
TypeKind::Half => rustc_codegen_ssa::common::TypeKind::Half,
TypeKind::Float => rustc_codegen_ssa::common::TypeKind::Float,
TypeKind::Double => rustc_codegen_ssa::common::TypeKind::Double,
TypeKind::X86_FP80 => rustc_codegen_ssa::common::TypeKind::X86_FP80,
TypeKind::FP128 => rustc_codegen_ssa::common::TypeKind::FP128,
TypeKind::PPC_FP128 => rustc_codegen_ssa::common::TypeKind::PPC_FP128,
TypeKind::Label => rustc_codegen_ssa::common::TypeKind::Label,
TypeKind::Integer => rustc_codegen_ssa::common::TypeKind::Integer,
TypeKind::Function => rustc_codegen_ssa::common::TypeKind::Function,
TypeKind::Struct => rustc_codegen_ssa::common::TypeKind::Struct,
TypeKind::Array => rustc_codegen_ssa::common::TypeKind::Array,
TypeKind::Pointer => rustc_codegen_ssa::common::TypeKind::Pointer,
TypeKind::Vector => rustc_codegen_ssa::common::TypeKind::Vector,
TypeKind::Metadata => rustc_codegen_ssa::common::TypeKind::Metadata,
TypeKind::Token => rustc_codegen_ssa::common::TypeKind::Token,
TypeKind::ScalableVector => rustc_codegen_ssa::common::TypeKind::ScalableVector,
TypeKind::BFloat => rustc_codegen_ssa::common::TypeKind::BFloat,
TypeKind::X86_AMX => rustc_codegen_ssa::common::TypeKind::X86_AMX,
Self::Void => Common::Void,
Self::Half => Common::Half,
Self::Float => Common::Float,
Self::Double => Common::Double,
Self::X86_FP80 => Common::X86_FP80,
Self::FP128 => Common::FP128,
Self::PPC_FP128 => Common::PPC_FP128,
Self::Label => Common::Label,
Self::Integer => Common::Integer,
Self::Function => Common::Function,
Self::Struct => Common::Struct,
Self::Array => Common::Array,
Self::Pointer => Common::Pointer,
Self::Vector => Common::Vector,
Self::Metadata => Common::Metadata,
Self::Token => Common::Token,
Self::ScalableVector => Common::ScalableVector,
Self::BFloat => Common::BFloat,
Self::X86_AMX => Common::X86_AMX,
}
}
}
@ -354,18 +353,19 @@ pub enum AtomicRmwBinOp {
impl AtomicRmwBinOp {
pub fn from_generic(op: rustc_codegen_ssa::common::AtomicRmwBinOp) -> Self {
use rustc_codegen_ssa::common::AtomicRmwBinOp as Common;
match op {
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicXchg => AtomicRmwBinOp::AtomicXchg,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicAdd => AtomicRmwBinOp::AtomicAdd,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicSub => AtomicRmwBinOp::AtomicSub,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicAnd => AtomicRmwBinOp::AtomicAnd,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicNand => AtomicRmwBinOp::AtomicNand,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicOr => AtomicRmwBinOp::AtomicOr,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicXor => AtomicRmwBinOp::AtomicXor,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicMax => AtomicRmwBinOp::AtomicMax,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicMin => AtomicRmwBinOp::AtomicMin,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicUMax => AtomicRmwBinOp::AtomicUMax,
rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicUMin => AtomicRmwBinOp::AtomicUMin,
Common::AtomicXchg => Self::AtomicXchg,
Common::AtomicAdd => Self::AtomicAdd,
Common::AtomicSub => Self::AtomicSub,
Common::AtomicAnd => Self::AtomicAnd,
Common::AtomicNand => Self::AtomicNand,
Common::AtomicOr => Self::AtomicOr,
Common::AtomicXor => Self::AtomicXor,
Common::AtomicMax => Self::AtomicMax,
Common::AtomicMin => Self::AtomicMin,
Common::AtomicUMax => Self::AtomicUMax,
Common::AtomicUMin => Self::AtomicUMin,
}
}
}
@ -387,17 +387,14 @@ pub enum AtomicOrdering {
impl AtomicOrdering {
pub fn from_generic(ao: rustc_codegen_ssa::common::AtomicOrdering) -> Self {
use rustc_codegen_ssa::common::AtomicOrdering as Common;
match ao {
rustc_codegen_ssa::common::AtomicOrdering::Unordered => AtomicOrdering::Unordered,
rustc_codegen_ssa::common::AtomicOrdering::Relaxed => AtomicOrdering::Monotonic,
rustc_codegen_ssa::common::AtomicOrdering::Acquire => AtomicOrdering::Acquire,
rustc_codegen_ssa::common::AtomicOrdering::Release => AtomicOrdering::Release,
rustc_codegen_ssa::common::AtomicOrdering::AcquireRelease => {
AtomicOrdering::AcquireRelease
}
rustc_codegen_ssa::common::AtomicOrdering::SequentiallyConsistent => {
AtomicOrdering::SequentiallyConsistent
}
Common::Unordered => Self::Unordered,
Common::Relaxed => Self::Monotonic,
Common::Acquire => Self::Acquire,
Common::Release => Self::Release,
Common::AcquireRelease => Self::AcquireRelease,
Common::SequentiallyConsistent => Self::SequentiallyConsistent,
}
}
}
@ -563,13 +560,11 @@ pub enum ArchiveKind {
K_AIXBIG,
}
// LLVMRustThinLTOData
unsafe extern "C" {
// LLVMRustThinLTOData
pub type ThinLTOData;
}
// LLVMRustThinLTOBuffer
unsafe extern "C" {
// LLVMRustThinLTOBuffer
pub type ThinLTOBuffer;
}
@ -633,26 +628,12 @@ struct InvariantOpaque<'a> {
// Opaque pointer types
unsafe extern "C" {
pub type Module;
}
unsafe extern "C" {
pub type Context;
}
unsafe extern "C" {
pub type Type;
}
unsafe extern "C" {
pub type Value;
}
unsafe extern "C" {
pub type ConstantInt;
}
unsafe extern "C" {
pub type Attribute;
}
unsafe extern "C" {
pub type Metadata;
}
unsafe extern "C" {
pub type BasicBlock;
}
#[repr(C)]
@ -661,11 +642,7 @@ pub struct Builder<'a>(InvariantOpaque<'a>);
pub struct PassManager<'a>(InvariantOpaque<'a>);
unsafe extern "C" {
pub type Pass;
}
unsafe extern "C" {
pub type TargetMachine;
}
unsafe extern "C" {
pub type Archive;
}
#[repr(C)]
@ -674,11 +651,7 @@ pub struct ArchiveIterator<'a>(InvariantOpaque<'a>);
pub struct ArchiveChild<'a>(InvariantOpaque<'a>);
unsafe extern "C" {
pub type Twine;
}
unsafe extern "C" {
pub type DiagnosticInfo;
}
unsafe extern "C" {
pub type SMDiagnostic;
}
#[repr(C)]
@ -2177,7 +2150,8 @@ unsafe extern "C" {
pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char;
// This function makes copies of pointed to data, so the data's lifetime may end after this function returns
// This function makes copies of pointed to data, so the data's lifetime may end after this
// function returns.
pub fn LLVMRustCreateTargetMachine(
Triple: *const c_char,
CPU: *const c_char,

View File

@ -217,10 +217,10 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
// where `{ARCH}` is the architecture name. Look for instances of `SubtargetFeature`.
//
// Check the current rustc fork of LLVM in the repo at https://github.com/rust-lang/llvm-project/.
// The commit in use can be found via the `llvm-project` submodule in https://github.com/rust-lang/rust/tree/master/src
// Though note that Rust can also be build with an external precompiled version of LLVM
// which might lead to failures if the oldest tested / supported LLVM version
// doesn't yet support the relevant intrinsics
// The commit in use can be found via the `llvm-project` submodule in
// https://github.com/rust-lang/rust/tree/master/src Though note that Rust can also be build with
// an external precompiled version of LLVM which might lead to failures if the oldest tested /
// supported LLVM version doesn't yet support the relevant intrinsics.
pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFeature<'a>> {
let arch = if sess.target.arch == "x86_64" {
"x86"
@ -258,28 +258,14 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")),
("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")),
// Filter out features that are not supported by the current LLVM version
("aarch64", "faminmax") if get_version().0 < 18 => None,
("aarch64", "fp8") if get_version().0 < 18 => None,
("aarch64", "fp8dot2") if get_version().0 < 18 => None,
("aarch64", "fp8dot4") if get_version().0 < 18 => None,
("aarch64", "fp8fma") if get_version().0 < 18 => None,
("aarch64", "fpmr") if get_version().0 != 18 => None,
("aarch64", "lut") if get_version().0 < 18 => None,
("aarch64", "sme-f8f16") if get_version().0 < 18 => None,
("aarch64", "sme-f8f32") if get_version().0 < 18 => None,
("aarch64", "sme-fa64") if get_version().0 < 18 => None,
("aarch64", "sme-lutv2") if get_version().0 < 18 => None,
("aarch64", "ssve-fp8dot2") if get_version().0 < 18 => None,
("aarch64", "ssve-fp8dot4") if get_version().0 < 18 => None,
("aarch64", "ssve-fp8fma") if get_version().0 < 18 => None,
("aarch64", "v9.5a") if get_version().0 < 18 => None,
// In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single feature called
// `fast-unaligned-access`. In LLVM 19, it was split back out.
// In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single
// feature called `fast-unaligned-access`. In LLVM 19, it was split back out.
("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
Some(LLVMFeature::new("fast-unaligned-access"))
}
// For LLVM 18, enable the evex512 target feature if a avx512 target feature is enabled.
("x86", s) if get_version().0 >= 18 && s.starts_with("avx512") => {
// Enable the evex512 target feature if an avx512 target feature is enabled.
("x86", s) if s.starts_with("avx512") => {
Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")))
}
(_, s) => Some(LLVMFeature::new(s)),
@ -420,7 +406,8 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
.supported_target_features()
.iter()
.filter_map(|(feature, _gate, _implied)| {
// LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
// LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these
// strings.
let llvm_feature = to_llvm_features(sess, *feature)?.llvm_feature_name;
let desc =
match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() {
@ -587,7 +574,6 @@ pub(crate) fn global_llvm_features(
// -Ctarget-features
if !only_base_features {
let supported_features = sess.target.supported_target_features();
let (llvm_major, _, _) = get_version();
let mut featsmap = FxHashMap::default();
// insert implied features
@ -664,12 +650,6 @@ pub(crate) fn global_llvm_features(
return None;
}
// if the target-feature is "backchain" and LLVM version is greater than 18
// then we also need to add "+backchain" to the target-features attribute.
// otherwise, we will only add the naked `backchain` attribute to the attribute-group.
if feature == "backchain" && llvm_major < 18 {
return None;
}
// ... otherwise though we run through `to_llvm_features` when
// passing requests down to LLVM. This means that all in-language
// features also work on the command line instead of having two

View File

@ -14,7 +14,7 @@ use crate::errors::SymbolAlreadyDefined;
use crate::type_of::LayoutLlvmExt;
use crate::{base, llvm};
impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
fn predefine_static(
&self,
def_id: DefId,
@ -24,8 +24,8 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
) {
let instance = Instance::mono(self.tcx, def_id);
let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out
// the llvm type from the actual evaluated initializer.
// Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure
// out the llvm type from the actual evaluated initializer.
let ty = if nested {
self.tcx.types.unit
} else {

View File

@ -141,7 +141,7 @@ impl<'ll> CodegenCx<'ll, '_> {
}
}
impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
impl<'ll, 'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn type_i8(&self) -> &'ll Type {
unsafe { llvm::LLVMInt8TypeInContext(self.llcx) }
}
@ -245,7 +245,7 @@ impl Type {
}
}
impl<'ll, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
impl<'ll, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn backend_type(&self, layout: TyAndLayout<'tcx>) -> &'ll Type {
layout.llvm_type(self)
}
@ -280,7 +280,7 @@ impl<'ll, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
}
}
impl<'ll, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'ll, 'tcx> {
impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn add_type_metadata(&self, function: &'ll Value, typeid: String) {
let typeid_metadata = self.typeid_metadata(typeid).unwrap();
let v = [self.const_usize(0), typeid_metadata];

View File

@ -1,6 +1,6 @@
use rustc_codegen_ssa::common::IntPredicate;
use rustc_codegen_ssa::mir::operand::OperandRef;
use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods, ConstMethods};
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_middle::ty::Ty;
use rustc_target::abi::{Align, Endian, HasDataLayout, Size};

View File

@ -157,7 +157,7 @@ pub trait ArchiveBuilderBuilder {
}
}
pub fn create_mingw_dll_import_lib(
fn create_mingw_dll_import_lib(
sess: &Session,
lib_name: &str,
import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,

View File

@ -8,7 +8,7 @@ use std::{fmt, io, mem};
use rustc_target::spec::LldFlavor;
#[derive(Clone)]
pub struct Command {
pub(crate) struct Command {
program: Program,
args: Vec<OsString>,
env: Vec<(OsString, OsString)>,
@ -23,15 +23,15 @@ enum Program {
}
impl Command {
pub fn new<P: AsRef<OsStr>>(program: P) -> Command {
pub(crate) fn new<P: AsRef<OsStr>>(program: P) -> Command {
Command::_new(Program::Normal(program.as_ref().to_owned()))
}
pub fn bat_script<P: AsRef<OsStr>>(program: P) -> Command {
pub(crate) fn bat_script<P: AsRef<OsStr>>(program: P) -> Command {
Command::_new(Program::CmdBatScript(program.as_ref().to_owned()))
}
pub fn lld<P: AsRef<OsStr>>(program: P, flavor: LldFlavor) -> Command {
pub(crate) fn lld<P: AsRef<OsStr>>(program: P, flavor: LldFlavor) -> Command {
Command::_new(Program::Lld(program.as_ref().to_owned(), flavor))
}
@ -39,12 +39,12 @@ impl Command {
Command { program, args: Vec::new(), env: Vec::new(), env_remove: Vec::new() }
}
pub fn arg<P: AsRef<OsStr>>(&mut self, arg: P) -> &mut Command {
pub(crate) fn arg<P: AsRef<OsStr>>(&mut self, arg: P) -> &mut Command {
self._arg(arg.as_ref());
self
}
pub fn args<I>(&mut self, args: I) -> &mut Command
pub(crate) fn args<I>(&mut self, args: I) -> &mut Command
where
I: IntoIterator<Item: AsRef<OsStr>>,
{
@ -58,7 +58,7 @@ impl Command {
self.args.push(arg.to_owned());
}
pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Command
pub(crate) fn env<K, V>(&mut self, key: K, value: V) -> &mut Command
where
K: AsRef<OsStr>,
V: AsRef<OsStr>,
@ -71,7 +71,7 @@ impl Command {
self.env.push((key.to_owned(), value.to_owned()));
}
pub fn env_remove<K>(&mut self, key: K) -> &mut Command
pub(crate) fn env_remove<K>(&mut self, key: K) -> &mut Command
where
K: AsRef<OsStr>,
{
@ -83,11 +83,11 @@ impl Command {
self.env_remove.push(key.to_owned());
}
pub fn output(&mut self) -> io::Result<Output> {
pub(crate) fn output(&mut self) -> io::Result<Output> {
self.command().output()
}
pub fn command(&self) -> process::Command {
pub(crate) fn command(&self) -> process::Command {
let mut ret = match self.program {
Program::Normal(ref p) => process::Command::new(p),
Program::CmdBatScript(ref p) => {
@ -111,17 +111,17 @@ impl Command {
// extensions
pub fn get_args(&self) -> &[OsString] {
pub(crate) fn get_args(&self) -> &[OsString] {
&self.args
}
pub fn take_args(&mut self) -> Vec<OsString> {
pub(crate) fn take_args(&mut self) -> Vec<OsString> {
mem::take(&mut self.args)
}
/// Returns a `true` if we're pretty sure that this'll blow OS spawn limits,
/// or `false` if we should attempt to spawn and see what the OS says.
pub fn very_likely_to_exceed_some_spawn_limit(&self) -> bool {
pub(crate) fn very_likely_to_exceed_some_spawn_limit(&self) -> bool {
// We mostly only care about Windows in this method, on Unix the limits
// can be gargantuan anyway so we're pretty unlikely to hit them
if cfg!(unix) {

View File

@ -30,7 +30,7 @@ use crate::errors;
/// and prevent inspection of linker output in case of errors, which we occasionally do.
/// This should be acceptable because other messages from rustc are in English anyway,
/// and may also be desirable to improve searchability of the linker diagnostics.
pub fn disable_localization(linker: &mut Command) {
pub(crate) fn disable_localization(linker: &mut Command) {
// No harm in setting both env vars simultaneously.
// Unix-style linkers.
linker.env("LC_ALL", "C");
@ -41,7 +41,7 @@ pub fn disable_localization(linker: &mut Command) {
/// The third parameter is for env vars, used on windows to set up the
/// path for MSVC to find its DLLs, and gcc to find its bundled
/// toolchain
pub fn get_linker<'a>(
pub(crate) fn get_linker<'a>(
sess: &'a Session,
linker: &Path,
flavor: LinkerFlavor,
@ -215,28 +215,36 @@ fn link_or_cc_args<L: Linker + ?Sized>(
macro_rules! generate_arg_methods {
($($ty:ty)*) => { $(
impl $ty {
pub fn verbatim_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
#[allow(unused)]
pub(crate) fn verbatim_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
verbatim_args(self, args)
}
pub fn verbatim_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
#[allow(unused)]
pub(crate) fn verbatim_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
verbatim_args(self, iter::once(arg))
}
pub fn link_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>, IntoIter: ExactSizeIterator>) -> &mut Self {
#[allow(unused)]
pub(crate) fn link_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>, IntoIter: ExactSizeIterator>) -> &mut Self {
link_args(self, args)
}
pub fn link_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
#[allow(unused)]
pub(crate) fn link_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
link_args(self, iter::once(arg))
}
pub fn cc_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
#[allow(unused)]
pub(crate) fn cc_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
cc_args(self, args)
}
pub fn cc_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
#[allow(unused)]
pub(crate) fn cc_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
cc_args(self, iter::once(arg))
}
pub fn link_or_cc_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
#[allow(unused)]
pub(crate) fn link_or_cc_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
link_or_cc_args(self, args)
}
pub fn link_or_cc_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
#[allow(unused)]
pub(crate) fn link_or_cc_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
link_or_cc_args(self, iter::once(arg))
}
}
@ -263,7 +271,7 @@ generate_arg_methods! {
/// represents the meaning of each option being passed down. This trait is then
/// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an
/// MSVC linker (e.g., `link.exe`) is being used.
pub trait Linker {
pub(crate) trait Linker {
fn cmd(&mut self) -> &mut Command;
fn is_cc(&self) -> bool {
false
@ -314,12 +322,12 @@ pub trait Linker {
}
impl dyn Linker + '_ {
pub fn take_cmd(&mut self) -> Command {
pub(crate) fn take_cmd(&mut self) -> Command {
mem::replace(self.cmd(), Command::new(""))
}
}
pub struct GccLinker<'a> {
struct GccLinker<'a> {
cmd: Command,
sess: &'a Session,
target_cpu: &'a str,
@ -849,7 +857,7 @@ impl<'a> Linker for GccLinker<'a> {
}
}
pub struct MsvcLinker<'a> {
struct MsvcLinker<'a> {
cmd: Command,
sess: &'a Session,
}
@ -1103,7 +1111,7 @@ impl<'a> Linker for MsvcLinker<'a> {
}
}
pub struct EmLinker<'a> {
struct EmLinker<'a> {
cmd: Command,
sess: &'a Session,
}
@ -1220,7 +1228,7 @@ impl<'a> Linker for EmLinker<'a> {
}
}
pub struct WasmLd<'a> {
struct WasmLd<'a> {
cmd: Command,
sess: &'a Session,
}
@ -1404,7 +1412,7 @@ impl<'a> WasmLd<'a> {
}
/// Linker shepherd script for L4Re (Fiasco)
pub struct L4Bender<'a> {
struct L4Bender<'a> {
cmd: Command,
sess: &'a Session,
hinted_static: bool,
@ -1510,7 +1518,7 @@ impl<'a> Linker for L4Bender<'a> {
}
impl<'a> L4Bender<'a> {
pub fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> {
fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> {
L4Bender { cmd, sess, hinted_static: false }
}
@ -1523,14 +1531,14 @@ impl<'a> L4Bender<'a> {
}
/// Linker for AIX.
pub struct AixLinker<'a> {
struct AixLinker<'a> {
cmd: Command,
sess: &'a Session,
hinted_static: Option<bool>,
}
impl<'a> AixLinker<'a> {
pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> {
fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> {
AixLinker { cmd, sess, hinted_static: None }
}
@ -1758,7 +1766,7 @@ pub(crate) fn linked_symbols(
/// Much simplified and explicit CLI for the NVPTX linker. The linker operates
/// with bitcode and uses LLVM backend to generate a PTX assembly.
pub struct PtxLinker<'a> {
struct PtxLinker<'a> {
cmd: Command,
sess: &'a Session,
}
@ -1824,7 +1832,7 @@ impl<'a> Linker for PtxLinker<'a> {
}
/// The `self-contained` LLVM bitcode linker
pub struct LlbcLinker<'a> {
struct LlbcLinker<'a> {
cmd: Command,
sess: &'a Session,
}
@ -1895,7 +1903,7 @@ impl<'a> Linker for LlbcLinker<'a> {
fn linker_plugin_lto(&mut self) {}
}
pub struct BpfLinker<'a> {
struct BpfLinker<'a> {
cmd: Command,
sess: &'a Session,
}

View File

@ -32,7 +32,7 @@ use rustc_target::spec::{ef_avr_arch, RelocModel, Target};
/// <dd>The metadata can be found in the `.rustc` section of the shared library.</dd>
/// </dl>
#[derive(Debug)]
pub struct DefaultMetadataLoader;
pub(crate) struct DefaultMetadataLoader;
static AIX_METADATA_SYMBOL_NAME: &'static str = "__aix_rust_metadata";
@ -416,7 +416,7 @@ fn macho_is_arm64e(target: &Target) -> bool {
target.llvm_target.starts_with("arm64e")
}
pub enum MetadataPosition {
pub(crate) enum MetadataPosition {
First,
Last,
}
@ -452,7 +452,7 @@ pub enum MetadataPosition {
/// * ELF - All other targets are similar to Windows in that there's a
/// `SHF_EXCLUDE` flag we can set on sections in an object file to get
/// automatically removed from the final output.
pub fn create_wrapper_file(
pub(crate) fn create_wrapper_file(
sess: &Session,
section_name: String,
data: &[u8],

View File

@ -1,9 +1,9 @@
pub mod archive;
pub mod command;
pub(crate) mod command;
pub mod link;
pub mod linker;
pub(crate) mod linker;
pub mod lto;
pub mod metadata;
pub mod rpath;
pub(crate) mod rpath;
pub mod symbol_export;
pub mod write;

View File

@ -6,14 +6,14 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_fs_util::try_canonicalize;
use tracing::debug;
pub struct RPathConfig<'a> {
pub(super) struct RPathConfig<'a> {
pub libs: &'a [&'a Path],
pub out_filename: PathBuf,
pub is_like_osx: bool,
pub linker_is_gnu: bool,
}
pub fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec<OsString> {
pub(super) fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec<OsString> {
debug!("preparing the RPATH!");
let rpaths = get_rpaths(config);

View File

@ -18,7 +18,7 @@ use tracing::debug;
use crate::base::allocator_kind_for_codegen;
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
crates_export_threshold(tcx.crate_types())
}
@ -484,7 +484,7 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId)
!tcx.reachable_set(()).contains(&def_id)
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.reachable_non_generics = reachable_non_generics_provider;
providers.is_reachable_non_generic = is_reachable_non_generic_provider_local;
providers.exported_symbols = exported_symbols_provider_local;
@ -525,7 +525,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel
}
/// This is the symbol name of the given instance instantiated in a specific crate.
pub fn symbol_name_for_instance_in_crate<'tcx>(
pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
tcx: TyCtxt<'tcx>,
symbol: ExportedSymbol<'tcx>,
instantiating_crate: CrateNum,
@ -582,7 +582,7 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
/// This is the symbol name of the given instance as seen by the linker.
///
/// On 32-bit Windows symbols are decorated according to their calling conventions.
pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
tcx: TyCtxt<'tcx>,
symbol: ExportedSymbol<'tcx>,
instantiating_crate: CrateNum,
@ -661,7 +661,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
format!("{prefix}{undecorated}{suffix}{args_in_bytes}")
}
pub fn exporting_symbol_name_for_instance_in_crate<'tcx>(
pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
tcx: TyCtxt<'tcx>,
symbol: ExportedSymbol<'tcx>,
cnum: CrateNum,

View File

@ -16,7 +16,7 @@ use rustc_errors::emitter::Emitter;
use rustc_errors::translation::Translate;
use rustc_errors::{
Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, FluentBundle, Level, MultiSpan,
Style,
Style, Suggestions,
};
use rustc_fs_util::link_or_copy;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
@ -335,7 +335,7 @@ pub type TargetMachineFactoryFn<B> = Arc<
+ Sync,
>;
pub type ExportedSymbols = FxHashMap<CrateNum, Arc<Vec<(String, SymbolExportInfo)>>>;
type ExportedSymbols = FxHashMap<CrateNum, Arc<Vec<(String, SymbolExportInfo)>>>;
/// Additional resources used by optimize_and_codegen (not module specific)
#[derive(Clone)]
@ -437,9 +437,9 @@ fn generate_lto_work<B: ExtraBackendMethods>(
}
}
pub struct CompiledModules {
pub modules: Vec<CompiledModule>,
pub allocator_module: Option<CompiledModule>,
struct CompiledModules {
modules: Vec<CompiledModule>,
allocator_module: Option<CompiledModule>,
}
fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool {
@ -462,7 +462,7 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
}
}
pub fn start_async_codegen<B: ExtraBackendMethods>(
pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'_>,
target_cpu: String,
@ -836,13 +836,13 @@ pub enum FatLtoInput<B: WriteBackendMethods> {
}
/// Actual LTO type we end up choosing based on multiple factors.
pub enum ComputedLtoType {
pub(crate) enum ComputedLtoType {
No,
Thin,
Fat,
}
pub fn compute_per_cgu_lto_type(
pub(crate) fn compute_per_cgu_lto_type(
sess_lto: &Lto,
opts: &config::Options,
sess_crate_types: &[CrateType],
@ -1087,7 +1087,7 @@ struct Diagnostic {
// A cut-down version of `rustc_errors::Subdiag` that impls `Send`. It's
// missing the following fields from `rustc_errors::Subdiag`.
// - `span`: it doesn't impl `Send`.
pub struct Subdiagnostic {
pub(crate) struct Subdiagnostic {
level: Level,
messages: Vec<(DiagMessage, Style)>,
}
@ -1779,7 +1779,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
/// `FatalError` is explicitly not `Send`.
#[must_use]
pub struct WorkerFatalError;
pub(crate) struct WorkerFatalError;
fn spawn_work<'a, B: ExtraBackendMethods>(
cgcx: &'a CodegenContext<B>,
@ -1867,7 +1867,7 @@ pub struct SharedEmitterMain {
}
impl SharedEmitter {
pub fn new() -> (SharedEmitter, SharedEmitterMain) {
fn new() -> (SharedEmitter, SharedEmitterMain) {
let (sender, receiver) = channel();
(SharedEmitter { sender }, SharedEmitterMain { receiver })
@ -1883,7 +1883,7 @@ impl SharedEmitter {
drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)));
}
pub fn fatal(&self, msg: &str) {
fn fatal(&self, msg: &str) {
drop(self.sender.send(SharedEmitterMessage::Fatal(msg.to_string())));
}
}
@ -1903,7 +1903,7 @@ impl Emitter for SharedEmitter {
// Check that we aren't missing anything interesting when converting to
// the cut-down local `DiagInner`.
assert_eq!(diag.span, MultiSpan::new());
assert_eq!(diag.suggestions, Ok(vec![]));
assert_eq!(diag.suggestions, Suggestions::Enabled(vec![]));
assert_eq!(diag.sort_span, rustc_span::DUMMY_SP);
assert_eq!(diag.is_lint, None);
// No sensible check for `diag.emitted_at`.
@ -1930,7 +1930,7 @@ impl Emitter for SharedEmitter {
}
impl SharedEmitterMain {
pub fn check(&self, sess: &Session, blocking: bool) {
fn check(&self, sess: &Session, blocking: bool) {
loop {
let message = if blocking {
match self.receiver.recv() {
@ -2087,17 +2087,17 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
)
}
pub fn codegen_finished(&self, tcx: TyCtxt<'_>) {
pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) {
self.wait_for_signal_to_codegen_item();
self.check_for_errors(tcx.sess);
drop(self.coordinator.sender.send(Box::new(Message::CodegenComplete::<B>)));
}
pub fn check_for_errors(&self, sess: &Session) {
pub(crate) fn check_for_errors(&self, sess: &Session) {
self.shared_emitter_main.check(sess, false);
}
pub fn wait_for_signal_to_codegen_item(&self) {
pub(crate) fn wait_for_signal_to_codegen_item(&self) {
match self.codegen_worker_receive.recv() {
Ok(CguMessage) => {
// Ok to proceed.
@ -2110,7 +2110,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
}
}
pub fn submit_codegened_module_to_llvm<B: ExtraBackendMethods>(
pub(crate) fn submit_codegened_module_to_llvm<B: ExtraBackendMethods>(
_backend: &B,
tx_to_llvm_workers: &Sender<Box<dyn Any + Send>>,
module: ModuleCodegen<B::Module>,
@ -2120,7 +2120,7 @@ pub fn submit_codegened_module_to_llvm<B: ExtraBackendMethods>(
drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone::<B> { llvm_work_item, cost })));
}
pub fn submit_post_lto_module_to_llvm<B: ExtraBackendMethods>(
pub(crate) fn submit_post_lto_module_to_llvm<B: ExtraBackendMethods>(
_backend: &B,
tx_to_llvm_workers: &Sender<Box<dyn Any + Send>>,
module: CachedModuleCodegen,
@ -2129,7 +2129,7 @@ pub fn submit_post_lto_module_to_llvm<B: ExtraBackendMethods>(
drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone::<B> { llvm_work_item, cost: 0 })));
}
pub fn submit_pre_lto_module_to_llvm<B: ExtraBackendMethods>(
pub(crate) fn submit_pre_lto_module_to_llvm<B: ExtraBackendMethods>(
_backend: &B,
tcx: TyCtxt<'_>,
tx_to_llvm_workers: &Sender<Box<dyn Any + Send>>,

View File

@ -44,47 +44,23 @@ use crate::{
errors, meth, mir, CachedModuleCodegen, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
};
pub fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
match op {
BinOp::Eq => IntPredicate::IntEQ,
BinOp::Ne => IntPredicate::IntNE,
BinOp::Lt => {
if signed {
IntPredicate::IntSLT
} else {
IntPredicate::IntULT
}
}
BinOp::Le => {
if signed {
IntPredicate::IntSLE
} else {
IntPredicate::IntULE
}
}
BinOp::Gt => {
if signed {
IntPredicate::IntSGT
} else {
IntPredicate::IntUGT
}
}
BinOp::Ge => {
if signed {
IntPredicate::IntSGE
} else {
IntPredicate::IntUGE
}
}
op => bug!(
"comparison_op_to_icmp_predicate: expected comparison operator, \
found {:?}",
op
),
pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
match (op, signed) {
(BinOp::Eq, _) => IntPredicate::IntEQ,
(BinOp::Ne, _) => IntPredicate::IntNE,
(BinOp::Lt, true) => IntPredicate::IntSLT,
(BinOp::Lt, false) => IntPredicate::IntULT,
(BinOp::Le, true) => IntPredicate::IntSLE,
(BinOp::Le, false) => IntPredicate::IntULE,
(BinOp::Gt, true) => IntPredicate::IntSGT,
(BinOp::Gt, false) => IntPredicate::IntUGT,
(BinOp::Ge, true) => IntPredicate::IntSGE,
(BinOp::Ge, false) => IntPredicate::IntUGE,
op => bug!("bin_op_to_icmp_predicate: expected comparison operator, found {:?}", op),
}
}
pub fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate {
pub(crate) fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate {
match op {
BinOp::Eq => RealPredicate::RealOEQ,
BinOp::Ne => RealPredicate::RealUNE,
@ -92,13 +68,7 @@ pub fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate {
BinOp::Le => RealPredicate::RealOLE,
BinOp::Gt => RealPredicate::RealOGT,
BinOp::Ge => RealPredicate::RealOGE,
op => {
bug!(
"comparison_op_to_fcmp_predicate: expected comparison operator, \
found {:?}",
op
);
}
op => bug!("bin_op_to_fcmp_predicate: expected comparison operator, found {:?}", op),
}
}
@ -135,7 +105,7 @@ pub fn compare_simd_types<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
///
/// The `old_info` argument is a bit odd. It is intended for use in an upcast,
/// where the new vtable for an object will be derived from the old one.
pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
source: Ty<'tcx>,
target: Ty<'tcx>,
@ -145,16 +115,17 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let (source, target) =
cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.param_env());
match (source.kind(), target.kind()) {
(&ty::Array(_, len), &ty::Slice(_)) => {
cx.const_usize(len.eval_target_usize(cx.tcx(), ty::ParamEnv::reveal_all()))
}
(&ty::Array(_, len), &ty::Slice(_)) => cx.const_usize(
len.try_to_target_usize(cx.tcx()).expect("expected monomorphic const in codegen"),
),
(&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind))
if src_dyn_kind == target_dyn_kind =>
{
let old_info =
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
if data_a.principal_def_id() == data_b.principal_def_id() {
// A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
// A NOP cast that doesn't actually change anything, should be allowed even with
// invalid vtables.
return old_info;
}
@ -182,7 +153,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
/// Coerces `src` to `dst_ty`. `src_ty` must be a pointer.
pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
src: Bx::Value,
src_ty: Ty<'tcx>,
@ -227,7 +198,7 @@ pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type.
pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
src: Bx::Value,
src_ty_and_layout: TyAndLayout<'tcx>,
@ -250,7 +221,7 @@ pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
/// Coerces `src`, which is a reference to a value of type `src_ty`,
/// to a value of type `dst_ty`, and stores the result in `dst`.
pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
src: PlaceRef<'tcx, Bx::Value>,
dst: PlaceRef<'tcx, Bx::Value>,
@ -305,7 +276,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
///
/// If `is_unchecked` is true, this does no masking, and adds sufficient `assume`
/// calls or operation flags to preserve as much freedom to optimize as possible.
pub fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
lhs: Bx::Value,
mut rhs: Bx::Value,
@ -369,11 +340,11 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
/// Returns `true` if this session's target requires the new exception
/// handling LLVM IR instructions (catchpad / cleanuppad / ... instead
/// of landingpad)
pub fn wants_new_eh_instructions(sess: &Session) -> bool {
pub(crate) fn wants_new_eh_instructions(sess: &Session) -> bool {
wants_wasm_eh(sess) || wants_msvc_seh(sess)
}
pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
instance: Instance<'tcx>,
) {
@ -454,7 +425,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let isize_ty = cx.type_isize();
let ptr_ty = cx.type_ptr();
let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
let (arg_argc, arg_argv) = get_argc_argv(&mut bx);
let (start_fn, start_ty, args, instance) = if let EntryFnType::Main { sigpipe } = entry_type
{
@ -497,33 +468,30 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
/// Obtain the `argc` and `argv` values to pass to the rust start function.
fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
bx: &mut Bx,
) -> (Bx::Value, Bx::Value) {
if cx.sess().target.os.contains("uefi") {
fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(bx: &mut Bx) -> (Bx::Value, Bx::Value) {
if bx.cx().sess().target.os.contains("uefi") {
// Params for UEFI
let param_handle = bx.get_param(0);
let param_system_table = bx.get_param(1);
let ptr_size = bx.tcx().data_layout.pointer_size;
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
let arg_argc = bx.const_int(cx.type_isize(), 2);
let arg_argc = bx.const_int(bx.cx().type_isize(), 2);
let arg_argv = bx.alloca(2 * ptr_size, ptr_align);
bx.store(param_handle, arg_argv, ptr_align);
let arg_argv_el1 = bx.inbounds_ptradd(arg_argv, bx.const_usize(ptr_size.bytes()));
bx.store(param_system_table, arg_argv_el1, ptr_align);
(arg_argc, arg_argv)
} else if cx.sess().target.main_needs_argc_argv {
} else if bx.cx().sess().target.main_needs_argc_argv {
// Params from native `main()` used as args for rust start function
let param_argc = bx.get_param(0);
let param_argv = bx.get_param(1);
let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
let arg_argc = bx.intcast(param_argc, bx.cx().type_isize(), true);
let arg_argv = param_argv;
(arg_argc, arg_argv)
} else {
// The Rust start function doesn't need `argc` and `argv`, so just pass zeros.
let arg_argc = bx.const_int(cx.type_int(), 0);
let arg_argv = bx.const_null(cx.type_ptr());
let arg_argc = bx.const_int(bx.cx().type_int(), 0);
let arg_argv = bx.const_null(bx.cx().type_ptr());
(arg_argc, arg_argv)
}
}
@ -985,7 +953,8 @@ impl CrateInfo {
false
}
CrateType::Staticlib | CrateType::Rlib => {
// We don't invoke the linker for these, so we don't need to collect the NatVis for them.
// We don't invoke the linker for these, so we don't need to collect the NatVis for
// them.
false
}
});
@ -999,7 +968,7 @@ impl CrateInfo {
}
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
providers.backend_optimization_level = |tcx, cratenum| {
let for_speed = match tcx.sess.opts.optimize {
// If globally no optimisation is done, #[optimize] has no effect.

View File

@ -317,9 +317,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
"extern mutable statics are not allowed with `#[linkage]`",
);
diag.note(
"marking the extern static mutable would allow changing which symbol \
the static references rather than make the target of the symbol \
mutable",
"marking the extern static mutable would allow changing which \
symbol the static references rather than make the target of the \
symbol mutable",
);
diag.emit();
}
@ -711,18 +711,19 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
sole_meta_list
{
// According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header,
// the ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information
// to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
// According to the table at
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
// ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
// in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import
// information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
//
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for this:
// both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that specifies
// a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import library
// for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an import
// library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I don't know yet
// if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment
// about LINK.EXE failing.)
// FIXME: should we allow an ordinal of 0? The MSVC toolchain has inconsistent support for
// this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that
// specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import
// library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an
// import library produced by LLVM with an ordinal of 0, and it generates an .EXE. (I
// don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
// see earlier comment about LINK.EXE failing.)
if *ordinal <= u16::MAX as u128 {
Some(ordinal.get() as u16)
} else {
@ -755,6 +756,6 @@ fn check_link_name_xor_ordinal(
}
}
pub fn provide(providers: &mut Providers) {
pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
}

View File

@ -118,7 +118,7 @@ mod temp_stable_hash_impls {
}
}
pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &Bx,
span: Option<Span>,
li: LangItem,
@ -129,7 +129,7 @@ pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
(bx.fn_abi_of_instance(instance, ty::List::empty()), bx.get_fn_addr(instance), instance)
}
pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
llty: Bx::Type,
mask_llty: Bx::Type,
@ -200,7 +200,8 @@ pub fn i686_decorated_name(
let mut decorated_name = String::with_capacity(name.len() + 6);
if disable_name_mangling {
// LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be disabled.
// LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be
// disabled.
decorated_name.push('\x01');
}

View File

@ -54,7 +54,7 @@ pub fn tag_base_type<'tcx>(tcx: TyCtxt<'tcx>, enum_type_and_layout: TyAndLayout<
})
}
pub fn tag_base_type_opt<'tcx>(
fn tag_base_type_opt<'tcx>(
tcx: TyCtxt<'tcx>,
enum_type_and_layout: TyAndLayout<'tcx>,
) -> Option<Ty<'tcx>> {
@ -76,9 +76,9 @@ pub fn tag_base_type_opt<'tcx>(
Primitive::Float(f) => Integer::from_size(f.size()).unwrap(),
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
Primitive::Pointer(_) => {
// If the niche is the NULL value of a reference, then `discr_enum_ty` will be
// a RawPtr. CodeView doesn't know what to do with enums whose base type is a
// pointer so we fix this up to just be `usize`.
// If the niche is the NULL value of a reference, then `discr_enum_ty` will
// be a RawPtr. CodeView doesn't know what to do with enums whose base type
// is a pointer so we fix this up to just be `usize`.
// DWARF might be able to deal with this but with an integer type we are on
// the safe side there too.
tcx.data_layout.ptr_sized_integer()

View File

@ -95,7 +95,8 @@ fn push_debuginfo_type_name<'tcx>(
}
Err(e) => {
// Computing the layout can still fail here, e.g. if the target architecture
// cannot represent the type. See https://github.com/rust-lang/rust/issues/94961.
// cannot represent the type. See
// https://github.com/rust-lang/rust/issues/94961.
tcx.dcx().emit_fatal(e.into_diagnostic());
}
}
@ -187,7 +188,8 @@ fn push_debuginfo_type_name<'tcx>(
_ => write!(
output,
",{}>",
len.eval_target_usize(tcx, ty::ParamEnv::reveal_all())
len.try_to_target_usize(tcx)
.expect("expected monomorphic const in codegen")
)
.unwrap(),
}
@ -199,7 +201,8 @@ fn push_debuginfo_type_name<'tcx>(
_ => write!(
output,
"; {}]",
len.eval_target_usize(tcx, ty::ParamEnv::reveal_all())
len.try_to_target_usize(tcx)
.expect("expected monomorphic const in codegen")
)
.unwrap(),
}
@ -575,33 +578,20 @@ pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &
}
fn coroutine_kind_label(coroutine_kind: Option<CoroutineKind>) -> &'static str {
use CoroutineDesugaring::*;
use CoroutineKind::*;
use CoroutineSource::*;
match coroutine_kind {
Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Block)) => {
"gen_block"
}
Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Closure)) => {
"gen_closure"
}
Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Fn)) => "gen_fn",
Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Block)) => {
"async_block"
}
Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)) => {
"async_closure"
}
Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Fn)) => {
"async_fn"
}
Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Block)) => {
"async_gen_block"
}
Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Closure)) => {
"async_gen_closure"
}
Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Fn)) => {
"async_gen_fn"
}
Some(CoroutineKind::Coroutine(_)) => "coroutine",
Some(Desugared(Gen, Block)) => "gen_block",
Some(Desugared(Gen, Closure)) => "gen_closure",
Some(Desugared(Gen, Fn)) => "gen_fn",
Some(Desugared(Async, Block)) => "async_block",
Some(Desugared(Async, Closure)) => "async_closure",
Some(Desugared(Async, Fn)) => "async_fn",
Some(Desugared(AsyncGen, Block)) => "async_gen_block",
Some(Desugared(AsyncGen, Closure)) => "async_gen_closure",
Some(Desugared(AsyncGen, Fn)) => "async_gen_fn",
Some(Coroutine(_)) => "coroutine",
None => "closure",
}
}

View File

@ -21,7 +21,7 @@ use crate::fluent_generated as fluent;
#[derive(Diagnostic)]
#[diag(codegen_ssa_incorrect_cgu_reuse_type)]
pub struct IncorrectCguReuseType<'a> {
pub(crate) struct IncorrectCguReuseType<'a> {
#[primary_span]
pub span: Span,
pub cgu_user_name: &'a str,
@ -32,14 +32,14 @@ pub struct IncorrectCguReuseType<'a> {
#[derive(Diagnostic)]
#[diag(codegen_ssa_cgu_not_recorded)]
pub struct CguNotRecorded<'a> {
pub(crate) struct CguNotRecorded<'a> {
pub cgu_user_name: &'a str,
pub cgu_name: &'a str,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_unknown_reuse_kind)]
pub struct UnknownReuseKind {
pub(crate) struct UnknownReuseKind {
#[primary_span]
pub span: Span,
pub kind: Symbol,
@ -47,14 +47,14 @@ pub struct UnknownReuseKind {
#[derive(Diagnostic)]
#[diag(codegen_ssa_missing_query_depgraph)]
pub struct MissingQueryDepGraph {
pub(crate) struct MissingQueryDepGraph {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_malformed_cgu_name)]
pub struct MalformedCguName {
pub(crate) struct MalformedCguName {
#[primary_span]
pub span: Span,
pub user_path: String,
@ -63,7 +63,7 @@ pub struct MalformedCguName {
#[derive(Diagnostic)]
#[diag(codegen_ssa_no_module_named)]
pub struct NoModuleNamed<'a> {
pub(crate) struct NoModuleNamed<'a> {
#[primary_span]
pub span: Span,
pub user_path: &'a str,
@ -73,7 +73,7 @@ pub struct NoModuleNamed<'a> {
#[derive(Diagnostic)]
#[diag(codegen_ssa_field_associated_value_expected)]
pub struct FieldAssociatedValueExpected {
pub(crate) struct FieldAssociatedValueExpected {
#[primary_span]
pub span: Span,
pub name: Symbol,
@ -81,7 +81,7 @@ pub struct FieldAssociatedValueExpected {
#[derive(Diagnostic)]
#[diag(codegen_ssa_no_field)]
pub struct NoField {
pub(crate) struct NoField {
#[primary_span]
pub span: Span,
pub name: Symbol,
@ -89,49 +89,49 @@ pub struct NoField {
#[derive(Diagnostic)]
#[diag(codegen_ssa_lib_def_write_failure)]
pub struct LibDefWriteFailure {
pub(crate) struct LibDefWriteFailure {
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_version_script_write_failure)]
pub struct VersionScriptWriteFailure {
pub(crate) struct VersionScriptWriteFailure {
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_symbol_file_write_failure)]
pub struct SymbolFileWriteFailure {
pub(crate) struct SymbolFileWriteFailure {
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_ld64_unimplemented_modifier)]
pub struct Ld64UnimplementedModifier;
pub(crate) struct Ld64UnimplementedModifier;
#[derive(Diagnostic)]
#[diag(codegen_ssa_linker_unsupported_modifier)]
pub struct LinkerUnsupportedModifier;
pub(crate) struct LinkerUnsupportedModifier;
#[derive(Diagnostic)]
#[diag(codegen_ssa_L4Bender_exporting_symbols_unimplemented)]
pub struct L4BenderExportingSymbolsUnimplemented;
pub(crate) struct L4BenderExportingSymbolsUnimplemented;
#[derive(Diagnostic)]
#[diag(codegen_ssa_no_natvis_directory)]
pub struct NoNatvisDirectory {
pub(crate) struct NoNatvisDirectory {
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_no_saved_object_file)]
pub struct NoSavedObjectFile<'a> {
pub(crate) struct NoSavedObjectFile<'a> {
pub cgu_name: &'a str,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_copy_path_buf)]
pub struct CopyPathBuf {
pub(crate) struct CopyPathBuf {
pub source_file: PathBuf,
pub output_path: PathBuf,
pub error: Error,
@ -180,20 +180,20 @@ pub struct IgnoringOutput {
#[derive(Diagnostic)]
#[diag(codegen_ssa_create_temp_dir)]
pub struct CreateTempDir {
pub(crate) struct CreateTempDir {
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_add_native_library)]
pub struct AddNativeLibrary {
pub(crate) struct AddNativeLibrary {
pub library_path: PathBuf,
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_multiple_external_func_decl)]
pub struct MultipleExternalFuncDecl<'a> {
pub(crate) struct MultipleExternalFuncDecl<'a> {
#[primary_span]
pub span: Span,
pub function: Symbol,
@ -215,7 +215,7 @@ pub enum LinkRlibError {
IncompatibleDependencyFormats { ty1: String, ty2: String, list1: String, list2: String },
}
pub struct ThorinErrorWrapper(pub thorin::Error);
pub(crate) struct ThorinErrorWrapper(pub thorin::Error);
impl<G: EmissionGuarantee> Diagnostic<'_, G> for ThorinErrorWrapper {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
@ -343,7 +343,7 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ThorinErrorWrapper {
}
}
pub struct LinkingFailed<'a> {
pub(crate) struct LinkingFailed<'a> {
pub linker_path: &'a PathBuf,
pub exit_status: ExitStatus,
pub command: &'a Command,
@ -376,28 +376,28 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
#[derive(Diagnostic)]
#[diag(codegen_ssa_link_exe_unexpected_error)]
pub struct LinkExeUnexpectedError;
pub(crate) struct LinkExeUnexpectedError;
#[derive(Diagnostic)]
#[diag(codegen_ssa_repair_vs_build_tools)]
pub struct RepairVSBuildTools;
pub(crate) struct RepairVSBuildTools;
#[derive(Diagnostic)]
#[diag(codegen_ssa_missing_cpp_build_tool_component)]
pub struct MissingCppBuildToolComponent;
pub(crate) struct MissingCppBuildToolComponent;
#[derive(Diagnostic)]
#[diag(codegen_ssa_select_cpp_build_tool_workload)]
pub struct SelectCppBuildToolWorkload;
pub(crate) struct SelectCppBuildToolWorkload;
#[derive(Diagnostic)]
#[diag(codegen_ssa_visual_studio_not_installed)]
pub struct VisualStudioNotInstalled;
pub(crate) struct VisualStudioNotInstalled;
#[derive(Diagnostic)]
#[diag(codegen_ssa_linker_not_found)]
#[note]
pub struct LinkerNotFound {
pub(crate) struct LinkerNotFound {
pub linker_path: PathBuf,
pub error: Error,
}
@ -406,7 +406,7 @@ pub struct LinkerNotFound {
#[diag(codegen_ssa_unable_to_exe_linker)]
#[note]
#[note(codegen_ssa_command_note)]
pub struct UnableToExeLinker {
pub(crate) struct UnableToExeLinker {
pub linker_path: PathBuf,
pub error: Error,
pub command_formatted: String,
@ -414,38 +414,38 @@ pub struct UnableToExeLinker {
#[derive(Diagnostic)]
#[diag(codegen_ssa_msvc_missing_linker)]
pub struct MsvcMissingLinker;
pub(crate) struct MsvcMissingLinker;
#[derive(Diagnostic)]
#[diag(codegen_ssa_self_contained_linker_missing)]
pub struct SelfContainedLinkerMissing;
pub(crate) struct SelfContainedLinkerMissing;
#[derive(Diagnostic)]
#[diag(codegen_ssa_check_installed_visual_studio)]
pub struct CheckInstalledVisualStudio;
pub(crate) struct CheckInstalledVisualStudio;
#[derive(Diagnostic)]
#[diag(codegen_ssa_insufficient_vs_code_product)]
pub struct InsufficientVSCodeProduct;
pub(crate) struct InsufficientVSCodeProduct;
#[derive(Diagnostic)]
#[diag(codegen_ssa_processing_dymutil_failed)]
#[note]
pub struct ProcessingDymutilFailed {
pub(crate) struct ProcessingDymutilFailed {
pub status: ExitStatus,
pub output: String,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_unable_to_run_dsymutil)]
pub struct UnableToRunDsymutil {
pub(crate) struct UnableToRunDsymutil {
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_stripping_debug_info_failed)]
#[note]
pub struct StrippingDebugInfoFailed<'a> {
pub(crate) struct StrippingDebugInfoFailed<'a> {
pub util: &'a str,
pub status: ExitStatus,
pub output: String,
@ -453,58 +453,59 @@ pub struct StrippingDebugInfoFailed<'a> {
#[derive(Diagnostic)]
#[diag(codegen_ssa_unable_to_run)]
pub struct UnableToRun<'a> {
pub(crate) struct UnableToRun<'a> {
pub util: &'a str,
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_linker_file_stem)]
pub struct LinkerFileStem;
pub(crate) struct LinkerFileStem;
#[derive(Diagnostic)]
#[diag(codegen_ssa_static_library_native_artifacts)]
pub struct StaticLibraryNativeArtifacts;
pub(crate) struct StaticLibraryNativeArtifacts;
#[derive(Diagnostic)]
#[diag(codegen_ssa_static_library_native_artifacts_to_file)]
pub struct StaticLibraryNativeArtifactsToFile<'a> {
pub(crate) struct StaticLibraryNativeArtifactsToFile<'a> {
pub path: &'a Path,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_link_script_unavailable)]
pub struct LinkScriptUnavailable;
pub(crate) struct LinkScriptUnavailable;
#[derive(Diagnostic)]
#[diag(codegen_ssa_link_script_write_failure)]
pub struct LinkScriptWriteFailure {
pub(crate) struct LinkScriptWriteFailure {
pub path: PathBuf,
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_failed_to_write)]
pub struct FailedToWrite {
pub(crate) struct FailedToWrite {
pub path: PathBuf,
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_unable_to_write_debugger_visualizer)]
pub struct UnableToWriteDebuggerVisualizer {
pub(crate) struct UnableToWriteDebuggerVisualizer {
pub path: PathBuf,
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_rlib_archive_build_failure)]
pub struct RlibArchiveBuildFailure {
pub(crate) struct RlibArchiveBuildFailure {
pub path: PathBuf,
pub error: Error,
}
#[derive(Diagnostic)]
// Public for rustc_codegen_llvm::back::archive
pub enum ExtractBundledLibsError<'a> {
#[diag(codegen_ssa_extract_bundled_libs_open_file)]
OpenFile { rlib: &'a Path, error: Box<dyn std::error::Error> },
@ -533,26 +534,26 @@ pub enum ExtractBundledLibsError<'a> {
#[derive(Diagnostic)]
#[diag(codegen_ssa_unsupported_arch)]
pub struct UnsupportedArch<'a> {
pub(crate) struct UnsupportedArch<'a> {
pub arch: &'a str,
pub os: &'a str,
}
#[derive(Diagnostic)]
pub enum AppleSdkRootError<'a> {
pub(crate) enum AppleSdkRootError<'a> {
#[diag(codegen_ssa_apple_sdk_error_sdk_path)]
SdkPath { sdk_name: &'a str, error: Error },
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_read_file)]
pub struct ReadFileError {
pub(crate) struct ReadFileError {
pub message: std::io::Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_unsupported_link_self_contained)]
pub struct UnsupportedLinkSelfContained;
pub(crate) struct UnsupportedLinkSelfContained;
#[derive(Diagnostic)]
#[diag(codegen_ssa_archive_build_failure)]
@ -571,7 +572,7 @@ pub struct UnknownArchiveKind<'a> {
#[derive(Diagnostic)]
#[diag(codegen_ssa_expected_used_symbol)]
pub struct ExpectedUsedSymbol {
pub(crate) struct ExpectedUsedSymbol {
#[primary_span]
pub span: Span,
}
@ -579,45 +580,45 @@ pub struct ExpectedUsedSymbol {
#[derive(Diagnostic)]
#[diag(codegen_ssa_multiple_main_functions)]
#[help]
pub struct MultipleMainFunctions {
pub(crate) struct MultipleMainFunctions {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_metadata_object_file_write)]
pub struct MetadataObjectFileWrite {
pub(crate) struct MetadataObjectFileWrite {
pub error: Error,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_invalid_windows_subsystem)]
pub struct InvalidWindowsSubsystem {
pub(crate) struct InvalidWindowsSubsystem {
pub subsystem: Symbol,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_shuffle_indices_evaluation)]
pub struct ShuffleIndicesEvaluation {
pub(crate) struct ShuffleIndicesEvaluation {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_missing_memory_ordering)]
pub struct MissingMemoryOrdering;
pub(crate) struct MissingMemoryOrdering;
#[derive(Diagnostic)]
#[diag(codegen_ssa_unknown_atomic_ordering)]
pub struct UnknownAtomicOrdering;
pub(crate) struct UnknownAtomicOrdering;
#[derive(Diagnostic)]
#[diag(codegen_ssa_atomic_compare_exchange)]
pub struct AtomicCompareExchange;
pub(crate) struct AtomicCompareExchange;
#[derive(Diagnostic)]
#[diag(codegen_ssa_unknown_atomic_operation)]
pub struct UnknownAtomicOperation;
pub(crate) struct UnknownAtomicOperation;
#[derive(Diagnostic)]
pub enum InvalidMonomorphization<'tcx> {
@ -986,7 +987,7 @@ impl IntoDiagArg for ExpectedPointerMutability {
#[derive(Diagnostic)]
#[diag(codegen_ssa_invalid_no_sanitize)]
#[note]
pub struct InvalidNoSanitize {
pub(crate) struct InvalidNoSanitize {
#[primary_span]
pub span: Span,
}
@ -994,7 +995,7 @@ pub struct InvalidNoSanitize {
#[derive(Diagnostic)]
#[diag(codegen_ssa_invalid_link_ordinal_nargs)]
#[note]
pub struct InvalidLinkOrdinalNargs {
pub(crate) struct InvalidLinkOrdinalNargs {
#[primary_span]
pub span: Span,
}
@ -1002,14 +1003,14 @@ pub struct InvalidLinkOrdinalNargs {
#[derive(Diagnostic)]
#[diag(codegen_ssa_illegal_link_ordinal_format)]
#[note]
pub struct InvalidLinkOrdinalFormat {
pub(crate) struct InvalidLinkOrdinalFormat {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_target_feature_safe_trait)]
pub struct TargetFeatureSafeTrait {
pub(crate) struct TargetFeatureSafeTrait {
#[primary_span]
#[label]
pub span: Span,
@ -1050,7 +1051,7 @@ pub(crate) struct ErrorCallingDllTool<'a> {
#[derive(Diagnostic)]
#[diag(codegen_ssa_error_creating_remark_dir)]
pub struct ErrorCreatingRemarkDir {
pub(crate) struct ErrorCreatingRemarkDir {
pub error: std::io::Error,
}

View File

@ -11,6 +11,7 @@
#![feature(negative_impls)]
#![feature(rustdoc_internals)]
#![feature(strict_provenance)]
#![feature(trait_alias)]
#![feature(try_blocks)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
@ -128,7 +129,7 @@ impl CompiledModule {
}
}
pub struct CachedModuleCodegen {
pub(crate) struct CachedModuleCodegen {
pub name: String,
pub source: WorkProduct,
}

View File

@ -8,10 +8,10 @@ use tracing::{debug, instrument};
use crate::traits::*;
#[derive(Copy, Clone, Debug)]
pub struct VirtualIndex(u64);
pub(crate) struct VirtualIndex(u64);
impl<'a, 'tcx> VirtualIndex {
pub fn from_index(index: usize) -> Self {
pub(crate) fn from_index(index: usize) -> Self {
VirtualIndex(index as u64)
}
@ -51,7 +51,7 @@ impl<'a, 'tcx> VirtualIndex {
}
}
pub fn get_optional_fn<Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn get_optional_fn<Bx: BuilderMethods<'a, 'tcx>>(
self,
bx: &mut Bx,
llvtable: Bx::Value,
@ -61,7 +61,7 @@ impl<'a, 'tcx> VirtualIndex {
self.get_fn_inner(bx, llvtable, ty, fn_abi, false)
}
pub fn get_fn<Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn get_fn<Bx: BuilderMethods<'a, 'tcx>>(
self,
bx: &mut Bx,
llvtable: Bx::Value,
@ -71,7 +71,7 @@ impl<'a, 'tcx> VirtualIndex {
self.get_fn_inner(bx, llvtable, ty, fn_abi, true)
}
pub fn get_usize<Bx: BuilderMethods<'a, 'tcx>>(
pub(crate) fn get_usize<Bx: BuilderMethods<'a, 'tcx>>(
self,
bx: &mut Bx,
llvtable: Bx::Value,
@ -115,7 +115,7 @@ fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
/// making an object `Foo<dyn Trait>` from a value of type `Foo<T>`, then
/// `trait_ref` would map `T: Trait`.
#[instrument(level = "debug", skip(cx))]
pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &Cx,
ty: Ty<'tcx>,
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,

View File

@ -69,13 +69,13 @@ enum LocalKind {
SSA(DefLocation),
}
struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
fx: &'mir FunctionCx<'a, 'tcx, Bx>,
dominators: &'mir Dominators<mir::BasicBlock>,
struct LocalAnalyzer<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> {
fx: &'a FunctionCx<'b, 'tcx, Bx>,
dominators: &'a Dominators<mir::BasicBlock>,
locals: IndexVec<mir::Local, LocalKind>,
}
impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> LocalAnalyzer<'a, 'b, 'tcx, Bx> {
fn define(&mut self, local: mir::Local, location: DefLocation) {
let kind = &mut self.locals[local];
match *kind {
@ -152,9 +152,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx,
}
}
impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
for LocalAnalyzer<'mir, 'a, 'tcx, Bx>
{
impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer<'a, 'b, 'tcx, Bx> {
fn visit_assign(
&mut self,
place: &mir::Place<'tcx>,

View File

@ -996,7 +996,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
// we get a value of a built-in pointer type.
//
// This is also relevant for `Pin<&mut Self>`, where we need to peel the `Pin`.
// This is also relevant for `Pin<&mut Self>`, where we need to peel the
// `Pin`.
while !op.layout.ty.is_unsafe_ptr() && !op.layout.ty.is_ref() {
let (idx, _) = op.layout.non_1zst_field(bx).expect(
"not exactly one non-1-ZST field in a `DispatchFromDyn` type",
@ -1004,9 +1005,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
op = op.extract_field(bx, idx);
}
// now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
// Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
// data pointer and vtable. Look up the method in the vtable, and pass
// the data pointer as the first argument
// the data pointer as the first argument.
llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
bx,
meta,
@ -1212,10 +1213,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mergeable_succ,
)
}
}
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn codegen_block(&mut self, mut bb: mir::BasicBlock) {
pub(crate) fn codegen_block(&mut self, mut bb: mir::BasicBlock) {
let llbb = match self.try_llbb(bb) {
Some(llbb) => llbb,
None => return,
@ -1255,7 +1254,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
pub fn codegen_block_as_unreachable(&mut self, bb: mir::BasicBlock) {
pub(crate) fn codegen_block_as_unreachable(&mut self, bb: mir::BasicBlock) {
let llbb = match self.try_llbb(bb) {
Some(llbb) => llbb,
None => return,
@ -1440,8 +1439,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let (mut llval, align, by_ref) = match op.val {
Immediate(_) | Pair(..) => match arg.mode {
PassMode::Indirect { attrs, .. } => {
// Indirect argument may have higher alignment requirements than the type's alignment.
// This can happen, e.g. when passing types with <4 byte alignment on the stack on x86.
// Indirect argument may have higher alignment requirements than the type's
// alignment. This can happen, e.g. when passing types with <4 byte alignment
// on the stack on x86.
let required_align = match attrs.pointee_align {
Some(pointee_align) => cmp::max(pointee_align, arg.layout.align.abi),
None => arg.layout.align.abi,
@ -1740,7 +1740,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
/// Like `llbb`, but may fail if the basic block should be skipped.
pub fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option<Bx::BasicBlock> {
pub(crate) fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option<Bx::BasicBlock> {
match self.cached_llbbs[bb] {
CachedLlbb::None => {
let llbb = Bx::append_block(self.cx, self.llfn, &format!("{bb:?}"));

View File

@ -10,7 +10,7 @@ use crate::mir::operand::OperandRef;
use crate::traits::*;
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn eval_mir_constant_to_operand(
pub(crate) fn eval_mir_constant_to_operand(
&self,
bx: &mut Bx,
constant: &mir::ConstOperand<'tcx>,
@ -32,27 +32,28 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
/// that the given `constant` is an `Const::Unevaluated` and must be convertible to
/// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
///
/// Note that this function is cursed, since usually MIR consts should not be evaluated to valtrees!
pub fn eval_unevaluated_mir_constant_to_valtree(
/// Note that this function is cursed, since usually MIR consts should not be evaluated to
/// valtrees!
fn eval_unevaluated_mir_constant_to_valtree(
&self,
constant: &mir::ConstOperand<'tcx>,
) -> Result<Result<ty::ValTree<'tcx>, Ty<'tcx>>, ErrorHandled> {
let uv = match self.monomorphize(constant.const_) {
mir::Const::Unevaluated(uv, _) => uv.shrink(),
mir::Const::Ty(_, c) => match c.kind() {
// A constant that came from a const generic but was then used as an argument to old-style
// simd_shuffle (passing as argument instead of as a generic param).
// A constant that came from a const generic but was then used as an argument to
// old-style simd_shuffle (passing as argument instead of as a generic param).
rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Ok(valtree)),
other => span_bug!(constant.span, "{other:#?}"),
},
// We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
// a constant and write that value back into `Operand`s. This could happen, but is unlikely.
// Also: all users of `simd_shuffle` are on unstable and already need to take a lot of care
// around intrinsics. For an issue to happen here, it would require a macro expanding to a
// `simd_shuffle` call without wrapping the constant argument in a `const {}` block, but
// the user pass through arbitrary expressions.
// FIXME(oli-obk): replace the magic const generic argument of `simd_shuffle` with a real
// const generic, and get rid of this entire function.
// a constant and write that value back into `Operand`s. This could happen, but is
// unlikely. Also: all users of `simd_shuffle` are on unstable and already need to take
// a lot of care around intrinsics. For an issue to happen here, it would require a
// macro expanding to a `simd_shuffle` call without wrapping the constant argument in a
// `const {}` block, but the user pass through arbitrary expressions.
// FIXME(oli-obk): replace the magic const generic argument of `simd_shuffle` with a
// real const generic, and get rid of this entire function.
other => span_bug!(constant.span, "{other:#?}"),
};
let uv = self.monomorphize(uv);

View File

@ -5,7 +5,7 @@ use super::FunctionCx;
use crate::traits::*;
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) {
pub(crate) fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) {
// Determine the instance that coverage data was originally generated for.
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
self.monomorphize(inlined)

View File

@ -24,6 +24,7 @@ pub struct FunctionDebugContext<'tcx, S, L> {
/// Maps from an inlined function to its debug info declaration.
pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
}
#[derive(Copy, Clone)]
pub enum VariableKind {
ArgumentVariable(usize /*index*/),
@ -243,7 +244,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
/// Apply debuginfo and/or name, after creating the `alloca` for a local,
/// or initializing the local with an operand (whichever applies).
pub fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) {
pub(crate) fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) {
let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full;
let vars = match &self.per_local_var_debug_info {
@ -426,7 +427,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
pub fn debug_introduce_locals(&self, bx: &mut Bx) {
pub(crate) fn debug_introduce_locals(&self, bx: &mut Bx) {
if bx.sess().opts.debuginfo == DebugInfo::Full || !bx.sess().fewer_names() {
for local in self.locals.indices() {
self.debug_introduce_local(bx, local);
@ -435,7 +436,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
/// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`.
pub fn compute_per_local_var_debug_info(
pub(crate) fn compute_per_local_var_debug_info(
&self,
bx: &mut Bx,
) -> Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>> {

View File

@ -15,8 +15,8 @@ use crate::traits::*;
mod analyze;
mod block;
pub mod constant;
pub mod coverageinfo;
mod constant;
mod coverageinfo;
pub mod debuginfo;
mod intrinsic;
mod locals;

View File

@ -27,32 +27,32 @@ pub enum OperandValue<V> {
/// which indicates that it refers to an unsized rvalue.
///
/// An `OperandValue` *must* be this variant for any type for which
/// [`LayoutTypeMethods::is_backend_ref`] returns `true`.
/// [`LayoutTypeCodegenMethods::is_backend_ref`] returns `true`.
/// (That basically amounts to "isn't one of the other variants".)
///
/// This holds a [`PlaceValue`] (like a [`PlaceRef`] does) with a pointer
/// to the location holding the value. The type behind that pointer is the
/// one returned by [`LayoutTypeMethods::backend_type`].
/// one returned by [`LayoutTypeCodegenMethods::backend_type`].
Ref(PlaceValue<V>),
/// A single LLVM immediate value.
///
/// An `OperandValue` *must* be this variant for any type for which
/// [`LayoutTypeMethods::is_backend_immediate`] returns `true`.
/// [`LayoutTypeCodegenMethods::is_backend_immediate`] returns `true`.
/// The backend value in this variant must be the *immediate* backend type,
/// as returned by [`LayoutTypeMethods::immediate_backend_type`].
/// as returned by [`LayoutTypeCodegenMethods::immediate_backend_type`].
Immediate(V),
/// A pair of immediate LLVM values. Used by fat pointers too.
///
/// An `OperandValue` *must* be this variant for any type for which
/// [`LayoutTypeMethods::is_backend_scalar_pair`] returns `true`.
/// [`LayoutTypeCodegenMethods::is_backend_scalar_pair`] returns `true`.
/// The backend values in this variant must be the *immediate* backend types,
/// as returned by [`LayoutTypeMethods::scalar_pair_element_backend_type`]
/// as returned by [`LayoutTypeCodegenMethods::scalar_pair_element_backend_type`]
/// with `immediate: true`.
Pair(V, V),
/// A value taking no bytes, and which therefore needs no LLVM value at all.
///
/// If you ever need a `V` to pass to something, get a fresh poison value
/// from [`ConstMethods::const_poison`].
/// from [`ConstCodegenMethods::const_poison`].
///
/// An `OperandValue` *must* be this variant for any type for which
/// `is_zst` on its `Layout` returns `true`. Note however that
@ -64,7 +64,7 @@ impl<V: CodegenObject> OperandValue<V> {
/// If this is ZeroSized/Immediate/Pair, return an array of the 0/1/2 values.
/// If this is Ref, return the place.
#[inline]
pub fn immediates_or_place(self) -> Either<ArrayVec<V, 2>, PlaceValue<V>> {
pub(crate) fn immediates_or_place(self) -> Either<ArrayVec<V, 2>, PlaceValue<V>> {
match self {
OperandValue::ZeroSized => Either::Left(ArrayVec::new()),
OperandValue::Immediate(a) => Either::Left(ArrayVec::from_iter([a])),
@ -75,7 +75,7 @@ impl<V: CodegenObject> OperandValue<V> {
/// Given an array of 0/1/2 immediate values, return ZeroSized/Immediate/Pair.
#[inline]
pub fn from_immediates(immediates: ArrayVec<V, 2>) -> Self {
pub(crate) fn from_immediates(immediates: ArrayVec<V, 2>) -> Self {
let mut it = immediates.into_iter();
let Some(a) = it.next() else {
return OperandValue::ZeroSized;
@ -90,7 +90,7 @@ impl<V: CodegenObject> OperandValue<V> {
/// optional metadata as backend values.
///
/// If you're making a place, use [`Self::deref`] instead.
pub fn pointer_parts(self) -> (V, Option<V>) {
pub(crate) fn pointer_parts(self) -> (V, Option<V>) {
match self {
OperandValue::Immediate(llptr) => (llptr, None),
OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)),
@ -105,12 +105,12 @@ impl<V: CodegenObject> OperandValue<V> {
/// alignment, then maybe you want [`OperandRef::deref`] instead.
///
/// This is the inverse of [`PlaceValue::address`].
pub fn deref(self, align: Align) -> PlaceValue<V> {
pub(crate) fn deref(self, align: Align) -> PlaceValue<V> {
let (llval, llextra) = self.pointer_parts();
PlaceValue { llval, llextra, align }
}
pub(crate) fn is_expected_variant_for_type<'tcx, Cx: LayoutTypeMethods<'tcx>>(
pub(crate) fn is_expected_variant_for_type<'tcx, Cx: LayoutTypeCodegenMethods<'tcx>>(
&self,
cx: &Cx,
ty: TyAndLayout<'tcx>,
@ -153,7 +153,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
OperandRef { val: OperandValue::ZeroSized, layout }
}
pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
pub(crate) fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx,
val: mir::ConstValue<'tcx>,
ty: Ty<'tcx>,
@ -280,7 +280,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
///
/// If you don't need the type, see [`OperandValue::pointer_parts`]
/// or [`OperandValue::deref`].
pub fn deref<Cx: LayoutTypeMethods<'tcx>>(self, cx: &Cx) -> PlaceRef<'tcx, V> {
pub fn deref<Cx: CodegenMethods<'tcx>>(self, cx: &Cx) -> PlaceRef<'tcx, V> {
if self.layout.ty.is_box() {
// Derefer should have removed all Box derefs
bug!("dereferencing {:?} in codegen", self.layout.ty);
@ -334,7 +334,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
OperandRef { val, layout }
}
pub fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
pub(crate) fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
&self,
bx: &mut Bx,
i: usize,
@ -478,8 +478,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
match self {
OperandValue::ZeroSized => {
// Avoid generating stores of zero-sized values, because the only way to have a zero-sized
// value is through `undef`/`poison`, and the store itself is useless.
// Avoid generating stores of zero-sized values, because the only way to have a
// zero-sized value is through `undef`/`poison`, and the store itself is useless.
}
OperandValue::Ref(val) => {
assert!(dest.layout.is_sized(), "cannot directly store unsized values");

View File

@ -133,7 +133,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
Self::alloca(bx, ptr_layout)
}
pub fn len<Cx: ConstMethods<'tcx, Value = V>>(&self, cx: &Cx) -> V {
pub fn len<Cx: ConstCodegenMethods<'tcx, Value = V>>(&self, cx: &Cx) -> V {
if let FieldsShape::Array { count, .. } = self.layout.fields {
if self.layout.is_unsized() {
assert_eq!(count, 0);

View File

@ -19,7 +19,7 @@ use crate::{base, MemFlags};
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
#[instrument(level = "trace", skip(self, bx))]
pub fn codegen_rvalue(
pub(crate) fn codegen_rvalue(
&mut self,
bx: &mut Bx,
dest: PlaceRef<'tcx, Bx::Value>,
@ -114,7 +114,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let count = self
.monomorphize(count)
.eval_target_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all());
.try_to_target_usize(bx.tcx())
.expect("expected monomorphic const in codegen");
bx.write_operand_repeatedly(cg_elem, count, dest);
}
@ -419,7 +420,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
pub fn codegen_rvalue_unsized(
pub(crate) fn codegen_rvalue_unsized(
&mut self,
bx: &mut Bx,
indirect_dest: PlaceRef<'tcx, Bx::Value>,
@ -440,7 +441,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
pub fn codegen_rvalue_operand(
pub(crate) fn codegen_rvalue_operand(
&mut self,
bx: &mut Bx,
rvalue: &mir::Rvalue<'tcx>,
@ -803,7 +804,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
if let Some(index) = place.as_local() {
if let LocalRef::Operand(op) = self.locals[index] {
if let ty::Array(_, n) = op.layout.ty.kind() {
let n = n.eval_target_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all());
let n = n
.try_to_target_usize(bx.tcx())
.expect("expected monomorphic const in codegen");
return bx.cx().const_usize(n);
}
}
@ -836,7 +839,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
OperandRef { val, layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)) }
}
pub fn codegen_scalar_binop(
fn codegen_scalar_binop(
&mut self,
bx: &mut Bx,
op: mir::BinOp,
@ -981,7 +984,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
pub fn codegen_fat_ptr_binop(
fn codegen_fat_ptr_binop(
&mut self,
bx: &mut Bx,
op: mir::BinOp,
@ -1023,7 +1026,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
pub fn codegen_scalar_checked_binop(
fn codegen_scalar_checked_binop(
&mut self,
bx: &mut Bx,
op: mir::BinOp,
@ -1047,10 +1050,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
OperandValue::Pair(val, of)
}
}
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool {
pub(crate) fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool {
match *rvalue {
mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, cast_ty) => {
let operand_ty = operand.ty(self.mir, self.cx.tcx());

View File

@ -7,7 +7,7 @@ use crate::traits::*;
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
#[instrument(level = "debug", skip(self, bx))]
pub fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) {
pub(crate) fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) {
self.set_debug_loc(bx, statement.source_info);
match statement.kind {
mir::StatementKind::Assign(box (ref place, ref rvalue)) => {

View File

@ -45,11 +45,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// The info in this case is the length of the str, so the size is that
// times the unit size.
(
// All slice sizes must fit into `isize`, so this multiplication cannot (signed) wrap.
// All slice sizes must fit into `isize`, so this multiplication cannot (signed)
// wrap.
// NOTE: ideally, we want the effects of both `unchecked_smul` and `unchecked_umul`
// (resulting in `mul nsw nuw` in LLVM IR), since we know that the multiplication
// cannot signed wrap, and that both operands are non-negative. But at the time of writing,
// the `LLVM-C` binding can't do this, and it doesn't seem to enable any further optimizations.
// cannot signed wrap, and that both operands are non-negative. But at the time of
// writing, the `LLVM-C` binding can't do this, and it doesn't seem to enable any
// further optimizations.
bx.unchecked_smul(info.unwrap(), bx.const_usize(unit.size.bytes())),
bx.const_usize(unit.align.abi.bytes()),
)
@ -67,9 +69,9 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
let (fn_abi, llfn, _instance) =
common::build_langcall(bx, None, LangItem::PanicNounwind);
// Generate the call.
// Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`.
// (But we are in good company, this code is duplicated plenty of times.)
// Generate the call. Cannot use `do_call` since we don't have a MIR terminator so we
// can't create a `TerminationCodegenHelper`. (But we are in good company, this code is
// duplicated plenty of times.)
let fn_ty = bx.fn_decl_backend_type(fn_abi);
bx.call(
@ -148,9 +150,14 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// The full formula for the size would be:
// let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align);
// let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align);
// However, `unsized_size` is a multiple of `unsized_align`.
// Therefore, we can equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`:
// let full_size = (unsized_offset_unadjusted + unsized_size).align_to(unsized_align).align_to(full_align);
// However, `unsized_size` is a multiple of `unsized_align`. Therefore, we can
// equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`:
//
// let full_size =
// (unsized_offset_unadjusted + unsized_size)
// .align_to(unsized_align)
// .align_to(full_align);
//
// Furthermore, `align >= unsized_align`, and therefore we only need to do:
// let full_size = (unsized_offset_unadjusted + unsized_size).align_to(full_align);

View File

@ -15,7 +15,7 @@ use rustc_span::Span;
use crate::errors;
pub fn from_target_feature(
pub(crate) fn from_target_feature(
tcx: TyCtxt<'_>,
attr: &ast::Attribute,
supported_target_features: &UnordMap<String, Option<Symbol>>,
@ -146,7 +146,7 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet<Symbol> {
/// Checks the function annotated with `#[target_feature]` is not a safe
/// trait method implementation, reporting an error if it is.
pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) {
pub(crate) fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) {
if let DefKind::AssocFn = tcx.def_kind(id) {
let parent_id = tcx.local_parent(id);
if let DefKind::Trait | DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {

View File

@ -60,7 +60,7 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
);
}
pub trait AsmMethods<'tcx> {
pub trait AsmCodegenMethods<'tcx> {
fn codegen_global_asm(
&self,
template: &[InlineAsmTemplatePiece],

View File

@ -8,13 +8,11 @@ use rustc_errors::ErrorGuaranteed;
use rustc_metadata::creader::MetadataLoaderDyn;
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_middle::ty::TyCtxt;
use rustc_middle::util::Providers;
use rustc_session::config::{self, OutputFilenames, PrintRequest};
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_target::abi::call::FnAbi;
use super::write::WriteBackendMethods;
use super::CodegenObject;
@ -36,34 +34,21 @@ pub trait BackendTypes {
type DIVariable: Copy;
}
pub trait Backend<'tcx>:
Sized
+ BackendTypes
+ HasTyCtxt<'tcx>
+ LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
+ FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
{
}
impl<'tcx, T> Backend<'tcx> for T where
Self: BackendTypes
+ HasTyCtxt<'tcx>
+ LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
+ FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
{
}
pub trait CodegenBackend {
/// Locale resources for diagnostic messages - a string the content of the Fluent resource.
/// Called before `init` so that all other functions are able to emit translatable diagnostics.
fn locale_resource(&self) -> &'static str;
fn init(&self, _sess: &Session) {}
fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
vec![]
}
fn print_passes(&self) {}
fn print_version(&self) {}
/// The metadata loader used to load rlib and dylib metadata.
@ -75,6 +60,7 @@ pub trait CodegenBackend {
}
fn provide(&self, _providers: &mut Providers) {}
fn codegen_crate<'tcx>(
&self,
tcx: TyCtxt<'tcx>,
@ -120,6 +106,7 @@ pub trait ExtraBackendMethods:
kind: AllocatorKind,
alloc_error_handler_kind: AllocatorKind,
) -> Self::Module;
/// This generates the codegen unit and returns it along with
/// a `u64` giving an estimate of the unit's processing cost.
fn compile_codegen_unit(
@ -127,6 +114,7 @@ pub trait ExtraBackendMethods:
tcx: TyCtxt<'_>,
cgu_name: Symbol,
) -> (ModuleCodegen<Self::Module>, u64);
fn target_machine_factory(
&self,
sess: &Session,

View File

@ -1,23 +1,23 @@
use std::assert_matches::assert_matches;
use std::ops::Deref;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
use rustc_middle::ty::{Instance, Ty};
use rustc_session::config::OptLevel;
use rustc_span::Span;
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange};
use rustc_target::spec::HasTargetSpec;
use super::abi::AbiBuilderMethods;
use super::asm::AsmBuilderMethods;
use super::consts::ConstMethods;
use super::consts::ConstCodegenMethods;
use super::coverageinfo::CoverageInfoBuilderMethods;
use super::debuginfo::DebugInfoBuilderMethods;
use super::intrinsic::IntrinsicCallMethods;
use super::misc::MiscMethods;
use super::type_::{ArgAbiMethods, BaseTypeMethods, LayoutTypeMethods};
use super::{HasCodegen, StaticBuilderMethods};
use super::intrinsic::IntrinsicCallBuilderMethods;
use super::misc::MiscCodegenMethods;
use super::type_::{ArgAbiBuilderMethods, BaseTypeCodegenMethods, LayoutTypeCodegenMethods};
use super::{CodegenMethods, StaticBuilderMethods};
use crate::common::{
AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind,
};
@ -33,17 +33,33 @@ pub enum OverflowOp {
}
pub trait BuilderMethods<'a, 'tcx>:
HasCodegen<'tcx>
Sized
+ LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
+ FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
+ Deref<Target = Self::CodegenCx>
+ CoverageInfoBuilderMethods<'tcx>
+ DebugInfoBuilderMethods
+ ArgAbiMethods<'tcx>
+ ArgAbiBuilderMethods<'tcx>
+ AbiBuilderMethods<'tcx>
+ IntrinsicCallMethods<'tcx>
+ IntrinsicCallBuilderMethods<'tcx>
+ AsmBuilderMethods<'tcx>
+ StaticBuilderMethods
+ HasParamEnv<'tcx>
+ HasTargetSpec
{
// `BackendTypes` is a supertrait of both `CodegenMethods` and
// `BuilderMethods`. This bound ensures all impls agree on the associated
// types within.
type CodegenCx: CodegenMethods<
'tcx,
Value = Self::Value,
Function = Self::Function,
BasicBlock = Self::BasicBlock,
Type = Self::Type,
Funclet = Self::Funclet,
DIScope = Self::DIScope,
DILocation = Self::DILocation,
DIVariable = Self::DIVariable,
>;
fn build(cx: &'a Self::CodegenCx, llbb: Self::BasicBlock) -> Self;
fn cx(&self) -> &Self::CodegenCx;

View File

@ -3,7 +3,7 @@ use rustc_target::abi;
use super::BackendTypes;
pub trait ConstMethods<'tcx>: BackendTypes {
pub trait ConstCodegenMethods<'tcx>: BackendTypes {
// Constant constructors
fn const_null(&self, t: Self::Type) -> Self::Value;
/// Generate an uninitialized value (matching uninitialized memory in MIR).
@ -14,18 +14,20 @@ pub trait ConstMethods<'tcx>: BackendTypes {
/// (including code that e.g. copies uninit memory with `MaybeUninit`) can never encounter a
/// poison value.
fn const_poison(&self, t: Self::Type) -> Self::Value;
fn const_int(&self, t: Self::Type, i: i64) -> Self::Value;
fn const_uint(&self, t: Self::Type, i: u64) -> Self::Value;
fn const_uint_big(&self, t: Self::Type, u: u128) -> Self::Value;
fn const_bool(&self, val: bool) -> Self::Value;
fn const_i8(&self, i: i8) -> Self::Value;
fn const_i16(&self, i: i16) -> Self::Value;
fn const_i32(&self, i: i32) -> Self::Value;
fn const_i8(&self, i: i8) -> Self::Value;
fn const_int(&self, t: Self::Type, i: i64) -> Self::Value;
fn const_u8(&self, i: u8) -> Self::Value;
fn const_u32(&self, i: u32) -> Self::Value;
fn const_u64(&self, i: u64) -> Self::Value;
fn const_u128(&self, i: u128) -> Self::Value;
fn const_usize(&self, i: u64) -> Self::Value;
fn const_u8(&self, i: u8) -> Self::Value;
fn const_uint(&self, t: Self::Type, i: u64) -> Self::Value;
fn const_uint_big(&self, t: Self::Type, u: u128) -> Self::Value;
fn const_real(&self, t: Self::Type, val: f64) -> Self::Value;
fn const_str(&self, s: &str) -> (Self::Value, Self::Value);

View File

@ -1,9 +1,7 @@
use rustc_middle::mir::coverage::CoverageKind;
use rustc_middle::ty::Instance;
use super::BackendTypes;
pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
pub trait CoverageInfoBuilderMethods<'tcx> {
/// Performs any start-of-function codegen needed for coverage instrumentation.
///
/// Can be a no-op in backends that don't support coverage instrumentation.

View File

@ -9,7 +9,7 @@ use rustc_target::abi::Size;
use super::BackendTypes;
use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
pub trait DebugInfoMethods<'tcx>: BackendTypes {
pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes {
fn create_vtable_debuginfo(
&self,
ty: Ty<'tcx>,

View File

@ -2,9 +2,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::mir::mono::{Linkage, Visibility};
use rustc_middle::ty::Instance;
use super::BackendTypes;
pub trait PreDefineMethods<'tcx>: BackendTypes {
pub trait PreDefineCodegenMethods<'tcx> {
fn predefine_static(
&self,
def_id: DefId,

View File

@ -5,7 +5,7 @@ use rustc_target::abi::call::FnAbi;
use super::BackendTypes;
use crate::mir::operand::OperandRef;
pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes {
/// Remember to add all intrinsics here, in `compiler/rustc_hir_analysis/src/check/mod.rs`,
/// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics,
/// add them to `compiler/rustc_codegen_llvm/src/context.rs`.

View File

@ -7,7 +7,7 @@ use rustc_session::Session;
use super::BackendTypes;
pub trait MiscMethods<'tcx>: BackendTypes {
pub trait MiscCodegenMethods<'tcx>: BackendTypes {
fn vtables(
&self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
@ -25,6 +25,7 @@ pub trait MiscMethods<'tcx>: BackendTypes {
fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>;
fn set_frame_pointer_type(&self, llfn: Self::Function);
fn apply_target_cpu_attr(&self, llfn: Self::Function);
/// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists.
/// Declares the extern "C" main function for the entry point. Returns None if the symbol
/// already exists.
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function>;
}

View File

@ -8,9 +8,6 @@
//! actual codegen, while the builder stores the information about the function during codegen and
//! is used to produce the instructions of the backend IR.
//!
//! Finally, a third `Backend` structure has to implement methods related to how codegen information
//! is passed to the backend, especially for asynchronous compilation.
//!
//! The traits contain associated types that are backend-specific, such as the backend's value or
//! basic blocks.
@ -30,71 +27,36 @@ mod write;
use std::fmt;
use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt};
use rustc_target::spec::HasTargetSpec;
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
use rustc_middle::ty::Ty;
use rustc_target::abi::call::FnAbi;
pub use self::abi::AbiBuilderMethods;
pub use self::asm::{AsmBuilderMethods, AsmMethods, GlobalAsmOperandRef, InlineAsmOperandRef};
pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods};
pub use self::asm::{
AsmBuilderMethods, AsmCodegenMethods, GlobalAsmOperandRef, InlineAsmOperandRef,
};
pub use self::backend::{BackendTypes, CodegenBackend, ExtraBackendMethods};
pub use self::builder::{BuilderMethods, OverflowOp};
pub use self::consts::ConstMethods;
pub use self::consts::ConstCodegenMethods;
pub use self::coverageinfo::CoverageInfoBuilderMethods;
pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
pub use self::declare::PreDefineMethods;
pub use self::intrinsic::IntrinsicCallMethods;
pub use self::misc::MiscMethods;
pub use self::statics::{StaticBuilderMethods, StaticMethods};
pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoCodegenMethods};
pub use self::declare::PreDefineCodegenMethods;
pub use self::intrinsic::IntrinsicCallBuilderMethods;
pub use self::misc::MiscCodegenMethods;
pub use self::statics::{StaticBuilderMethods, StaticCodegenMethods};
pub use self::type_::{
ArgAbiMethods, BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMembershipMethods,
TypeMethods,
ArgAbiBuilderMethods, BaseTypeCodegenMethods, DerivedTypeCodegenMethods,
LayoutTypeCodegenMethods, TypeCodegenMethods, TypeMembershipCodegenMethods,
};
pub use self::write::{ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
pub trait CodegenObject: Copy + PartialEq + fmt::Debug {}
impl<T: Copy + PartialEq + fmt::Debug> CodegenObject for T {}
pub trait CodegenObject = Copy + PartialEq + fmt::Debug;
pub trait CodegenMethods<'tcx>:
Backend<'tcx>
+ TypeMethods<'tcx>
+ MiscMethods<'tcx>
+ ConstMethods<'tcx>
+ StaticMethods
+ DebugInfoMethods<'tcx>
+ AsmMethods<'tcx>
+ PreDefineMethods<'tcx>
+ HasParamEnv<'tcx>
+ HasTyCtxt<'tcx>
+ HasTargetSpec
{
}
impl<'tcx, T> CodegenMethods<'tcx> for T where
Self: Backend<'tcx>
+ TypeMethods<'tcx>
+ MiscMethods<'tcx>
+ ConstMethods<'tcx>
+ StaticMethods
+ DebugInfoMethods<'tcx>
+ AsmMethods<'tcx>
+ PreDefineMethods<'tcx>
+ HasParamEnv<'tcx>
+ HasTyCtxt<'tcx>
+ HasTargetSpec
{
}
pub trait HasCodegen<'tcx>:
Backend<'tcx> + std::ops::Deref<Target = <Self as HasCodegen<'tcx>>::CodegenCx>
{
type CodegenCx: CodegenMethods<'tcx>
+ BackendTypes<
Value = Self::Value,
Function = Self::Function,
BasicBlock = Self::BasicBlock,
Type = Self::Type,
Funclet = Self::Funclet,
DIScope = Self::DIScope,
DILocation = Self::DILocation,
DIVariable = Self::DIVariable,
>;
}
pub trait CodegenMethods<'tcx> = LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
+ FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
+ TypeCodegenMethods<'tcx>
+ ConstCodegenMethods<'tcx>
+ StaticCodegenMethods
+ DebugInfoCodegenMethods<'tcx>
+ AsmCodegenMethods<'tcx>
+ PreDefineCodegenMethods<'tcx>;

View File

@ -3,7 +3,7 @@ use rustc_target::abi::Align;
use super::BackendTypes;
pub trait StaticMethods: BackendTypes {
pub trait StaticCodegenMethods: BackendTypes {
fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
fn codegen_static(&self, def_id: DefId);

View File

@ -1,17 +1,15 @@
use rustc_middle::bug;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
use rustc_middle::ty::{self, Ty};
use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
use rustc_target::abi::{AddressSpace, Float, Integer};
use super::misc::MiscMethods;
use super::{Backend, HasCodegen};
use super::misc::MiscCodegenMethods;
use super::BackendTypes;
use crate::common::TypeKind;
use crate::mir::place::PlaceRef;
// 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> {
pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes {
fn type_i8(&self) -> Self::Type;
fn type_i16(&self) -> Self::Type;
fn type_i32(&self) -> Self::Type;
@ -42,7 +40,9 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
fn val_ty(&self, v: Self::Value) -> Self::Type;
}
pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
pub trait DerivedTypeCodegenMethods<'tcx>:
BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx>
{
fn type_int(&self) -> Self::Type {
match &self.sess().target.c_int_width[..] {
"16" => self.type_i16(),
@ -100,9 +100,12 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
}
}
impl<'tcx, T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {}
impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where
Self: BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx>
{
}
pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
pub trait LayoutTypeCodegenMethods<'tcx>: BackendTypes {
/// The backend type used for a rust type when it's in memory,
/// such as when it's stack-allocated or when it's being loaded or stored.
fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
@ -114,7 +117,7 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
///
/// For nearly all types this is the same as the [`Self::backend_type`], however
/// `bool` (and other `0`-or-`1` values) are kept as `i1` in registers but as
/// [`BaseTypeMethods::type_i8`] in memory.
/// [`BaseTypeCodegenMethods::type_i8`] in memory.
///
/// Converting values between the two different backend types is done using
/// [`from_immediate`](super::BuilderMethods::from_immediate) and
@ -146,7 +149,7 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
// For backends that support CFI using type membership (i.e., testing whether a given pointer is
// associated with a type identifier).
pub trait TypeMembershipMethods<'tcx>: Backend<'tcx> {
pub trait TypeMembershipCodegenMethods<'tcx>: BackendTypes {
fn add_type_metadata(&self, _function: Self::Function, _typeid: String) {}
fn set_type_metadata(&self, _function: Self::Function, _typeid: String) {}
fn typeid_metadata(&self, _typeid: String) -> Option<Self::Value> {
@ -156,7 +159,7 @@ pub trait TypeMembershipMethods<'tcx>: Backend<'tcx> {
fn set_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {}
}
pub trait ArgAbiMethods<'tcx>: HasCodegen<'tcx> {
pub trait ArgAbiBuilderMethods<'tcx>: BackendTypes {
fn store_fn_arg(
&mut self,
arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
@ -172,12 +175,6 @@ pub trait ArgAbiMethods<'tcx>: HasCodegen<'tcx> {
fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type;
}
pub trait TypeMethods<'tcx>:
DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> + TypeMembershipMethods<'tcx>
{
}
impl<'tcx, T> TypeMethods<'tcx> for T where
Self: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> + TypeMembershipMethods<'tcx>
{
}
pub trait TypeCodegenMethods<'tcx> = DerivedTypeCodegenMethods<'tcx>
+ LayoutTypeCodegenMethods<'tcx>
+ TypeMembershipCodegenMethods<'tcx>;

View File

@ -320,7 +320,7 @@ fn run_compiler(
output_dir: odir,
ice_file,
file_loader,
locale_resources: DEFAULT_LOCALE_RESOURCES,
locale_resources: DEFAULT_LOCALE_RESOURCES.to_vec(),
lint_caps: Default::default(),
psess_created: None,
hash_untracked_state: None,
@ -1218,17 +1218,30 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
// Parse with *all* options defined in the compiler, we don't worry about
// option stability here we just want to parse as much as possible.
let mut options = getopts::Options::new();
for option in config::rustc_optgroups() {
let optgroups = config::rustc_optgroups();
for option in &optgroups {
(option.apply)(&mut options);
}
let matches = options.parse(args).unwrap_or_else(|e| {
let msg = match e {
let msg: Option<String> = match e {
getopts::Fail::UnrecognizedOption(ref opt) => CG_OPTIONS
.iter()
.map(|&(name, ..)| ('C', name))
.chain(Z_OPTIONS.iter().map(|&(name, ..)| ('Z', name)))
.find(|&(_, name)| *opt == name.replace('_', "-"))
.map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
getopts::Fail::ArgumentMissing(ref opt) => {
optgroups.iter().find(|option| option.name == opt).map(|option| {
// Print the help just for the option in question.
let mut options = getopts::Options::new();
(option.apply)(&mut options);
// getopt requires us to pass a function for joining an iterator of
// strings, even though in this case we expect exactly one string.
options.usage_with_format(|it| {
it.fold(format!("{e}\nUsage:"), |a, b| a + "\n" + &b)
})
})
}
_ => None,
};
early_dcx.early_fatal(msg.unwrap_or_else(|| e.to_string()));

View File

@ -35,6 +35,8 @@ macro raw_errln($tokens:tt) {
}
/// Signal handler installed for SIGSEGV
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#[allow(static_mut_refs)]
extern "C" fn print_stack_trace(_: libc::c_int) {
const MAX_FRAMES: usize = 256;
// Reserve data segment so we don't have to malloc in a signal handler, which might fail

View File

@ -1,14 +1,14 @@
#### Note: this error code is no longer emitted by the compiler.
You have created a reference to a mutable static.
Erroneous code example:
```compile_fail,edition2024,E0796
```
static mut X: i32 = 23;
fn work() {
let _val = unsafe { X };
}
let x_ref = unsafe { &mut X };
work();
// The next line has Undefined Behavior!

View File

@ -681,3 +681,4 @@ E0800: 0800,
// E0723, // unstable feature in `const` context
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
// E0744, // merged into E0728
// E0796, // unused error code. We use `static_mut_refs` lint instead.

View File

@ -48,7 +48,7 @@ impl Emitter for AnnotateSnippetEmitter {
fn emit_diagnostic(&mut self, mut diag: DiagInner) {
let fluent_args = to_fluent_args(diag.args.iter());
let mut suggestions = diag.suggestions.unwrap_or(vec![]);
let mut suggestions = diag.suggestions.unwrap_tag();
self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
self.fix_multispans_in_extern_macros_and_render_macro_backtrace(

View File

@ -19,13 +19,9 @@ use crate::snippet::Style;
use crate::{
CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level,
MultiSpan, StashKey, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle,
Suggestions,
};
/// Error type for `DiagInner`'s `suggestions` field, indicating that
/// `.disable_suggestions()` was called on the `DiagInner`.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
pub struct SuggestionsDisabled;
/// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of
/// `DiagArg` are converted to `FluentArgs` (consuming the collection) at the start of diagnostic
/// emission.
@ -296,7 +292,7 @@ pub struct DiagInner {
pub code: Option<ErrCode>,
pub span: MultiSpan,
pub children: Vec<Subdiag>,
pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
pub suggestions: Suggestions,
pub args: DiagArgMap,
/// This is not used for highlighting or rendering any error message. Rather, it can be used
@ -325,7 +321,7 @@ impl DiagInner {
code: None,
span: MultiSpan::new(),
children: vec![],
suggestions: Ok(vec![]),
suggestions: Suggestions::Enabled(vec![]),
args: Default::default(),
sort_span: DUMMY_SP,
is_lint: None,
@ -409,7 +405,7 @@ impl DiagInner {
&Option<ErrCode>,
&MultiSpan,
&[Subdiag],
&Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
&Suggestions,
Vec<(&DiagArgName, &DiagArgValue)>,
&Option<IsLint>,
) {
@ -823,16 +819,32 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
self
}
/// Disallow attaching suggestions this diagnostic.
/// Disallow attaching suggestions to this diagnostic.
/// Any suggestions attached e.g. with the `span_suggestion_*` methods
/// (before and after the call to `disable_suggestions`) will be ignored.
#[rustc_lint_diagnostics]
pub fn disable_suggestions(&mut self) -> &mut Self {
self.suggestions = Err(SuggestionsDisabled);
self.suggestions = Suggestions::Disabled;
self
}
/// Helper for pushing to `self.suggestions`, if available (not disable).
/// Prevent new suggestions from being added to this diagnostic.
///
/// Suggestions added before the call to `.seal_suggestions()` will be preserved
/// and new suggestions will be ignored.
#[rustc_lint_diagnostics]
pub fn seal_suggestions(&mut self) -> &mut Self {
if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
let suggestions_slice = std::mem::take(suggestions).into_boxed_slice();
self.suggestions = Suggestions::Sealed(suggestions_slice);
}
self
}
/// Helper for pushing to `self.suggestions`.
///
/// A new suggestion is added if suggestions are enabled for this diagnostic.
/// Otherwise, they are ignored.
#[rustc_lint_diagnostics]
fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
for subst in &suggestion.substitutions {
@ -846,7 +858,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
}
}
if let Ok(suggestions) = &mut self.suggestions {
if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
suggestions.push(suggestion);
}
}

Some files were not shown because too many files have changed in this diff Show More