diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 1271773fa02b3c4816743f2e23f25cab5d1cef23..d9c18e6cf0c4069bd9fa181b4d3dd7d4c1ca981e 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -1739,6 +1739,7 @@ pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char, pub fn LLVMRustModuleCost(M: ModuleRef) -> u64; pub fn LLVMRustThinLTOAvailable() -> bool; + pub fn LLVMRustPGOAvailable() -> bool; pub fn LLVMRustWriteThinBitcodeToFile(PMR: PassManagerRef, M: ModuleRef, BC: *const c_char) -> bool; diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 56eece9f31e7ee135c8e82c10be44a9da58aa008..c839e5340f58dd7062c34a71ef639b68d5e6be21 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -708,6 +708,13 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } + if (tcx.sess.opts.debugging_opts.pgo_gen.is_some() || + !tcx.sess.opts.debugging_opts.pgo_use.is_empty()) && + unsafe { !llvm::LLVMRustPGOAvailable() } + { + tcx.sess.fatal("this compiler's LLVM does not support PGO"); + } + let crate_hash = tcx.crate_hash(LOCAL_CRATE); let link_meta = link::build_link_meta(crate_hash); diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index bee8ae5853f86c511f3fd5b116159531e2d50365..3d5cce81278ac872979800bbcbe3c1f740eeae82 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -44,6 +44,10 @@ #include "llvm-c/Transforms/PassManagerBuilder.h" +#if LLVM_VERSION_GE(4, 0) +#define PGO_AVAILABLE +#endif + using namespace llvm; using namespace llvm::legacy; @@ -435,6 +439,8 @@ extern "C" void LLVMRustConfigurePassManagerBuilder( unwrap(PMBR)->SLPVectorize = SLPVectorize; unwrap(PMBR)->OptLevel = fromRust(OptLevel); unwrap(PMBR)->LoopVectorize = LoopVectorize; + +#ifdef PGO_AVAILABLE if (PGOGenPath) { assert(!PGOUsePath); unwrap(PMBR)->EnablePGOInstrGen = true; @@ -444,6 +450,9 @@ extern "C" void LLVMRustConfigurePassManagerBuilder( assert(!PGOGenPath); unwrap(PMBR)->PGOInstrUse = PGOUsePath; } +#else + assert(!PGOGenPath && !PGOUsePath && "Should've caught earlier"); +#endif } // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo` @@ -776,6 +785,15 @@ LLVMRustThinLTOAvailable() { #endif } +extern "C" bool +LLVMRustPGOAvailable() { +#ifdef PGO_AVAILABLE + return true; +#else + return false; +#endif +} + #if LLVM_VERSION_GE(4, 0) // Here you'll find an implementation of ThinLTO as used by the Rust compiler