<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I'd like to give some additional information about my recent commit <a href="https://github.com/apple/swift/commit/aaaf36e83521f153ba4b0720795efe4980d9b124" class="">https://github.com/apple/swift/commit/aaaf36e83521f153ba4b0720795efe4980d9b124</a></div><div class="">The idea is to run the swiftc's llvm-pipeline only if the llvm IR (the output of IRGen) did change. The llvm pipeline takes about 45% to 60% of total compilation time.</div><div class="">It's done by storing a MD5 hash of the IR in the generated object files. Specifically, on macho-o the hash is stored in a special section in the __LLVM segment, which is ignored by the linker.</div><div class=""><br class=""></div><div class="">The intention is to speed-up whole module compilation. We are already running the llvm part multi-threaded, which gives us about 30% speedup with 4 cores. Incremental gives us another 15% to 20%, assuming only a "small" thing changed in one of many files.</div><div class="">Of course the incremental speed-up totally depends on what changes are done on the sources. In worst case a small change might trigger a complete re-compilation e.g. if it's in an often inlined function.&nbsp;</div><div class=""><br class=""></div><div class="">Here are some numbers for three different modules: a 64 file module which quite large files, a 500 file module with smaller files and the Adventure project. The percentages are similar for all three modules.&nbsp;</div><div class=""><br class=""></div><img apple-inline="yes" id="C36878D0-E7D9-4BD1-A51F-5EA538931CB8" height="288" width="247" apple-width="yes" apple-height="yes" class="" src="cid:71F677B5-9026-44FD-89F4-96222647F971@apple.com"><img apple-inline="yes" id="F07F9DBA-9C31-49E3-87CD-FA719D0AD689" height="300" width="237" apple-width="yes" apple-height="yes" class="" src="cid:4DACCAE2-3D47-4F06-B25F-CC0E704BEBFF@apple.com"><img apple-inline="yes" id="CCD5C377-F932-4424-AB7A-AB65F09A4B9F" height="300" width="292" apple-width="yes" apple-height="yes" class="" src="cid:F2FE9BDD-D61C-42B1-9B82-D34DA3022262@apple.com"><div class=""><br class=""></div><div class="">A nice side-effect of incremental compilation is that it works for every type of compilation which produces an object file (not only for multi-threaded wmo). For example if you make changes in the compiler which do not affect code generation, then a library build (ninja swift-stdlib) is faster by 60%.</div><div class=""><br class=""></div><div class=""><img apple-inline="yes" id="2ABDA619-880F-4384-B3C2-F5FCF81EAE0C" height="300" width="293" apple-width="yes" apple-height="yes" class="" src="cid:1F3E4CBB-72BF-41E9-B2F1-052539E4ED7D@apple.com"></div><div class=""><br class=""></div><div class="">One additional note about the hash. It also includes the full compiler version, which contains e.g. the git SHAs (in a development build). So every time the branch head changes, everything is recompiled.</div><div class="">The hash also includes some option settings, like -disable-llvm-optzns.</div><div class="">There is only one situation where you should think of incremental compilation: if you make some local changes in swiftc's llvm-pipeline you should explicitly clean all compiled libraries, etc.</div><div class=""><br class=""></div><div class="">Erik</div><div class=""><br class=""></div></body></html>