Alex Lorenz, Michael Spencer, Apple LLVM Developers’ Meeting, Brussels, Belgium, April 2019
- clang-scan-deps
- Fast Dependency Scanning For Explicit Modules
- 1
clang-scan-deps Fast Dependency Scanning For Explicit Modules - - PowerPoint PPT Presentation
clang-scan-deps Fast Dependency Scanning For Explicit Modules Alex Lorenz, Michael Spencer, Apple LLVM Developers Meeting, Brussels, Belgium, April 2019 1 Clang Modules Dependency Scanning Fast Dependency Scanning
Alex Lorenz, Michael Spencer, Apple LLVM Developers’ Meeting, Brussels, Belgium, April 2019
Clang Modules
😬
Implicit Modules
A.cpp B.cpp C.cpp D.cpp
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms
Compiler Discovered Build System Known
Module Maps Implicit Modules
module LLVM_Transforms { requires cplusplus umbrella "Transforms" module * { export * } }
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis Analysis
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR E.cpp -DFOO
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR E.cpp -DFOO Transforms
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR E.cpp -DFOO Transforms Analysis
Compiler Discovered Build System Known
Implicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR E.cpp -DFOO Transforms Analysis IR
Compiler Discovered Build System Known
Explicit Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR E.cpp -DFOO Transforms Analysis IR
Compiler Discovered Build System Known
Transforms IR
Explicit Clang Modules
🏏
Canonical Dependency Scanning Phase
Clang and LLVM sources: preprocessing time on an 18-Core iMac Pro
Time (seconds)
15 30 45 60
Number Of Workers
6 12 18 24 30 36
Preprocessing Time
Time (seconds)
15 30 45 60
Number Of Workers
6 12 18 24 30 36
Preprocessing Time
Clang and LLVM sources: the 12 workers scenario
31 seconds to preprocess
Time (seconds)
15 30 45 60
Number Of Workers
6 12 18 24 30 36
Preprocessing Time
Clang and LLVM sources: the 12 workers scenario
31 seconds to preprocess 👏 Not fast enough for every build! 31 seconds to preprocess
What Does The Preprocessor Do?
#ifndef HEADER_FILE #define HEADER_FILE #include “Compiler.h” // Clang is an awesome tool! class Clang: public Compiler { public: void buildAllCode(); #ifndef NDEBUG void dump(); #endif }; #endif
Lex tokens… Evaluate #ifndef & #define Lex more tokens… Include “Compiler.h” Lex more tokens… Lex even more tokens 😬
Reducing Preprocessor Workload
#ifndef HEADER_FILE #define HEADER_FILE #include “Compiler.h” // Clang is an awesome tool! class Clang: public Compiler { public: void buildAllCode(); #ifndef NDEBUG void dump(); #endif }; #endif
31 seconds to preprocess 31 seconds to preprocess Dependencies aren’t affected by these tokens
Reducing Preprocessor Workload
#ifndef HEADER_FILE #define HEADER_FILE #include “Compiler.h” // Clang is an awesome tool! class Clang: public Compiler { public: void buildAllCode(); #ifndefdNDEBUG void dump(); #endif }; #endif
31 seconds to preprocess 31 seconds to preprocess Dependencies aren’t affected by these tokens
Source Minimization
#ifndef HEADER_FILE #define HEADER_FILE #include “Compiler.h” #endif
Source Minimization
#ifndef HEADER_FILE #define HEADER_FILE #include “Compiler.h” #endif
💢 Keep directives that may affect dependency list Strip everything else Context free: source reused in any compilation
Clang and LLVM sources: 30% faster preprocessing
Time (seconds)
15 30 45 60
Number Of Workers
6 12 18 24 30 36
Preprocessing Time Minimized Source Preprocessing Time
Problem: Clang Invocations
Preprocess Preprocess Minimize Source Minimize Source #include “Test.h” Preprocess #include “Test.h” Preprocess
Parallel invocations do redundant work Read the same file twice Minimize the same file twice
Introducing clang-scan-deps
Minimized File Cache
Time (seconds)
1.25 2.5 3.75 5
Number Of Workers
18 24 30 36
One StringMap
Optimizing Minimized File Cache
Time (seconds)
1.25 2.5 3.75 5
Number Of Workers
18 24 30 36
One StringMap Nine StringMaps
Preprocessor Block Skipping
#ifdef NOT_TAKEN // Important comment #include “LexMeNot.h” #elif #include “IAmLexed.h” #endif
When this #ifdef is not taken…
The tokens inside it are lexed… Until the #elif is found Took up to 10-15% of time in our profiles
Optimizing Preprocessor Block Skipping
#ifdef NOT_TAKEN // Important comment #include “LexMeNot.h” #elif #include “IAmLexed.h” #endif
When this #ifdef is not taken…
Skip to #elif: add offset to Lexer’s pointer Offset computed when minimizing file
Clang and LLVM sources: 5-10x faster dependency scanning
Time (seconds)
10 20 30 40
Number Of Workers
6 12 18 24 30 36
Preprocessing Time scan-deps Time
#define AT_IMPORT @import AT_IMPORT Foundation;
Things We Aren’t Going To Support
➡ We want to disallow this behavior in Clang
#define WHY(X) _##X ("clang module import X") WHY(Pragma);
Modular Dependencies
Dependency Extraction
A.cpp.min B.cpp.min C.cpp.min D.cpp.min Transforms.min Analysis.min IR.min
Dependency Extraction
A.cpp.min B.cpp.min C.cpp.min D.cpp.min Transforms.min Analysis.min IR.min
Dependency Extraction
A.cpp.min B.cpp.min C.cpp.min D.cpp.min Transforms.min Analysis.min IR.min
Dependency Extraction
build LLVM_Transforms.pcm: cxx_explicit_module llvm/include/llvm/module.modulemap | LLVM_IR.pcm LLVM_Analysis.pcm std.pcm module_id = LLVM_Transforms moduledeps = -fmodule-file=LLVM_Config_Config.pcm -fmodule-file=std.pcm
args = builds/release/bin/clang++ -cc1 -fmodules ...
Initial Results - Scanning
☹
Scan Time (seconds)
50 100 150 200
Number Of Workers
6 12 18 24 30 36
Modules -Eonly
Modules scan-deps scan-deps
Initial Results - Scanning
Scan Time (seconds)
15 30 45 60
Number Of Workers
6 12 18 24 30 36
Modules -Eonly
Modules scan-deps scan-deps
Initial Results - Scanning
Scan Time (seconds)
5.5 11 16.5 22
Number Of Workers
6 12 18 24 30 36
Modules -Eonly
Modules scan-deps scan-deps
The cost of building modules during scanning
Initial Results - Building
Build Time (seconds)
325 650 975 1300
Number Of Workers
6 12 18 24 30 36
Implicit Scan + Explicit Explicit
Bugs 🐟
Future Work
Merging Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR E.cpp -DFOO Transforms Analysis IR
Compiler Discovered Build System Known
Transforms IR
Merging Modules
A.cpp B.cpp C.cpp D.cpp Transforms Analysis IR E.cpp
Compiler Discovered Build System Known
Future Optimization
Future Work
clang-scan-deps – Fast Dependency Scanning For Explicit Modules Alex Lorenz, Michael Spencer, LLVM Developers’ Meeting, Brussels, Belgium, April 2019