Skip to content

Commit 644e806

Browse files
committed
Auto merge of #113722 - bjorn3:allocator_shim_refactor, r=jackh726
Extract a create_wrapper_function for use in allocator shim writing This deduplicates some logic and makes it easier to follow what wrappers are produced. In the future it may allow moving the code to determine which wrappers to create to cg_ssa.
2 parents 2b26bf5 + 49ae3b7 commit 644e806

File tree

1 file changed

+90
-92
lines changed

1 file changed

+90
-92
lines changed

compiler/rustc_codegen_llvm/src/allocator.rs

+90-92
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::ty::TyCtxt;
99
use rustc_session::config::{DebugInfo, OomStrategy};
1010

1111
use crate::debuginfo;
12-
use crate::llvm::{self, False, True};
12+
use crate::llvm::{self, Context, False, Module, True, Type};
1313
use crate::ModuleLlvm;
1414

1515
pub(crate) unsafe fn codegen(
@@ -29,7 +29,6 @@ pub(crate) unsafe fn codegen(
2929
};
3030
let i8 = llvm::LLVMInt8TypeInContext(llcx);
3131
let i8p = llvm::LLVMPointerTypeInContext(llcx, 0);
32-
let void = llvm::LLVMVoidTypeInContext(llcx);
3332

3433
if kind == AllocatorKind::Default {
3534
for method in ALLOCATOR_METHODS {
@@ -54,102 +53,25 @@ pub(crate) unsafe fn codegen(
5453
panic!("invalid allocator output")
5554
}
5655
};
57-
let ty = llvm::LLVMFunctionType(
58-
output.unwrap_or(void),
59-
args.as_ptr(),
60-
args.len() as c_uint,
61-
False,
62-
);
63-
let name = global_fn_name(method.name);
64-
let llfn =
65-
llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
66-
67-
if tcx.sess.target.default_hidden_visibility {
68-
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
69-
}
70-
if tcx.sess.must_emit_unwind_tables() {
71-
let uwtable = attributes::uwtable_attr(llcx);
72-
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
73-
}
7456

75-
let callee = default_fn_name(method.name);
76-
let callee =
77-
llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
78-
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
79-
80-
let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
81-
82-
let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
83-
llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
84-
let args = args
85-
.iter()
86-
.enumerate()
87-
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
88-
.collect::<Vec<_>>();
89-
let ret = llvm::LLVMRustBuildCall(
90-
llbuilder,
91-
ty,
92-
callee,
93-
args.as_ptr(),
94-
args.len() as c_uint,
95-
[].as_ptr(),
96-
0 as c_uint,
97-
);
98-
llvm::LLVMSetTailCall(ret, True);
99-
if output.is_some() {
100-
llvm::LLVMBuildRet(llbuilder, ret);
101-
} else {
102-
llvm::LLVMBuildRetVoid(llbuilder);
103-
}
104-
llvm::LLVMDisposeBuilder(llbuilder);
57+
let from_name = global_fn_name(method.name);
58+
let to_name = default_fn_name(method.name);
59+
60+
create_wrapper_function(tcx, llcx, llmod, &from_name, &to_name, &args, output, false);
10561
}
10662
}
10763

10864
// rust alloc error handler
109-
let args = [usize, usize]; // size, align
110-
111-
let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False);
112-
let name = "__rust_alloc_error_handler";
113-
let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
114-
// -> ! DIFlagNoReturn
115-
let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx);
116-
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
117-
118-
if tcx.sess.target.default_hidden_visibility {
119-
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
120-
}
121-
if tcx.sess.must_emit_unwind_tables() {
122-
let uwtable = attributes::uwtable_attr(llcx);
123-
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
124-
}
125-
126-
let callee = alloc_error_handler_name(alloc_error_handler_kind);
127-
let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
128-
// -> ! DIFlagNoReturn
129-
attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
130-
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
131-
132-
let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
133-
134-
let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
135-
llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
136-
let args = args
137-
.iter()
138-
.enumerate()
139-
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
140-
.collect::<Vec<_>>();
141-
let ret = llvm::LLVMRustBuildCall(
142-
llbuilder,
143-
ty,
144-
callee,
145-
args.as_ptr(),
146-
args.len() as c_uint,
147-
[].as_ptr(),
148-
0 as c_uint,
65+
create_wrapper_function(
66+
tcx,
67+
llcx,
68+
llmod,
69+
"__rust_alloc_error_handler",
70+
&alloc_error_handler_name(alloc_error_handler_kind),
71+
&[usize, usize], // size, align
72+
None,
73+
true,
14974
);
150-
llvm::LLVMSetTailCall(ret, True);
151-
llvm::LLVMBuildRetVoid(llbuilder);
152-
llvm::LLVMDisposeBuilder(llbuilder);
15375

15476
// __rust_alloc_error_handler_should_panic
15577
let name = OomStrategy::SYMBOL;
@@ -175,3 +97,79 @@ pub(crate) unsafe fn codegen(
17597
dbg_cx.finalize(tcx.sess);
17698
}
17799
}
100+
101+
fn create_wrapper_function(
102+
tcx: TyCtxt<'_>,
103+
llcx: &Context,
104+
llmod: &Module,
105+
from_name: &str,
106+
to_name: &str,
107+
args: &[&Type],
108+
output: Option<&Type>,
109+
no_return: bool,
110+
) {
111+
unsafe {
112+
let ty = llvm::LLVMFunctionType(
113+
output.unwrap_or_else(|| llvm::LLVMVoidTypeInContext(llcx)),
114+
args.as_ptr(),
115+
args.len() as c_uint,
116+
False,
117+
);
118+
let llfn = llvm::LLVMRustGetOrInsertFunction(
119+
llmod,
120+
from_name.as_ptr().cast(),
121+
from_name.len(),
122+
ty,
123+
);
124+
let no_return = if no_return {
125+
// -> ! DIFlagNoReturn
126+
let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx);
127+
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
128+
Some(no_return)
129+
} else {
130+
None
131+
};
132+
133+
if tcx.sess.target.default_hidden_visibility {
134+
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
135+
}
136+
if tcx.sess.must_emit_unwind_tables() {
137+
let uwtable = attributes::uwtable_attr(llcx);
138+
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
139+
}
140+
141+
let callee =
142+
llvm::LLVMRustGetOrInsertFunction(llmod, to_name.as_ptr().cast(), to_name.len(), ty);
143+
if let Some(no_return) = no_return {
144+
// -> ! DIFlagNoReturn
145+
attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
146+
}
147+
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
148+
149+
let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
150+
151+
let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
152+
llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
153+
let args = args
154+
.iter()
155+
.enumerate()
156+
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
157+
.collect::<Vec<_>>();
158+
let ret = llvm::LLVMRustBuildCall(
159+
llbuilder,
160+
ty,
161+
callee,
162+
args.as_ptr(),
163+
args.len() as c_uint,
164+
[].as_ptr(),
165+
0 as c_uint,
166+
);
167+
llvm::LLVMSetTailCall(ret, True);
168+
if output.is_some() {
169+
llvm::LLVMBuildRet(llbuilder, ret);
170+
} else {
171+
llvm::LLVMBuildRetVoid(llbuilder);
172+
}
173+
llvm::LLVMDisposeBuilder(llbuilder);
174+
}
175+
}

0 commit comments

Comments
 (0)