1+ use std:: cell:: RefCell ;
12use std:: collections:: BTreeMap ;
3+ use std:: mem;
24use std:: sync:: { Arc , OnceLock } ;
35
46use cranelift_codegen:: control:: ControlPlane ;
57use cranelift_codegen:: entity:: SecondaryMap ;
6- use cranelift_codegen:: ir:: { Signature , UserExternalName } ;
8+ use cranelift_codegen:: ir:: function:: FunctionParameters ;
9+ use cranelift_codegen:: ir:: { ExternalName , Signature , UserExternalName } ;
710use cranelift_codegen:: isa:: TargetIsa ;
11+ use cranelift_codegen:: { Final , FinalizedMachReloc , FinalizedRelocTarget , MachBufferFinalized } ;
812use cranelift_module:: {
913 DataId , ModuleDeclarations , ModuleError , ModuleReloc , ModuleRelocTarget , ModuleResult ,
1014} ;
@@ -18,14 +22,20 @@ pub(super) struct SerializableModule {
1822 serialized : OnceLock < Vec < u8 > > ,
1923}
2024
21- #[ derive( Debug , serde:: Serialize , serde:: Deserialize ) ]
25+ #[ derive( serde:: Serialize , serde:: Deserialize ) ]
2226struct SerializableModuleInner {
2327 declarations : ModuleDeclarations ,
24- functions : BTreeMap < FuncId , Function > ,
28+ functions : BTreeMap < FuncId , RefCell < FunctionMaybeCompiled > > ,
2529 data_objects : BTreeMap < DataId , DataDescription > ,
2630 global_asm : String ,
2731}
2832
33+ #[ derive( serde:: Serialize , serde:: Deserialize ) ]
34+ enum FunctionMaybeCompiled {
35+ Ir ( Function ) ,
36+ Compiled ( MachBufferFinalized < Final > , FunctionParameters ) ,
37+ }
38+
2939impl < CTX > HashStable < CTX > for SerializableModule {
3040 fn hash_stable (
3141 & self ,
@@ -52,6 +62,7 @@ impl SerializableModule {
5262 }
5363
5464 pub ( crate ) fn serialize ( & self ) -> Vec < u8 > {
65+ self . compile_funcs ( ) ;
5566 postcard:: to_stdvec ( & self . inner ) . unwrap ( )
5667 }
5768
@@ -68,7 +79,26 @@ impl SerializableModule {
6879 self . inner . global_asm . push_str ( asm) ;
6980 }
7081
82+ fn compile_funcs ( & self ) {
83+ let mut ctx = Context :: new ( ) ;
84+ for func in self . inner . functions . values ( ) {
85+ let mut func = func. borrow_mut ( ) ;
86+ match & mut * func {
87+ FunctionMaybeCompiled :: Ir ( ir_func) => {
88+ // FIXME lazily do this during serialize/apply_to
89+ ctx. func = mem:: replace ( ir_func, Function :: new ( ) ) ;
90+ let res = ctx. compile ( & * self . isa , & mut ControlPlane :: default ( ) ) . unwrap ( ) ;
91+
92+ let buffer = res. buffer . clone ( ) ;
93+ * func = FunctionMaybeCompiled :: Compiled ( buffer, ctx. func . params ) ;
94+ }
95+ FunctionMaybeCompiled :: Compiled ( _, _) => { }
96+ }
97+ }
98+ }
99+
71100 pub ( crate ) fn apply_to ( self , module : & mut dyn Module ) -> String {
101+ self . compile_funcs ( ) ;
72102 let mut function_map: SecondaryMap < FuncId , Option < FuncId > > = SecondaryMap :: new ( ) ;
73103 let mut data_object_map: SecondaryMap < DataId , Option < DataId > > = SecondaryMap :: new ( ) ;
74104
@@ -98,41 +128,62 @@ impl SerializableModule {
98128 data_object_map[ data_id] . unwrap ( )
99129 } ;
100130
101- for ( func_id, mut func) in self . inner . functions {
131+ for ( func_id, func) in self . inner . functions {
102132 let func_id = remap_func_id ( module, & self . inner . declarations , func_id) ;
103- let user_named_funcs = func. params . user_named_funcs ( ) . clone ( ) ;
104- for ( ext_name_ref, ext_name) in user_named_funcs {
105- if ext_name. namespace == 0 {
106- func. params . reset_user_func_name (
107- ext_name_ref,
108- UserExternalName :: new (
109- 0 ,
110- remap_func_id (
111- module,
112- & self . inner . declarations ,
113- FuncId :: from_u32 ( ext_name. index ) ,
133+
134+ let FunctionMaybeCompiled :: Compiled ( buffer, params) = & * func. borrow ( ) else {
135+ unreachable ! ( )
136+ } ;
137+
138+ let remap_reloc = |reloc : & FinalizedMachReloc | {
139+ let name = match reloc. target {
140+ FinalizedRelocTarget :: ExternalName ( ExternalName :: User ( reff) ) => {
141+ let ext_name = & params. user_named_funcs ( ) [ reff] ;
142+ let ext_name = if ext_name. namespace == 0 {
143+ UserExternalName :: new (
144+ 0 ,
145+ remap_func_id (
146+ module,
147+ & self . inner . declarations ,
148+ FuncId :: from_u32 ( ext_name. index ) ,
149+ )
150+ . as_u32 ( ) ,
114151 )
115- . as_u32 ( ) ,
116- ) ,
117- ) ;
118- } else if ext_name. namespace == 1 {
119- func. params . reset_user_func_name (
120- ext_name_ref,
121- UserExternalName :: new (
122- 1 ,
123- remap_data_id (
124- module,
125- & self . inner . declarations ,
126- DataId :: from_u32 ( ext_name. index ) ,
152+ } else if ext_name. namespace == 1 {
153+ UserExternalName :: new (
154+ 1 ,
155+ remap_data_id (
156+ module,
157+ & self . inner . declarations ,
158+ DataId :: from_u32 ( ext_name. index ) ,
159+ )
160+ . as_u32 ( ) ,
127161 )
128- . as_u32 ( ) ,
129- ) ,
130- ) ;
131- } else {
132- unreachable ! ( ) ;
133- }
134- }
135- module. define_function ( func_id, & mut Context :: for_function ( func) ) . unwrap ( ) ;
162+ } else {
163+ unreachable ! ( ) ;
164+ } ;
165+ ModuleRelocTarget :: user ( ext_name. namespace , ext_name. index )
166+ }
167+ FinalizedRelocTarget :: ExternalName ( ExternalName :: TestCase ( _) ) => {
168+ unimplemented ! ( )
169+ }
170+ FinalizedRelocTarget :: ExternalName ( ExternalName :: LibCall ( libcall) ) => {
171+ ModuleRelocTarget :: LibCall ( libcall)
172+ }
173+ FinalizedRelocTarget :: ExternalName ( ExternalName :: KnownSymbol ( ks) ) => {
174+ ModuleRelocTarget :: KnownSymbol ( ks)
175+ }
176+ FinalizedRelocTarget :: Func ( offset) => {
177+ ModuleRelocTarget :: FunctionOffset ( func_id, offset)
178+ }
179+ } ;
180+ ModuleReloc { offset : reloc. offset , kind : reloc. kind , name, addend : reloc. addend }
181+ } ;
182+
183+ let relocs = buffer. relocs ( ) . iter ( ) . map ( remap_reloc) . collect :: < Vec < _ > > ( ) ;
184+ module
185+ . define_function_bytes ( func_id, buffer. alignment as u64 , buffer. data ( ) , & relocs)
186+ . unwrap ( ) ;
136187 }
137188
138189 for ( data_id, mut data) in self . inner . data_objects {
@@ -219,7 +270,7 @@ impl Module for SerializableModule {
219270 & mut self ,
220271 func_id : FuncId ,
221272 ctx : & mut Context ,
222- ctrl_plane : & mut ControlPlane ,
273+ _ctrl_plane : & mut ControlPlane ,
223274 ) -> ModuleResult < ( ) > {
224275 let decl = self . inner . declarations . get_function_decl ( func_id) ;
225276 if !decl. linkage . is_definable ( ) {
@@ -234,12 +285,9 @@ impl Module for SerializableModule {
234285 ) ) ;
235286 }
236287
237- ctx. verify_if ( & * self . isa ) ?;
238- ctx. optimize ( & * self . isa , ctrl_plane) ?;
239-
240- // FIXME compile to machine code
241-
242- self . inner . functions . insert ( func_id, ctx. func . clone ( ) ) ;
288+ self . inner
289+ . functions
290+ . insert ( func_id, RefCell :: new ( FunctionMaybeCompiled :: Ir ( ctx. func . clone ( ) ) ) ) ;
243291
244292 Ok ( ( ) )
245293 }
0 commit comments