Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Spiking on asm! + pointer as const #132045

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
23 changes: 16 additions & 7 deletions compiler/rustc_codegen_gcc/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ 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, AsmCodegenMethods, BaseTypeCodegenMethods, BuilderMethods,
GlobalAsmOperandRef, InlineAsmOperandRef,
AsmBuilderMethods, AsmCodegenMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, GlobalAsmOperandRef, InlineAsmOperandRef
};
use rustc_middle::bug;
use rustc_middle::ty::Instance;
Expand Down Expand Up @@ -282,7 +281,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
// or byte count suffixes (x86 Windows).
constants_len += self.tcx.symbol_name(instance).name.len();
}
InlineAsmOperandRef::SymStatic { def_id } => {
InlineAsmOperandRef::SymStatic { def_id, offset } => {
// TODO(@Amanieu): Additional mangling is needed on
// some targets to add a leading underscore (Mach-O).
constants_len +=
Expand Down Expand Up @@ -379,11 +378,18 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
});
}

InlineAsmOperandRef::SymStatic { def_id } => {
InlineAsmOperandRef::SymStatic { def_id, offset } => {
let val = self.cx.get_static(def_id).get_address(None);
let val = if offset.bytes() > 0 {
let offset = self.cx.const_int(self.int_type, offset.bytes().try_into().expect("offset is out of range"));
val + offset
} else {
val
};
inputs.push(AsmInOperand {
constraint: "X".into(),
rust_idx,
val: self.cx.get_static(def_id).get_address(None),
val,
});
}

Expand Down Expand Up @@ -472,7 +478,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
template_str.push_str(name);
}

