@@ -21,7 +21,7 @@ use std::fs::{self, File};
21
21
use std:: path:: { Path , PathBuf } ;
22
22
use std:: sync:: Arc ;
23
23
24
- use gccjit:: { Context , OutputKind } ;
24
+ use gccjit:: { Context , FnAttribute , FunctionType , GlobalKind , OutputKind } ;
25
25
use object:: read:: archive:: ArchiveFile ;
26
26
use rustc_codegen_ssa:: back:: lto:: { LtoModuleCodegen , SerializedModule , ThinModule , ThinShared } ;
27
27
use rustc_codegen_ssa:: back:: symbol_export;
@@ -50,7 +50,7 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
50
50
51
51
struct LtoData {
52
52
// TODO(antoyo): use symbols_below_threshold.
53
- // symbols_below_threshold: Vec<CString >,
53
+ symbols_below_threshold : Vec < String > ,
54
54
upstream_modules : Vec < ( SerializedModule < ModuleBuffer > , CString ) > ,
55
55
tmp_path : TempDir ,
56
56
}
@@ -79,18 +79,21 @@ fn prepare_lto(
79
79
80
80
let symbol_filter = & |& ( ref name, info) : & ( String , SymbolExportInfo ) | {
81
81
if info. level . is_below_threshold ( export_threshold) || info. used {
82
- Some ( CString :: new ( name. as_str ( ) ) . unwrap ( ) )
82
+ Some ( name. clone ( ) )
83
83
} else {
84
84
None
85
85
}
86
86
} ;
87
87
let exported_symbols = cgcx. exported_symbols . as_ref ( ) . expect ( "needs exported symbols for LTO" ) ;
88
+ //println!("1. {:?}", exported_symbols);
88
89
let mut symbols_below_threshold = {
89
90
let _timer = cgcx. prof . generic_activity ( "GCC_lto_generate_symbols_below_threshold" ) ;
90
- exported_symbols[ & LOCAL_CRATE ] . iter ( ) . filter_map ( symbol_filter) . collect :: < Vec < CString > > ( )
91
+ exported_symbols[ & LOCAL_CRATE ] . iter ( ) . filter_map ( symbol_filter) . collect :: < Vec < String > > ( )
91
92
} ;
92
93
info ! ( "{} symbols to preserve in this crate" , symbols_below_threshold. len( ) ) ;
93
94
95
+ //println!("2. {:?}", symbols_below_threshold);
96
+
94
97
// If we're performing LTO for the entire crate graph, then for each of our
95
98
// upstream dependencies, find the corresponding rlib and load the bitcode
96
99
// from the archive.
@@ -119,6 +122,7 @@ fn prepare_lto(
119
122
for & ( cnum, ref path) in cgcx. each_linked_rlib_for_lto . iter ( ) {
120
123
let exported_symbols =
121
124
cgcx. exported_symbols . as_ref ( ) . expect ( "needs exported symbols for LTO" ) ;
125
+ //println!("3. {:?}", exported_symbols);
122
126
{
123
127
let _timer = cgcx. prof . generic_activity ( "GCC_lto_generate_symbols_below_threshold" ) ;
124
128
symbols_below_threshold
@@ -155,8 +159,9 @@ fn prepare_lto(
155
159
}
156
160
}
157
161
162
+ println ! ( "**** 4. {:?}" , symbols_below_threshold) ;
158
163
Ok ( LtoData {
159
- // symbols_below_threshold,
164
+ symbols_below_threshold,
160
165
upstream_modules,
161
166
tmp_path,
162
167
} )
@@ -187,7 +192,7 @@ pub(crate) fn run_fat(
187
192
cached_modules,
188
193
lto_data. upstream_modules ,
189
194
lto_data. tmp_path ,
190
- //& symbols_below_threshold,
195
+ & lto_data . symbols_below_threshold ,
191
196
)
192
197
}
193
198
@@ -198,7 +203,7 @@ fn fat_lto(
198
203
cached_modules : Vec < ( SerializedModule < ModuleBuffer > , WorkProduct ) > ,
199
204
mut serialized_modules : Vec < ( SerializedModule < ModuleBuffer > , CString ) > ,
200
205
tmp_path : TempDir ,
201
- // symbols_below_threshold: &[*const libc::c_char ],
206
+ symbols_below_threshold : & [ String ] ,
202
207
) -> Result < LtoModuleCodegen < GccCodegenBackend > , FatalError > {
203
208
let _timer = cgcx. prof . generic_activity ( "GCC_fat_lto_build_monolithic_module" ) ;
204
209
info ! ( "going for a fat lto" ) ;
@@ -323,6 +328,14 @@ fn fat_lto(
323
328
ptr as *const *const libc::c_char,
324
329
symbols_below_threshold.len() as libc::size_t,
325
330
);*/
331
+ let int_type = module. module_llvm . context . new_type :: < i32 > ( ) ;
332
+ for symbol in symbols_below_threshold {
333
+ println ! ( "*** Keeping symbol: {}" , symbol) ;
334
+ module. module_llvm . context . new_global ( None , GlobalKind :: Imported , int_type, symbol) ;
335
+ }
336
+ let void_type = module. module_llvm . context . new_type :: < ( ) > ( ) ;
337
+ let func = module. module_llvm . context . new_function ( None , FunctionType :: Extern , void_type, & [ ] , "__rust_alloc" , false ) ;
338
+ func. add_attribute ( FnAttribute :: Used ) ;
326
339
save_temp_bitcode ( cgcx, & module, "lto.after-restriction" ) ;
327
340
//}
328
341
}
@@ -359,8 +372,6 @@ pub(crate) fn run_thin(
359
372
let dcx = cgcx. create_dcx ( ) ;
360
373
let dcx = dcx. handle ( ) ;
361
374
let lto_data = prepare_lto ( cgcx, dcx) ?;
362
- /*let symbols_below_threshold =
363
- symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
364
375
if cgcx. opts . cg . linker_plugin_lto . enabled ( ) {
365
376
unreachable ! (
366
377
"We should never reach this case if the LTO step \
@@ -373,7 +384,8 @@ pub(crate) fn run_thin(
373
384
modules,
374
385
lto_data. upstream_modules ,
375
386
lto_data. tmp_path ,
376
- cached_modules, /*, &symbols_below_threshold*/
387
+ cached_modules,
388
+ & lto_data. symbols_below_threshold ,
377
389
)
378
390
}
379
391
@@ -424,8 +436,10 @@ fn thin_lto(
424
436
serialized_modules : Vec < ( SerializedModule < ModuleBuffer > , CString ) > ,
425
437
tmp_path : TempDir ,
426
438
cached_modules : Vec < ( SerializedModule < ModuleBuffer > , WorkProduct ) > ,
427
- // symbols_below_threshold: &[*const libc::c_char ],
439
+ symbols_below_threshold : & [ String ] ,
428
440
) -> Result < ( Vec < LtoModuleCodegen < GccCodegenBackend > > , Vec < WorkProduct > ) , FatalError > {
441
+ println ! ( "********* Thin LTO" ) ;
442
+
429
443
let _timer = cgcx. prof . generic_activity ( "LLVM_thin_lto_global_analysis" ) ;
430
444
info ! ( "going for that thin, thin LTO" ) ;
431
445
@@ -495,6 +509,12 @@ fn thin_lto(
495
509
}
496
510
}
497
511
512
+ /*for symbol in symbols_below_threshold {
513
+ module.module_llvm.context.new_global(symbol);
514
+ }*/
515
+
516
+ println ! ( "**** Name: {:?}\n ******" , name) ;
517
+
498
518
serialized. push ( module) ;
499
519
module_names. push ( name) ;
500
520
}
0 commit comments