about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2018-02-19 01:57:12 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2018-03-25 03:30:04 +0200
commit324ca7acd59be59abe0562287d5493f78a60823a (patch)
tree6625e70d0c0eec2fb29e3aa47c2522f9d063e0c6
parent50a38725e1841aa2283f198dbc8ef2bd5bd1370b (diff)
downloadrust-324ca7acd59be59abe0562287d5493f78a60823a.tar.gz
rust-324ca7acd59be59abe0562287d5493f78a60823a.zip
rustc_llvm: rustc_trans: Thread the PGO config down to the pass manager builder.
Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
-rw-r--r--src/librustc_llvm/ffi.rs4
-rw-r--r--src/librustc_trans/back/write.rs37
-rw-r--r--src/rustllvm/PassWrapper.cpp12
3 files changed, 46 insertions, 7 deletions
diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs
index c0cdd212770..25506f6a86e 100644
--- a/src/librustc_llvm/ffi.rs
+++ b/src/librustc_llvm/ffi.rs
@@ -1641,7 +1641,9 @@ extern "C" {
                                                OptLevel: CodeGenOptLevel,
                                                MergeFunctions: bool,
                                                SLPVectorize: bool,
-                                               LoopVectorize: bool);
+                                               LoopVectorize: bool,
+                                               PGOGenPath: *const c_char,
+                                               PGOUsePath: *const c_char);
     pub fn LLVMRustAddLibraryInfo(PM: PassManagerRef,
                                   M: ModuleRef,
                                   DisableSimplifyLibCalls: bool);
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 3e7422557e9..2a8d280ee26 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -240,6 +240,9 @@ pub struct ModuleConfig {
     /// Some(level) to optimize binary size, or None to not affect program size.
     opt_size: Option<llvm::CodeGenOptSize>,
 
+    pgo_gen: Option<String>,
+    pgo_use: String,
+
     // Flags indicating which outputs to produce.
     emit_no_opt_bc: bool,
     emit_bc: bool,
@@ -274,6 +277,9 @@ impl ModuleConfig {
             opt_level: None,
             opt_size: None,
 
+            pgo_gen: None,
+            pgo_use: String::new(),
+
             emit_no_opt_bc: false,
             emit_bc: false,
             emit_bc_compressed: false,
@@ -932,6 +938,9 @@ pub fn start_async_translation(tcx: TyCtxt,
         modules_config.passes.push("insert-gcov-profiling".to_owned())
     }
 
+    modules_config.pgo_gen = sess.opts.cg.pgo_gen.clone();
+    modules_config.pgo_use = sess.opts.cg.pgo_use.clone();
+
     modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize));
     modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize));
 
@@ -2046,6 +2055,8 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
                             config: &ModuleConfig,
                             opt_level: llvm::CodeGenOptLevel,
                             f: &mut FnMut(llvm::PassManagerBuilderRef)) {
+    use std::ptr;
+
     // Create the PassManagerBuilder for LLVM. We configure it with
     // reasonable defaults and prepare it to actually populate the pass
     // manager.
@@ -2053,11 +2064,27 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
     let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone);
     let inline_threshold = config.inline_threshold;
 
-    llvm::LLVMRustConfigurePassManagerBuilder(builder,
-                                              opt_level,
-                                              config.merge_functions,
-                                              config.vectorize_slp,
-                                              config.vectorize_loop);
+    let pgo_gen_path = config.pgo_gen.as_ref().map(|s| {
+        let s = if s.is_empty() { "default_%m.profraw" } else { s };
+        CString::new(s.as_bytes()).unwrap()
+    });
+
+    let pgo_use_path = if config.pgo_use.is_empty() {
+        None
+    } else {
+        Some(CString::new(config.pgo_use.as_bytes()).unwrap())
+    };
+
+    llvm::LLVMRustConfigurePassManagerBuilder(
+        builder,
+        opt_level,
+        config.merge_functions,
+        config.vectorize_slp,
+        config.vectorize_loop,
+        pgo_gen_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
+        pgo_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
+    );
+
     llvm::LLVMPassManagerBuilderSetSizeLevel(builder, opt_size as u32);
 
     if opt_size != llvm::CodeGenOptSizeNone {
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index 06d1301d700..bee8ae5853f 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -428,12 +428,22 @@ extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
 
 extern "C" void LLVMRustConfigurePassManagerBuilder(
     LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
-    bool MergeFunctions, bool SLPVectorize, bool LoopVectorize) {
+    bool MergeFunctions, bool SLPVectorize, bool LoopVectorize,
+    const char* PGOGenPath, const char* PGOUsePath) {
   // Ignore mergefunc for now as enabling it causes crashes.
   // unwrap(PMBR)->MergeFunctions = MergeFunctions;
   unwrap(PMBR)->SLPVectorize = SLPVectorize;
   unwrap(PMBR)->OptLevel = fromRust(OptLevel);
   unwrap(PMBR)->LoopVectorize = LoopVectorize;
+  if (PGOGenPath) {
+    assert(!PGOUsePath);
+    unwrap(PMBR)->EnablePGOInstrGen = true;
+    unwrap(PMBR)->PGOInstrGen = PGOGenPath;
+  }
+  if (PGOUsePath) {
+    assert(!PGOGenPath);
+    unwrap(PMBR)->PGOInstrUse = PGOUsePath;
+  }
 }
 
 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`