48
48
49
49
LLVM_BOLT_CRATES = LLVM_PGO_CRATES
50
50
51
+
51
52
class Pipeline :
52
53
# Paths
53
54
def checkout_path (self ) -> Path :
@@ -86,6 +87,9 @@ def opt_artifacts(self) -> Path:
86
87
def llvm_profile_dir_root (self ) -> Path :
87
88
return self .opt_artifacts () / "llvm-pgo"
88
89
90
+ def llvm_profile_merged_file_intermediate (self ) -> Path :
91
+ return self .opt_artifacts () / "llvm-pgo-intermediate.profdata"
92
+
89
93
def llvm_profile_merged_file (self ) -> Path :
90
94
return self .opt_artifacts () / "llvm-pgo.profdata"
91
95
@@ -450,6 +454,7 @@ def cmd(
450
454
)
451
455
return subprocess .run (args , env = environment , check = True )
452
456
457
+
453
458
class BenchmarkRunner :
454
459
def run_rustc (self , pipeline : Pipeline ):
455
460
raise NotImplementedError
@@ -460,6 +465,7 @@ def run_llvm(self, pipeline: Pipeline):
460
465
def run_bolt (self , pipeline : Pipeline ):
461
466
raise NotImplementedError
462
467
468
+
463
469
class DefaultBenchmarkRunner (BenchmarkRunner ):
464
470
def run_rustc (self , pipeline : Pipeline ):
465
471
# Here we're profiling the `rustc` frontend, so we also include `Check`.
@@ -473,6 +479,7 @@ def run_rustc(self, pipeline: Pipeline):
473
479
LLVM_PROFILE_FILE = str (pipeline .rustc_profile_template_path ())
474
480
)
475
481
)
482
+
476
483
def run_llvm (self , pipeline : Pipeline ):
477
484
run_compiler_benchmarks (
478
485
pipeline ,
@@ -489,6 +496,7 @@ def run_bolt(self, pipeline: Pipeline):
489
496
crates = LLVM_BOLT_CRATES
490
497
)
491
498
499
+
492
500
def run_compiler_benchmarks (
493
501
pipeline : Pipeline ,
494
502
profiles : List [str ],
@@ -622,7 +630,7 @@ def gather_llvm_profiles(pipeline: Pipeline, runner: BenchmarkRunner):
622
630
623
631
runner .run_llvm (pipeline )
624
632
625
- profile_path = pipeline .llvm_profile_merged_file ()
633
+ profile_path = pipeline .llvm_profile_merged_file_intermediate ()
626
634
LOGGER .info (f"Merging LLVM PGO profiles to { profile_path } " )
627
635
cmd ([
628
636
pipeline .downloaded_llvm_dir () / "bin" / "llvm-profdata" ,
@@ -642,13 +650,37 @@ def gather_llvm_profiles(pipeline: Pipeline, runner: BenchmarkRunner):
642
650
delete_directory (pipeline .llvm_profile_dir_root ())
643
651
644
652
653
+ def gather_llvm_cs_profiles (pipeline : Pipeline , runner : BenchmarkRunner ):
654
+ LOGGER .info ("Running benchmarks with CS PGO instrumented LLVM" )
655
+
656
+ runner .run_llvm (pipeline )
657
+
658
+ profile_path = pipeline .llvm_profile_merged_file ()
659
+ LOGGER .info (f"Merging LLVM CS PGO profiles to { profile_path } " )
660
+ cmd ([
661
+ pipeline .downloaded_llvm_dir () / "bin" / "llvm-profdata" ,
662
+ "merge" ,
663
+ "-o" , profile_path ,
664
+ pipeline .llvm_profile_dir_root (),
665
+ pipeline .llvm_profile_merged_file_intermediate ()
666
+ ])
667
+
668
+ LOGGER .info ("LLVM CS PGO statistics" )
669
+ LOGGER .info (f"{ profile_path } : { format_bytes (get_path_size (profile_path ))} " )
670
+ LOGGER .info (
671
+ f"{ pipeline .llvm_profile_dir_root ()} : { format_bytes (get_path_size (pipeline .llvm_profile_dir_root ()))} " )
672
+ LOGGER .info (f"Profile file count: { count_files (pipeline .llvm_profile_dir_root ())} " )
673
+
674
+ # We don't need the individual .profraw files now that they have been merged
675
+ # into a final .profdata
676
+ delete_directory (pipeline .llvm_profile_dir_root ())
677
+
678
+
645
679
def gather_rustc_profiles (pipeline : Pipeline , runner : BenchmarkRunner ):
646
680
LOGGER .info ("Running benchmarks with PGO instrumented rustc" )
647
681
648
-
649
682
runner .run_rustc (pipeline )
650
683
651
-
652
684
profile_path = pipeline .rustc_profile_merged_file ()
653
685
LOGGER .info (f"Merging Rustc PGO profiles to { profile_path } " )
654
686
cmd ([
@@ -787,6 +819,27 @@ def execute_build_pipeline(timer: Timer, pipeline: Pipeline, runner: BenchmarkRu
787
819
print_free_disk_space (pipeline )
788
820
789
821
clear_llvm_files (pipeline )
822
+
823
+ # Stage 1b: Build rustc + CS PGO instrumented LLVM
824
+ with timer .section ("Stage 1b (LLVM CS PGO)" ) as stage1b :
825
+ with stage1 .section ("Build rustc and LLVM" ) as rustc_build :
826
+ build_rustc (pipeline , args = [
827
+ "--llvm-profile-generate" ,
828
+ "--llvm-profile-use" ,
829
+ pipeline .llvm_profile_merged_file_intermediate ()
830
+ ], env = dict (
831
+ LLVM_USE_CS_PGO = "1" ,
832
+ LLVM_PROFILE_DIR = str (pipeline .llvm_profile_dir_root () / "prof-%p" ),
833
+
834
+ ))
835
+ record_metrics (pipeline , rustc_build )
836
+
837
+ with stage1b .section ("Gather profiles" ):
838
+ gather_llvm_cs_profiles (pipeline , runner )
839
+ print_free_disk_space (pipeline )
840
+
841
+ clear_llvm_files (pipeline )
842
+
790
843
final_build_args += [
791
844
"--llvm-profile-use" ,
792
845
pipeline .llvm_profile_merged_file ()
@@ -865,6 +918,7 @@ def run(runner: BenchmarkRunner):
865
918
866
919
print_binary_sizes (pipeline )
867
920
921
+
868
922
if __name__ == "__main__" :
869
923
runner = DefaultBenchmarkRunner ()
870
924
run (runner )
0 commit comments