@@ -9,111 +9,122 @@ use rustc_middle::ty::TyCtxt;
99use rustc_symbol_mangling:: mangle_internal_symbol;
1010
1111// adapted from rustc_codegen_llvm
12- pub ( crate ) unsafe fn codegen (
12+ pub ( crate ) fn codegen (
1313 tcx : TyCtxt < ' _ > ,
1414 mods : & mut LlvmMod ,
1515 _module_name : & str ,
1616 methods : & [ AllocatorMethod ] ,
1717) {
18- let llcx = & * mods. llcx ;
19- let llmod = mods. llmod . as_ref ( ) . unwrap ( ) ;
20- let usize = target:: usize_ty ( llcx) ;
21- let i8 = llvm:: LLVMInt8TypeInContext ( llcx) ;
22- let i8p = llvm:: LLVMPointerType ( i8, 0 ) ;
23- let void = llvm:: LLVMVoidTypeInContext ( llcx) ;
18+ unsafe {
19+ let llcx = & * mods. llcx ;
20+ let llmod = mods. llmod . as_ref ( ) . unwrap ( ) ;
21+ let usize = target:: usize_ty ( llcx) ;
22+ let i8 = llvm:: LLVMInt8TypeInContext ( llcx) ;
23+ let i8p = llvm:: LLVMPointerType ( i8, 0 ) ;
24+ let void = llvm:: LLVMVoidTypeInContext ( llcx) ;
2425
25- let mut used = Vec :: new ( ) ;
26+ let mut used = Vec :: new ( ) ;
2627
27- for method in methods {
28- let mut args = Vec :: with_capacity ( method. inputs . len ( ) ) ;
29- for input in method. inputs {
30- match input. ty {
31- AllocatorTy :: Layout => {
32- args. push ( usize) ;
33- args. push ( usize) ;
28+ for method in methods {
29+ let mut args = Vec :: with_capacity ( method. inputs . len ( ) ) ;
30+ for input in method. inputs {
31+ match input. ty {
32+ AllocatorTy :: Layout => {
33+ args. push ( usize) ;
34+ args. push ( usize) ;
35+ }
36+ AllocatorTy :: Ptr => args. push ( i8p) ,
37+ AllocatorTy :: Usize => args. push ( usize) ,
38+ AllocatorTy :: Never | AllocatorTy :: ResultPtr | AllocatorTy :: Unit => {
39+ panic ! ( "invalid allocator arg" )
40+ }
3441 }
35- AllocatorTy :: Ptr => args. push ( i8p) ,
36- AllocatorTy :: Usize => args. push ( usize) ,
37- AllocatorTy :: Never | AllocatorTy :: ResultPtr | AllocatorTy :: Unit => {
38- panic ! ( "invalid allocator arg" )
42+ }
43+
44+ let no_return = matches ! ( method. output, AllocatorTy :: Never ) ;
45+ let output = match method. output {
46+ AllocatorTy :: ResultPtr => Some ( i8p) ,
47+ AllocatorTy :: Never | AllocatorTy :: Unit => None ,
48+ AllocatorTy :: Layout | AllocatorTy :: Usize | AllocatorTy :: Ptr => {
49+ panic ! ( "invalid allocator output" )
3950 }
51+ } ;
52+
53+ let ty = llvm:: LLVMFunctionType (
54+ output. unwrap_or ( void) ,
55+ args. as_ptr ( ) ,
56+ args. len ( ) as c_uint ,
57+ False ,
58+ ) ;
59+ let from_name = mangle_internal_symbol ( tcx, & global_fn_name ( method. name ) ) ;
60+ let llfn = llvm:: LLVMRustGetOrInsertFunction (
61+ llmod,
62+ from_name. as_ptr ( ) . cast ( ) ,
63+ from_name. len ( ) ,
64+ ty,
65+ ) ;
66+ used. push ( llfn) ;
67+ if no_return {
68+ llvm:: Attribute :: NoReturn . apply_llfn ( llvm:: AttributePlace :: Function , llfn) ;
4069 }
41- }
4270
43- let no_return = matches ! ( method. output, AllocatorTy :: Never ) ;
44- let output = match method. output {
45- AllocatorTy :: ResultPtr => Some ( i8p) ,
46- AllocatorTy :: Never | AllocatorTy :: Unit => None ,
47- AllocatorTy :: Layout | AllocatorTy :: Usize | AllocatorTy :: Ptr => {
48- panic ! ( "invalid allocator output" )
71+ let to_name = mangle_internal_symbol ( tcx, & default_fn_name ( method. name ) ) ;
72+ let callee = llvm:: LLVMRustGetOrInsertFunction (
73+ llmod,
74+ to_name. as_ptr ( ) . cast ( ) ,
75+ to_name. len ( ) ,
76+ ty,
77+ ) ;
78+ used. push ( callee) ;
79+ if no_return {
80+ llvm:: Attribute :: NoReturn . apply_llfn ( llvm:: AttributePlace :: Function , callee) ;
4981 }
50- } ;
82+ llvm :: LLVMRustSetVisibility ( callee , llvm :: Visibility :: Hidden ) ;
5183
52- let ty = llvm:: LLVMFunctionType (
53- output. unwrap_or ( void) ,
54- args. as_ptr ( ) ,
55- args. len ( ) as c_uint ,
56- False ,
57- ) ;
58- let from_name = mangle_internal_symbol ( tcx, & global_fn_name ( method. name ) ) ;
59- let llfn = llvm:: LLVMRustGetOrInsertFunction (
60- llmod,
61- from_name. as_ptr ( ) . cast ( ) ,
62- from_name. len ( ) ,
63- ty,
64- ) ;
65- used. push ( llfn) ;
66- if no_return {
67- llvm:: Attribute :: NoReturn . apply_llfn ( llvm:: AttributePlace :: Function , llfn) ;
84+ let llbb = llvm:: LLVMAppendBasicBlockInContext ( llcx, llfn, c"entry" . as_ptr ( ) . cast ( ) ) ;
85+ let llbuilder = llvm:: LLVMCreateBuilderInContext ( llcx) ;
86+ llvm:: LLVMPositionBuilderAtEnd ( llbuilder, llbb) ;
87+ let args = args
88+ . iter ( )
89+ . enumerate ( )
90+ . map ( |( i, _) | llvm:: LLVMGetParam ( llfn, i as c_uint ) )
91+ . collect :: < Vec < _ > > ( ) ;
92+ let ret = llvm:: LLVMRustBuildCall (
93+ llbuilder,
94+ callee,
95+ args. as_ptr ( ) ,
96+ args. len ( ) as c_uint ,
97+ None ,
98+ ) ;
99+ llvm:: LLVMSetTailCall ( ret, True ) ;
100+ if output. is_some ( ) {
101+ llvm:: LLVMBuildRet ( llbuilder, ret) ;
102+ } else {
103+ llvm:: LLVMBuildRetVoid ( llbuilder) ;
104+ }
105+ llvm:: LLVMDisposeBuilder ( llbuilder) ;
68106 }
69107
70- let to_name = mangle_internal_symbol ( tcx, & default_fn_name ( method. name ) ) ;
71- let callee =
72- llvm:: LLVMRustGetOrInsertFunction ( llmod, to_name. as_ptr ( ) . cast ( ) , to_name. len ( ) , ty) ;
73- used. push ( callee) ;
74- if no_return {
75- llvm:: Attribute :: NoReturn . apply_llfn ( llvm:: AttributePlace :: Function , callee) ;
76- }
77- llvm:: LLVMRustSetVisibility ( callee, llvm:: Visibility :: Hidden ) ;
108+ let shim_ty = llvm:: LLVMFunctionType ( void, std:: ptr:: null ( ) , 0 , False ) ;
109+ let shim_name = mangle_internal_symbol ( tcx, NO_ALLOC_SHIM_IS_UNSTABLE ) ;
110+ let shim = llvm:: LLVMRustGetOrInsertFunction (
111+ llmod,
112+ shim_name. as_ptr ( ) . cast ( ) ,
113+ shim_name. len ( ) ,
114+ shim_ty,
115+ ) ;
116+ used. push ( shim) ;
78117
79- let llbb = llvm:: LLVMAppendBasicBlockInContext ( llcx, llfn, c"entry" . as_ptr ( ) . cast ( ) ) ;
80- let llbuilder = llvm:: LLVMCreateBuilderInContext ( llcx) ;
81- llvm:: LLVMPositionBuilderAtEnd ( llbuilder, llbb) ;
82- let args = args
83- . iter ( )
84- . enumerate ( )
85- . map ( |( i, _) | llvm:: LLVMGetParam ( llfn, i as c_uint ) )
86- . collect :: < Vec < _ > > ( ) ;
87- let ret =
88- llvm:: LLVMRustBuildCall ( llbuilder, callee, args. as_ptr ( ) , args. len ( ) as c_uint , None ) ;
89- llvm:: LLVMSetTailCall ( ret, True ) ;
90- if output. is_some ( ) {
91- llvm:: LLVMBuildRet ( llbuilder, ret) ;
92- } else {
93- llvm:: LLVMBuildRetVoid ( llbuilder) ;
118+ let ptr_ty = llvm:: LLVMPointerType ( llvm:: LLVMInt8TypeInContext ( llcx) , 0 ) ;
119+ for used in & mut used {
120+ * used = llvm:: LLVMConstBitCast ( used, ptr_ty) ;
94121 }
95- llvm:: LLVMDisposeBuilder ( llbuilder) ;
96- }
97-
98- let shim_ty = llvm:: LLVMFunctionType ( void, std:: ptr:: null ( ) , 0 , False ) ;
99- let shim_name = mangle_internal_symbol ( tcx, NO_ALLOC_SHIM_IS_UNSTABLE ) ;
100- let shim = llvm:: LLVMRustGetOrInsertFunction (
101- llmod,
102- shim_name. as_ptr ( ) . cast ( ) ,
103- shim_name. len ( ) ,
104- shim_ty,
105- ) ;
106- used. push ( shim) ;
107122
108- let ptr_ty = llvm:: LLVMPointerType ( llvm:: LLVMInt8TypeInContext ( llcx) , 0 ) ;
109- for used in & mut used {
110- * used = llvm:: LLVMConstBitCast ( * used, ptr_ty) ;
123+ let section = c"llvm.metadata" ;
124+ let array = llvm:: LLVMConstArray ( ptr_ty, used. as_ptr ( ) , used. len ( ) as u32 ) ;
125+ let g = llvm:: LLVMAddGlobal ( llmod, llvm:: LLVMTypeOf ( array) , c"llvm.used" . as_ptr ( ) . cast ( ) ) ;
126+ llvm:: LLVMSetInitializer ( g, array) ;
127+ llvm:: LLVMRustSetLinkage ( g, llvm:: Linkage :: AppendingLinkage ) ;
128+ llvm:: LLVMSetSection ( g, section. as_ptr ( ) ) ;
111129 }
112-
113- let section = c"llvm.metadata" ;
114- let array = llvm:: LLVMConstArray ( ptr_ty, used. as_ptr ( ) , used. len ( ) as u32 ) ;
115- let g = llvm:: LLVMAddGlobal ( llmod, llvm:: LLVMTypeOf ( array) , c"llvm.used" . as_ptr ( ) . cast ( ) ) ;
116- llvm:: LLVMSetInitializer ( g, array) ;
117- llvm:: LLVMRustSetLinkage ( g, llvm:: Linkage :: AppendingLinkage ) ;
118- llvm:: LLVMSetSection ( g, section. as_ptr ( ) ) ;
119130}
0 commit comments