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