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.
The temporary files created should be unique for parallel processes (e.g. in a test suite where LDC is called in parallel with perhaps same input).
These files will be deleted after execution so their name is not relevant. For better linking errors, the new filenames are created by appending random characters to their name.
Also adds the CMake infrastructure to compile and link the D source files.
The build is partially broken:
- A few files in Phobos and druntime do not build
- MSVC build is broken because of unresolved symbols involving reals
LLVM assumes UTF-8 input, but our args mainly come from the LDC command
line (+ some from the config file and some implicit ASCII ones).
LDC doesn't use UTF-16 on Windows, so afaik, the command-line args are
encoded in the current codepage and so should just be written untouched
into the response file.
writeFileWithEncoding()'s default encoding is UTF-8, meaning no
conversion.
Also check for errors when trying to create and write the response file,
and refactor the executeAndWait() part.
This command line sent to CreateProcess():
"C:\LDC\bin\amd64.bat" 1 2 "3" 4
is internally transformed to:
C:\Windows\system32\cmd.exe /c "C:\LDC\bin\amd64.bat" 1 2 "3" 4
Now guess what - cmd.exe treats the command string after /c or /k in a
very special way if it begins with double quotes and is followed by other
quoted args. In this example, it tries to invoke:
C:\LDC\bin\amd64.bat" 1 2 "3
Another example:
C:\Windows\system32\cmd.exe /c "C:\L D C\bin\amd64.bat" 1 2 "3" 4
=> C:\L
The fix seems to be enclosing the whole command with additional double
quotes (but no additional escaping of the command!) and using /s for
cmd.exe:
C:\Windows\system32\cmd.exe /s /c ""C:\L D C\bin\amd64.bat" 1 2 "3" 4"
So the command is quoted, but not escaped, i.e., no regular argument to
cmd.exe, so we can't use LLVM's executeAndWait() to launch the cmd.exe
process. :/
Additionally, LLVM's arg-quoting code is not public, so we can't use it
to quote & escape the regular args inside the command.
I therefore implemented a simple quoteArgs() variant which should
suffice for our use cases.
If a static library is created then the driver now prepends the
path from -od option to the library name if that name is not
absolute. In case of Linux/Unix, automatic prepending of 'lib'
to the library name is removed.
This fixes failure of runnable/test13774.sh.
Adds a new command line option -mabi= and uses the value to compute
the ABI to use. Adds the ABI to linker and assembler invocation, too.
Allows consistent invocation of the whole tool chain.