@@ -9,7 +9,7 @@ use rustc_middle::ty::TyCtxt;
9
9
use rustc_session:: config:: { DebugInfo , OomStrategy } ;
10
10
11
11
use crate :: debuginfo;
12
- use crate :: llvm:: { self , False , True } ;
12
+ use crate :: llvm:: { self , Context , False , Module , True , Type } ;
13
13
use crate :: ModuleLlvm ;
14
14
15
15
pub ( crate ) unsafe fn codegen (
@@ -29,7 +29,6 @@ pub(crate) unsafe fn codegen(
29
29
} ;
30
30
let i8 = llvm:: LLVMInt8TypeInContext ( llcx) ;
31
31
let i8p = llvm:: LLVMPointerTypeInContext ( llcx, 0 ) ;
32
- let void = llvm:: LLVMVoidTypeInContext ( llcx) ;
33
32
34
33
if kind == AllocatorKind :: Default {
35
34
for method in ALLOCATOR_METHODS {
@@ -54,102 +53,25 @@ pub(crate) unsafe fn codegen(
54
53
panic ! ( "invalid allocator output" )
55
54
}
56
55
} ;
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
- }
74
56
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 ) ;
105
61
}
106
62
}
107
63
108
64
// 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 ,
149
74
) ;
150
- llvm:: LLVMSetTailCall ( ret, True ) ;
151
- llvm:: LLVMBuildRetVoid ( llbuilder) ;
152
- llvm:: LLVMDisposeBuilder ( llbuilder) ;
153
75
154
76
// __rust_alloc_error_handler_should_panic
155
77
let name = OomStrategy :: SYMBOL ;
@@ -175,3 +97,79 @@ pub(crate) unsafe fn codegen(
175
97
dbg_cx. finalize ( tcx. sess ) ;
176
98
}
177
99
}
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