@@ -240,6 +240,9 @@ pub struct ModuleConfig {
240240 /// Some(level) to optimize binary size, or None to not affect program size.
241241 opt_size : Option < llvm:: CodeGenOptSize > ,
242242
243+ pgo_gen : Option < String > ,
244+ pgo_use : String ,
245+
243246 // Flags indicating which outputs to produce.
244247 emit_no_opt_bc : bool ,
245248 emit_bc : bool ,
@@ -274,6 +277,9 @@ impl ModuleConfig {
274277 opt_level : None ,
275278 opt_size : None ,
276279
280+ pgo_gen : None ,
281+ pgo_use : String :: new ( ) ,
282+
277283 emit_no_opt_bc : false ,
278284 emit_bc : false ,
279285 emit_bc_compressed : false ,
@@ -492,8 +498,13 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
492498 opt. message) ) ;
493499 }
494500 }
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 ( ..) => { } ,
497508 }
498509}
499510
@@ -932,6 +943,9 @@ pub fn start_async_translation(tcx: TyCtxt,
932943 modules_config. passes . push ( "insert-gcov-profiling" . to_owned ( ) )
933944 }
934945
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+
935949 modules_config. opt_level = Some ( get_llvm_opt_level ( sess. opts . optimize ) ) ;
936950 modules_config. opt_size = Some ( get_llvm_opt_size ( sess. opts . optimize ) ) ;
937951
@@ -2046,18 +2060,36 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
20462060 config : & ModuleConfig ,
20472061 opt_level : llvm:: CodeGenOptLevel ,
20482062 f : & mut FnMut ( llvm:: PassManagerBuilderRef ) ) {
2063+ use std:: ptr;
2064+
20492065 // Create the PassManagerBuilder for LLVM. We configure it with
20502066 // reasonable defaults and prepare it to actually populate the pass
20512067 // manager.
20522068 let builder = llvm:: LLVMPassManagerBuilderCreate ( ) ;
20532069 let opt_size = config. opt_size . unwrap_or ( llvm:: CodeGenOptSizeNone ) ;
20542070 let inline_threshold = config. inline_threshold ;
20552071
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+
20612093 llvm:: LLVMPassManagerBuilderSetSizeLevel ( builder, opt_size as u32 ) ;
20622094
20632095 if opt_size != llvm:: CodeGenOptSizeNone {
0 commit comments