@@ -240,6 +240,9 @@ pub struct ModuleConfig {
240
240
/// Some(level) to optimize binary size, or None to not affect program size.
241
241
opt_size : Option < llvm:: CodeGenOptSize > ,
242
242
243
+ pgo_gen : Option < String > ,
244
+ pgo_use : String ,
245
+
243
246
// Flags indicating which outputs to produce.
244
247
emit_no_opt_bc : bool ,
245
248
emit_bc : bool ,
@@ -274,6 +277,9 @@ impl ModuleConfig {
274
277
opt_level : None ,
275
278
opt_size : None ,
276
279
280
+ pgo_gen : None ,
281
+ pgo_use : String :: new ( ) ,
282
+
277
283
emit_no_opt_bc : false ,
278
284
emit_bc : false ,
279
285
emit_bc_compressed : false ,
@@ -492,8 +498,13 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
492
498
opt. message) ) ;
493
499
}
494
500
}
495
-
496
- _ => ( ) ,
501
+ llvm:: diagnostic:: PGO ( diagnostic_ref) => {
502
+ let msg = llvm:: build_string ( |s| {
503
+ llvm:: LLVMRustWriteDiagnosticInfoToString ( diagnostic_ref, s)
504
+ } ) . expect ( "non-UTF8 PGO diagnostic" ) ;
505
+ diag_handler. warn ( & msg) ;
506
+ }
507
+ llvm:: diagnostic:: UnknownDiagnostic ( ..) => { } ,
497
508
}
498
509
}
499
510
@@ -932,6 +943,9 @@ pub fn start_async_translation(tcx: TyCtxt,
932
943
modules_config. passes . push ( "insert-gcov-profiling" . to_owned ( ) )
933
944
}
934
945
946
+ modules_config. pgo_gen = sess. opts . debugging_opts . pgo_gen . clone ( ) ;
947
+ modules_config. pgo_use = sess. opts . debugging_opts . pgo_use . clone ( ) ;
948
+
935
949
modules_config. opt_level = Some ( get_llvm_opt_level ( sess. opts . optimize ) ) ;
936
950
modules_config. opt_size = Some ( get_llvm_opt_size ( sess. opts . optimize ) ) ;
937
951
@@ -2046,18 +2060,36 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
2046
2060
config : & ModuleConfig ,
2047
2061
opt_level : llvm:: CodeGenOptLevel ,
2048
2062
f : & mut FnMut ( llvm:: PassManagerBuilderRef ) ) {
2063
+ use std:: ptr;
2064
+
2049
2065
// Create the PassManagerBuilder for LLVM. We configure it with
2050
2066
// reasonable defaults and prepare it to actually populate the pass
2051
2067
// manager.
2052
2068
let builder = llvm:: LLVMPassManagerBuilderCreate ( ) ;
2053
2069
let opt_size = config. opt_size . unwrap_or ( llvm:: CodeGenOptSizeNone ) ;
2054
2070
let inline_threshold = config. inline_threshold ;
2055
2071
2056
- llvm:: LLVMRustConfigurePassManagerBuilder ( builder,
2057
- opt_level,
2058
- config. merge_functions ,
2059
- config. vectorize_slp ,
2060
- config. vectorize_loop ) ;
2072
+ let pgo_gen_path = config. pgo_gen . as_ref ( ) . map ( |s| {
2073
+ let s = if s. is_empty ( ) { "default_%m.profraw" } else { s } ;
2074
+ CString :: new ( s. as_bytes ( ) ) . unwrap ( )
2075
+ } ) ;
2076
+
2077
+ let pgo_use_path = if config. pgo_use . is_empty ( ) {
2078
+ None
2079
+ } else {
2080
+ Some ( CString :: new ( config. pgo_use . as_bytes ( ) ) . unwrap ( ) )
2081
+ } ;
2082
+
2083
+ llvm:: LLVMRustConfigurePassManagerBuilder (
2084
+ builder,
2085
+ opt_level,
2086
+ config. merge_functions ,
2087
+ config. vectorize_slp ,
2088
+ config. vectorize_loop ,
2089
+ pgo_gen_path. as_ref ( ) . map_or ( ptr:: null ( ) , |s| s. as_ptr ( ) ) ,
2090
+ pgo_use_path. as_ref ( ) . map_or ( ptr:: null ( ) , |s| s. as_ptr ( ) ) ,
2091
+ ) ;
2092
+
2061
2093
llvm:: LLVMPassManagerBuilderSetSizeLevel ( builder, opt_size as u32 ) ;
2062
2094
2063
2095
if opt_size != llvm:: CodeGenOptSizeNone {
0 commit comments