mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 01:34:21 +00:00
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:
commit
a3fea24971
@ -4630,7 +4630,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfmt-nightly"
|
||||
version = "1.7.1"
|
||||
version = "1.8.0"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.9.2",
|
||||
"anyhow",
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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::*;
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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 =>
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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],
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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>,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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>>,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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> {}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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]) =>
|
||||
{
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
&[
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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`.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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};
|
||||
|
@ -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};
|
||||
|
@ -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>,
|
||||
|
@ -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 {
|
||||
|
@ -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};
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
@ -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};
|
||||
|
@ -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>)>,
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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],
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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>>,
|
||||
|
@ -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.
|
||||
|
@ -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 };
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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",
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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>>,
|
||||
|
@ -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>,
|
||||
|
@ -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:?}"));
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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>>>> {
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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)) => {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -60,7 +60,7 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
|
||||
);
|
||||
}
|
||||
|
||||
pub trait AsmMethods<'tcx> {
|
||||
pub trait AsmCodegenMethods<'tcx> {
|
||||
fn codegen_global_asm(
|
||||
&self,
|
||||
template: &[InlineAsmTemplatePiece],
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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>,
|
||||
|
@ -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,
|
||||
|
@ -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`.
|
||||
|
@ -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>;
|
||||
}
|
||||
|
@ -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>;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>;
|
||||
|
@ -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()));
|
||||
|
@ -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
|
||||
|
@ -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!
|
||||
|
@ -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.
|
||||
|
@ -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(
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user