Skip to content
Open
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
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a,
span,
"Unexpected CopyNonOverlapping, should only appear after lower_intrinsics",
),
NonDivergingIntrinsic::CodeviewAnnotation(_) => {}
},
// Only relevant for mir typeck
StatementKind::AscribeUserType(..) => {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
self.consume_operand(location, dst);
self.consume_operand(location, count);
}
// Doesn't have any language semantics
StatementKind::Intrinsic(NonDivergingIntrinsic::CodeviewAnnotation(_)) => {}
// Only relevant for mir typeck
StatementKind::AscribeUserType(..)
// Only relevant for liveness and unsafeck
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
StatementKind::Intrinsic(NonDivergingIntrinsic::Assume(..))
| StatementKind::Intrinsic(NonDivergingIntrinsic::CodeviewAnnotation(..))
| StatementKind::FakeRead(..)
| StatementKind::StorageLive(..)
| StatementKind::StorageDead(..)
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,8 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
StatementKind::Intrinsic(intrinsic) => match &**intrinsic {
// We ignore `assume` intrinsics, they are only useful for optimizations
NonDivergingIntrinsic::Assume(_) => {}
// codeview_annotation is supported only by the LLVM backend
NonDivergingIntrinsic::CodeviewAnnotation(_) => {}
NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
src,
dst,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
StatementKind::Intrinsic(intrinsic) => match **intrinsic {
NonDivergingIntrinsic::CopyNonOverlapping(..) => return None,
NonDivergingIntrinsic::Assume(..) => {}
NonDivergingIntrinsic::CodeviewAnnotation(..) => {}
},
// conservative handling
StatementKind::Assign(_)
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,11 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
fn retag_mem(&mut self, _ptr: Self::Value, _info: &RetagInfo<Self::Value>) {
unimplemented!()
}

fn codeview_annotation(&mut self, _strings: &[&[u8]]) {
// No-op as codeview_annotation is supported only by the LLVM backend.
// GCC has no intrinsic we can lower to
}
}

impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
Expand Down
20 changes: 19 additions & 1 deletion compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use crate::diagnostics::{
OffloadWithoutEnable, OffloadWithoutFatLTO, UnknownIntrinsic,
};
use crate::intrinsic::ty::typetree::fnc_typetrees;
use crate::llvm::{self, Attribute, AttributePlace, Type, Value};
use crate::llvm::{self, Attribute, AttributePlace, Metadata, Type, Value};
use crate::type_of::LayoutLlvmExt;
use crate::va_arg::emit_va_arg;

Expand Down Expand Up @@ -1072,6 +1072,24 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
fn retag_mem(&mut self, ptr: Self::Value, info: &RetagInfo<Self::Value>) {
codegen_retag_inner(self, "__rust_retag_mem", ptr, info);
}

fn codeview_annotation(&mut self, strings: &[&[u8]]) {
if !self.cx.sess().target.is_like_msvc {
return;
}

if strings.is_empty() {
bug!("codeview_annotation with empty strings should not reach codegen");
}

let md_strings: Vec<&Metadata> =
strings.iter().map(|s| self.cx.create_metadata(s)).collect();
let md_tuple = self.cx.md_node_in_context(&md_strings);
let md_value = self.cx.get_metadata_value(md_tuple);
let (fn_ty, intrinsic_fn) = self.cx.get_intrinsic("llvm.codeview.annotation".into(), &[]);

self.call(fn_ty, None, None, intrinsic_fn, &[md_value], None, None);
}
}

fn llvm_arch_for(rust_arch: &Arch) -> Option<&'static str> {
Expand Down
28 changes: 28 additions & 0 deletions compiler/rustc_codegen_ssa/src/mir/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,34 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

