10
10
11
11
use back:: lto;
12
12
use back:: link:: { get_linker, remove} ;
13
+ use rustc_incremental:: save_trans_partition;
13
14
use session:: config:: { OutputFilenames , Passes , SomePasses , AllPasses } ;
14
15
use session:: Session ;
15
16
use session:: config:: { self , OutputType } ;
16
17
use llvm;
17
18
use llvm:: { ModuleRef , TargetMachineRef , PassManagerRef , DiagnosticInfoRef , ContextRef } ;
18
19
use llvm:: SMDiagnosticRef ;
19
- use { CrateTranslation , ModuleTranslation } ;
20
+ use { CrateTranslation , ModuleLlvm , ModuleSource , ModuleTranslation } ;
20
21
use util:: common:: time;
21
22
use util:: common:: path2cstr;
22
23
use errors:: { self , Handler , Level , DiagnosticBuilder } ;
@@ -26,6 +27,7 @@ use syntax_pos::MultiSpan;
26
27
use std:: collections:: HashMap ;
27
28
use std:: ffi:: { CStr , CString } ;
28
29
use std:: fs;
30
+ use std:: io;
29
31
use std:: path:: { Path , PathBuf } ;
30
32
use std:: str;
31
33
use std:: sync:: { Arc , Mutex } ;
@@ -422,10 +424,11 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
422
424
// Unsafe due to LLVM calls.
423
425
unsafe fn optimize_and_codegen ( cgcx : & CodegenContext ,
424
426
mtrans : ModuleTranslation ,
427
+ mllvm : ModuleLlvm ,
425
428
config : ModuleConfig ,
426
429
output_names : OutputFilenames ) {
427
- let llmod = mtrans . llmod ;
428
- let llcx = mtrans . llcx ;
430
+ let llmod = mllvm . llmod ;
431
+ let llcx = mllvm . llcx ;
429
432
let tm = config. tm ;
430
433
431
434
// llcx doesn't outlive this function, so we can put this on the stack.
@@ -628,8 +631,14 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
628
631
pub fn cleanup_llvm ( trans : & CrateTranslation ) {
629
632
for module in trans. modules . iter ( ) {
630
633
unsafe {
631
- llvm:: LLVMDisposeModule ( module. llmod ) ;
632
- llvm:: LLVMContextDispose ( module. llcx ) ;
634
+ match module. source {
635
+ ModuleSource :: Translated ( llvm) => {
636
+ llvm:: LLVMDisposeModule ( llvm. llmod ) ;
637
+ llvm:: LLVMContextDispose ( llvm. llcx ) ;
638
+ }
639
+ ModuleSource :: Preexisting ( _) => {
640
+ }
641
+ }
633
642
}
634
643
}
635
644
}
@@ -743,6 +752,13 @@ pub fn run_passes(sess: &Session,
743
752
run_work_multithreaded ( sess, work_items, num_workers) ;
744
753
}
745
754
755
+ // If in incr. comp. mode, preserve the `.o` files for potential re-use
756
+ for mtrans in trans. modules . iter ( ) {
757
+ let path_to_obj = crate_output. temp_path ( OutputType :: Object , Some ( & mtrans. name ) ) ;
758
+ debug ! ( "wrote module {:?} to {:?}" , mtrans. name, path_to_obj) ;
759
+ save_trans_partition ( sess, & mtrans. name , mtrans. symbol_name_hash , & path_to_obj) ;
760
+ }
761
+
746
762
// All codegen is finished.
747
763
unsafe {
748
764
llvm:: LLVMRustDisposeTargetMachine ( tm) ;
@@ -913,13 +929,46 @@ fn build_work_item(sess: &Session,
913
929
}
914
930
}
915
931
932
+ fn link_or_copy < P : AsRef < Path > , Q : AsRef < Path > > ( p : P , q : Q ) -> io:: Result < ( ) > {
933
+ let p = p. as_ref ( ) ;
934
+ let q = q. as_ref ( ) ;
935
+ if q. exists ( ) {
936
+ try!( fs:: remove_file ( & q) ) ;
937
+ }
938
+ fs:: hard_link ( p, q)
939
+ . or_else ( |_| fs:: copy ( p, q) . map ( |_| ( ) ) )
940
+ }
941
+
916
942
fn execute_work_item ( cgcx : & CodegenContext ,
917
943
work_item : WorkItem ) {
918
944
unsafe {
919
- optimize_and_codegen ( cgcx,
920
- work_item. mtrans ,
921
- work_item. config ,
922
- work_item. output_names ) ;
945
+ match work_item. mtrans . source {
946
+ ModuleSource :: Translated ( mllvm) => {
947
+ debug ! ( "llvm-optimizing {:?}" , work_item. mtrans. name) ;
948
+ optimize_and_codegen ( cgcx,
949
+ work_item. mtrans ,
950
+ mllvm,
951
+ work_item. config ,
952
+ work_item. output_names ) ;
953
+ }
954
+ ModuleSource :: Preexisting ( ref buf) => {
955
+ let obj_out = work_item. output_names . temp_path ( OutputType :: Object ,
956
+ Some ( & work_item. mtrans . name ) ) ;
957
+ debug ! ( "copying pre-existing module `{}` from {} to {}" ,
958
+ work_item. mtrans. name,
959
+ buf. display( ) ,
960
+ obj_out. display( ) ) ;
961
+ match link_or_copy ( buf, & obj_out) {
962
+ Ok ( ( ) ) => { }
963
+ Err ( err) => {
964
+ cgcx. handler . err ( & format ! ( "unable to copy {} to {}: {}" ,
965
+ buf. display( ) ,
966
+ obj_out. display( ) ,
967
+ err) ) ;
968
+ }
969
+ }
970
+ }
971
+ }
923
972
}
924
973
}
925
974
0 commit comments