blob: d37b76736b0d787fef7dcc6f65809dd085455dd3 [file] [log] [blame]
Sean Silva93ca0212012-12-13 01:10:46 +00001==========================
2Pretokenized Headers (PTH)
3==========================
4
5This document first describes the low-level interface for using PTH and
6then briefly elaborates on its design and implementation. If you are
7interested in the end-user view, please see the `User's
8Manual <UsersManual.html#precompiledheaders>`_.
9
10Using Pretokenized Headers with ``clang`` (Low-level Interface)
11===============================================================
12
13The Clang compiler frontend, ``clang -cc1``, supports three command line
14options for generating and using PTH files.
15
16To generate PTH files using ``clang -cc1``, use the option
17``-emit-pth``:
18
19::
20
21 $ clang -cc1 test.h -emit-pth -o test.h.pth
22
23This option is transparently used by ``clang`` when generating PTH
24files. Similarly, PTH files can be used as prefix headers using the
25``-include-pth`` option:
26
27::
28
29 $ clang -cc1 -include-pth test.h.pth test.c -o test.s
30
31Alternatively, Clang's PTH files can be used as a raw "token-cache" (or
32"content" cache) of the source included by the original header file.
33This means that the contents of the PTH file are searched as substitutes
34for *any* source files that are used by ``clang -cc1`` to process a
35source file. This is done by specifying the ``-token-cache`` option:
36
37::
38
39 $ cat test.h
40 #include <stdio.h>
41 $ clang -cc1 -emit-pth test.h -o test.h.pth
42 $ cat test.c
43 #include "test.h"
44 $ clang -cc1 test.c -o test -token-cache test.h.pth
45
46In this example the contents of ``stdio.h`` (and the files it includes)
47will be retrieved from ``test.h.pth``, as the PTH file is being used in
48this case as a raw cache of the contents of ``test.h``. This is a
49low-level interface used to both implement the high-level PTH interface
50as well as to provide alternative means to use PTH-style caching.
51
52PTH Design and Implementation
53=============================
54
55Unlike GCC's precompiled headers, which cache the full ASTs and
56preprocessor state of a header file, Clang's pretokenized header files
57mainly cache the raw lexer *tokens* that are needed to segment the
58stream of characters in a source file into keywords, identifiers, and
59operators. Consequently, PTH serves to mainly directly speed up the
60lexing and preprocessing of a source file, while parsing and
61type-checking must be completely redone every time a PTH file is used.
62
63Basic Design Tradeoffs
64~~~~~~~~~~~~~~~~~~~~~~
65
66In the long term there are plans to provide an alternate PCH
67implementation for Clang that also caches the work for parsing and type
68checking the contents of header files. The current implementation of PCH
69in Clang as pretokenized header files was motivated by the following
70factors:
71
72**Language independence**
73 PTH files work with any language that
74 Clang's lexer can handle, including C, Objective-C, and (in the early
75 stages) C++. This means development on language features at the
76 parsing level or above (which is basically almost all interesting
77 pieces) does not require PTH to be modified.
78
79**Simple design**
80 Relatively speaking, PTH has a simple design and
81 implementation, making it easy to test. Further, because the
82 machinery for PTH resides at the lower-levels of the Clang library
83 stack it is fairly straightforward to profile and optimize.
84
85Further, compared to GCC's PCH implementation (which is the dominate
86precompiled header file implementation that Clang can be directly
87compared against) the PTH design in Clang yields several attractive
88features:
89
90**Architecture independence**
91 In contrast to GCC's PCH files (and
92 those of several other compilers), Clang's PTH files are architecture
93 independent, requiring only a single PTH file when building an
94 program for multiple architectures.
95
96 For example, on Mac OS X one may wish to compile a "universal binary"
97 that runs on PowerPC, 32-bit Intel (i386), and 64-bit Intel
98 architectures. In contrast, GCC requires a PCH file for each
99 architecture, as the definitions of types in the AST are
100 architecture-specific. Since a Clang PTH file essentially represents
101 a lexical cache of header files, a single PTH file can be safely used
102 when compiling for multiple architectures. This can also reduce
103 compile times because only a single PTH file needs to be generated
104 during a build instead of several.
105
106**Reduced memory pressure**
107 Similar to GCC, Clang reads PTH files
108 via the use of memory mapping (i.e., ``mmap``). Clang, however,
109 memory maps PTH files as read-only, meaning that multiple invocations
110 of ``clang -cc1`` can share the same pages in memory from a
111 memory-mapped PTH file. In comparison, GCC also memory maps its PCH
112 files but also modifies those pages in memory, incurring the
113 copy-on-write costs. The read-only nature of PTH can greatly reduce
114 memory pressure for builds involving multiple cores, thus improving
115 overall scalability.
116
117**Fast generation**
118 PTH files can be generated in a small fraction
119 of the time needed to generate GCC's PCH files. Since PTH/PCH
120 generation is a serial operation that typically blocks progress
121 during a build, faster generation time leads to improved processor
122 utilization with parallel builds on multicore machines.
123
124Despite these strengths, PTH's simple design suffers some algorithmic
125handicaps compared to other PCH strategies such as those used by GCC.
126While PTH can greatly speed up the processing time of a header file, the
127amount of work required to process a header file is still roughly linear
128in the size of the header file. In contrast, the amount of work done by
129GCC to process a precompiled header is (theoretically) constant (the
130ASTs for the header are literally memory mapped into the compiler). This
131means that only the pieces of the header file that are referenced by the
132source file including the header are the only ones the compiler needs to
133process during actual compilation. While GCC's particular implementation
134of PCH mitigates some of these algorithmic strengths via the use of
135copy-on-write pages, the approach itself can fundamentally dominate at
136an algorithmic level, especially when one considers header files of
137arbitrary size.
138
139There are plans to potentially implement an complementary PCH
140implementation for Clang based on the lazy deserialization of ASTs. This
141approach would theoretically have the same constant-time algorithmic
142advantages just mentioned but would also retain some of the strengths of
143PTH such as reduced memory pressure (ideal for multi-core builds).
144
145Internal PTH Optimizations
146~~~~~~~~~~~~~~~~~~~~~~~~~~
147
148While the main optimization employed by PTH is to reduce lexing time of
149header files by caching pre-lexed tokens, PTH also employs several other
150optimizations to speed up the processing of header files:
151
152- ``stat`` caching: PTH files cache information obtained via calls to
153 ``stat`` that ``clang -cc1`` uses to resolve which files are included
154 by ``#include`` directives. This greatly reduces the overhead
155 involved in context-switching to the kernel to resolve included
156 files.
157
158- Fasting skipping of ``#ifdef``... ``#endif`` chains: PTH files
159 record the basic structure of nested preprocessor blocks. When the
160 condition of the preprocessor block is false, all of its tokens are
161 immediately skipped instead of requiring them to be handled by
162 Clang's preprocessor.
163
164