about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/allocator.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/allocator.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/allocator.rs182
1 files changed, 90 insertions, 92 deletions
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index ca123334fca..48d4a9cf803 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -9,7 +9,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{DebugInfo, OomStrategy};
 
 use crate::debuginfo;
-use crate::llvm::{self, False, True};
+use crate::llvm::{self, Context, False, Module, True, Type};
 use crate::ModuleLlvm;
 
 pub(crate) unsafe fn codegen(
@@ -29,7 +29,6 @@ pub(crate) unsafe fn codegen(
     };
     let i8 = llvm::LLVMInt8TypeInContext(llcx);
     let i8p = llvm::LLVMPointerTypeInContext(llcx, 0);
-    let void = llvm::LLVMVoidTypeInContext(llcx);
 
     if kind == AllocatorKind::Default {
         for method in ALLOCATOR_METHODS {
@@ -54,102 +53,25 @@ pub(crate) unsafe fn codegen(
                     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 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);
+            let from_name = global_fn_name(method.name);
+            let to_name = default_fn_name(method.name);
+
+            create_wrapper_function(tcx, llcx, llmod, &from_name, &to_name, &args, output, false);
         }
     }
 
     // rust alloc error handler
-    let args = [usize, usize]; // size, align
-
-    let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False);
-    let name = "__rust_alloc_error_handler";
-    let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
-    // -> ! DIFlagNoReturn
-    let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx);
-    attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
-
-    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 = 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]);
-    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,
+    create_wrapper_function(
+        tcx,
+        llcx,
+        llmod,
+        "__rust_alloc_error_handler",
+        &alloc_error_handler_name(alloc_error_handler_kind),
+        &[usize, usize], // size, align
+        None,
+        true,
     );
-    llvm::LLVMSetTailCall(ret, True);
-    llvm::LLVMBuildRetVoid(llbuilder);
-    llvm::LLVMDisposeBuilder(llbuilder);
 
     // __rust_alloc_error_handler_should_panic
     let name = OomStrategy::SYMBOL;
@@ -175,3 +97,79 @@ pub(crate) unsafe fn codegen(
         dbg_cx.finalize(tcx.sess);
     }
 }
+
+fn create_wrapper_function(
+    tcx: TyCtxt<'_>,
+    llcx: &Context,
+    llmod: &Module,
+    from_name: &str,
+    to_name: &str,
+    args: &[&Type],
+    output: Option<&Type>,
+    no_return: bool,
+) {
+    unsafe {
+        let ty = llvm::LLVMFunctionType(
+            output.unwrap_or_else(|| llvm::LLVMVoidTypeInContext(llcx)),
+            args.as_ptr(),
+            args.len() as c_uint,
+            False,
+        );
+        let llfn = llvm::LLVMRustGetOrInsertFunction(
+            llmod,
+            from_name.as_ptr().cast(),
+            from_name.len(),
+            ty,
+        );
+        let no_return = if no_return {
+            // -> ! DIFlagNoReturn
+            let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx);
+            attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
+            Some(no_return)
+        } else {
+            None
+        };
+
+        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 =
+            llvm::LLVMRustGetOrInsertFunction(llmod, to_name.as_ptr().cast(), to_name.len(), ty);
+        if let Some(no_return) = no_return {
+            // -> ! DIFlagNoReturn
+            attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
+        }
+        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);
+    }
+}