Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 39 additions & 39 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::borrow::Borrow;
use std::cmp;

use libc::c_uint;
Expand All @@ -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,
};
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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,
},
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>) -> ! {
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 3 additions & 5 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}
}
Expand Down Expand Up @@ -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,
);
Expand Down
45 changes: 1 addition & 44 deletions compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId};

/// Must match the layout of `LLVMRustCounterKind`.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
Expand All @@ -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`.
Expand Down Expand Up @@ -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)]
Expand Down
27 changes: 25 additions & 2 deletions compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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++.
Expand Down
27 changes: 19 additions & 8 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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> {
Expand Down Expand Up @@ -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);
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
Loading
Loading