about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <17426603+bjorn3@users.noreply.github.com>2024-12-13 10:01:09 +0000
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2025-04-14 09:38:04 +0000
commit3066da813b66ffe46bbe5ea62c56bd079b158cf8 (patch)
tree15af5f831e9bc5c7d75eb261c0d7bca08ef140ac
parentf5c93fa3feb29b1161acf07191ff2684776b9abf (diff)
downloadrust-3066da813b66ffe46bbe5ea62c56bd079b158cf8.tar.gz
rust-3066da813b66ffe46bbe5ea62c56bd079b158cf8.zip
Share part of the global_asm!() implementation between cg_ssa and cg_clif
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/aot.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/src/global_asm.rs68
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs67
-rw-r--r--compiler/rustc_codegen_ssa/src/mono_item.rs71
4 files changed, 73 insertions, 138 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 1cb8f8bc439..5d07c94859f 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -570,7 +570,10 @@ fn codegen_cgu_content(
                 }
             }
             MonoItem::GlobalAsm(item_id) => {
-                crate::global_asm::codegen_global_asm_item(tcx, &mut cx.global_asm, item_id);
+                rustc_codegen_ssa::base::codegen_global_asm(
+                    &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm },
+                    item_id,
+                );
             }
         }
     }
diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs
index 18944a3be27..eef5288027c 100644
--- a/compiler/rustc_codegen_cranelift/src/global_asm.rs
+++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs
@@ -8,8 +8,6 @@ use std::sync::Arc;
 
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_codegen_ssa::traits::{AsmCodegenMethods, GlobalAsmOperandRef};
-use rustc_hir::{InlineAsmOperand, ItemId};
-use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::TyCtxt;
 use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTyCtxt, HasTypingEnv, LayoutError, LayoutOfHelpers,
@@ -84,72 +82,6 @@ impl<'tcx> HasTypingEnv<'tcx> for GlobalAsmContext<'_, 'tcx> {
     }
 }
 
-pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, item_id: ItemId) {
-    let item = tcx.hir_item(item_id);
-    let rustc_hir::ItemKind::GlobalAsm { asm, .. } = item.kind else {
-        bug!("Expected GlobalAsm found {:?}", item);
-    };
-
-    // Adapted from rustc_codegen_ssa::mono_items::MonoItem::define
-    let operands: Vec<_> = asm
-        .operands
-        .iter()
-        .map(|(op, op_sp)| match *op {
-            InlineAsmOperand::Const { ref anon_const } => {
-                match tcx.const_eval_poly(anon_const.def_id.to_def_id()) {
-                    Ok(const_value) => {
-                        let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id);
-                        let string = rustc_codegen_ssa::common::asm_const_to_str(
-                            tcx,
-                            *op_sp,
-                            const_value,
-                            FullyMonomorphizedLayoutCx(tcx).layout_of(ty),
-                        );
-                        GlobalAsmOperandRef::Const { string }
-                    }
-                    Err(ErrorHandled::Reported { .. }) => {
-                        // An error has already been reported and
-                        // compilation is guaranteed to fail if execution
-                        // hits this path. So an empty string instead of
-                        // a stringified constant value will suffice.
-                        GlobalAsmOperandRef::Const { string: String::new() }
-                    }
-                    Err(ErrorHandled::TooGeneric(_)) => {
-                        span_bug!(*op_sp, "asm const cannot be resolved; too generic")
-                    }
-                }
-            }
-            InlineAsmOperand::SymFn { expr } => {
-                if cfg!(not(feature = "inline_asm_sym")) {
-                    tcx.dcx().span_err(
-                        item.span,
-                        "asm! and global_asm! sym operands are not yet supported",
-                    );
-                }
-
-                let ty = tcx.typeck(item_id.owner_id).expr_ty(expr);
-                let instance = match ty.kind() {
-                    &ty::FnDef(def_id, args) => Instance::new(def_id, args),
-                    _ => span_bug!(*op_sp, "asm sym is not a function"),
-                };
-                GlobalAsmOperandRef::SymFn { instance }
-            }
-            InlineAsmOperand::SymStatic { path: _, def_id } => {
-                GlobalAsmOperandRef::SymStatic { def_id }
-            }
-            InlineAsmOperand::In { .. }
-            | InlineAsmOperand::Out { .. }
-            | InlineAsmOperand::InOut { .. }
-            | InlineAsmOperand::SplitInOut { .. }
-            | InlineAsmOperand::Label { .. } => {
-                span_bug!(*op_sp, "invalid operand type for global_asm!")
-            }
-        })
-        .collect();
-
-    codegen_global_asm_inner(tcx, global_asm, asm.template, &operands, asm.options);
-}
-
 fn codegen_global_asm_inner<'tcx>(
     tcx: TyCtxt<'tcx>,
     global_asm: &mut String,
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 12b7a487455..f5480da2808 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -12,19 +12,21 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
 use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
 use rustc_data_structures::unord::UnordMap;
