@@ -25,35 +25,21 @@ use std::sync::Arc;
25
25
use gccjit:: { Context , OutputKind } ;
26
26
use object:: read:: archive:: ArchiveFile ;
27
27
use rustc_codegen_ssa:: back:: lto:: { SerializedModule , ThinModule , ThinShared } ;
28
- use rustc_codegen_ssa:: back:: symbol_export;
29
28
use rustc_codegen_ssa:: back:: write:: { CodegenContext , FatLtoInput } ;
30
29
use rustc_codegen_ssa:: traits:: * ;
31
30
use rustc_codegen_ssa:: { ModuleCodegen , ModuleKind , looks_like_rust_object_file} ;
32
31
use rustc_data_structures:: memmap:: Mmap ;
33
32
use rustc_errors:: { DiagCtxtHandle , FatalError } ;
34
- use rustc_hir:: def_id:: LOCAL_CRATE ;
35
33
use rustc_middle:: bug;
36
34
use rustc_middle:: dep_graph:: WorkProduct ;
37
- use rustc_middle:: middle:: exported_symbols:: { SymbolExportInfo , SymbolExportLevel } ;
38
- use rustc_session:: config:: { CrateType , Lto } ;
35
+ use rustc_session:: config:: Lto ;
39
36
use rustc_target:: spec:: RelocModel ;
40
37
use tempfile:: { TempDir , tempdir} ;
41
38
42
39
use crate :: back:: write:: save_temp_bitcode;
43
- use crate :: errors:: { DynamicLinkingWithLTO , LtoBitcodeFromRlib , LtoDisallowed , LtoDylib } ;
40
+ use crate :: errors:: LtoBitcodeFromRlib ;
44
41
use crate :: { GccCodegenBackend , GccContext , SyncContext , to_gcc_opt_level} ;
45
42
46
- pub fn crate_type_allows_lto ( crate_type : CrateType ) -> bool {
47
- match crate_type {
48
- CrateType :: Executable
49
- | CrateType :: Dylib
50
- | CrateType :: Staticlib
51
- | CrateType :: Cdylib
52
- | CrateType :: Sdylib => true ,
53
- CrateType :: Rlib | CrateType :: ProcMacro => false ,
54
- }
55
- }
56
-
57
43
struct LtoData {
58
44
// TODO(antoyo): use symbols_below_threshold.
59
45
//symbols_below_threshold: Vec<String>,
@@ -63,18 +49,9 @@ struct LtoData {
63
49
64
50
fn prepare_lto (
65
51
cgcx : & CodegenContext < GccCodegenBackend > ,
52
+ each_linked_rlib_for_lto : & [ PathBuf ] ,
66
53
dcx : DiagCtxtHandle < ' _ > ,
67
54
) -> Result < LtoData , FatalError > {
68
- let export_threshold = match cgcx. lto {
69
- // We're just doing LTO for our one crate
70
- Lto :: ThinLocal => SymbolExportLevel :: Rust ,
71
-
72
- // We're doing LTO for the entire crate graph
73
- Lto :: Fat | Lto :: Thin => symbol_export:: crates_export_threshold ( & cgcx. crate_types ) ,
74
-
75
- Lto :: No => panic ! ( "didn't request LTO but we're doing LTO" ) ,
76
- } ;
77
-
78
55
let tmp_path = match tempdir ( ) {
79
56
Ok ( tmp_path) => tmp_path,
80
57
Err ( error) => {
@@ -83,20 +60,6 @@ fn prepare_lto(
83
60
}
84
61
} ;
85
62
86
- let symbol_filter = & |& ( ref name, info) : & ( String , SymbolExportInfo ) | {
87
- if info. level . is_below_threshold ( export_threshold) || info. used {
88
- Some ( name. clone ( ) )
89
- } else {
90
- None
91
- }
92
- } ;
93
- let exported_symbols = cgcx. exported_symbols . as_ref ( ) . expect ( "needs exported symbols for LTO" ) ;
94
- let mut symbols_below_threshold = {
95
- let _timer = cgcx. prof . generic_activity ( "GCC_lto_generate_symbols_below_threshold" ) ;
96
- exported_symbols[ & LOCAL_CRATE ] . iter ( ) . filter_map ( symbol_filter) . collect :: < Vec < String > > ( )
97
- } ;
98
- info ! ( "{} symbols to preserve in this crate" , symbols_below_threshold. len( ) ) ;
99
-
100
63
// If we're performing LTO for the entire crate graph, then for each of our
101
64
// upstream dependencies, find the corresponding rlib and load the bitcode
102
65
// from the archive.
@@ -105,32 +68,7 @@ fn prepare_lto(
105
68
// with either fat or thin LTO
106
69
let mut upstream_modules = Vec :: new ( ) ;
107
70
if cgcx. lto != Lto :: ThinLocal {
108
- // Make sure we actually can run LTO
109
- for crate_type in cgcx. crate_types . iter ( ) {
110
- if !crate_type_allows_lto ( * crate_type) {
111
- dcx. emit_err ( LtoDisallowed ) ;
112
- return Err ( FatalError ) ;
113
- }
114
- if * crate_type == CrateType :: Dylib && !cgcx. opts . unstable_opts . dylib_lto {
115
- dcx. emit_err ( LtoDylib ) ;
116
- return Err ( FatalError ) ;
117
- }
118
- }
119
-
120
- if cgcx. opts . cg . prefer_dynamic && !cgcx. opts . unstable_opts . dylib_lto {
121
- dcx. emit_err ( DynamicLinkingWithLTO ) ;
122
- return Err ( FatalError ) ;
123
- }
124
-
125
- for & ( cnum, ref path) in cgcx. each_linked_rlib_for_lto . iter ( ) {
126
- let exported_symbols =
127
- cgcx. exported_symbols . as_ref ( ) . expect ( "needs exported symbols for LTO" ) ;
128
- {
129
- let _timer = cgcx. prof . generic_activity ( "GCC_lto_generate_symbols_below_threshold" ) ;
130
- symbols_below_threshold
131
- . extend ( exported_symbols[ & cnum] . iter ( ) . filter_map ( symbol_filter) ) ;
132
- }
133
-
71
+ for path in each_linked_rlib_for_lto {
134
72
let archive_data = unsafe {
135
73
Mmap :: map ( File :: open ( path) . expect ( "couldn't open rlib" ) ) . expect ( "couldn't map rlib" )
136
74
} ;
@@ -174,19 +112,18 @@ fn save_as_file(obj: &[u8], path: &Path) -> Result<(), LtoBitcodeFromRlib> {
174
112
/// for further optimization.
175
113
pub ( crate ) fn run_fat (
176
114
cgcx : & CodegenContext < GccCodegenBackend > ,
115
+ each_linked_rlib_for_lto : & [ PathBuf ] ,
177
116
modules : Vec < FatLtoInput < GccCodegenBackend > > ,
178
- cached_modules : Vec < ( SerializedModule < ModuleBuffer > , WorkProduct ) > ,
179
117
) -> Result < ModuleCodegen < GccContext > , FatalError > {
180
118
let dcx = cgcx. create_dcx ( ) ;
181
119
let dcx = dcx. handle ( ) ;
182
- let lto_data = prepare_lto ( cgcx, dcx) ?;
120
+ let lto_data = prepare_lto ( cgcx, each_linked_rlib_for_lto , dcx) ?;
183
121
/*let symbols_below_threshold =
184
122
lto_data.symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
185
123
fat_lto (
186
124
cgcx,
187
125
dcx,
188
126
modules,
189
- cached_modules,
190
127
lto_data. upstream_modules ,
191
128
lto_data. tmp_path ,
192
129
//<o_data.symbols_below_threshold,
@@ -197,7 +134,6 @@ fn fat_lto(
197
134
cgcx : & CodegenContext < GccCodegenBackend > ,
198
135
_dcx : DiagCtxtHandle < ' _ > ,
199
136
modules : Vec < FatLtoInput < GccCodegenBackend > > ,
200
- cached_modules : Vec < ( SerializedModule < ModuleBuffer > , WorkProduct ) > ,
201
137
mut serialized_modules : Vec < ( SerializedModule < ModuleBuffer > , CString ) > ,
202
138
tmp_path : TempDir ,
203
139
//symbols_below_threshold: &[String],
@@ -211,21 +147,12 @@ fn fat_lto(
211
147
// modules that are serialized in-memory.
212
148
// * `in_memory` contains modules which are already parsed and in-memory,
213
149
// such as from multi-CGU builds.
214
- //
215
- // All of `cached_modules` (cached from previous incremental builds) can
216
- // immediately go onto the `serialized_modules` modules list and then we can
217
- // split the `modules` array into these two lists.
218
150
let mut in_memory = Vec :: new ( ) ;
219
- serialized_modules. extend ( cached_modules. into_iter ( ) . map ( |( buffer, wp) | {
220
- info ! ( "pushing cached module {:?}" , wp. cgu_name) ;
221
- ( buffer, CString :: new ( wp. cgu_name ) . unwrap ( ) )
222
- } ) ) ;
223
151
for module in modules {
224
152
match module {
225
153
FatLtoInput :: InMemory ( m) => in_memory. push ( m) ,
226
154
FatLtoInput :: Serialized { name, buffer } => {
227
155
info ! ( "pushing serialized module {:?}" , name) ;
228
- let buffer = SerializedModule :: Local ( buffer) ;
229
156
serialized_modules. push ( ( buffer, CString :: new ( name) . unwrap ( ) ) ) ;
230
157
}
231
158
}
@@ -356,12 +283,13 @@ impl ModuleBufferMethods for ModuleBuffer {
356
283
/// can simply be copied over from the incr. comp. cache.
357
284
pub ( crate ) fn run_thin (
358
285
cgcx : & CodegenContext < GccCodegenBackend > ,
286
+ each_linked_rlib_for_lto : & [ PathBuf ] ,
359
287
modules : Vec < ( String , ThinBuffer ) > ,
360
288
cached_modules : Vec < ( SerializedModule < ModuleBuffer > , WorkProduct ) > ,
361
289
) -> Result < ( Vec < ThinModule < GccCodegenBackend > > , Vec < WorkProduct > ) , FatalError > {
362
290
let dcx = cgcx. create_dcx ( ) ;
363
291
let dcx = dcx. handle ( ) ;
364
- let lto_data = prepare_lto ( cgcx, dcx) ?;
292
+ let lto_data = prepare_lto ( cgcx, each_linked_rlib_for_lto , dcx) ?;
365
293
if cgcx. opts . cg . linker_plugin_lto . enabled ( ) {
366
294
unreachable ! (
367
295
"We should never reach this case if the LTO step \
0 commit comments