llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.15k stars 12.03k forks source link

Instrumentation-based PGO handles programs that change directory poorly if the profile filename is relative #23503

Open nico opened 9 years ago

nico commented 9 years ago
Bugzilla Link 23129
Version trunk
OS All
CC @bogner

Extended Description

I'm trying to follow the http://clang.llvm.org/docs/UsersManual.html#profile-guided-optimization instructions for building ninja. I can't seem to get it to work -- either I'm holding it wrong, or it broke when it got reshuffled.

I'm doing:

$ git clone https://github.com/martine/ninja.git Cloning into 'ninja'... remote: Counting objects: 8458, done. remote: Compressing objects: 100% (36/36), done. remote: Total 8458 (delta 15), reused 0 (delta 0), pack-reused 8422 Receiving objects: 100% (8458/8458), 1.86 MiB | 635.00 KiB/s, done. Resolving deltas: 100% (5974/5974), done. Checking connectivity... done. $ cd ninja $ CXX=/Users/thakis/src/llvm-build/bin/clang++ CFLAGS="-stdlib=libstdc++ -fprofile-instr-generate -isysroot $(xcrun -show-sdk-path)" LDFLAGS='-stdlib=libstdc++ -fprofile-instr-generate' ./configure.py warning: A compatible version of re2c (>= 0.11.3) was not found; changes to src/*.in.cc will not affect your build. wrote build.ninja. $ ninja -v [1/24] /Users/thakis/src/llvm-build/bin/clang++ -MMD -MT build/build.o -MF build/build.o.d -g -Wall -Wextra -Wno-deprecated -Wno-unused-parameter -fno-rtti -fno-exceptions -fvisibility=hidden -pipe -Wno-missing-field-initializers '-DNINJA_PYTHON="python"' -O2 -DNDEBUG -fdiagnostics-color -DNINJA_HAVE_BROWSE -stdlib=libstdc++ -fprofile-instr-generate -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -c src/build.cc -o build/build.o

... (omitted, just wanted to show that the flags are there)

[24/24] /Users/thakis/src/llvm-build/bin/clang++ -Lbuild -stdlib=libstdc++ -fprofile-instr-generate -o ninja build/ninja.o -lninja $ ./ninja manifest_parser_perftest [2/2] LINK manifest_parser_perftest Nicos-MBP-8:ninja thakis$ ./manifest_parser_perftest Creating manifest data...done. 1128ms (hash: c617022) 1117ms (hash: c617022) 1145ms (hash: c617022) 1131ms (hash: c617022) 1148ms (hash: c617022) min 1117ms max 1148ms avg 1133.8ms $ ls -l default.profraw -rw-r--r-- 1 thakis staff 0 Apr 5 13:56 default.profraw

Note that default.profraw is getting generated, but it ends up empty.

bogner commented 9 years ago

Yeah, I think the right thing to do is to turn the path absolute when we first set it up. I'll look into doing that later this week.

nico commented 9 years ago

Aha, thanks!

Maybe the library should get an absolute path at startup and stash that somewhere? The pwd probably changes over the lifetime of many apps.

bogner commented 9 years ago

So what's happening here is that manifest_parser_perftests changes directory while it runs, so we end up initializing the file in one directory and then writing it out in another. A non-empty profile ends up in ./build/manifest_perftest/default.profraw, but we also emit an empty one in the current directory. You can work around this for now by specifying a profile to write to, like LLVM_PROFILE_FILE="/path/to/whatever.profraw".

nico commented 9 years ago

Note that I'm trying to run ./manifest_parser_perftests to generate profiling data. The perftest should be instrumented too, yet it doesn't work.

My checkout includes compiler-rt. I just synced llvm, clang, and compiler-rt to trunk, rebuilt clang and libclang_rt.profile_osx.a, and then rebuilt ninja's manifest_parser_perftest and all its .o files (ninja -t clean manifest_parser_perftest) and rebuilt it; it still repros.

Building with libc++ instead of libstdc++ doesn't change things.

bogner commented 9 years ago

I don't have libstdc++ and I have commandline tools instead of Xcode on this machine, so I dropped the -stdlib and -isysroot flags, but it sems to work for me:

% git clone https://github.com/martine/ninja.git Cloning into 'ninja'... remote: Counting objects: 8458, done. remote: Compressing objects: 100% (36/36), done. remote: Total 8458 (delta 15), reused 0 (delta 0), pack-reused 8422 Receiving objects: 100% (8458/8458), 1.86 MiB | 1.39 MiB/s, done. Resolving deltas: 100% (5974/5974), done. Checking connectivity... done. % cd ninja % CXX=$HOME/build/llvm/bin/clang++ CFLAGS="-fprofile-instr-generate" LDFLAGS='-fprofile-instr-generate' ./configure.py warning: A compatible version of re2c (>= 0.11.3) was not found; changes to src/*.in.cc will not affect your build. wrote build.ninja. % ninja -v [1/24] src/inline.sh kBrowsePy < src/browse.py > build/browse_py.h [2/24] /Users/bogner/build/llvm/bin/clang++ -MMD -MT build/build.o -MF build/build.o.d -g -Wall -Wextra -Wno-deprecated -Wno-unused-parameter -fno-rtti -fno-exceptions -fvisibility=hidden -pipe -Wno-missing-field-initializers '-DNINJA_PYTHON="python"' -O2 -DNDEBUG -fdiagnostics-color -DNINJA_HAVE_BROWSE -fprofile-instr-generate -c src/build.cc -o build/build.o

...

% ./ninja manifest_parser_perftest [2/2] LINK manifest_parser_perftest % ls -l default.profraw -rw-r--r-- 1 bogner staff 456720 Apr 5 14:12 default.profraw % ~/build/llvm/bin/llvm-profdata show default.profraw Total functions: 3222 Maximum function count: 47345 Maximum internal block count: 3341

Things that come to mind:

nico commented 9 years ago

assigned to @bogner