summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_llvm/src/allocator.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_codegen_llvm/src/allocator.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/allocator.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/allocator.rs145
1 files changed, 79 insertions, 66 deletions
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index 668d92927..a57508815 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -1,10 +1,12 @@
use crate::attributes;
use libc::c_uint;
-use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
+use rustc_ast::expand::allocator::{
+ alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind, AllocatorTy,
+ ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE,
+};
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{DebugInfo, OomStrategy};
-use rustc_span::symbol::sym;
use crate::debuginfo;
use crate::llvm::{self, False, True};
@@ -29,75 +31,78 @@ pub(crate) unsafe fn codegen(
let i8p = llvm::LLVMPointerType(i8, 0);
let void = llvm::LLVMVoidTypeInContext(llcx);
- for method in ALLOCATOR_METHODS {
- let mut args = Vec::with_capacity(method.inputs.len());
- for ty in method.inputs.iter() {
- match *ty {
- AllocatorTy::Layout => {
- args.push(usize); // size
- args.push(usize); // align
+ if kind == AllocatorKind::Default {
+ for method in ALLOCATOR_METHODS {
+ let mut args = Vec::with_capacity(method.inputs.len());
+ for ty in method.inputs.iter() {
+ match *ty {
+ AllocatorTy::Layout => {
+ args.push(usize); // size
+ args.push(usize); // align
+ }
+ AllocatorTy::Ptr => args.push(i8p),
+ AllocatorTy::Usize => args.push(usize),
+
+ AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
}
- AllocatorTy::Ptr => args.push(i8p),
- AllocatorTy::Usize => args.push(usize),
-
- AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
}
- }
- let output = match method.output {
- AllocatorTy::ResultPtr => Some(i8p),
- AllocatorTy::Unit => None,
+ let output = match method.output {
+ AllocatorTy::ResultPtr => Some(i8p),
+ AllocatorTy::Unit => None,
- AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
- panic!("invalid allocator output")
+ AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
+ panic!("invalid allocator output")
+ }
+ };
+ let ty = llvm::LLVMFunctionType(
+ output.unwrap_or(void),
+ args.as_ptr(),
+ args.len() as c_uint,
+ False,
+ );
+ let name = global_fn_name(method.name);
+ let llfn =
+ llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
+
+ if tcx.sess.target.default_hidden_visibility {
+ llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
+ }
+ if tcx.sess.must_emit_unwind_tables() {
+ let uwtable = attributes::uwtable_attr(llcx);
+ attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
}
- };
- let ty = llvm::LLVMFunctionType(
- output.unwrap_or(void),
- args.as_ptr(),
- args.len() as c_uint,
- False,
- );
- let name = format!("__rust_{}", method.name);
- let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
-
- if tcx.sess.target.default_hidden_visibility {
- llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
- }
- if tcx.sess.must_emit_unwind_tables() {
- let uwtable = attributes::uwtable_attr(llcx);
- attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
- }
- let callee = kind.fn_name(method.name);
- let callee =
- llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
- llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
-
- let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
-
- let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
- llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
- let args = args
- .iter()
- .enumerate()
- .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
- .collect::<Vec<_>>();
- let ret = llvm::LLVMRustBuildCall(
- llbuilder,
- ty,
- callee,
- args.as_ptr(),
- args.len() as c_uint,
- [].as_ptr(),
- 0 as c_uint,
- );
- llvm::LLVMSetTailCall(ret, True);
- if output.is_some() {
- llvm::LLVMBuildRet(llbuilder, ret);
- } else {
- llvm::LLVMBuildRetVoid(llbuilder);
+ let callee = default_fn_name(method.name);
+ let callee =
+ llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
+ llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
+
+ let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
+
+ let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
+ llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
+ let args = args
+ .iter()
+ .enumerate()
+ .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
+ .collect::<Vec<_>>();
+ let ret = llvm::LLVMRustBuildCall(
+ llbuilder,
+ ty,
+ callee,
+ args.as_ptr(),
+ args.len() as c_uint,
+ [].as_ptr(),
+ 0 as c_uint,
+ );
+ llvm::LLVMSetTailCall(ret, True);
+ if output.is_some() {
+ llvm::LLVMBuildRet(llbuilder, ret);
+ } else {
+ llvm::LLVMBuildRetVoid(llbuilder);
+ }
+ llvm::LLVMDisposeBuilder(llbuilder);
}
- llvm::LLVMDisposeBuilder(llbuilder);
}
// rust alloc error handler
@@ -118,7 +123,7 @@ pub(crate) unsafe fn codegen(
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
}
- let callee = alloc_error_handler_kind.fn_name(sym::oom);
+ let callee = alloc_error_handler_name(alloc_error_handler_kind);
let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
// -> ! DIFlagNoReturn
attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
@@ -156,6 +161,14 @@ pub(crate) unsafe fn codegen(
let llval = llvm::LLVMConstInt(i8, val as u64, False);
llvm::LLVMSetInitializer(ll_g, llval);
+ let name = NO_ALLOC_SHIM_IS_UNSTABLE;
+ let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);
+ if tcx.sess.target.default_hidden_visibility {
+ llvm::LLVMRustSetVisibility(ll_g, llvm::Visibility::Hidden);
+ }
+ let llval = llvm::LLVMConstInt(i8, 0, False);
+ llvm::LLVMSetInitializer(ll_g, llval);
+
if tcx.sess.opts.debuginfo != DebugInfo::None {
let dbg_cx = debuginfo::CodegenUnitDebugContext::new(llmod);
debuginfo::metadata::build_compile_unit_di_node(tcx, module_name, &dbg_cx);