@@ -540,13 +540,12 @@ pub fn run_passes(sess: &Session,
540540 metadata_config. emit_bc = true ;
541541 }
542542
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.
544544 // Whenever an rlib is created, the bitcode is inserted into the
545545 // archive in order to allow LTO against it.
546546 let needs_crate_bitcode =
547547 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 ) ;
550549 if needs_crate_bitcode {
551550 modules_config. emit_bc = true ;
552551 }
@@ -602,19 +601,8 @@ pub fn run_passes(sess: &Session,
602601 // Process the work items, optionally using worker threads.
603602 if sess. opts . cg . codegen_units == 1 {
604603 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- }
613604 } else {
614605 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" ) ;
618606 }
619607
620608 // All codegen is finished.
@@ -624,14 +612,14 @@ pub fn run_passes(sess: &Session,
624612
625613 // Produce final compile outputs.
626614
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 | {
628616 // Three cases:
629617 if sess. opts . cg . codegen_units == 1 {
630618 // 1) Only one codegen unit. In this case it's no difficulty
631619 // to copy `foo.0.x` to `foo.x`.
632620 fs:: copy ( & crate_output. with_extension ( ext) ,
633621 & crate_output. path ( output_type) ) . unwrap ( ) ;
634- if !sess. opts . cg . save_temps {
622+ if !sess. opts . cg . save_temps && !keep_numbered {
635623 // The user just wants `foo.x`, not `foo.0.x`.
636624 remove ( sess, & crate_output. with_extension ( ext) ) ;
637625 }
@@ -716,17 +704,18 @@ pub fn run_passes(sess: &Session,
716704 // Flag to indicate whether the user explicitly requested bitcode.
717705 // Otherwise, we produced it only as a temporary output, and will need
718706 // 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 ;
722708 for output_type in output_types. iter ( ) {
723709 match * output_type {
724710 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 ) ;
727716 } ,
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 ) ; } ,
730719 OutputTypeObject => { link_obj ( & crate_output. path ( OutputTypeObject ) ) ; } ,
731720 OutputTypeExe => {
732721 // If OutputTypeObject is already in the list, then
@@ -739,7 +728,7 @@ pub fn run_passes(sess: &Session,
739728 } ,
740729 }
741730 }
742- let save_bitcode = save_bitcode ;
731+ let user_wants_bitcode = user_wants_bitcode ;
743732
744733 // Clean up unwanted temporary files.
745734
@@ -755,22 +744,36 @@ pub fn run_passes(sess: &Session,
755744
756745 if !sess. opts . cg . save_temps {
757746 // 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+
761764 for i in range ( 0 , trans. modules . len ( ) ) {
762765 if modules_config. emit_obj {
763766 let ext = format ! ( "{}.o" , i) ;
764767 remove ( sess, & crate_output. with_extension ( ext. as_slice ( ) ) ) ;
765768 }
766769
767- if modules_config. emit_bc && !save_bitcode {
770+ if modules_config. emit_bc && !keep_numbered_bitcode {
768771 let ext = format ! ( "{}.bc" , i) ;
769772 remove ( sess, & crate_output. with_extension ( ext. as_slice ( ) ) ) ;
770773 }
771774 }
772775
773- if metadata_config. emit_bc && !save_bitcode {
776+ if metadata_config. emit_bc && !user_wants_bitcode {
774777 remove ( sess, & crate_output. with_extension ( "metadata.bc" ) ) ;
775778 }
776779 }
0 commit comments