InlineAsmOperandRef::SymStatic { def_id } => {
InlineAsmOperandRef::SymStatic { def_id, offset } => {
// TODO(@Amanieu): Additional mangling is needed on
// some targets to add a leading underscore (Mach-O).
let instance = Instance::mono(self.tcx, def_id);
Expand Down Expand Up @@ -833,10 +839,13 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
template_str.push_str(name);
}

GlobalAsmOperandRef::SymStatic { def_id } => {
GlobalAsmOperandRef::SymStatic { def_id, offset } => {
// TODO(antoyo): set the global variable as used.
// TODO(@Amanieu): Additional mangling is needed on
// some targets to add a leading underscore (Mach-O).
if offset.bytes() > 0 {
bug!("We don't know how to handle statics with non-zero offset")
}
let instance = Instance::mono(self.tcx, def_id);
let name = self.tcx.symbol_name(instance).name;
template_str.push_str(name);
Expand Down
18 changes: 15 additions & 3 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,15 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
op_idx.insert(idx, constraints.len());
constraints.push("s".to_string());
}
InlineAsmOperandRef::SymStatic { def_id } => {
inputs.push(self.cx.get_static(def_id));
InlineAsmOperandRef::SymStatic { def_id, offset } => {
let llval = self.cx.get_static(def_id);
let llval = if offset.bytes() > 0 {
let offset = self.const_usize(offset.bytes());
self.ptradd(llval, offset)
} else {
llval
};
inputs.push(llval);
op_idx.insert(idx, constraints.len());
constraints.push("s".to_string());
}
Expand Down Expand Up @@ -395,7 +402,12 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
.expect("symbol is not valid UTF-8");
template_str.push_str(&symbol);
}
GlobalAsmOperandRef::SymStatic { def_id } => {
GlobalAsmOperandRef::SymStatic { def_id, offset } => {
if offset.bytes() > 0 {
bug!(
"We don't know how to codegen on static with a non-zero offset"
);
}
let llval = self
.renamed_statics
.borrow()
Expand Down
59 changes: 45 additions & 14 deletions compiler/rustc_codegen_ssa/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![allow(non_camel_case_types)]

use rustc_abi::Size;
use rustc_hir::LangItem;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::{self, Instance, TyCtxt};
use rustc_middle::{bug, mir, span_bug};
Expand Down Expand Up @@ -155,27 +157,56 @@ pub(crate) fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
}

pub fn asm_const_to_str<'tcx>(
pub enum AsmConstOperandRef {
Const { string: String },
Static { def_id: DefId, offset: Size, ptr_size: u8 },
}

pub fn asm_const_to_opr_ref<'tcx>(
tcx: TyCtxt<'tcx>,
sp: Span,
const_value: mir::ConstValue<'tcx>,
ty_and_layout: TyAndLayout<'tcx>,
) -> String {
) -> AsmConstOperandRef {
let mir::ConstValue::Scalar(scalar) = const_value else {
span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value)
};
let value = scalar.assert_scalar_int().to_bits(ty_and_layout.size);
match ty_and_layout.ty.kind() {
ty::Uint(_) => value.to_string(),
ty::Int(int_ty) => match int_ty.normalize(tcx.sess.target.pointer_width) {
ty::IntTy::I8 => (value as i8).to_string(),
ty::IntTy::I16 => (value as i16).to_string(),
ty::IntTy::I32 => (value as i32).to_string(),
ty::IntTy::I64 => (value as i64).to_string(),
ty::IntTy::I128 => (value as i128).to_string(),
ty::IntTy::Isize => unreachable!(),
},
_ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty),
match scalar.try_to_scalar_int() {
Ok(value) => {
let value = value.to_bits(ty_and_layout.size);
AsmConstOperandRef::Const {
string: match ty_and_layout.ty.kind() {
ty::Uint(_) => value.to_string(),
ty::Int(int_ty) => match int_ty.normalize(tcx.sess.target.pointer_width) {
ty::IntTy::I8 => (value as i8).to_string(),
ty::IntTy::I16 => (value as i16).to_string(),
ty::IntTy::I32 => (value as i32).to_string(),
ty::IntTy::I64 => (value as i64).to_string(),
ty::IntTy::I128 => (value as i128).to_string(),
ty::IntTy::Isize => unreachable!(),
},
_ => span_bug!(sp, "asm const has bad type {}", ty_and_layout.ty),
},
}
}
Err(mir::interpret::Scalar::Ptr(ptr, sz)) => {
let (alloc, offset) = ptr.into_parts();
match tcx.global_alloc(alloc) {
mir::interpret::GlobalAlloc::Memory(alloc) => {
span_bug!(sp, "unexpected memory for `{alloc:?}` for a const operand")
}
mir::interpret::GlobalAlloc::Function { instance } => {
span_bug!(sp, "unexpected function for `{instance}` for a const operand")
}
mir::interpret::GlobalAlloc::VTable(ty, _) => {
span_bug!(sp, "unexpected vtable for `{ty}` for a const operand")
}
mir::interpret::GlobalAlloc::Static(def_id) => {
AsmConstOperandRef::Static { def_id, offset, ptr_size: sz }
}
}
}
Err(scalar) => span_bug!(sp, "unexpected `{:#?}` for a const operand", scalar),
}
}

Expand Down
36 changes: 21 additions & 15 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::cmp;

use rustc_abi::Size;
use rustc_ast as ast;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::lang_items::LangItem;
Expand Down Expand Up @@ -1167,31 +1168,36 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
mir::InlineAsmOperand::Const { ref value } => {
let const_value = self.eval_mir_constant(value);
let string = common::asm_const_to_str(
match common::asm_const_to_opr_ref(
bx.tcx(),
span,
const_value,
bx.layout_of(value.ty()),
);
InlineAsmOperandRef::Const { string }
) {
common::AsmConstOperandRef::Const { string } => {
InlineAsmOperandRef::Const { string }
}
common::AsmConstOperandRef::Static { def_id, offset, ptr_size: _ } => {
InlineAsmOperandRef::SymStatic { def_id, offset }
}
}
}
mir::InlineAsmOperand::SymFn { ref value } => {
let const_ = self.monomorphize(value.const_);
if let ty::FnDef(def_id, args) = *const_.ty().kind() {
let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
args,
)
.unwrap();
InlineAsmOperandRef::SymFn { instance }
} else {
let ty::FnDef(def_id, args) = *const_.ty().kind() else {
span_bug!(span, "invalid type for asm sym (fn)");
}
};
let instance = ty::Instance::resolve_for_fn_ptr(
bx.tcx(),
ty::ParamEnv::reveal_all(),
def_id,
args,
)
.unwrap();
InlineAsmOperandRef::SymFn { instance }
}
mir::InlineAsmOperand::SymStatic { def_id } => {
InlineAsmOperandRef::SymStatic { def_id }
InlineAsmOperandRef::SymStatic { def_id, offset: Size::ZERO }
}
mir::InlineAsmOperand::Label { target_index } => {
InlineAsmOperandRef::Label { label: self.llbb(targets[target_index]) }
Expand Down
17 changes: 13 additions & 4 deletions compiler/rustc_codegen_ssa/src/mono_item.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustc_abi::Size;
use rustc_hir as hir;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
Expand Down Expand Up @@ -47,13 +48,21 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
.tcx()
.typeck_body(anon_const.body)
.node_type(anon_const.hir_id);
let string = common::asm_const_to_str(
match common::asm_const_to_opr_ref(
cx.tcx(),
*op_sp,
const_value,
cx.layout_of(ty),
);
GlobalAsmOperandRef::Const { string }
) {
common::AsmConstOperandRef::Const { string } => {
GlobalAsmOperandRef::Const { string }
}
common::AsmConstOperandRef::Static {
def_id,
offset,
ptr_size: _,
} => GlobalAsmOperandRef::SymStatic { def_id, offset },
}
}
Err(ErrorHandled::Reported { .. }) => {
// An error has already been reported and
Expand Down Expand Up @@ -83,7 +92,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
GlobalAsmOperandRef::SymFn { instance }
}
hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
GlobalAsmOperandRef::SymStatic { def_id }
GlobalAsmOperandRef::SymStatic { def_id, offset: Size::ZERO }
}
hir::InlineAsmOperand::In { .. }
| hir::InlineAsmOperand::Out { .. }
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_ssa/src/traits/asm.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use rustc_abi::Size;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::def_id::DefId;
use rustc_middle::ty::Instance;
Expand Down Expand Up @@ -33,6 +34,7 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> {
},
SymStatic {
def_id: DefId,
offset: Size,
},
Label {
label: B::BasicBlock,
Expand All @@ -43,7 +45,7 @@ pub enum InlineAsmOperandRef<'tcx, B: BackendTypes + ?Sized> {
pub enum GlobalAsmOperandRef<'tcx> {
Const { string: String },
SymFn { instance: Instance<'tcx> },
SymStatic { def_id: DefId },
SymStatic { def_id: DefId, offset: Size },
}

pub trait AsmBuilderMethods<'tcx>: BackendTypes {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
hir::InlineAsmOperand::Const { anon_const } => {
debug_assert_matches!(
self.tcx.type_of(anon_const.def_id).instantiate_identity().kind(),
ty::Error(_) | ty::Int(_) | ty::Uint(_)
ty::Error(_) | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..)
);
}
// Typeck has checked that SymFn refers to a function.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
match ty.kind() {
ty::Error(_) => ty,
ty::Int(_) | ty::Uint(_) => ty,
ty::RawPtr(..) => ty,
_ => {
let guar = tcx
.dcx()
Expand Down
Loading