mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 02:45:25 +03:00
[PGO] Add PGO to LDC. Supported for LLVM >= 3.7
Add the commandline options -fprofile-instr-generate[=filename] and -profile-instr-use=filename -fprofile-instr-generate -- Add instrumentation on branches, switches, and function entry; uses LLVM's InstrProf pass. -- Link to profile runtime that writes instrumentation counters to a file. -fprofile-instr-use -- Read profile data from a file and apply branch weights to branches and switches, and annotate functions with entrycount in LLVM IR. -- Functions with low or high entrycount are marked with 'cold' or 'inlinehint'. The only statement type without PGO yet is "try-finally". A new pragma, `pragma(LDC_profile_instr, [ true | false ])`, is added to selectively disable/enable instrumentation of functions (granularity = whole functions). The runtime library ldc-profile-rt is a copy of LLVM compiler-rt lib/profile. It has to be exactly in-sync with the LLVM version, and thus we need a copy for each PGO-supported LLVM (>=3.7). import ldc.profile for a D interface to ldc-profile-rt (for example to reset execution counts after a program startup phase). The instrumentation data is mainly passed on to LLVM: function-entry counts and branch counts/probabilities. LDC marks functions as hot when "execution count is 30% of the maximum function execution count", and marks functions as cold if their count is 1% of maximum function execution count. The source of LLVM's llvm-profdata tool is hereby included in LDCs repository (different source for each LLVM version), and the binary is included in the install bin folder. The executable is named "ldc-profdata" to avoid clashing with llvm-profdata on the same machine. This is needed because profdata executable has to be in-sync with the LLVM version used to build LDC. Maintenance burden: for trunk LLVM, we have to keep ldc-profile-rt and llvm-profdata in sync. There is no diff with upstream; but because of active development there are the occasional API changes.
This commit is contained in:
parent
a81ac7d790
commit
e0d9c58443
99 changed files with 11857 additions and 64 deletions
|
@ -21,6 +21,7 @@
|
|||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/IRReader/IRReader.h"
|
||||
#include "llvm/Linker/Linker.h"
|
||||
#include "llvm/ProfileData/InstrProf.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
@ -222,12 +223,28 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
|
|||
args.push_back(p);
|
||||
}
|
||||
|
||||
// Link with profile-rt library when generating an instrumented binary
|
||||
if (global.params.genInstrProf) {
|
||||
#if LDC_LLVM_VER >= 308
|
||||
if (global.params.targetTriple->isOSLinux()) {
|
||||
// For Linux, explicitly define __llvm_profile_runtime as undefined
|
||||
// symbol, so that the initialization part of profile-rt is linked in.
|
||||
args.push_back(("-Wl,-u," + llvm::getInstrProfRuntimeHookVarName()).str());
|
||||
}
|
||||
#endif
|
||||
args.push_back("-lldc-profile-rt");
|
||||
}
|
||||
|
||||
// default libs
|
||||
bool addSoname = false;
|
||||
switch (global.params.targetTriple->getOS()) {
|
||||
case llvm::Triple::Linux:
|
||||
addSoname = true;
|
||||
if (!opts::disableLinkerStripDead) {
|
||||
// Make sure we don't do --gc-sections when generating a profile-
|
||||
// instrumented binary. The runtime relies on magic sections, which
|
||||
// would be stripped by gc-section on older version of ld, see bug:
|
||||
// https://sourceware.org/bugzilla/show_bug.cgi?id=19161
|
||||
if (!opts::disableLinkerStripDead && !global.params.genInstrProf) {
|
||||
args.push_back("-Wl,--gc-sections");
|
||||
}
|
||||
if (global.params.targetTriple->getEnvironment() == llvm::Triple::Android) {
|
||||
|
@ -627,6 +644,11 @@ static int linkObjToBinaryWin(bool sharedLib) {
|
|||
args.push_back("comdlg32.lib");
|
||||
args.push_back("advapi32.lib");
|
||||
|
||||
// Link with profile-rt library when generating an instrumented binary
|
||||
if (global.params.genInstrProf) {
|
||||
args.push_back("ldc-profile-rt.lib");
|
||||
}
|
||||
|
||||
Logger::println("Linking with: ");
|
||||
Stream logstr = Logger::cout();
|
||||
for (const auto &arg : args) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue