Add codegen for global_asm! sym operands

This commit is contained in:
Amanieu d'Antras 2022-03-01 00:53:25 +00:00
parent dc345d8bff
commit 547405e801
11 changed files with 137 additions and 22 deletions

View file

@ -312,11 +312,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
}
impl AsmMethods for CodegenCx<'_, '_> {
impl<'tcx> AsmMethods<'tcx> for CodegenCx<'_, 'tcx> {
fn codegen_global_asm(
&self,
template: &[InlineAsmTemplatePiece],
operands: &[GlobalAsmOperandRef],
operands: &[GlobalAsmOperandRef<'tcx>],
options: InlineAsmOptions,
_line_spans: &[Span],
) {
@ -342,6 +342,29 @@ impl AsmMethods for CodegenCx<'_, '_> {
// here unlike normal inline assembly.
template_str.push_str(string);
}
GlobalAsmOperandRef::SymFn { instance } => {
let llval = self.get_fn(instance);
self.add_compiler_used_global(llval);
let symbol = llvm::build_string(|s| unsafe {
llvm::LLVMRustGetMangledName(llval, s);
})
.expect("symbol is not valid UTF-8");
template_str.push_str(&symbol);
}
GlobalAsmOperandRef::SymStatic { def_id } => {
let llval = self
.renamed_statics
.borrow()
.get(&def_id)
.copied()
.unwrap_or_else(|| self.get_static(def_id));
self.add_compiler_used_global(llval);
let symbol = llvm::build_string(|s| unsafe {
llvm::LLVMRustGetMangledName(llval, s);
})
.expect("symbol is not valid UTF-8");
template_str.push_str(&symbol);
}
}
}
}

View file

@ -99,15 +99,6 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs);
}
// Run replace-all-uses-with for statics that need it
for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() {
unsafe {
let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g));
llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
llvm::LLVMDeleteGlobal(old_g);
}
}
// Finalize code coverage by injecting the coverage map. Note, the coverage map will
// also be added to the `llvm.compiler.used` variable, created next.
if cx.sess().instrument_coverage() {
@ -122,6 +113,16 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen
cx.create_compiler_used_variable()
}
// Run replace-all-uses-with for statics that need it. This must
// happen after the llvm.used variables are created.
for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() {
unsafe {
let bitcast = llvm::LLVMConstPointerCast(new_g, cx.val_ty(old_g));
llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
llvm::LLVMDeleteGlobal(old_g);
}
}
// Finalize debuginfo
if cx.sess().opts.debuginfo != DebugInfo::None {
cx.debuginfo_finalize();

View file

@ -412,6 +412,13 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
llvm::LLVMRustSetLinkage(new_g, linkage);
llvm::LLVMRustSetVisibility(new_g, visibility);
// The old global has had its name removed but is returned by
// get_static since it is in the instance cache. Provide an
// alternative lookup that points to the new global so that
// global_asm! can compute the correct mangled symbol name
// for the global.
self.renamed_statics.borrow_mut().insert(def_id, new_g);
// To avoid breaking any invariants, we leave around the old
// global for the moment; we'll replace all references to it
// with the new global later. (See base::codegen_backend.)

View file

@ -14,6 +14,7 @@ use rustc_codegen_ssa::traits::*;
use rustc_data_structures::base_n;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
@ -105,6 +106,12 @@ pub struct CodegenCx<'ll, 'tcx> {
/// A counter that is used for generating local symbol names
local_gen_sym_counter: Cell<usize>,
/// `codegen_static` will sometimes create a second global variable with a
/// different type and clear the symbol name of the original global.
/// `global_asm!` needs to be able to find this new global so that it can
/// compute the correct mangled symbol name to insert into the asm.
pub renamed_statics: RefCell<FxHashMap<DefId, &'ll Value>>,
}
pub struct TypeLowering<'ll> {
@ -436,6 +443,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
rust_try_fn: Cell::new(None),
intrinsics: Default::default(),
local_gen_sym_counter: Cell::new(0),
renamed_statics: Default::default(),
}
}

View file

@ -2537,4 +2537,6 @@ extern "C" {
remark_passes_len: usize,
);
#[allow(improper_ctypes)]
pub fn LLVMRustGetMangledName(V: &Value, out: &RustString);
}