@@ -3,33 +3,31 @@ use rustc_ast::expand::allocator::{
33 ALLOCATOR_METHODS , AllocatorKind , AllocatorTy , NO_ALLOC_SHIM_IS_UNSTABLE ,
44 alloc_error_handler_name, default_fn_name, global_fn_name,
55} ;
6+ use rustc_codegen_ssa:: traits:: BaseTypeCodegenMethods as _;
67use rustc_middle:: bug;
78use rustc_middle:: ty:: TyCtxt ;
89use rustc_session:: config:: { DebugInfo , OomStrategy } ;
910
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} ;
1315
1416pub ( crate ) unsafe fn codegen (
1517 tcx : TyCtxt < ' _ > ,
16- module_llvm : & mut ModuleLlvm ,
18+ cx : SimpleCx < ' _ > ,
1719 module_name : & str ,
1820 kind : AllocatorKind ,
1921 alloc_error_handler_kind : AllocatorKind ,
2022) {
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) ,
3028 } ;
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 ( ) ;
3331
3432 if kind == AllocatorKind :: Default {
3533 for method in ALLOCATOR_METHODS {
@@ -58,15 +56,14 @@ pub(crate) unsafe fn codegen(
5856 let from_name = global_fn_name ( method. name ) ;
5957 let to_name = default_fn_name ( method. name ) ;
6058
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 ) ;
6260 }
6361 }
6462
6563 // rust alloc error handler
6664 create_wrapper_function (
6765 tcx,
68- llcx,
69- llmod,
66+ & cx,
7067 "__rust_alloc_error_handler" ,
7168 alloc_error_handler_name ( alloc_error_handler_kind) ,
7269 & [ usize, usize] , // size, align
@@ -77,99 +74,86 @@ pub(crate) unsafe fn codegen(
7774 unsafe {
7875 // __rust_alloc_error_handler_should_panic
7976 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) ;
8178 llvm:: set_visibility ( ll_g, llvm:: Visibility :: from_generic ( tcx. sess . default_visibility ( ) ) ) ;
8279 let val = tcx. sess . opts . unstable_opts . oom . should_panic ( ) ;
8380 let llval = llvm:: LLVMConstInt ( i8, val as u64 , False ) ;
8481 llvm:: set_initializer ( ll_g, llval) ;
8582
8683 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) ;
8885 llvm:: set_visibility ( ll_g, llvm:: Visibility :: from_generic ( tcx. sess . default_visibility ( ) ) ) ;
8986 let llval = llvm:: LLVMConstInt ( i8, 0 , False ) ;
9087 llvm:: set_initializer ( ll_g, llval) ;
9188 }
9289
9390 if tcx. sess . opts . debuginfo != DebugInfo :: None {
94- let dbg_cx = debuginfo:: CodegenUnitDebugContext :: new ( llmod) ;
91+ let dbg_cx = debuginfo:: CodegenUnitDebugContext :: new ( cx . llmod ) ;
9592 debuginfo:: metadata:: build_compile_unit_di_node ( tcx, module_name, & dbg_cx) ;
9693 dbg_cx. finalize ( tcx. sess ) ;
9794 }
9895}
9996
10097fn create_wrapper_function (
10198 tcx : TyCtxt < ' _ > ,
102- llcx : & Context ,
103- llmod : & Module ,
99+ cx : & SimpleCx < ' _ > ,
104100 from_name : & str ,
105101 to_name : & str ,
106102 args : & [ & Type ] ,
107103 output : Option < & Type > ,
108104 no_return : bool ,
109105) {
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+ } ;
139123
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 ( )
174158 }
175159}
0 commit comments