Skip to content

Commit ef86f9d

Browse files
committed
Share part of the global_asm!() implementation between cg_ssa and cg_clif
1 parent 3efaf3b commit ef86f9d

File tree

4 files changed

+73
-138
lines changed

4 files changed

+73
-138
lines changed

compiler/rustc_codegen_cranelift/src/driver/aot.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,10 @@ fn codegen_cgu_content(
560560
}
561561
}
562562
MonoItem::GlobalAsm(item_id) => {
563-
crate::global_asm::codegen_global_asm_item(tcx, &mut cx.global_asm, item_id);
563+
rustc_codegen_ssa::base::codegen_global_asm(
564+
&mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm },
565+
item_id,
566+
);
564567
}
565568
}
566569
}

compiler/rustc_codegen_cranelift/src/global_asm.rs

-68
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ use std::sync::Arc;
88

99
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
1010
use rustc_codegen_ssa::traits::{AsmCodegenMethods, GlobalAsmOperandRef};
11-
use rustc_hir::{InlineAsmOperand, ItemId};
12-
use rustc_middle::mir::interpret::ErrorHandled;
1311
use rustc_middle::ty::TyCtxt;
1412
use rustc_middle::ty::layout::{
1513
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers,
@@ -84,72 +82,6 @@ impl<'tcx> HasTypingEnv<'tcx> for GlobalAsmContext<'_, 'tcx> {
8482
}
8583
}
8684

87-
pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, item_id: ItemId) {
88-
let item = tcx.hir_item(item_id);
89-
let rustc_hir::ItemKind::GlobalAsm { asm, .. } = item.kind else {
90-
bug!("Expected GlobalAsm found {:?}", item);
91-
};
92-
93-
// Adapted from rustc_codegen_ssa::mono_items::MonoItem::define
94-
let operands: Vec<_> = asm
95-
.operands
96-
.iter()
97-
.map(|(op, op_sp)| match *op {
98-
InlineAsmOperand::Const { ref anon_const } => {
99-
match tcx.const_eval_poly(anon_const.def_id.to_def_id()) {
100-
Ok(const_value) => {
101-
let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
102-
let string = rustc_codegen_ssa::common::asm_const_to_str(
103-
tcx,
104-
*op_sp,
105-
const_value,
106-
FullyMonomorphizedLayoutCx(tcx).layout_of(ty),
107-
);
108-
GlobalAsmOperandRef::Const { string }
109-
}
110-
Err(ErrorHandled::Reported { .. }) => {
111-
// An error has already been reported and
112-
// compilation is guaranteed to fail if execution
113-
// hits this path. So an empty string instead of
114-
// a stringified constant value will suffice.
115-
GlobalAsmOperandRef::Const { string: String::new() }
116-
}
117-
Err(ErrorHandled::TooGeneric(_)) => {
118-
span_bug!(*op_sp, "asm const cannot be resolved; too generic")
119-
}
120-
}
121-
}
122-
InlineAsmOperand::SymFn { expr } => {
123-
if cfg!(not(feature = "inline_asm_sym")) {
124-
tcx.dcx().span_err(
125-
item.span,
126-
"asm! and global_asm! sym operands are not yet supported",
127-
);
128-
}
129-
130-
let ty = tcx.typeck(item_id.owner_id).expr_ty(expr);
131-
let instance = match ty.kind() {
132-
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
133-
_ => span_bug!(*op_sp, "asm sym is not a function"),
134-
};
135-
GlobalAsmOperandRef::SymFn { instance }
136-
}
137-
InlineAsmOperand::SymStatic { path: _, def_id } => {
138-
GlobalAsmOperandRef::SymStatic { def_id }
139-
}
140-
InlineAsmOperand::In { .. }
141-
| InlineAsmOperand::Out { .. }
142-
| InlineAsmOperand::InOut { .. }
143-
| InlineAsmOperand::SplitInOut { .. }
144-
| InlineAsmOperand::Label { .. } => {
145-
span_bug!(*op_sp, "invalid operand type for global_asm!")
146-
}
147-
})
148-
.collect();
149-
150-
codegen_global_asm_inner(tcx, global_asm, asm.template, &operands, asm.options);
151-
}
152-
15385
fn codegen_global_asm_inner<'tcx>(
15486
tcx: TyCtxt<'tcx>,
15587
global_asm: &mut String,

compiler/rustc_codegen_ssa/src/base.rs

+66-1
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,21 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
1212
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
1313
use rustc_data_structures::sync::par_map;
1414
use rustc_data_structures::unord::UnordMap;
15+
use rustc_hir::ItemId;
1516
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1617
use rustc_hir::lang_items::LangItem;
1718
use rustc_metadata::EncodedMetadata;
18-
use rustc_middle::bug;
1919
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
2020
use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
2121
use rustc_middle::middle::exported_symbols::SymbolExportKind;
2222
use rustc_middle::middle::{exported_symbols, lang_items};
2323
use rustc_middle::mir::BinOp;
24+
use rustc_middle::mir::interpret::ErrorHandled;
2425
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem, MonoItemPartitions};
2526
use rustc_middle::query::Providers;
2627
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
2728
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
29+
use rustc_middle::{bug, span_bug};
2830
use rustc_session::Session;
2931
use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
3032
use rustc_span::{DUMMY_SP, Symbol, sym};
@@ -416,6 +418,69 @@ pub(crate) fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
416418
mir::codegen_mir::<Bx>(cx, instance);
417419
}
418420

