@@ -540,13 +540,12 @@ pub fn run_passes(sess: &Session,
540
540
metadata_config. emit_bc = true ;
541
541
}
542
542
543
- // Emit a bitcode file for the crate if we're emitting an rlib.
543
+ // Emit bitcode files for the crate if we're emitting an rlib.
544
544
// Whenever an rlib is created, the bitcode is inserted into the
545
545
// archive in order to allow LTO against it.
546
546
let needs_crate_bitcode =
547
547
sess. crate_types . borrow ( ) . contains ( & config:: CrateTypeRlib ) &&
548
- sess. opts . output_types . contains ( & OutputTypeExe ) &&
549
- sess. opts . cg . codegen_units == 1 ;
548
+ sess. opts . output_types . contains ( & OutputTypeExe ) ;
550
549
if needs_crate_bitcode {
551
550
modules_config. emit_bc = true ;
552
551
}
@@ -602,19 +601,8 @@ pub fn run_passes(sess: &Session,
602
601
// Process the work items, optionally using worker threads.
603
602
if sess. opts . cg . codegen_units == 1 {
604
603
run_work_singlethreaded ( sess, trans. reachable . as_slice ( ) , work_items) ;
605
-
606
- if needs_crate_bitcode {
607
- // The only bitcode file produced (aside from metadata) was
608
- // "crate.0.bc". Rename to "crate.bc" since that's what
609
- // `link_rlib` expects to find.
610
- fs:: copy ( & crate_output. with_extension ( "0.bc" ) ,
611
- & crate_output. temp_path ( OutputTypeBitcode ) ) . unwrap ( ) ;
612
- }
613
604
} else {
614
605
run_work_multithreaded ( sess, work_items, sess. opts . cg . codegen_units ) ;
615
-
616
- assert ! ( !needs_crate_bitcode,
617
- "can't produce a crate bitcode file from multiple compilation units" ) ;
618
606
}
619
607
620
608
// All codegen is finished.
@@ -624,14 +612,14 @@ pub fn run_passes(sess: &Session,
624
612
625
613
// Produce final compile outputs.
626
614
627
- let copy_if_one_unit = |ext : & str , output_type : OutputType | {
615
+ let copy_if_one_unit = |ext : & str , output_type : OutputType , keep_numbered : bool | {
628
616
// Three cases:
629
617
if sess. opts . cg . codegen_units == 1 {
630
618
// 1) Only one codegen unit. In this case it's no difficulty
631
619
// to copy `foo.0.x` to `foo.x`.
632
620
fs:: copy ( & crate_output. with_extension ( ext) ,
633
621
& crate_output. path ( output_type) ) . unwrap ( ) ;
634
- if !sess. opts . cg . save_temps {
622
+ if !sess. opts . cg . save_temps && !keep_numbered {
635
623
// The user just wants `foo.x`, not `foo.0.x`.
636
624
remove ( sess, & crate_output. with_extension ( ext) ) ;
637
625
}
@@ -716,17 +704,18 @@ pub fn run_passes(sess: &Session,
716
704
// Flag to indicate whether the user explicitly requested bitcode.
717
705
// Otherwise, we produced it only as a temporary output, and will need
718
706
// to get rid of it.
719
- // FIXME: Since we don't support LTO anyway, maybe we can avoid
720
- // producing the temporary .0.bc's in the first place?
721
- let mut save_bitcode = false ;
707
+ let mut user_wants_bitcode = false ;
722
708
for output_type in output_types. iter ( ) {
723
709
match * output_type {
724
710
OutputTypeBitcode => {
725
- save_bitcode = true ;
726
- copy_if_one_unit ( "0.bc" , OutputTypeBitcode ) ;
711
+ user_wants_bitcode = true ;
712
+ // Copy to .bc, but always keep the .0.bc. There is a later
713
+ // check to figure out if we should delete .0.bc files, or keep
714
+ // them for making an rlib.
715
+ copy_if_one_unit ( "0.bc" , OutputTypeBitcode , true ) ;
727
716
} ,
728
- OutputTypeLlvmAssembly => { copy_if_one_unit ( "0.ll" , OutputTypeLlvmAssembly ) ; } ,
729
- OutputTypeAssembly => { copy_if_one_unit ( "0.s" , OutputTypeAssembly ) ; } ,
717
+ OutputTypeLlvmAssembly => { copy_if_one_unit ( "0.ll" , OutputTypeLlvmAssembly , false ) ; } ,
718
+ OutputTypeAssembly => { copy_if_one_unit ( "0.s" , OutputTypeAssembly , false ) ; } ,
730
719
OutputTypeObject => { link_obj ( & crate_output. path ( OutputTypeObject ) ) ; } ,
731
720
OutputTypeExe => {
732
721
// If OutputTypeObject is already in the list, then
@@ -739,7 +728,7 @@ pub fn run_passes(sess: &Session,
739
728
} ,
740
729
}
741
730
}
742
- let save_bitcode = save_bitcode ;
731
+ let user_wants_bitcode = user_wants_bitcode ;
743
732
744
733
// Clean up unwanted temporary files.
745
734
@@ -755,22 +744,36 @@ pub fn run_passes(sess: &Session,
755
744
756
745
if !sess. opts . cg . save_temps {
757
746
// Remove the temporary .0.o objects. If the user didn't
758
- // explicitly request bitcode (with --emit=bc), we must remove
759
- // .0.bc as well. (We don't touch the crate.bc that may have been
760
- // produced earlier.)
747
+ // explicitly request bitcode (with --emit=bc), and the bitcode is not
748
+ // needed for building an rlib, then we must remove .0.bc as well.
749
+
750
+ // Specific rules for keeping .0.bc:
751
+ // - If we're building an rlib (`needs_crate_bitcode`), then keep
752
+ // it.
753
+ // - If the user requested bitcode (`user_wants_bitcode`), and
754
+ // codegen_units > 1, then keep it.
755
+ // - If the user requested bitcode but codegen_units == 1, then we
756
+ // can toss .0.bc because we copied it to .bc earlier.
757
+ // - If we're not building an rlib and the user didn't request
758
+ // bitcode, then delete .0.bc.
759
+ // If you change how this works, also update back::link::link_rlib,
760
+ // where .0.bc files are (maybe) deleted after making an rlib.
761
+ let keep_numbered_bitcode = needs_crate_bitcode ||
762
+ ( user_wants_bitcode && sess. opts . cg . codegen_units > 1 ) ;
763
+
761
764
for i in range ( 0 , trans. modules . len ( ) ) {
762
765
if modules_config. emit_obj {
763
766
let ext = format ! ( "{}.o" , i) ;
764
767
remove ( sess, & crate_output. with_extension ( ext. as_slice ( ) ) ) ;
765
768
}
766
769
767
- if modules_config. emit_bc && !save_bitcode {
770
+ if modules_config. emit_bc && !keep_numbered_bitcode {
768
771
let ext = format ! ( "{}.bc" , i) ;
769
772
remove ( sess, & crate_output. with_extension ( ext. as_slice ( ) ) ) ;
770
773
}
771
774
}
772
775
773
- if metadata_config. emit_bc && !save_bitcode {
776
+ if metadata_config. emit_bc && !user_wants_bitcode {
774
777
remove ( sess, & crate_output. with_extension ( "metadata.bc" ) ) ;
775
778
}
776
779
}
0 commit comments