@@ -206,6 +206,8 @@ impl Step for Llvm {
206
206
}
207
207
}
208
208
209
+ let pgo_compiler_flags = make_pgo_compiler_flags ( & builder, target) ;
210
+
209
211
// This setting makes the LLVM tools link to the dynamic LLVM library,
210
212
// which saves both memory during parallel links and overall disk space
211
213
// for the tools. We don't do this on every platform as it doesn't work
@@ -316,7 +318,7 @@ impl Step for Llvm {
316
318
cfg. define ( "LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN" , "YES" ) ;
317
319
}
318
320
319
- configure_cmake ( builder, target, & mut cfg, true ) ;
321
+ configure_cmake ( builder, target, & mut cfg, pgo_compiler_flags , true ) ;
320
322
321
323
// FIXME: we don't actually need to build all LLVM tools and all LLVM
322
324
// libraries here, e.g., we just want a few components and a few
@@ -359,6 +361,7 @@ fn configure_cmake(
359
361
builder : & Builder < ' _ > ,
360
362
target : TargetSelection ,
361
363
cfg : & mut cmake:: Config ,
364
+ pgo_compiler_flags : Option < String > ,
362
365
use_compiler_launcher : bool ,
363
366
) {
364
367
// Do not print installation messages for up-to-date files.
@@ -470,6 +473,10 @@ fn configure_cmake(
470
473
if let Some ( ref s) = builder. config . llvm_cflags {
471
474
cflags. push_str ( & format ! ( " {}" , s) ) ;
472
475
}
476
+ if let & Some ( ref pgo_compiler_flags) = & pgo_compiler_flags {
477
+ cflags. push_str ( & format ! ( " {}" , pgo_compiler_flags) ) ;
478
+ }
479
+
473
480
// Some compiler features used by LLVM (such as thread locals) will not work on a min version below iOS 10.
474
481
if target. contains ( "apple-ios" ) {
475
482
if target. contains ( "86-" ) {
@@ -489,6 +496,9 @@ fn configure_cmake(
489
496
if let Some ( ref s) = builder. config . llvm_cxxflags {
490
497
cxxflags. push_str ( & format ! ( " {}" , s) ) ;
491
498
}
499
+ if let & Some ( ref pgo_compiler_flags) = & pgo_compiler_flags {
500
+ cxxflags. push_str ( & format ! ( " {}" , pgo_compiler_flags) ) ;
501
+ }
492
502
if builder. config . llvm_clang_cl . is_some ( ) {
493
503
cxxflags. push_str ( & format ! ( " --target={}" , target) )
494
504
}
@@ -557,7 +567,7 @@ impl Step for Lld {
557
567
t ! ( fs:: create_dir_all( & out_dir) ) ;
558
568
559
569
let mut cfg = cmake:: Config :: new ( builder. src . join ( "src/llvm-project/lld" ) ) ;
560
- configure_cmake ( builder, target, & mut cfg, true ) ;
570
+ configure_cmake ( builder, target, & mut cfg, None , true ) ;
561
571
562
572
// This is an awful, awful hack. Discovered when we migrated to using
563
573
// clang-cl to compile LLVM/LLD it turns out that LLD, when built out of
@@ -747,7 +757,7 @@ impl Step for Sanitizers {
747
757
// Unfortunately sccache currently lacks support to build them successfully.
748
758
// Disable compiler launcher on Darwin targets to avoid potential issues.
749
759
let use_compiler_launcher = !self . target . contains ( "apple-darwin" ) ;
750
- configure_cmake ( builder, self . target , & mut cfg, use_compiler_launcher) ;
760
+ configure_cmake ( builder, self . target , & mut cfg, None , use_compiler_launcher) ;
751
761
752
762
t ! ( fs:: create_dir_all( & out_dir) ) ;
753
763
cfg. out_dir ( out_dir) ;
@@ -853,3 +863,79 @@ impl HashStamp {
853
863
fs:: write ( & self . path , self . hash . as_deref ( ) . unwrap_or ( b"" ) )
854
864
}
855
865
}
866
+
867
+
868
+ fn make_pgo_compiler_flags ( builder : & Builder < ' _ > , target : TargetSelection ) -> Option < String > {
869
+ let profile_generate_path = profiling_path ( builder, target, & builder. config . llvm_profile_generate , false ) ;
870
+ let profile_use_path = profiling_path ( builder, target, & builder. config . llvm_profile_use , true ) ;
871
+
872
+ let mut pgo_compiler_flags = String :: new ( ) ;
873
+
874
+ match ( profile_generate_path, profile_use_path) {
875
+ ( Some ( _) , Some ( _) ) => {
876
+ panic ! ( "error: only one of llvm.profile-generate and \
877
+ llvm.profile-use is allowed to be set at a time") ;
878
+ }
879
+ ( None , None ) => {
880
+ return None ;
881
+ }
882
+ ( Some ( profile_generate_path) , None ) => {
883
+ if !builder. config . llvm_link_shared {
884
+ panic ! ( "error: llvm.link_shared is false but \
885
+ llvm.profile-generate requires it to be true") ;
886
+ }
887
+
888
+ pgo_compiler_flags += & format ! ( "-fprofile-generate={}" , profile_generate_path. display( ) ) ;
889
+ }
890
+ ( None , Some ( profile_use_path) ) => {
891
+ pgo_compiler_flags += & format ! ( "-fprofile-use={}" , profile_use_path. display( ) ) ;
892
+ pgo_compiler_flags += " -mllvm -pgo-warn-missing-function" ;
893
+ }
894
+ }
895
+
896
+ assert_cc_is_clang_for_pgo ( builder, target) ;
897
+
898
+ pgo_compiler_flags += & format ! ( " -mllvm -static-func-strip-dirname-prefix={}" ,
899
+ builder. config. src. components( ) . count( ) ) ;
900
+
901
+ Some ( pgo_compiler_flags)
902
+ }
903
+
904
+ fn profiling_path (
905
+ builder : & Builder < ' _ > ,
906
+ target : TargetSelection ,
907
+ flag : & Option < String > ,
908
+ is_use_phase : bool
909
+ ) -> Option < PathBuf > {
910
+
911
+ let out_dir = builder. profdata_out ( target) ;
912
+
913
+ flag. as_ref ( ) . and_then ( |path| {
914
+ if path == "default-path" {
915
+ assert ! ( out_dir. is_absolute( ) ) ;
916
+
917
+ if is_use_phase {
918
+ Some ( out_dir. join ( "llvm" ) . join ( "merged.profdata" ) )
919
+ } else {
920
+ Some ( out_dir. join ( "llvm" ) )
921
+ }
922
+ } else {
923
+ let path = PathBuf :: from ( & path) ;
924
+ if !path. is_absolute ( ) {
925
+ eprintln ! ( "warning: Ignoring llvm.profile-generate because \
926
+ it is a relative path: `{}`", path. display( ) ) ;
927
+ None
928
+ } else {
929
+ Some ( path)
930
+ }
931
+ }
932
+ } )
933
+ }
934
+
935
+ fn assert_cc_is_clang_for_pgo ( builder : & Builder < ' _ > , target : TargetSelection ) {
936
+ // This is a stub impl. Make more intelligent.
937
+ if !builder. cc ( target) . to_string_lossy ( ) . contains ( "clang" ) ||
938
+ !builder. cxx ( target) . map ( |cxx| cxx. to_string_lossy ( ) . contains ( "clang" ) ) . unwrap_or ( false ) {
939
+ panic ! ( "error: using PGO for LLVM is currently only supported with Clang" ) ;
940
+ }
941
+ }
0 commit comments