421+
pub fn codegen_global_asm<'tcx, Cx>(cx: &mut Cx, item_id: ItemId)
422+
where
423+
Cx: LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>> + AsmCodegenMethods<'tcx>,
424+
{
425+
let item = cx.tcx().hir_item(item_id);
426+
if let rustc_hir::ItemKind::GlobalAsm { asm, .. } = item.kind {
427+
let operands: Vec<_> = asm
428+
.operands
429+
.iter()
430+
.map(|(op, op_sp)| match *op {
431+
rustc_hir::InlineAsmOperand::Const { ref anon_const } => {
432+
match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) {
433+
Ok(const_value) => {
434+
let ty =
435+
cx.tcx().typeck_body(anon_const.body).node_type(anon_const.hir_id);
436+
let string = common::asm_const_to_str(
437+
cx.tcx(),
438+
*op_sp,
439+
const_value,
440+
cx.layout_of(ty),
441+
);
442+
GlobalAsmOperandRef::Const { string }
443+
}
444+
Err(ErrorHandled::Reported { .. }) => {
445+
// An error has already been reported and
446+
// compilation is guaranteed to fail if execution
447+
// hits this path. So an empty string instead of
448+
// a stringified constant value will suffice.
449+
GlobalAsmOperandRef::Const { string: String::new() }
450+
}
451+
Err(ErrorHandled::TooGeneric(_)) => {
452+
span_bug!(*op_sp, "asm const cannot be resolved; too generic")
453+
}
454+
}
455+
}
456+
rustc_hir::InlineAsmOperand::SymFn { expr } => {
457+
let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr);
458+
let instance = match ty.kind() {
459+
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
460+
_ => span_bug!(*op_sp, "asm sym is not a function"),
461+
};
462+
463+
GlobalAsmOperandRef::SymFn { instance }
464+
}
465+
rustc_hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
466+
GlobalAsmOperandRef::SymStatic { def_id }
467+
}
468+
rustc_hir::InlineAsmOperand::In { .. }
469+
| rustc_hir::InlineAsmOperand::Out { .. }
470+
| rustc_hir::InlineAsmOperand::InOut { .. }
471+
| rustc_hir::InlineAsmOperand::SplitInOut { .. }
472+
| rustc_hir::InlineAsmOperand::Label { .. } => {
473+
span_bug!(*op_sp, "invalid operand type for global_asm!")
474+
}
475+
})
476+
.collect();
477+
478+
cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
479+
} else {
480+
span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
481+
}
482+
}
483+
419484
/// Creates the `main` function which will initialize the rust runtime and call
420485
/// users main function.
421486
pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(

compiler/rustc_codegen_ssa/src/mono_item.rs

+3-68
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
use rustc_hir as hir;
21
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
3-
use rustc_middle::mir::interpret::ErrorHandled;
42
use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
5-
use rustc_middle::ty::Instance;
6-
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
7-
use rustc_middle::{span_bug, ty};
3+
use rustc_middle::ty::layout::HasTyCtxt;
84
use tracing::debug;
95

6+
use crate::base;
107
use crate::mir::naked_asm;
118
use crate::traits::*;
12-
use crate::{base, common};
139

1410
pub trait MonoItemExt<'a, 'tcx> {
1511
fn define<Bx: BuilderMethods<'a, 'tcx>>(
@@ -44,68 +40,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
4440
cx.codegen_static(def_id);
4541
}
4642
MonoItem::GlobalAsm(item_id) => {
47-
let item = cx.tcx().hir_item(item_id);
48-
if let hir::ItemKind::GlobalAsm { asm, .. } = item.kind {
49-
let operands: Vec<_> = asm
50-
.operands
51-
.iter()
52-
.map(|(op, op_sp)| match *op {
53-
hir::InlineAsmOperand::Const { ref anon_const } => {
54-
match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) {
55-
Ok(const_value) => {
56-
let ty = cx
57-
.tcx()
58-
.typeck_body(anon_const.body)
59-
.node_type(anon_const.hir_id);
60-
let string = common::asm_const_to_str(
61-
cx.tcx(),
62-
*op_sp,
63-
const_value,
64-
cx.layout_of(ty),
65-
);
66-
GlobalAsmOperandRef::Const { string }
67-
}
68-
Err(ErrorHandled::Reported { .. }) => {
69-
// An error has already been reported and
70-
// compilation is guaranteed to fail if execution
71-
// hits this path. So an empty string instead of
72-
// a stringified constant value will suffice.
73-
GlobalAsmOperandRef::Const { string: String::new() }
74-
}
75-
Err(ErrorHandled::TooGeneric(_)) => {
76-
span_bug!(
77-
*op_sp,
78-
"asm const cannot be resolved; too generic"
79-
)
80-
}
81-
}
82-
}
83-
hir::InlineAsmOperand::SymFn { expr } => {
84-
let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr);
85-
let instance = match ty.kind() {
86-
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
87-
_ => span_bug!(*op_sp, "asm sym is not a function"),
88-
};
89-
90-
GlobalAsmOperandRef::SymFn { instance }
91-
}
92-
hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
93-
GlobalAsmOperandRef::SymStatic { def_id }
94-
}
95-
hir::InlineAsmOperand::In { .. }
96-
| hir::InlineAsmOperand::Out { .. }
97-
| hir::InlineAsmOperand::InOut { .. }
98-
| hir::InlineAsmOperand::SplitInOut { .. }
99-
| hir::InlineAsmOperand::Label { .. } => {
100-
span_bug!(*op_sp, "invalid operand type for global_asm!")
101-
}
102-
})
103-
.collect();
104-
105-
cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
106-
} else {
107-
span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
108-
}
43+
base::codegen_global_asm(cx, item_id);
10944
}
11045
MonoItem::Fn(instance) => {
11146
if cx

0 commit comments

Comments
 (0)