Index: include/llvm/LTO/Config.h =================================================================== --- include/llvm/LTO/Config.h +++ include/llvm/LTO/Config.h @@ -65,6 +65,9 @@ /// with this triple. std::string DefaultTriple; + /// Sample PGO profile path. + std::string SampleProfile; + bool ShouldDiscardValueNames = true; DiagnosticHandlerFunction DiagHandler; Index: lib/LTO/LTO.cpp =================================================================== --- lib/LTO/LTO.cpp +++ lib/LTO/LTO.cpp @@ -129,6 +129,12 @@ ArrayRef((const uint8_t *)&Linkage, sizeof(Linkage))); } + if (!Conf.SampleProfile.empty()) { + auto FileOrErr = MemoryBuffer::getFile(Conf.SampleProfile); + if (FileOrErr) + Hasher.update(FileOrErr.get()->getBuffer()); + } + Key = toHex(Hasher.result()); } Index: lib/LTO/LTOBackend.cpp =================================================================== --- lib/LTO/LTOBackend.cpp +++ lib/LTO/LTOBackend.cpp @@ -182,6 +182,7 @@ PMB.LoopVectorize = true; PMB.SLPVectorize = true; PMB.OptLevel = Conf.OptLevel; + PMB.PGOSampleUse = Conf.SampleProfile; if (IsThinLTO) PMB.populateThinLTOPassManager(passes); else Index: test/tools/gold/X86/Inputs/afdo.prof =================================================================== --- /dev/null +++ test/tools/gold/X86/Inputs/afdo.prof @@ -0,0 +1,2 @@ +f:100:3 + 1: 100 Index: test/tools/gold/X86/thinlto_afdo.ll =================================================================== --- /dev/null +++ test/tools/gold/X86/thinlto_afdo.ll @@ -0,0 +1,25 @@ +; Generate summary sections +; RUN: opt -module-summary %s -o %t1.o +; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o + +; RUN: rm -f %t1.o.4.opt.bc +; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: --plugin-opt=thinlto \ +; RUN: --plugin-opt=save-temps \ +; RUN: --plugin-opt=sample-profile=%p/Inputs/afdo.prof \ +; RUN: --plugin-opt=jobs=1 \ +; RUN: -shared %t1.o %t2.o -o %t3 +; RUN: opt -S %t1.o.4.opt.bc | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; CHECK: ProfileSummary +declare void @g(...) +declare void @h(...) + +define void @f() { +entry: + call void (...) @g() + call void (...) @h() + ret void +} Index: tools/gold/gold-plugin.cpp =================================================================== --- tools/gold/gold-plugin.cpp +++ tools/gold/gold-plugin.cpp @@ -171,6 +171,8 @@ // Note: This array will contain all plugin options which are not claimed // as plugin exclusive to pass to the code generator. static std::vector extra; + // Sample profile file path + static std::string sample_profile; static void process_plugin_option(const char *opt_) { @@ -220,6 +222,8 @@ message(LDPL_FATAL, "Invalid codegen partition level: %s", opt_ + 5); } else if (opt == "disable-verify") { DisableVerify = true; + } else if (opt.startswith("sample-profile=")) { + sample_profile= opt.substr(strlen("sample-profile=")); } else { // Save this option to pass to the code generator. // ParseCommandLineOptions() expects argv[0] to be program name. Lazily @@ -728,6 +732,9 @@ break; } + if (!options::sample_profile.empty()) + Conf.SampleProfile = options::sample_profile; + return llvm::make_unique(std::move(Conf), Backend, options::ParallelCodeGenParallelismLevel); }