+use rustc_hir::ItemId;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::lang_items::LangItem;
 use rustc_metadata::EncodedMetadata;
-use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
 use rustc_middle::middle::{exported_symbols, lang_items};
 use rustc_middle::mir::BinOp;
+use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, MonoItem, MonoItemPartitions};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
+use rustc_middle::{bug, span_bug};
 use rustc_session::Session;
 use rustc_session::config::{self, CrateType, EntryFnType, OutputType};
 use rustc_span::{DUMMY_SP, Symbol, sym};
@@ -417,6 +419,69 @@ pub(crate) fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
     mir::codegen_mir::<Bx>(cx, instance);
 }
 
+pub fn codegen_global_asm<'tcx, Cx>(cx: &mut Cx, item_id: ItemId)
+where
+    Cx: LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>> + AsmCodegenMethods<'tcx>,
+{
+    let item = cx.tcx().hir_item(item_id);
+    if let rustc_hir::ItemKind::GlobalAsm { asm, .. } = item.kind {
+        let operands: Vec<_> = asm
+            .operands
+            .iter()
+            .map(|(op, op_sp)| match *op {
+                rustc_hir::InlineAsmOperand::Const { ref anon_const } => {
+                    match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) {
+                        Ok(const_value) => {
+                            let ty =
+                                cx.tcx().typeck_body(anon_const.body).node_type(anon_const.hir_id);
+                            let string = common::asm_const_to_str(
+                                cx.tcx(),
+                                *op_sp,
+                                const_value,
+                                cx.layout_of(ty),
+                            );
+                            GlobalAsmOperandRef::Const { string }
+                        }
+                        Err(ErrorHandled::Reported { .. }) => {
+                            // An error has already been reported and
+                            // compilation is guaranteed to fail if execution
+                            // hits this path. So an empty string instead of
+                            // a stringified constant value will suffice.
+                            GlobalAsmOperandRef::Const { string: String::new() }
+                        }
+                        Err(ErrorHandled::TooGeneric(_)) => {
+                            span_bug!(*op_sp, "asm const cannot be resolved; too generic")
+                        }
+                    }
+                }
+                rustc_hir::InlineAsmOperand::SymFn { expr } => {
+                    let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr);
+                    let instance = match ty.kind() {
+                        &ty::FnDef(def_id, args) => Instance::new(def_id, args),
+                        _ => span_bug!(*op_sp, "asm sym is not a function"),
+                    };
+
+                    GlobalAsmOperandRef::SymFn { instance }
+                }
+                rustc_hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
+                    GlobalAsmOperandRef::SymStatic { def_id }
+                }
+                rustc_hir::InlineAsmOperand::In { .. }
+                | rustc_hir::InlineAsmOperand::Out { .. }
+                | rustc_hir::InlineAsmOperand::InOut { .. }
+                | rustc_hir::InlineAsmOperand::SplitInOut { .. }
+                | rustc_hir::InlineAsmOperand::Label { .. } => {
+                    span_bug!(*op_sp, "invalid operand type for global_asm!")
+                }
+            })
+            .collect();
+
+        cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
+    } else {
+        span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
+    }
+}
+
 /// Creates the `main` function which will initialize the rust runtime and call
 /// users main function.
 pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