bx.memcpy(dst, align, src, align, bytes, crate::MemFlags::empty(), None);
}
mir::StatementKind::Intrinsic(NonDivergingIntrinsic::CodeviewAnnotation(
ref operands,
)) => {
if operands.is_empty() {
bug!("expected at least one operand in codeview annotation");
}

let strings = operands
.iter()
.map(|op| {
if let mir::Operand::Constant(c) = op {
let val = self.eval_mir_constant(c);
let mir::ConstValue::Slice { alloc_id, meta } = val else {
bug!("`CodeviewAnnotation` operand is not a `ConstValue::Slice`");
};
bx.tcx()
.global_alloc(alloc_id)
.unwrap_memory()
.inner()
.inspect_with_uninit_and_ptr_outside_interpreter(0..meta as usize)
} else {
bug!("`CodeviewAnnotation` operand is not a constant");
}
})
.collect::<Vec<_>>();

bx.codeview_annotation(&strings);
}
mir::StatementKind::FakeRead(..)
| mir::StatementKind::AscribeUserType(..)
| mir::StatementKind::ConstEvalCounter
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes {
fn retag_mem(&mut self, place: Self::Value, info: &RetagInfo<Self::Value>);
/// Trait method used to retag a pointer that has been loaded into a register.
fn retag_reg(&mut self, ptr: Self::Value, info: &RetagInfo<Self::Value>) -> Self::Value;
/// Emit a codeview_annotation with the given string bytes.
fn codeview_annotation(&mut self, strings: &[&[u8]]);
}
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let count = self.eval_operand(count, None)?;
self.copy_intrinsic(&src, &dst, &count, /* nonoverlapping */ true)
}
NonDivergingIntrinsic::CodeviewAnnotation(_) => interp_ok(()),
}
}

Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
| sym::ceilf32
| sym::ceilf64
| sym::ceilf128
| sym::codeview_annotation
| sym::cold_path
| sym::const_eval_select
| sym::contract_check_ensures
Expand Down Expand Up @@ -297,6 +298,20 @@ pub(crate) fn check_intrinsic_type(
sym::amdgpu_dispatch_ptr => (0, 0, vec![], Ty::new_imm_ptr(tcx, tcx.types.unit)),
sym::unreachable => (0, 0, vec![], tcx.types.never),
sym::breakpoint => (0, 0, vec![], tcx.types.unit),
sym::codeview_annotation => {
let str_ref = Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, tcx.types.str_);
let slice_ty = Ty::new_slice(tcx, str_ref);
let ref_to_slice = Ty::new_imm_ref(
tcx,
ty::Region::new_bound(
tcx,
ty::INNERMOST,
ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::Anon },
),
slice_ty,
);
(0, 0, vec![ref_to_slice], tcx.types.unit)
}
sym::size_of | sym::align_of | sym::variant_count => (1, 0, vec![], tcx.types.usize),
sym::size_of_val | sym::align_of_val => {
(1, 0, vec![Ty::new_imm_ptr(tcx, param(0))], tcx.types.usize)
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,16 @@ impl Display for NonDivergingIntrinsic<'_> {
Self::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
write!(f, "copy_nonoverlapping(dst = {dst:?}, src = {src:?}, count = {count:?})")
}
Self::CodeviewAnnotation(operands) => {
write!(f, "codeview_annotation(")?;
for (i, op) in operands.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{op:?}")?;
}
write!(f, ")")
}
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,12 @@ pub enum NonDivergingIntrinsic<'tcx> {
/// **Needs clarification**: Is this typed or not, ie is there a typed load and store involved?
/// I vaguely remember Ralf saying somewhere that he thought it should not be.
CopyNonOverlapping(CopyNonOverlapping<'tcx>),

/// Denotes a call to the intrinsic function `codeview_annotation`.
///
/// Gets lowered to `llvm.codeview.annotation` on LLVM for MSVC targets.
/// Is a no-op on other targets and backends.
CodeviewAnnotation(Box<[Operand<'tcx>]>),
}

/// Describes whether this operand use performs a retag.
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,11 @@ macro_rules! make_mir_visitor {
self.visit_operand(dst, location);
self.visit_operand(count, location);
}
NonDivergingIntrinsic::CodeviewAnnotation(operands) => {
for op in & $($mutability)? **operands {
self.visit_operand(op, location);
}
}
}
}
StatementKind::BackwardIncompatibleDropHint { place, .. } => {
Expand Down
Loading
Loading