Add codegen for global_asm! sym operands
This commit is contained in:
parent
dc345d8bff
commit
547405e801
11 changed files with 137 additions and 22 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.)
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2537,4 +2537,6 @@ extern "C" {
|
|||
remark_passes_len: usize,
|
||||
);
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
pub fn LLVMRustGetMangledName(V: &Value, out: &RustString);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue