@@ -9,7 +9,7 @@ use rustc_middle::ty::TyCtxt;
99use rustc_session:: config:: { DebugInfo , OomStrategy } ;
1010
1111use crate :: debuginfo;
12- use crate :: llvm:: { self , False , True } ;
12+ use crate :: llvm:: { self , Context , False , Module , True , Type } ;
1313use crate :: ModuleLlvm ;
1414
1515pub ( 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