mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-07 11:26:02 +03:00

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.
71 lines
1.9 KiB
D
71 lines
1.9 KiB
D
//===-- codegenerator.d ---------------------------------------------------===//
|
||
//
|
||
// LDC – the LLVM D compiler
|
||
//
|
||
// This file is distributed under the BSD-style LDC license. See the LICENSE
|
||
// file for details.
|
||
//
|
||
//===----------------------------------------------------------------------===//
|
||
|
||
module driver.codegenerator;
|
||
|
||
import ddmd.dmodule;
|
||
import ddmd.dscope;
|
||
import ddmd.globals;
|
||
import ddmd.id;
|
||
import ddmd.identifier;
|
||
import ddmd.parse;
|
||
import ddmd.tokens;
|
||
|
||
extern (C++) __gshared Module g_entrypointModule = null;
|
||
extern (C++) __gshared Module g_dMainModule = null;
|
||
|
||
/// Callback to generate a C main() function, invoked by the frontend.
|
||
extern (C++) void genCmain(Scope *sc) {
|
||
if (g_entrypointModule) {
|
||
return;
|
||
}
|
||
|
||
/* The D code to be generated is provided as D source code in the form of a
|
||
* string.
|
||
* Note that Solaris, for unknown reasons, requires both a main() and an
|
||
* _main()
|
||
*/
|
||
static __gshared const(char)[] code =
|
||
q{
|
||
pragma(LDC_profile_instr, false):
|
||
extern(C)
|
||
{
|
||
int _d_run_main(int argc, char **argv, void* mainFunc);
|
||
int _Dmain(char[][] args);
|
||
int main(int argc, char **argv)
|
||
{
|
||
return _d_run_main(argc, argv, &_Dmain);
|
||
}
|
||
version (Solaris) int _main(int argc, char** argv) { return main(argc, argv); }
|
||
}
|
||
pragma(LDC_no_moduleinfo);
|
||
};
|
||
|
||
Identifier id = Id.entrypoint;
|
||
auto m = new Module("__entrypoint.d", id, 0, 0);
|
||
|
||
scope Parser p = new Parser(m, code.ptr, code.length, 0);
|
||
p.scanloc = Loc();
|
||
p.nextToken();
|
||
m.members = p.parseModule();
|
||
assert(p.token.value == TOKeof);
|
||
|
||
bool v = global.params.verbose;
|
||
global.params.verbose = false;
|
||
m.importedFrom = m;
|
||
m.importAll(null);
|
||
m.semantic();
|
||
m.semantic2();
|
||
m.semantic3();
|
||
global.params.verbose = v;
|
||
|
||
g_entrypointModule = m;
|
||
g_dMainModule = sc._module;
|
||
}
|
||
|