@@ -3,33 +3,31 @@ use rustc_ast::expand::allocator::{
3
3
ALLOCATOR_METHODS , AllocatorKind , AllocatorTy , NO_ALLOC_SHIM_IS_UNSTABLE ,
4
4
alloc_error_handler_name, default_fn_name, global_fn_name,
5
5
} ;
6
+ use rustc_codegen_ssa:: traits:: BaseTypeCodegenMethods as _;
6
7
use rustc_middle:: bug;
7
8
use rustc_middle:: ty:: TyCtxt ;
8
9
use rustc_session:: config:: { DebugInfo , OomStrategy } ;
9
10
10
- use crate :: common:: AsCCharPtr ;
11
- use crate :: llvm:: { self , Context , False , Module , True , Type } ;
12
- use crate :: { ModuleLlvm , attributes, debuginfo} ;
11
+ use crate :: builder:: SBuilder ;
12
+ use crate :: declare:: declare_simple_fn;
13
+ use crate :: llvm:: { self , False , True , Type } ;
14
+ use crate :: { SimpleCx , attributes, debuginfo} ;
13
15
14
16
pub ( crate ) unsafe fn codegen (
15
17
tcx : TyCtxt < ' _ > ,
16
- module_llvm : & mut ModuleLlvm ,
18
+ cx : SimpleCx < ' _ > ,
17
19
module_name : & str ,
18
20
kind : AllocatorKind ,
19
21
alloc_error_handler_kind : AllocatorKind ,
20
22
) {
21
- let llcx = & * module_llvm. llcx ;
22
- let llmod = module_llvm. llmod ( ) ;
23
- let usize = unsafe {
24
- match tcx. sess . target . pointer_width {
25
- 16 => llvm:: LLVMInt16TypeInContext ( llcx) ,
26
- 32 => llvm:: LLVMInt32TypeInContext ( llcx) ,
27
- 64 => llvm:: LLVMInt64TypeInContext ( llcx) ,
28
- tws => bug ! ( "Unsupported target word size for int: {}" , tws) ,
29
- }
23
+ let usize = match tcx. sess . target . pointer_width {
24
+ 16 => cx. type_i16 ( ) ,
25
+ 32 => cx. type_i32 ( ) ,
26
+ 64 => cx. type_i64 ( ) ,
27
+ tws => bug ! ( "Unsupported target word size for int: {}" , tws) ,
30
28
} ;
31
- let i8 = unsafe { llvm :: LLVMInt8TypeInContext ( llcx ) } ;
32
- let i8p = unsafe { llvm :: LLVMPointerTypeInContext ( llcx , 0 ) } ;
29
+ let i8 = cx . type_i8 ( ) ;
30
+ let i8p = cx . type_ptr ( ) ;
33
31
34
32
if kind == AllocatorKind :: Default {
35
33
for method in ALLOCATOR_METHODS {
@@ -58,15 +56,14 @@ pub(crate) unsafe fn codegen(
58
56
let from_name = global_fn_name ( method. name ) ;
59
57
let to_name = default_fn_name ( method. name ) ;
60
58
61
- create_wrapper_function ( tcx, llcx , llmod , & from_name, & to_name, & args, output, false ) ;
59
+ create_wrapper_function ( tcx, & cx , & from_name, & to_name, & args, output, false ) ;
62
60
}
63
61
}
64
62
65
63
// rust alloc error handler
66
64
create_wrapper_function (
67
65
tcx,
68
- llcx,
69
- llmod,
66
+ & cx,
70
67
"__rust_alloc_error_handler" ,
71
68
alloc_error_handler_name ( alloc_error_handler_kind) ,
72
69
& [ usize, usize] , // size, align
@@ -77,99 +74,86 @@ pub(crate) unsafe fn codegen(
77
74
unsafe {
78
75
// __rust_alloc_error_handler_should_panic
79
76
let name = OomStrategy :: SYMBOL ;
80
- let ll_g = llvm :: LLVMRustGetOrInsertGlobal ( llmod , name . as_c_char_ptr ( ) , name. len ( ) , i8) ;
77
+ let ll_g = cx . declare_global ( name, i8) ;
81
78
llvm:: set_visibility ( ll_g, llvm:: Visibility :: from_generic ( tcx. sess . default_visibility ( ) ) ) ;
82
79
let val = tcx. sess . opts . unstable_opts . oom . should_panic ( ) ;
83
80
let llval = llvm:: LLVMConstInt ( i8, val as u64 , False ) ;
84
81
llvm:: set_initializer ( ll_g, llval) ;
85
82
86
83
let name = NO_ALLOC_SHIM_IS_UNSTABLE ;
87
- let ll_g = llvm :: LLVMRustGetOrInsertGlobal ( llmod , name . as_c_char_ptr ( ) , name. len ( ) , i8) ;
84
+ let ll_g = cx . declare_global ( name, i8) ;
88
85
llvm:: set_visibility ( ll_g, llvm:: Visibility :: from_generic ( tcx. sess . default_visibility ( ) ) ) ;
89
86
let llval = llvm:: LLVMConstInt ( i8, 0 , False ) ;
90
87
llvm:: set_initializer ( ll_g, llval) ;
91
88
}
92
89
93
90
if tcx. sess . opts . debuginfo != DebugInfo :: None {
94
- let dbg_cx = debuginfo:: CodegenUnitDebugContext :: new ( llmod) ;
91
+ let dbg_cx = debuginfo:: CodegenUnitDebugContext :: new ( cx . llmod ) ;
95
92
debuginfo:: metadata:: build_compile_unit_di_node ( tcx, module_name, & dbg_cx) ;
96
93
dbg_cx. finalize ( tcx. sess ) ;
97
94
}
98
95
}
99
96
100
97
fn create_wrapper_function (
101
98
tcx : TyCtxt < ' _ > ,
102
- llcx : & Context ,
103
- llmod : & Module ,
99
+ cx : & SimpleCx < ' _ > ,
104
100
from_name : & str ,
105
101
to_name : & str ,
106
102
args : & [ & Type ] ,
107
103
output : Option < & Type > ,
108
104
no_return : bool ,
109
105
) {
110
- unsafe {
111
- let ty = llvm:: LLVMFunctionType (
112
- output. unwrap_or_else ( || llvm:: LLVMVoidTypeInContext ( llcx) ) ,
113
- args. as_ptr ( ) ,
114
- args. len ( ) as c_uint ,
115
- False ,
116
- ) ;
117
- let llfn = llvm:: LLVMRustGetOrInsertFunction (
118
- llmod,
119
- from_name. as_c_char_ptr ( ) ,
120
- from_name. len ( ) ,
121
- ty,
122
- ) ;
123
- let no_return = if no_return {
124
- // -> ! DIFlagNoReturn
125
- let no_return = llvm:: AttributeKind :: NoReturn . create_attr ( llcx) ;
126
- attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Function , & [ no_return] ) ;
127
- Some ( no_return)
128
- } else {
129
- None
130
- } ;
131
-
132
- llvm:: set_visibility ( llfn, llvm:: Visibility :: from_generic ( tcx. sess . default_visibility ( ) ) ) ;
133
-
134
- if tcx. sess . must_emit_unwind_tables ( ) {
135
- let uwtable =
136
- attributes:: uwtable_attr ( llcx, tcx. sess . opts . unstable_opts . use_sync_unwind ) ;
137
- attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Function , & [ uwtable] ) ;
138
- }
106
+ let ty = cx. type_func ( args, output. unwrap_or_else ( || cx. type_void ( ) ) ) ;
107
+ let llfn = declare_simple_fn (
108
+ & cx,
109
+ from_name,
110
+ llvm:: CallConv :: CCallConv ,
111
+ llvm:: UnnamedAddr :: Global ,
112
+ llvm:: Visibility :: from_generic ( tcx. sess . default_visibility ( ) ) ,
113
+ ty,
114
+ ) ;
115
+ let no_return = if no_return {
116
+ // -> ! DIFlagNoReturn
117
+ let no_return = llvm:: AttributeKind :: NoReturn . create_attr ( cx. llcx ) ;
118
+ attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Function , & [ no_return] ) ;
119
+ Some ( no_return)
120
+ } else {
121
+ None
122
+ } ;
139
123
140
- let callee =
141
- llvm :: LLVMRustGetOrInsertFunction ( llmod , to_name . as_c_char_ptr ( ) , to_name . len ( ) , ty ) ;
142
- if let Some ( no_return ) = no_return {
143
- // -> ! DIFlagNoReturn
144
- attributes :: apply_to_llfn ( callee , llvm :: AttributePlace :: Function , & [ no_return ] ) ;
145
- }
146
- llvm :: set_visibility ( callee , llvm :: Visibility :: Hidden ) ;
147
-
148
- let llbb = llvm :: LLVMAppendBasicBlockInContext ( llcx , llfn , c"entry" . as_ptr ( ) ) ;
149
-
150
- let llbuilder = llvm:: LLVMCreateBuilderInContext ( llcx ) ;
151
- llvm:: LLVMPositionBuilderAtEnd ( llbuilder , llbb ) ;
152
- let args = args
153
- . iter ( )
154
- . enumerate ( )
155
- . map ( | ( i , _ ) | llvm :: LLVMGetParam ( llfn , i as c_uint ) )
156
- . collect :: < Vec < _ > > ( ) ;
157
- let ret = llvm :: LLVMBuildCallWithOperandBundles (
158
- llbuilder ,
159
- ty ,
160
- callee ,
161
- args . as_ptr ( ) ,
162
- args . len ( ) as c_uint ,
163
- [ ] . as_ptr ( ) ,
164
- 0 as c_uint ,
165
- c"" . as_ptr ( ) ,
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 ) ;
124
+ if tcx . sess . must_emit_unwind_tables ( ) {
125
+ let uwtable =
126
+ attributes :: uwtable_attr ( cx . llcx , tcx . sess . opts . unstable_opts . use_sync_unwind ) ;
127
+ attributes :: apply_to_llfn ( llfn , llvm :: AttributePlace :: Function , & [ uwtable ] ) ;
128
+ }
129
+
130
+ let callee = declare_simple_fn (
131
+ & cx ,
132
+ to_name ,
133
+ llvm :: CallConv :: CCallConv ,
134
+ llvm:: UnnamedAddr :: Global ,
135
+ llvm:: Visibility :: Hidden ,
136
+ ty ,
137
+ ) ;
138
+ if let Some ( no_return ) = no_return {
139
+ // -> ! DIFlagNoReturn
140
+ attributes :: apply_to_llfn ( callee , llvm :: AttributePlace :: Function , & [ no_return ] ) ;
141
+ }
142
+ llvm :: set_visibility ( callee , llvm :: Visibility :: Hidden ) ;
143
+
144
+ let llbb = unsafe { llvm :: LLVMAppendBasicBlockInContext ( cx . llcx , llfn , c"entry" . as_ptr ( ) ) } ;
145
+
146
+ let mut bx = SBuilder :: build ( & cx , llbb ) ;
147
+ let args = args
148
+ . iter ( )
149
+ . enumerate ( )
150
+ . map ( | ( i , _ ) | llvm :: get_param ( llfn , i as c_uint ) )
151
+ . collect :: < Vec < _ > > ( ) ;
152
+ let ret = bx . call ( ty , callee , & args , None ) ;
153
+ llvm:: LLVMSetTailCall ( ret , True ) ;
154
+ if output . is_some ( ) {
155
+ bx . ret ( ret ) ;
156
+ } else {
157
+ bx . ret_void ( )
174
158
}
175
159
}
0 commit comments