clang scan deps
play

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


  1. clang-scan-deps • • Fast Dependency Scanning For Explicit Modules Alex Lorenz, Michael Spencer, Apple LLVM Developers’ Meeting, Brussels, Belgium, April 2019 � 1

  2. • Clang Modules • Dependency Scanning • Fast Dependency Scanning • Dependency Extraction • Future Work � 2

  3. Clang Modules • Replace the textual preprocessor inclusions with an import of an AST • Widely used in SDKs shipped with Xcode • Implicit modules: Clang builds modules as they’re included • Users don’t have to specify modular dependencies • Requires a build system in the compiler 😬 � 3

  4. Compiler Discovered Build System Known Implicit Modules A.cpp B.cpp C.cpp D.cpp � 4

  5. Compiler Discovered Build System Known Implicit Modules Transforms A.cpp B.cpp C.cpp D.cpp � 5

  6. Implicit Modules Module Maps module LLVM_Transforms { requires cplusplus umbrella "Transforms" module * { export * } } � 6

  7. Compiler Discovered Build System Known Implicit Modules Transforms A.cpp B.cpp C.cpp D.cpp � 7

  8. Compiler Discovered Build System Known Implicit Modules Transforms A.cpp B.cpp C.cpp D.cpp � 8

  9. Compiler Discovered Build System Known Implicit Modules Analysis Analysis Transforms A.cpp B.cpp C.cpp D.cpp � 9

  10. Compiler Discovered Build System Known Implicit Modules Analysis Transforms A.cpp B.cpp C.cpp D.cpp � 10

  11. Compiler Discovered Build System Known Implicit Modules IR Analysis Transforms A.cpp B.cpp C.cpp D.cpp � 11

  12. Compiler Discovered Build System Known Implicit Modules IR Analysis Transforms A.cpp B.cpp C.cpp D.cpp � 12

  13. Compiler Discovered Build System Known Implicit Modules IR Analysis Transforms A.cpp B.cpp C.cpp D.cpp E.cpp -DFOO � 13

  14. Compiler Discovered Build System Known Implicit Modules IR Analysis Transforms Transforms A.cpp B.cpp C.cpp D.cpp E.cpp -DFOO � 14

  15. Compiler Discovered Build System Known Implicit Modules IR Analysis Analysis Transforms Transforms A.cpp B.cpp C.cpp D.cpp E.cpp -DFOO � 15

  16. Compiler Discovered Build System Known Implicit Modules ☹ IR IR Analysis Analysis Transforms Transforms A.cpp B.cpp C.cpp D.cpp E.cpp -DFOO � 16

  17. Compiler Discovered Build System Known Explicit Modules IR IR IR Analysis Analysis Transforms Transforms Transforms A.cpp B.cpp C.cpp D.cpp E.cpp -DFOO � 17

  18. Explicit Clang Modules • Better model: knowing modular dependencies before compiling • Allow more robust and reproducible builds • Faster builds 🏏 • Constraint: users shouldn’t have to specify modular dependencies • Problem: which modules are needed? • Solution: dependency discovery build phase for a build target � 18

  19. • Clang Modules • Dependency Scanning • Fast Dependency Scanning • Dependency Extraction • Future Work � 19

  20. Canonical Dependency Scanning Phase • Preprocess all translation units of a build target • Write out included files into a .d • clang -cc1 -Eonly -MT —dependency-file foo.d foo.c • How fast is the preprocessor? � 20

  21. Clang and LLVM sources: preprocessing time on an 18-Core iMac Pro 60 Preprocessing Time 45 Time (seconds) 30 15 0 6 12 18 24 30 36 Number Of Workers 21 �

  22. Clang and LLVM sources: the 12 workers scenario 60 Preprocessing Time 45 Time (seconds) 30 15 0 6 12 18 24 30 36 Number Of Workers � 22

  23. Clang and LLVM sources: the 12 workers scenario 60 Preprocessing Time 45 31 seconds to preprocess Time (seconds) 31 seconds to preprocess 31 seconds to preprocess 30 15 👏 Not fast enough for every build! 0 6 12 18 24 30 36 Number Of Workers � 23

  24. • Clang Modules • Dependency Scanning • Fast Dependency Scanning • Dependency Extraction • Future Work � 24

  25. What Does The Preprocessor Do? #ifndef HEADER_FILE #define HEADER_FILE Lex tokens… #include “Compiler.h” Evaluate #ifndef & #define // Clang is an awesome tool! Lex more tokens… class Clang: public Compiler { public: Include “Compiler.h” void buildAllCode(); #ifndef NDEBUG Lex more tokens… void dump(); Lex even more tokens 😬 #endif }; #endif � 25

  26. Reducing Preprocessor Workload #ifndef HEADER_FILE #define HEADER_FILE #include “Compiler.h” // Clang is an awesome tool! class Clang: public Compiler { Dependencies aren’t affected by these tokens 31 seconds to preprocess public: 31 seconds to preprocess void buildAllCode(); #ifndef NDEBUG void dump(); #endif }; #endif � 26

  27. Reducing Preprocessor Workload #ifndef HEADER_FILE #define HEADER_FILE #include “Compiler.h” // Clang is an awesome tool! class Clang: public Compiler { Dependencies aren’t affected by these tokens 31 seconds to preprocess public: 31 seconds to preprocess void buildAllCode(); #ifndefdNDEBUG void dump(); #endif }; #endif � 27

  28. Source Minimization #ifndef HEADER_FILE #define HEADER_FILE #include “Compiler.h” #endif � 28

  29. Source Minimization 💢 Keep directives that may affect dependency list #ifndef HEADER_FILE Strip everything else #define HEADER_FILE #include “Compiler.h” Context free: source reused in any compilation #endif � 29

  30. Clang and LLVM sources: 30% faster preprocessing 60 Preprocessing Time Minimized Source Preprocessing Time 45 Time (seconds) 30 15 0 6 12 18 24 30 36 Number Of Workers � 30

  31. Problem: Clang Invocations Preprocess Preprocess Parallel invocations do redundant work #include “Test.h” Read the same file twice #include “Test.h” Minimize Source Minimize the same file twice Minimize Source Preprocess Preprocess � 31

  32. Introducing clang-scan-deps • Library and command line tool for dependency scanning • Tool currently accepts compilation database and emits dependencies • Runs preprocessor invocations in parallel • Efficient: Reads and minimizes a source file only once • one shared FileSystem with shared minimized file cache • one shared FileManager � 32

  33. Minimized File Cache • Maps from file name to cache entry • Shared by worker threads: lock required access the StringMap • High lock contention for many threads 5 One StringMap Time (seconds) 3.75 2.5 1.25 0 18 24 30 36 Number Of Workers 33 �

  34. Optimizing Minimized File Cache • Solution: Array of StringMap addressed by hash of file name 5 One StringMap Time (seconds) Nine StringMaps 3.75 2.5 1.25 0 18 24 30 36 Number Of Workers 34 �

  35. Preprocessor Block Skipping When this #ifdef is not taken… #ifdef NOT_TAKEN // Important comment The tokens inside it are lexed… #include “LexMeNot.h” Until the #elif is found #elif Took up to 10-15% of time in our profiles #include “IAmLexed.h” #endif � 35

  36. Optimizing Preprocessor Block Skipping When this #ifdef is not taken… #ifdef NOT_TAKEN // Important comment #include “LexMeNot.h” Skip to #elif : add offset to Lexer’s pointer #elif Offset computed when minimizing file #include “IAmLexed.h” #endif � 36

  37. Clang and LLVM sources: 5-10x faster dependency scanning 40 Preprocessing Time scan-deps Time 30 Time (seconds) 20 10 0 6 12 18 24 30 36 Number Of Workers � 37

  38. Things We Aren’t Going To Support #define AT_IMPORT @import AT_IMPORT Foundation; #define WHY(X) _##X ("clang module import X") WHY(Pragma); ➡ We want to disallow this behavior in Clang � 38

  39. Modular Dependencies • clang-scan-deps builds implicit modules with minimized files • For now still uses old implicit module build machinery • Dependencies are extracted from the fast implicit build � 39

  40. • Clang Modules • Dependency Scanning • Fast Dependency Scanning • Dependency Extraction • Future Work � 40

  41. Dependency Extraction IR.min Analysis.min Transforms.min A.cpp.min B.cpp.min C.cpp.min D.cpp.min � 41

  42. Dependency Extraction IR.min Analysis.min Transforms.min A.cpp.min B.cpp.min C.cpp.min D.cpp.min � 42

  43. Dependency Extraction IR.min Analysis.min Transforms.min A.cpp.min B.cpp.min C.cpp.min D.cpp.min � 43

  44. 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 -fmodule-file=LLVM_IR.pcm -fmodule-file=LLVM_Analysis.pcm args = builds/release/bin/clang++ -cc1 -fmodules ...

  45. Initial Results - Scanning • Faster than modules -Eonly and -Eonly, but slower than scan-deps • Building modules takes time ☹ Modules -Eonly -Eonly 200 Modules scan-deps scan-deps Scan Time (seconds) 150 100 50 0 6 12 18 24 30 36 Number Of Workers � 45

  46. Initial Results - Scanning • Faster than modules -Eonly and -Eonly, but slower than scan-deps Modules -Eonly -Eonly 60 Modules scan-deps scan-deps Scan Time (seconds) 45 30 15 0 6 12 18 24 30 36 Number Of Workers � 46

  47. Initial Results - Scanning Modules -Eonly -Eonly 22 Modules scan-deps The cost of building modules during scanning scan-deps Scan Time (seconds) 16.5 11 5.5 0 6 12 18 24 30 36 Number Of Workers � 47

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend