@@ -38,7 +38,6 @@ pub type Result<T> = std::result::Result<T, ErrorGuaranteed>;
38
38
#[ derive( Default ) ]
39
39
pub struct Options {
40
40
pub compact_ids : bool ,
41
- pub dce : bool ,
42
41
pub early_report_zombies : bool ,
43
42
pub infer_storage_classes : bool ,
44
43
pub structurize : bool ,
@@ -272,6 +271,13 @@ pub fn link(
272
271
output
273
272
} ;
274
273
274
+ // FIXME(eddyb) do this before ever saving the original `.spv`s to disk.
275
+ {
276
+ let _timer = sess. timer ( "link_dce-post-merge" ) ;
277
+ dce:: dce ( & mut output) ;
278
+ }
279
+
280
+ // HACK(eddyb) this has to be after DCE, to not break SPIR-T w/ dead decorations.
275
281
if let Some ( dir) = & opts. dump_post_merge {
276
282
dump_spv_and_spirt ( & output, dir. join ( disambiguated_crate_name_for_dumps) ) ;
277
283
}
@@ -292,6 +298,11 @@ pub fn link(
292
298
import_export_link:: run ( opts, sess, & mut output) ?;
293
299
}
294
300
301
+ {
302
+ let _timer = sess. timer ( "link_dce-post-link" ) ;
303
+ dce:: dce ( & mut output) ;
304
+ }
305
+
295
306
{
296
307
let _timer = sess. timer ( "link_fragment_inst_check" ) ;
297
308
simple_passes:: check_fragment_insts ( sess, & output) ?;
@@ -306,29 +317,11 @@ pub fn link(
306
317
}
307
318
308
319
if opts. early_report_zombies {
309
- // HACK(eddyb) `report_and_remove_zombies` is bad at determining whether
310
- // some things are dead (such as whole blocks), and there's no reason to
311
- // *not* run DCE, given SPIR-T exists and makes DCE mandatory, but we're
312
- // still only going to do the minimum necessary ("block ordering").
313
- {
314
- let _timer = sess. timer ( "link_block_ordering_pass-before-report_and_remove_zombies" ) ;
315
- for func in & mut output. functions {
316
- simple_passes:: block_ordering_pass ( func) ;
317
- }
318
- }
319
-
320
320
let _timer = sess. timer ( "link_report_and_remove_zombies" ) ;
321
321
zombies:: report_and_remove_zombies ( sess, & mut output) ?;
322
322
}
323
323
324
324
if opts. infer_storage_classes {
325
- // HACK(eddyb) this is not the best approach, but storage class inference
326
- // can still fail in entirely legitimate ways (i.e. mismatches in zombies).
327
- if !opts. early_report_zombies {
328
- let _timer = sess. timer ( "link_dce-before-specialize_generic_storage_class" ) ;
329
- dce:: dce ( & mut output) ;
330
- }
331
-
332
325
let _timer = sess. timer ( "specialize_generic_storage_class" ) ;
333
326
// HACK(eddyb) `specializer` requires functions' blocks to be in RPO order
334
327
// (i.e. `block_ordering_pass`) - this could be relaxed by using RPO visit
@@ -361,7 +354,7 @@ pub fn link(
361
354
362
355
// NOTE(eddyb) with SPIR-T, we can do `mem2reg` before inlining, too!
363
356
{
364
- if opts . dce {
357
+ {
365
358
let _timer = sess. timer ( "link_dce-before-inlining" ) ;
366
359
dce:: dce ( & mut output) ;
367
360
}
@@ -404,13 +397,14 @@ pub fn link(
404
397
}
405
398
}
406
399
407
- if opts . dce {
400
+ {
408
401
let _timer =
409
402
sess. timer ( "link_dce-and-remove_duplicate_debuginfo-after-mem2reg-before-inlining" ) ;
410
403
dce:: dce ( & mut output) ;
411
404
duplicates:: remove_duplicate_debuginfo ( & mut output) ;
412
405
}
413
406
407
+ // HACK(eddyb) this has to be after DCE, to not break SPIR-T w/ dead decorations.
414
408
if let Some ( dir) = & opts. dump_pre_inline {
415
409
dump_spv_and_spirt ( & output, dir. join ( disambiguated_crate_name_for_dumps) ) ;
416
410
}
@@ -420,7 +414,7 @@ pub fn link(
420
414
inline:: inline ( sess, & mut output) ?;
421
415
}
422
416
423
- if opts . dce {
417
+ {
424
418
let _timer = sess. timer ( "link_dce-after-inlining" ) ;
425
419
dce:: dce ( & mut output) ;
426
420
}
@@ -469,7 +463,7 @@ pub fn link(
469
463
}
470
464
}
471
465
472
- if opts . dce {
466
+ {
473
467
let _timer =
474
468
sess. timer ( "link_dce-and-remove_duplicate_debuginfo-after-mem2reg-after-inlining" ) ;
475
469
dce:: dce ( & mut output) ;
@@ -711,6 +705,15 @@ pub fn link(
711
705
) ,
712
706
} ;
713
707
for ( file_stem, output) in output_module_iter {
708
+ // Run DCE again, even if module_output_type == ModuleOutputType::Multiple - the first DCE ran before
709
+ // structurization and mem2reg (for perf reasons), and mem2reg may remove references to
710
+ // invalid types, so we need to DCE again.
711
+ {
712
+ let _timer = sess. timer ( "link_dce-post-split" ) ;
713
+ dce:: dce ( output) ;
714
+ }
715
+
716
+ // HACK(eddyb) this has to be after DCE, to not break SPIR-T w/ dead decorations.
714
717
if let Some ( dir) = & opts. dump_post_split {
715
718
let mut file_name = disambiguated_crate_name_for_dumps. to_os_string ( ) ;
716
719
if let Some ( file_stem) = file_stem {
@@ -720,13 +723,6 @@ pub fn link(
720
723
721
724
dump_spv_and_spirt ( output, dir. join ( file_name) ) ;
722
725
}
723
- // Run DCE again, even if module_output_type == ModuleOutputType::Multiple - the first DCE ran before
724
- // structurization and mem2reg (for perf reasons), and mem2reg may remove references to
725
- // invalid types, so we need to DCE again.
726
- if opts. dce {
727
- let _timer = sess. timer ( "link_dce_2" ) ;
728
- dce:: dce ( output) ;
729
- }
730
726
731
727
{
732
728
let _timer = sess. timer ( "link_remove_duplicate_debuginfo" ) ;
0 commit comments