diff --git a/compiler/rustc_codegen_ssa/src/mono_item.rs b/compiler/rustc_codegen_ssa/src/mono_item.rs
index 647da01aa9e..c2067e52afe 100644
--- a/compiler/rustc_codegen_ssa/src/mono_item.rs
+++ b/compiler/rustc_codegen_ssa/src/mono_item.rs
@@ -1,15 +1,11 @@
-use rustc_hir as hir;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
-use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
-use rustc_middle::ty::Instance;
-use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
-use rustc_middle::{span_bug, ty};
+use rustc_middle::ty::layout::HasTyCtxt;
 use tracing::debug;
 
+use crate::base;
 use crate::mir::naked_asm;
 use crate::traits::*;
-use crate::{base, common};
 
 pub trait MonoItemExt<'a, 'tcx> {
     fn define<Bx: BuilderMethods<'a, 'tcx>>(
@@ -44,68 +40,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
                 cx.codegen_static(def_id);
             }
             MonoItem::GlobalAsm(item_id) => {
-                let item = cx.tcx().hir_item(item_id);
-                if let hir::ItemKind::GlobalAsm { asm, .. } = item.kind {
-                    let operands: Vec<_> = asm
-                        .operands
-                        .iter()
-                        .map(|(op, op_sp)| match *op {
-                            hir::InlineAsmOperand::Const { ref anon_const } => {
-                                match cx.tcx().const_eval_poly(anon_const.def_id.to_def_id()) {
-                                    Ok(const_value) => {
-                                        let ty = cx
-                                            .tcx()
-                                            .typeck_body(anon_const.body)
-                                            .node_type(anon_const.hir_id);
-                                        let string = common::asm_const_to_str(
-                                            cx.tcx(),
-                                            *op_sp,
-                                            const_value,
-                                            cx.layout_of(ty),
-                                        );
-                                        GlobalAsmOperandRef::Const { string }
-                                    }
-                                    Err(ErrorHandled::Reported { .. }) => {
-                                        // An error has already been reported and
-                                        // compilation is guaranteed to fail if execution
-                                        // hits this path. So an empty string instead of
-                                        // a stringified constant value will suffice.
-                                        GlobalAsmOperandRef::Const { string: String::new() }
-                                    }
-                                    Err(ErrorHandled::TooGeneric(_)) => {
-                                        span_bug!(
-                                            *op_sp,
-                                            "asm const cannot be resolved; too generic"
-                                        )
-                                    }
-                                }
-                            }
-                            hir::InlineAsmOperand::SymFn { expr } => {
-                                let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr);
-                                let instance = match ty.kind() {
-                                    &ty::FnDef(def_id, args) => Instance::new(def_id, args),
-                                    _ => span_bug!(*op_sp, "asm sym is not a function"),
-                                };
-
-                                GlobalAsmOperandRef::SymFn { instance }
-                            }
-                            hir::InlineAsmOperand::SymStatic { path: _, def_id } => {
-                                GlobalAsmOperandRef::SymStatic { def_id }
-                            }
-                            hir::InlineAsmOperand::In { .. }
-                            | hir::InlineAsmOperand::Out { .. }
-                            | hir::InlineAsmOperand::InOut { .. }
-                            | hir::InlineAsmOperand::SplitInOut { .. }
-                            | hir::InlineAsmOperand::Label { .. } => {
-                                span_bug!(*op_sp, "invalid operand type for global_asm!")
-                            }
-                        })
-                        .collect();
-
-                    cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
-                } else {
-                    span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
-                }
+                base::codegen_global_asm(cx, item_id);
             }
             MonoItem::Fn(instance) => {
                 if cx