Rollup merge of #147327 - Zalathar:inherent, r=workingjubilee

cg_llvm: Remove inherent methods from several LLVM FFI types

This is mainly motivated by rust-lang/rust#142897, which proposes to move the LLVM FFI bindings out of `rustc_codegen_llvm` and into `rustc_llvm`, which is arguably the more correct place for them from a linking perspective.

---

In order to perform that migration, all of the types used in FFI signatures also need to be moved. However, several of those types have inherent methods that convert from backend-independent types to LLVM FFI types.

Moving the inherent methods as-is would require adding a lot of otherwise-unnecessary dependencies to `rustc_llvm`. And we can't leave them behind as-is, because inherent methods can't be defined in another crate.

Therefore, this PR replaces several of those inherent methods with either extension trait methods or free functions.
This commit is contained in:
Jubilee 2025-10-05 11:59:23 -07:00 committed by GitHub
commit d8fc465bbb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 225 additions and 225 deletions

View file

@ -1,4 +1,3 @@
use std::borrow::Borrow;
use std::cmp;
use libc::c_uint;
@ -13,7 +12,7 @@ use rustc_codegen_ssa::traits::*;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::{bug, ty};
use rustc_session::config;
use rustc_session::{Session, config};
use rustc_target::callconv::{
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, PassMode,
};
@ -400,7 +399,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
}
fn llvm_cconv(&self, cx: &CodegenCx<'ll, 'tcx>) -> llvm::CallConv {
llvm::CallConv::from_conv(self.conv, cx.tcx.sess.target.arch.borrow())
to_llvm_calling_convention(cx.tcx.sess, self.conv)
}
fn apply_attrs_llfn(
@ -663,43 +662,44 @@ impl AbiBuilderMethods for Builder<'_, '_, '_> {
}
}
impl llvm::CallConv {
pub(crate) fn from_conv(conv: CanonAbi, arch: &str) -> Self {
match conv {
CanonAbi::C | CanonAbi::Rust => llvm::CCallConv,
CanonAbi::RustCold => llvm::PreserveMost,
// Functions with this calling convention can only be called from assembly, but it is
// possible to declare an `extern "custom"` block, so the backend still needs a calling
// convention for declaring foreign functions.
CanonAbi::Custom => llvm::CCallConv,
CanonAbi::GpuKernel => {
if arch == "amdgpu" {
llvm::AmdgpuKernel
} else if arch == "nvptx64" {
llvm::PtxKernel
} else {
panic!("Architecture {arch} does not support GpuKernel calling convention");
}
/// Determines the appropriate [`llvm::CallConv`] to use for a given function
/// ABI, for the current target.
pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm::CallConv {
match abi {
CanonAbi::C | CanonAbi::Rust => llvm::CCallConv,
CanonAbi::RustCold => llvm::PreserveMost,
// Functions with this calling convention can only be called from assembly, but it is
// possible to declare an `extern "custom"` block, so the backend still needs a calling
// convention for declaring foreign functions.
CanonAbi::Custom => llvm::CCallConv,
CanonAbi::GpuKernel => {
let arch = sess.target.arch.as_ref();
if arch == "amdgpu" {
llvm::AmdgpuKernel
} else if arch == "nvptx64" {
llvm::PtxKernel
} else {
panic!("Architecture {arch} does not support GpuKernel calling convention");
}
CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
InterruptKind::Avr => llvm::AvrInterrupt,
InterruptKind::AvrNonBlocking => llvm::AvrNonBlockingInterrupt,
InterruptKind::Msp430 => llvm::Msp430Intr,
InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => llvm::CCallConv,
InterruptKind::X86 => llvm::X86_Intr,
},
CanonAbi::Arm(arm_call) => match arm_call {
ArmCall::Aapcs => llvm::ArmAapcsCallConv,
ArmCall::CCmseNonSecureCall | ArmCall::CCmseNonSecureEntry => llvm::CCallConv,
},
CanonAbi::X86(x86_call) => match x86_call {
X86Call::Fastcall => llvm::X86FastcallCallConv,
X86Call::Stdcall => llvm::X86StdcallCallConv,
X86Call::SysV64 => llvm::X86_64_SysV,
X86Call::Thiscall => llvm::X86_ThisCall,
X86Call::Vectorcall => llvm::X86_VectorCall,
X86Call::Win64 => llvm::X86_64_Win64,
},
}
CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind {
InterruptKind::Avr => llvm::AvrInterrupt,
InterruptKind::AvrNonBlocking => llvm::AvrNonBlockingInterrupt,
InterruptKind::Msp430 => llvm::Msp430Intr,
InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => llvm::CCallConv,
InterruptKind::X86 => llvm::X86_Intr,
},
CanonAbi::Arm(arm_call) => match arm_call {
ArmCall::Aapcs => llvm::ArmAapcsCallConv,
ArmCall::CCmseNonSecureCall | ArmCall::CCmseNonSecureEntry => llvm::CCallConv,
},
CanonAbi::X86(x86_call) => match x86_call {
X86Call::Fastcall => llvm::X86FastcallCallConv,
X86Call::Stdcall => llvm::X86StdcallCallConv,
X86Call::SysV64 => llvm::X86_64_SysV,
X86Call::Thiscall => llvm::X86_ThisCall,
X86Call::Vectorcall => llvm::X86_VectorCall,
X86Call::Win64 => llvm::X86_64_Win64,
},
}
}

View file

@ -14,7 +14,7 @@ use rustc_symbol_mangling::mangle_internal_symbol;
use crate::attributes::llfn_attrs_from_instance;
use crate::builder::SBuilder;
use crate::declare::declare_simple_fn;
use crate::llvm::{self, FALSE, TRUE, Type, Value};
use crate::llvm::{self, FALSE, FromGeneric, TRUE, Type, Value};
use crate::{SimpleCx, attributes, debuginfo};
pub(crate) unsafe fn codegen(

View file

@ -44,7 +44,7 @@ use crate::errors::{
};
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
use crate::llvm::{self, DiagnosticInfo};
use crate::type_::Type;
use crate::type_::llvm_type_ptr;
use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util};
pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> ! {
@ -1160,7 +1160,7 @@ fn create_msvc_imps(
// underscores added in front).
let prefix = if cgcx.target_arch == "x86" { "\x01__imp__" } else { "\x01__imp_" };
let ptr_ty = Type::ptr_llcx(llcx);
let ptr_ty = llvm_type_ptr(llcx);
let globals = base::iter_globals(llmod)
.filter(|&val| {
llvm::get_linkage(val) == llvm::Linkage::ExternalLinkage && !llvm::is_declaration(val)

View file

@ -36,7 +36,8 @@ use crate::attributes;
use crate::common::Funclet;
use crate::context::{CodegenCx, FullCx, GenericCx, SCx};
use crate::llvm::{
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, GEPNoWrapFlags, Metadata, TRUE, ToLlvmBool,
self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, FromGeneric, GEPNoWrapFlags, Metadata, TRUE,
ToLlvmBool,
};
use crate::type_::Type;
use crate::type_of::LayoutLlvmExt;

View file

@ -31,6 +31,7 @@ use rustc_symbol_mangling::mangle_internal_symbol;
use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel};
use smallvec::SmallVec;
use crate::abi::to_llvm_calling_convention;
use crate::back::write::to_llvm_code_model;
use crate::callee::get_fn;
use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
@ -740,7 +741,7 @@ impl<'ll> SimpleCx<'ll> {
llcx: &'ll llvm::Context,
pointer_size: Size,
) -> Self {
let isize_ty = llvm::Type::ix_llcx(llcx, pointer_size.bits());
let isize_ty = llvm::LLVMIntTypeInContext(llcx, pointer_size.bits() as c_uint);
Self(SCx { llmod, llcx, isize_ty }, PhantomData)
}
}
@ -901,10 +902,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
if self.get_declared_value(entry_name).is_none() {
let llfn = self.declare_entry_fn(
entry_name,
llvm::CallConv::from_conv(
self.sess().target.entry_abi,
self.sess().target.arch.borrow(),
),
to_llvm_calling_convention(self.sess(), self.sess().target.entry_abi),
llvm::UnnamedAddr::Global,
fn_type,
);

View file

@ -1,5 +1,3 @@
use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId};
/// Must match the layout of `LLVMRustCounterKind`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
@ -26,30 +24,12 @@ pub(crate) enum CounterKind {
pub(crate) struct Counter {
// Important: The layout (order and types of fields) must match its C++ counterpart.
pub(crate) kind: CounterKind,
id: u32,
pub(crate) id: u32,
}
impl Counter {
/// A `Counter` of kind `Zero`. For this counter kind, the `id` is not used.
pub(crate) const ZERO: Self = Self { kind: CounterKind::Zero, id: 0 };
/// Constructs a new `Counter` of kind `CounterValueReference`.
pub(crate) fn counter_value_reference(counter_id: CounterId) -> Self {
Self { kind: CounterKind::CounterValueReference, id: counter_id.as_u32() }
}
/// Constructs a new `Counter` of kind `Expression`.
pub(crate) fn expression(expression_id: ExpressionId) -> Self {
Self { kind: CounterKind::Expression, id: expression_id.as_u32() }
}
pub(crate) fn from_term(term: CovTerm) -> Self {
match term {
CovTerm::Zero => Self::ZERO,
CovTerm::Counter(id) => Self::counter_value_reference(id),
CovTerm::Expression(id) => Self::expression(id),
}
}
}
/// Corresponds to enum `llvm::coverage::CounterExpression::ExprKind`.
@ -94,29 +74,6 @@ pub(crate) struct CoverageSpan {
pub(crate) end_col: u32,
}
/// Holds tables of the various region types in one struct.
///
/// Don't pass this struct across FFI; pass the individual region tables as
/// pointer/length pairs instead.
///
/// Each field name has a `_regions` suffix for improved readability after
/// exhaustive destructing, which ensures that all region types are handled.
#[derive(Clone, Debug, Default)]
pub(crate) struct Regions {
pub(crate) code_regions: Vec<CodeRegion>,
pub(crate) expansion_regions: Vec<ExpansionRegion>,
pub(crate) branch_regions: Vec<BranchRegion>,
}
impl Regions {
/// Returns true if none of this structure's tables contain any regions.
pub(crate) fn has_no_regions(&self) -> bool {
let Self { code_regions, expansion_regions, branch_regions } = self;
code_regions.is_empty() && expansion_regions.is_empty() && branch_regions.is_empty()
}
}
/// Must match the layout of `LLVMRustCoverageCodeRegion`.
#[derive(Clone, Debug)]
#[repr(C)]

View file

@ -57,12 +57,35 @@ pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef<str>]) -> Vec<u8
})
}
/// Holds tables of the various region types in one struct.
///
/// Don't pass this struct across FFI; pass the individual region tables as
/// pointer/length pairs instead.
///
/// Each field name has a `_regions` suffix for improved readability after
/// exhaustive destructing, which ensures that all region types are handled.
#[derive(Clone, Debug, Default)]
pub(crate) struct Regions {
pub(crate) code_regions: Vec<ffi::CodeRegion>,
pub(crate) expansion_regions: Vec<ffi::ExpansionRegion>,
pub(crate) branch_regions: Vec<ffi::BranchRegion>,
}
impl Regions {
/// Returns true if none of this structure's tables contain any regions.
pub(crate) fn has_no_regions(&self) -> bool {
let Self { code_regions, expansion_regions, branch_regions } = self;
code_regions.is_empty() && expansion_regions.is_empty() && branch_regions.is_empty()
}
}
pub(crate) fn write_function_mappings_to_buffer(
virtual_file_mapping: &[u32],
expressions: &[ffi::CounterExpression],
regions: &ffi::Regions,
regions: &Regions,
) -> Vec<u8> {
let ffi::Regions { code_regions, expansion_regions, branch_regions } = regions;
let Regions { code_regions, expansion_regions, branch_regions } = regions;
// SAFETY:
// - All types are FFI-compatible and have matching representations in Rust/C++.

View file

@ -10,8 +10,8 @@ use std::sync::Arc;
use rustc_abi::Align;
use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods as _, ConstCodegenMethods};
use rustc_middle::mir::coverage::{
BasicCoverageBlock, CovTerm, CoverageIdsInfo, Expression, FunctionCoverageInfo, Mapping,
MappingKind, Op,
BasicCoverageBlock, CounterId, CovTerm, CoverageIdsInfo, Expression, ExpressionId,
FunctionCoverageInfo, Mapping, MappingKind, Op,
};
use rustc_middle::ty::{Instance, TyCtxt};
use rustc_span::{SourceFile, Span};
@ -36,7 +36,7 @@ pub(crate) struct CovfunRecord<'tcx> {
virtual_file_mapping: VirtualFileMapping,
expressions: Vec<ffi::CounterExpression>,
regions: ffi::Regions,
regions: llvm_cov::Regions,
}
impl<'tcx> CovfunRecord<'tcx> {
@ -64,7 +64,7 @@ pub(crate) fn prepare_covfun_record<'tcx>(
is_used,
virtual_file_mapping: VirtualFileMapping::default(),
expressions,
regions: ffi::Regions::default(),
regions: llvm_cov::Regions::default(),
};
fill_region_tables(tcx, fn_cov_info, ids_info, &mut covfun);
@ -77,10 +77,21 @@ pub(crate) fn prepare_covfun_record<'tcx>(
Some(covfun)
}
pub(crate) fn counter_for_term(term: CovTerm) -> ffi::Counter {
use ffi::Counter;
match term {
CovTerm::Zero => Counter::ZERO,
CovTerm::Counter(id) => {
Counter { kind: ffi::CounterKind::CounterValueReference, id: CounterId::as_u32(id) }
}
CovTerm::Expression(id) => {
Counter { kind: ffi::CounterKind::Expression, id: ExpressionId::as_u32(id) }
}
}
}
/// Convert the function's coverage-counter expressions into a form suitable for FFI.
fn prepare_expressions(ids_info: &CoverageIdsInfo) -> Vec<ffi::CounterExpression> {
let counter_for_term = ffi::Counter::from_term;
// We know that LLVM will optimize out any unused expressions before
// producing the final coverage map, so there's no need to do the same
// thing on the Rust side unless we're confident we can do much better.
@ -113,7 +124,7 @@ fn fill_region_tables<'tcx>(
} else {
CovTerm::Zero
};
ffi::Counter::from_term(term)
counter_for_term(term)
};
// Currently a function's mappings must all be in the same file, so use the
@ -136,7 +147,7 @@ fn fill_region_tables<'tcx>(
if discard_all { None } else { spans::make_coords(source_map, &source_file, span) }
};
let ffi::Regions {
let llvm_cov::Regions {
code_regions,
expansion_regions: _, // FIXME(Zalathar): Fill out support for expansion regions
branch_regions,

View file

@ -37,11 +37,11 @@ use crate::common::{AsCCharPtr, CodegenCx};
use crate::debuginfo::dwarf_const;
use crate::debuginfo::metadata::type_map::build_type_with_children;
use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind};
use crate::llvm;
use crate::llvm::debuginfo::{
DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock,
DIScope, DIType, DebugEmissionKind, DebugNameTableKind,
};
use crate::llvm::{self, FromGeneric};
use crate::value::Value;
impl PartialEq for llvm::Metadata {

View file

@ -26,7 +26,7 @@ use crate::abi::FnAbiLlvmExt;
use crate::common::AsCCharPtr;
use crate::context::{CodegenCx, GenericCx, SCx, SimpleCx};
use crate::llvm::AttributePlace::Function;
use crate::llvm::Visibility;
use crate::llvm::{FromGeneric, Visibility};
use crate::type_::Type;
use crate::value::Value;
use crate::{attributes, llvm};

View file

@ -0,0 +1,115 @@
//! Conversions from backend-independent data types to/from LLVM FFI types.
use rustc_codegen_ssa::common::{AtomicRmwBinOp, IntPredicate, RealPredicate};
use rustc_middle::ty::AtomicOrdering;
use rustc_session::config::DebugInfo;
use rustc_target::spec::SymbolVisibility;
use crate::llvm;
/// Helper trait for converting backend-independent types to LLVM-specific
/// types, for FFI purposes.
pub(crate) trait FromGeneric<T> {
fn from_generic(other: T) -> Self;
}
impl FromGeneric<SymbolVisibility> for llvm::Visibility {
fn from_generic(visibility: SymbolVisibility) -> Self {
match visibility {
SymbolVisibility::Hidden => Self::Hidden,
SymbolVisibility::Protected => Self::Protected,
SymbolVisibility::Interposable => Self::Default,
}
}
}
impl FromGeneric<IntPredicate> for llvm::IntPredicate {
fn from_generic(int_pred: IntPredicate) -> Self {
match int_pred {
IntPredicate::IntEQ => Self::IntEQ,
IntPredicate::IntNE => Self::IntNE,
IntPredicate::IntUGT => Self::IntUGT,
IntPredicate::IntUGE => Self::IntUGE,
IntPredicate::IntULT => Self::IntULT,
IntPredicate::IntULE => Self::IntULE,
IntPredicate::IntSGT => Self::IntSGT,
IntPredicate::IntSGE => Self::IntSGE,
IntPredicate::IntSLT => Self::IntSLT,
IntPredicate::IntSLE => Self::IntSLE,
}
}
}
impl FromGeneric<RealPredicate> for llvm::RealPredicate {
fn from_generic(real_pred: RealPredicate) -> Self {
match real_pred {
RealPredicate::RealPredicateFalse => Self::RealPredicateFalse,
RealPredicate::RealOEQ => Self::RealOEQ,
RealPredicate::RealOGT => Self::RealOGT,
RealPredicate::RealOGE => Self::RealOGE,
RealPredicate::RealOLT => Self::RealOLT,
RealPredicate::RealOLE => Self::RealOLE,
RealPredicate::RealONE => Self::RealONE,
RealPredicate::RealORD => Self::RealORD,
RealPredicate::RealUNO => Self::RealUNO,
RealPredicate::RealUEQ => Self::RealUEQ,
RealPredicate::RealUGT => Self::RealUGT,
RealPredicate::RealUGE => Self::RealUGE,
RealPredicate::RealULT => Self::RealULT,
RealPredicate::RealULE => Self::RealULE,
RealPredicate::RealUNE => Self::RealUNE,
RealPredicate::RealPredicateTrue => Self::RealPredicateTrue,
}
}
}
impl FromGeneric<AtomicRmwBinOp> for llvm::AtomicRmwBinOp {
fn from_generic(op: AtomicRmwBinOp) -> Self {
match op {
AtomicRmwBinOp::AtomicXchg => Self::AtomicXchg,
AtomicRmwBinOp::AtomicAdd => Self::AtomicAdd,
AtomicRmwBinOp::AtomicSub => Self::AtomicSub,
AtomicRmwBinOp::AtomicAnd => Self::AtomicAnd,
AtomicRmwBinOp::AtomicNand => Self::AtomicNand,
AtomicRmwBinOp::AtomicOr => Self::AtomicOr,
AtomicRmwBinOp::AtomicXor => Self::AtomicXor,
AtomicRmwBinOp::AtomicMax => Self::AtomicMax,
AtomicRmwBinOp::AtomicMin => Self::AtomicMin,
AtomicRmwBinOp::AtomicUMax => Self::AtomicUMax,
AtomicRmwBinOp::AtomicUMin => Self::AtomicUMin,
}
}
}
impl FromGeneric<AtomicOrdering> for llvm::AtomicOrdering {
fn from_generic(ordering: AtomicOrdering) -> Self {
match ordering {
AtomicOrdering::Relaxed => Self::Monotonic,
AtomicOrdering::Acquire => Self::Acquire,
AtomicOrdering::Release => Self::Release,
AtomicOrdering::AcqRel => Self::AcquireRelease,
AtomicOrdering::SeqCst => Self::SequentiallyConsistent,
}
}
}
impl FromGeneric<DebugInfo> for llvm::debuginfo::DebugEmissionKind {
fn from_generic(kind: DebugInfo) -> Self {
// We should be setting LLVM's emission kind to `LineTablesOnly` if
// we are compiling with "limited" debuginfo. However, some of the
// existing tools relied on slightly more debuginfo being generated than
// would be the case with `LineTablesOnly`, and we did not want to break
// these tools in a "drive-by fix", without a good idea or plan about
// what limited debuginfo should exactly look like. So for now we are
// instead adding a new debuginfo option "line-tables-only" so as to
// not break anything and to allow users to have 'limited' debug info.
//
// See https://github.com/rust-lang/rust/issues/60020 for details.
match kind {
DebugInfo::None => Self::NoDebug,
DebugInfo::LineDirectivesOnly => Self::DebugDirectivesOnly,
DebugInfo::LineTablesOnly => Self::LineTablesOnly,
DebugInfo::Limited | DebugInfo::Full => Self::FullDebug,
}
}
}

View file

@ -20,7 +20,6 @@ use std::ptr;
use bitflags::bitflags;
use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t};
use rustc_macros::TryFromU32;
use rustc_target::spec::SymbolVisibility;
use super::RustString;
use super::debuginfo::{
@ -220,16 +219,6 @@ pub(crate) enum Visibility {
Protected = 2,
}
impl Visibility {
pub(crate) fn from_generic(visibility: SymbolVisibility) -> Self {
match visibility {
SymbolVisibility::Hidden => Visibility::Hidden,
SymbolVisibility::Protected => Visibility::Protected,
SymbolVisibility::Interposable => Visibility::Default,
}
}
}
/// LLVMUnnamedAddr
#[repr(C)]
pub(crate) enum UnnamedAddr {
@ -319,24 +308,6 @@ pub(crate) enum IntPredicate {
IntSLE = 41,
}
impl IntPredicate {
pub(crate) fn from_generic(intpre: rustc_codegen_ssa::common::IntPredicate) -> Self {
use rustc_codegen_ssa::common::IntPredicate as Common;
match intpre {
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,
}
}
}
/// LLVMRealPredicate
#[derive(Copy, Clone)]
#[repr(C)]
@ -359,30 +330,6 @@ pub(crate) enum RealPredicate {
RealPredicateTrue = 15,
}
impl RealPredicate {
pub(crate) fn from_generic(realp: rustc_codegen_ssa::common::RealPredicate) -> Self {
use rustc_codegen_ssa::common::RealPredicate as Common;
match realp {
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,
}
}
}
/// Must match the layout of `LLVMTypeKind`.
///
/// Use [`RawEnum<TypeKind>`] for values of `LLVMTypeKind` returned from LLVM,
@ -458,25 +405,6 @@ pub(crate) enum AtomicRmwBinOp {
AtomicUMin = 10,
}
impl AtomicRmwBinOp {
pub(crate) fn from_generic(op: rustc_codegen_ssa::common::AtomicRmwBinOp) -> Self {
use rustc_codegen_ssa::common::AtomicRmwBinOp as Common;
match op {
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,
}
}
}
/// LLVMAtomicOrdering
#[derive(Copy, Clone)]
#[repr(C)]
@ -493,19 +421,6 @@ pub(crate) enum AtomicOrdering {
SequentiallyConsistent = 7,
}
impl AtomicOrdering {
pub(crate) fn from_generic(ao: rustc_middle::ty::AtomicOrdering) -> Self {
use rustc_middle::ty::AtomicOrdering as Common;
match ao {
Common::Relaxed => Self::Monotonic,
Common::Acquire => Self::Acquire,
Common::Release => Self::Release,
Common::AcqRel => Self::AcquireRelease,
Common::SeqCst => Self::SequentiallyConsistent,
}
}
}
/// LLVMRustFileType
#[derive(Copy, Clone)]
#[repr(C)]
@ -940,28 +855,6 @@ pub(crate) mod debuginfo {
DebugDirectivesOnly,
}
impl DebugEmissionKind {
pub(crate) fn from_generic(kind: rustc_session::config::DebugInfo) -> Self {
// We should be setting LLVM's emission kind to `LineTablesOnly` if
// we are compiling with "limited" debuginfo. However, some of the
// existing tools relied on slightly more debuginfo being generated than
// would be the case with `LineTablesOnly`, and we did not want to break
// these tools in a "drive-by fix", without a good idea or plan about
// what limited debuginfo should exactly look like. So for now we are
// instead adding a new debuginfo option "line-tables-only" so as to
// not break anything and to allow users to have 'limited' debug info.
//
// See https://github.com/rust-lang/rust/issues/60020 for details.
use rustc_session::config::DebugInfo;
match kind {
DebugInfo::None => DebugEmissionKind::NoDebug,
DebugInfo::LineDirectivesOnly => DebugEmissionKind::DebugDirectivesOnly,
DebugInfo::LineTablesOnly => DebugEmissionKind::LineTablesOnly,
DebugInfo::Limited | DebugInfo::Full => DebugEmissionKind::FullDebug,
}
}
}
/// LLVMRustDebugNameTableKind
#[derive(Clone, Copy)]
#[repr(C)]
@ -1061,7 +954,7 @@ unsafe extern "C" {
pub(crate) fn LLVMInt16TypeInContext(C: &Context) -> &Type;
pub(crate) fn LLVMInt32TypeInContext(C: &Context) -> &Type;
pub(crate) fn LLVMInt64TypeInContext(C: &Context) -> &Type;
pub(crate) fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> &Type;
pub(crate) safe fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> &Type;
pub(crate) fn LLVMGetIntTypeWidth(IntegerTy: &Type) -> c_uint;
@ -1090,7 +983,7 @@ unsafe extern "C" {
) -> &'a Type;
// Operations on array, pointer, and vector types (sequence types)
pub(crate) fn LLVMPointerTypeInContext(C: &Context, AddressSpace: c_uint) -> &Type;
pub(crate) safe fn LLVMPointerTypeInContext(C: &Context, AddressSpace: c_uint) -> &Type;
pub(crate) fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type;
pub(crate) fn LLVMGetElementType(Ty: &Type) -> &Type;

View file

@ -11,10 +11,12 @@ use rustc_llvm::RustString;
pub(crate) use self::CallConv::*;
pub(crate) use self::CodeGenOptSize::*;
pub(crate) use self::conversions::*;
pub(crate) use self::ffi::*;
pub(crate) use self::metadata_kind::*;
use crate::common::AsCCharPtr;
mod conversions;
pub(crate) mod diagnostic;
pub(crate) mod enzyme_ffi;
mod ffi;

View file

@ -63,7 +63,7 @@ impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
///x Creates an integer type with the given number of bits, e.g., i24
pub(crate) fn type_ix(&self, num_bits: u64) -> &'ll Type {
unsafe { llvm::LLVMIntTypeInContext(self.llcx(), num_bits as c_uint) }
llvm::LLVMIntTypeInContext(self.llcx(), num_bits as c_uint)
}
pub(crate) fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type {
@ -178,7 +178,7 @@ impl<'ll, CX: Borrow<SCx<'ll>>> BaseTypeCodegenMethods for GenericCx<'ll, CX> {
}
fn type_i128(&self) -> &'ll Type {
unsafe { llvm::LLVMIntTypeInContext(self.llcx(), 128) }
self.type_ix(128)
}
fn type_isize(&self) -> &'ll Type {
@ -210,11 +210,11 @@ impl<'ll, CX: Borrow<SCx<'ll>>> BaseTypeCodegenMethods for GenericCx<'ll, CX> {
}
fn type_ptr(&self) -> &'ll Type {
self.type_ptr_ext(AddressSpace::ZERO)
llvm_type_ptr(self.llcx())
}
fn type_ptr_ext(&self, address_space: AddressSpace) -> &'ll Type {
unsafe { llvm::LLVMPointerTypeInContext(self.llcx(), address_space.0) }
llvm_type_ptr_in_address_space(self.llcx(), address_space)
}
fn element_type(&self, ty: &'ll Type) -> &'ll Type {
@ -253,15 +253,15 @@ impl<'ll, CX: Borrow<SCx<'ll>>> BaseTypeCodegenMethods for GenericCx<'ll, CX> {
}
}
impl Type {
/// Creates an integer type with the given number of bits, e.g., i24
pub(crate) fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> &Type {
unsafe { llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint) }
}
pub(crate) fn llvm_type_ptr(llcx: &llvm::Context) -> &Type {
llvm_type_ptr_in_address_space(llcx, AddressSpace::ZERO)
}
pub(crate) fn ptr_llcx(llcx: &llvm::Context) -> &Type {
unsafe { llvm::LLVMPointerTypeInContext(llcx, AddressSpace::ZERO.0) }
}
pub(crate) fn llvm_type_ptr_in_address_space<'ll>(
llcx: &'ll llvm::Context,
addr_space: AddressSpace,
) -> &'ll Type {
llvm::LLVMPointerTypeInContext(llcx, addr_space.0)
}
impl<'ll, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {