Bibliography¶
Every source cited anywhere in the course, merged from the chapters' references.yaml files and grouped by kind. Each entry says why and when to read it and links to the chapters that cite it.
Foundational and research papers¶
-
[AC72b] Frances E. Allen and John Cocke. A Catalogue of Optimizing Transformations. In R. Rustin (ed.), Design and Optimization of Compilers, Prentice-Hall, pp. 1–30, 1972.
Why and when: The catalogue that named code motion, strength reduction, unrolling and unswitching as standard transformations; skim it for the vocabulary Lessons 18.1, 18.4 and 18.5 inherit.
Note: A book chapter; no DOI. Found in university libraries and as scans of the Allen archive.
Chapters: Ch 18 -
[AC76] Frances E. Allen and John Cocke. A Program Data Flow Analysis Procedure. Communications of the ACM 19(3), p. 137, 1976. doi:10.1145/360018.360025
Why and when: Core reading. The interval-based elimination procedure of Lesson 14.5 (Algorithm 14.5.6) applied to the classic bit-vector problems; the paper that fixed the gen/kill vocabulary. Read after Lesson 14.5 §3.
Chapters: Ch 14, Ch 15 -
[ACK81] Frances E. Allen, John Cocke, and Ken Kennedy. Reduction of Operator Strength. In S. S. Muchnick and N. D. Jones (eds.), Program Flow Analysis: Theory and Applications, Prentice-Hall, pp. 79–101, 1981.
Why and when: Classic strength reduction of induction-variable multiplications in loops; the global ancestor of Lesson 12.3's local rewrites and the topic of Chapter 18.
Note: Book chapter; no DOI.
Chapters: Ch 12, Ch 18 -
[ACPPW08] Brian Aydemir, Arthur Charguéraud, Benjamin C. Pierce, Randy Pollack, and Stephanie Weirich. Engineering formal metatheory. POPL 2008, 3–15, 2008. doi:10.1145/1328438.1328443
Why and when: Locally nameless plus cofinite quantification, the recipe that the side condition of Lemma 5.2.13 alludes to. Read §2–3 after Lesson 5.2 §6.
Chapters: Ch 5 -
[AEH73] T. Anderson, J. Eve, and J. J. Horning. Efficient LR(1) parsers. Acta Informatica 2(1), 12–39, 1973. doi:10.1007/BF00571461
Why and when: How to make LR(1) parsers practical: compact encodings of the tables and space optimizations such as default reductions (Lessons 3.1 §6, 3.3 §1). Read it for the engineering side of table construction; optional.
Chapters: Ch 3 -
[AG01] Andrew W. Appel and Lal George. Optimal Spilling for CISC Machines with Few Registers. PLDI 2001, pp. 243–253, 2001. doi:10.1145/381694.378854
Why and when: Split the problem: decide optimally by ILP where each value is in a register, then assign registers by coalescing (Algorithm 22.7.7). Read §2–3.
Chapters: Ch 22 -
[AGG62] Bruce W. Arden, Bernard A. Galler, and Robert M. Graham. An Algorithm for Translating Boolean Expressions. Journal of the ACM 9(2), pp. 222–239, 1962. doi:10.1145/321119.321123
Why and when: The origin of jumping code: a Boolean expression becomes tests and jumps that stop as soon as the result is known. Compare its scheme with Algorithm 11.2.2 after Lesson 11.2 §2.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 11 -
[AGS97] Andrew Ayers, Richard Schooler, and Robert Gottlieb. Aggressive Inlining. PLDI 1997, pp. 134–145, 1997. doi:10.1145/258915.258928
Why and when: HP's profile-driven inliner and cloner for large programs: benefit/cost priorities and a global budget. Read §3–4 after Lesson 20.3's classic heuristics.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[AGT89] Alfred V. Aho, Mahadevan Ganapathi, and Steven W. K. Tjiang. Code Generation Using Tree Matching and Dynamic Programming. ACM TOPLAS 11(4), pp. 491–516, 1989. doi:10.1145/69558.75700
Why and when: Core reading. twig: tree patterns with costs and actions, top-down matching and the tiling DP of Algorithm 21.2.3. The paper that made DP tiling a generator (Lesson 21.2 §1 and §7).
Chapters: Ch 21 -
[AH00] John Aycock and Nigel Horspool. Simple Generation of Static Single-Assignment Form. Compiler Construction (CC 2000), LNCS 1781, 2000. doi:10.1007/3-540-46423-9_8
Why and when: Build "maximal" SSA (a phi for every variable at every join), then delete redundant phis with two rewrite rules until none applies; minimal for reducible CFGs. The second technique of Lesson 16.3 and the optional lab algorithm.
Chapters: Ch 16 -
[AH02] John Aycock and R. Nigel Horspool. Practical Earley parsing. The Computer Journal 45(6), 620–630, 2002. doi:10.1093/comjnl/45.6.620
Why and when: The nullable fix to the predictor used in Algorithm 4.3.3, with a proof that it is enough. Read §2–3 after the ε example of Lesson 4.3 §3.
Chapters: Ch 4 -
[AHLT99] Stephen Alstrup, Dov Harel, Peter W. Lauridsen, and Mikkel Thorup. Dominators in Linear Time. SIAM Journal on Computing 28(6), pp. 2117-2132, 1999. doi:10.1137/S0097539797317263
Why and when: Removes the inverse-Ackermann factor with microtrees; cited in Lesson 15.1 §6 as the theoretical end point. Read only the introduction: no production compiler uses it.
Chapters: Ch 15 -
[AJ76] Alfred V. Aho and Stephen C. Johnson. Optimal Code Generation for Expression Trees. Journal of the ACM 23(3), pp. 488–501, 1976. doi:10.1145/321958.321970
Why and when: Core reading. The origin of dynamic-programming tree tiling: contiguous evaluation, the cost vector per register count, and the optimality proof behind Algorithm 21.2.5 and Theorem 21.2.8. Read §3–4 after Lesson 21.2 §2.
Chapters: Ch 21 -
[AJ89] Andrew W. Appel and Trevor Jim. Continuation-Passing, Closure-Passing Style. POPL 1989, pp. 293–302, 1989. doi:10.1145/75277.75303
Why and when: Closure conversion as a source-to-source transformation in a CPS compiler, with flat vs linked environments and space safety; read after Lesson 11.8 §2 and §6.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 11 -
[AJU75] Alfred V. Aho, Stephen C. Johnson, and Jeffrey D. Ullman. Deterministic parsing of ambiguous grammars. Communications of the ACM 18(8), 441–452, 1975. doi:10.1145/360933.360969
Why and when: Precedence and associativity declarations instead of layered grammars: the idea behind yacc's and Bison's %left/%right, shown as a variant in Lesson 2.1 §6 and developed in Ch 3.
Chapters: Ch 2, Ch 3 -
[AJU77] Alfred V. Aho, Stephen C. Johnson, and Jeffrey D. Ullman. Code Generation for Expressions with Common Subexpressions. Journal of the ACM 24(1), pp. 146–160, 1977.
Why and when: Shows that generating optimal code from a DAG (unlike from a tree) is NP-complete, the reason block reassembly uses heuristics (Lesson 13.5 §5).
Note: ACM Digital Library.
Chapters: Ch 13, Ch 21 -
[AK84] John R. Allen and Ken Kennedy. Automatic Loop Interchange. SIGPLAN Symposium on Compiler Construction 1984 (SIGPLAN Notices 19(6)), pp. 233-246, 1984. doi:10.1145/502949.502897
Why and when: Interchange legality with direction vectors, as implemented in PFC; the origin of Theorem 18.7.4's two-loop case.
Chapters: Ch 18 -
[AK87] Randy Allen and Ken Kennedy. Automatic Translation of FORTRAN Programs to Vector Form. ACM TOPLAS 9(4), pp. 491-542, 1987. doi:10.1145/29873.29875
Why and when: The classic vectorizer: dependence graph, distribution by SCCs, vector statements (Lesson 18.7's Algorithm 18.7.2 and Lesson 18.8's history).
Chapters: Ch 18 -
[AKPW83] J. R. Allen, Ken Kennedy, Carrie Porterfield, and Joe Warren. Conversion of Control Dependence to Data Dependence. POPL 1983, pp. 177-189, 1983. doi:10.1145/567067.567085
Why and when: If-conversion, the basis of predication in Lesson 18.8 (Algorithm 18.8.9).
Chapters: Ch 18, Ch 23 -
[All70] Frances E. Allen. Control Flow Analysis. SIGPLAN Notices 5(7), Proc. Symposium on Compiler Optimization, pp. 1–19, 1970. doi:10.1145/390013.808479
Why and when: Basic blocks, flow graphs and intervals: the paper that made the CFG the foundation of optimization. Read §2 with Lesson 8.2.
Chapters: Ch 8, Ch 14, Ch 15 -
[Ant96] Valentin Antimirov. Partial derivatives of regular expressions and finite automaton constructions. Theoretical Computer Science 155(2), pp. 291–319, 1996. doi:10.1016/0304-3975(95)00182-4
Why and when: Partial derivatives and the partial-derivative automaton with at most (positions + 1) states (Theorem 1.3.13). Read §2–3 after Lesson 1.3; the rest treats proofs of regular-expression inequalities.
Chapters: Ch 1 -
[AP72] Alfred V. Aho and Thomas G. Peterson. A minimum distance error-correcting parser for context-free languages. SIAM Journal on Computing 1(4), 305–312, 1972. doi:10.1137/0201022
Why and when: Core reading. Global minimum-distance repair in O(n³) for every CFG: the dynamic program behind Algorithm 2.7.6 and Theorem 2.7.11. Read the construction of the covering grammar and the parser.
Chapters: Ch 2 -
[App98] Andrew W. Appel. SSA is Functional Programming. ACM SIGPLAN Notices 33(4), pp. 17–20, 1998. doi:10.1145/278283.278285
Why and when: Core reading. A four-page explanation of why "definitions dominate uses" is lexical scoping when blocks become nested functions. Read it before Lesson 8.6 §4.
Chapters: Ch 8, Ch 16 -
[AR22] Andreas Abel and Jan Reineke. uiCA: Accurate Throughput Prediction of Basic Blocks on Recent Intel Microarchitectures. ICS 2022, 2022. doi:10.1145/3524059.3532396 · pdf
Why and when: A detailed simulator of Intel front ends, measured against hardware, with a comparison ofllvm-mca, IACA and OSACA. Read it to see where Definition 23.1.10's bounds are not the whole story (Lesson 23.1 §6).
Chapters: Ch 23 -
[AWZ88] Bowen Alpern, Mark N. Wegman, and F. Kenneth Zadeck. Detecting Equality of Variables in Programs. POPL 1988, pp. 1–11, 1988. doi:10.1145/73560.73561
Why and when: One of the two 1988 papers that introduced SSA form, used here for global value numbering by partitioning. Read §1–2 for the motivation of Lesson 8.4.
Chapters: Ch 8, Ch 16, Ch 17 -
[BA06] Sorav Bansal and Alex Aiken. Automatic Generation of Peephole Superoptimizers. ASPLOS XII, pp. 394–403, 2006.
Why and when: Enumerate all short sequences once, index them by fingerprint, and harvest proven window→replacement rules from training programs (Algorithm 13.3.4). Read §3–4 after Lesson 13.3.
Note: ACM Digital Library (ASPLOS '06).
Chapters: Ch 13, Ch 21 -
[BA08] Hans-J. Boehm and Sarita V. Adve. Foundations of the C++ Concurrency Memory Model. PLDI 2008, pp. 68–78, 2008. doi:10.1145/1375581.1375591
Why and when: The rationale of the C++11 memory model that LLVM's atomics and orderings adopt (Lesson 9.4, Definition 9.4.11), including why data races are undefined. Read §1–4 after Lesson 9.4's atomics section.
Chapters: Ch 9 -
[Bak78] Henry G. Baker Jr.. Shallow binding in Lisp 1.5. Communications of the ACM 21(7), 565–569, 1978. doi:10.1145/359545.359566
Why and when: Rerooting: one global value cell per name, moved lazily between contexts, which reconciles deep and shallow binding (Lesson 5.1 §6). Short; read after Algorithm 5.1.8.
Chapters: Ch 5 -
[Ban79] John P. Banning. An Efficient Way to Find the Side Effects of Procedure Calls and the Aliases of Variables. POPL 1979, pp. 29–41, 1979. doi:10.1145/567752.567756
Why and when: Side-effect (MOD/REF) summaries of procedures, the ancestor of memory-effect inference. Read after Lesson 20.6 §2 (the effect equations of Definition 20.6.3).
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[BB68] Jean-Loup Baer and Daniel P. Bovet. Compilation of Arithmetic Expressions for Parallel Computations. Proc. IFIP Congress 1968, pp. 340–346, 1968.
Why and when: Early use of associativity and commutativity to reduce the height of expression trees for parallel evaluation (Lesson 13.6 §1). Historical.
Note: IFIP Congress proceedings (North-Holland).
Chapters: Ch 13 -
[BBB+57] John W. Backus, R. J. Beeber, S. Best, R. Goldberg, L. M. Haibt, H. L. Herrick, R. A. Nelson, D. Sayre, P. B. Sheridan, H. Stern, I. Ziller, R. A. Hughes, and R. Nutt. The FORTRAN Automatic Coding System. Proc. Western Joint Computer Conference, pp. 188–198, 1957. doi:10.1145/1455567.1455599
Why and when: The first optimizing compiler, organized as six sections run in sequence: the origin of the multi-pass pipeline and of AOT compilation (Lessons 0.1 and 0.3). Short and readable; skim the description of the sections.
Chapters: Ch 0 -
[BBH+13] Matthias Braun, Sebastian Buchwald, Sebastian Hack, Roland Leißa, Christoph Mallon, and Andreas Zwinkau. Simple and Efficient Construction of Static Single Assignment Form. CC 2013, LNCS 7791, pp. 102–122, 2013. doi:10.1007/978-3-642-37051-9_6
Why and when: SSA construction directly from the AST with trivial-phi removal, used by Cranelift'sSSABuilder; the trivial-parameter pruning of Lesson 8.4 is its removal rule on block arguments. Implemented in Ch 16.
Chapters: Ch 8, Ch 11, Ch 16 -
[BC93] Peter Bumbulis and Donald D. Cowan. RE2C: a more versatile scanner generator. ACM Letters on Programming Languages and Systems 2(1–4), pp. 70–84, 1993. doi:10.1145/176454.176487
Why and when: The origin of re2c and of generating DFAs as direct code instead of tables (Algorithm 1.5.8), with measurements against flex. Read after Lesson 1.5 §2.
Note: ACM journal article.
Chapters: Ch 1 -
[BC94] Preston Briggs and Keith D. Cooper. Effective Partial Redundancy Elimination. PLDI 1994, pp. 159–170, 1994.
Why and when: Core reading. The origin of rank-based global reassociation (Definition 13.6.2, Algorithm 13.6.3): it reorders expressions so that partial redundancy elimination and code motion find more. Read the reassociation sections after Lesson 13.6.
Note: ACM Digital Library (PLDI '94).
Chapters: Ch 13, Ch 17 -
[BCC+03] Bruno Blanchet, Patrick Cousot, Radhia Cousot, Jérôme Feret, Laurent Mauborgne, Antoine Miné, David Monniaux, and Xavier Rival. A Static Analyzer for Large Safety-Critical Software. PLDI 2003, pp. 196-207, 2003. doi:10.1145/781131.781153
Why and when: Astrée: abstract interpretation at industrial scale, widening with thresholds, octagon packs (Lesson 14.7 §6). Read for how the theory survives contact with 100 000-line programs.
Chapters: Ch 14 -
[BCFR09] Carl Friedrich Bolz, Antonio Cuni, Maciej Fijałkowski, and Armin Rigo. Tracing the Meta-Level: PyPy's Tracing JIT Compiler. ICOOOLPS 2009, pp. 18–25, 2009. doi:10.1145/1565824.1565827
Why and when: Core reading. Meta-tracing: trace the interpreter, not the program, with hints marking the dispatch loop — a practical, dynamic form of the first Futamura projection (Lesson 0.3).
Chapters: Ch 0 -
[BCH+02] Zoran Budimlić, Keith D. Cooper, Timothy J. Harvey, Ken Kennedy, Timothy S. Oberg, and Steven W. Reeves. Fast Copy Coalescing and Live-Range Identification. Proc. ACM SIGPLAN PLDI 2002, 2002. doi:10.1145/512529.512534
Why and when: The dominance-forest interference test that Boissinot et al. build on: in strict SSA two names interfere iff one is live at the definition of the other (Lemma 16.7.1).
Chapters: Ch 16, Ch 22 -
[BCHS98] Preston Briggs, Keith D. Cooper, Timothy J. Harvey, and L. Taylor Simpson. Practical Improvements to the Construction and Destruction of Static Single Assignment Form. Software: Practice and Experience 28(8), 1998. doi:10.1002/(SICI)1097-024X(19980710)28:8<859::AID-SPE188>3.0.CO;2-8
Why and when: Core reading. Two contributions in one paper: semi-pruned SSA (phis only for names live across a block boundary, Definition 16.1.7) and the lost-copy and swap problems of naive destruction with their fixes (Lesson 16.6). Read the construction half with Lesson 16.1, the destruction half with Lesson 16.6; its phi-count tables back the comparison in Lesson 16.1 §5.
Chapters: Ch 16 -
[BCS97] Preston Briggs, Keith D. Cooper, and L. Taylor Simpson. Value Numbering. Software: Practice and Experience 27(6), pp. 701–724, 1997.
Why and when: Local, superlocal, dominator-based and hash-based global value numbering compared experimentally. Read after Lessons 13.1 and 13.5 for the scope variants.
Note: Wiley Online Library.
Chapters: Ch 13, Ch 17 -
[BCT92] Preston Briggs, Keith D. Cooper, and Linda Torczon. Rematerialization. PLDI 1992, 1992. doi:10.1145/143095.143143
Why and when: Core reading. The origin of rematerialization in a Chaitin–Briggs allocator: tag values with the instruction that computes them by a sparse SSA propagation, split live ranges where the tag changes, and recompute instead of reloading. Read §3–4 with Lesson 22.9.
Chapters: Ch 22 -
[BCT94] Preston Briggs, Keith D. Cooper, and Linda Torczon. Improvements to Graph Coloring Register Allocation. ACM TOPLAS 16(3), pp. 428–455, 1994. doi:10.1145/177492.177575
Why and when: Core reading. Optimistic colouring (spill only when select fails), the Briggs coalescing test, and the measurements behind "never worse than Chaitin". Read §2–4 with Lessons 22.3 and 22.4.
Chapters: Ch 22 -
[BD77] R. M. Burstall and John Darlington. A Transformation System for Developing Recursive Programs. Journal of the ACM 24(1), pp. 44–67, 1977. doi:10.1145/321992.321996
Why and when: Fold/unfold transformations, including generalization with accumulating parameters — the program-transformation view of TRE with accumulators (Lesson 20.8, Theorem 20.8.5).
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 20 -
[BDB00] Vasanth Bala, Evelyn Duesterwald, and Sanjeev Banerjia. Dynamo: A Transparent Dynamic Optimization System. PLDI 2000, pp. 1–12, 2000. doi:10.1145/349299.349303
Why and when: Hot-path (trace) selection and optimization of running native code; the origin of the tracing idea that TraceMonkey and LuaJIT apply to language VMs (Lesson 0.3).
Chapters: Ch 0 -
[BDB90] A. Balachandran, D. M. Dhamdhere, and S. Biswas. Efficient Retargetable Code Generation Using Bottom-up Tree Pattern Matching. Computer Languages 15(3), pp. 127–140, 1990. doi:10.1016/0096-0551(90)90006-B
Why and when: A simpler BURS table construction for regular tree grammars with Graham–Glanville style costs; compare with Algorithm 21.3.5 after Lesson 21.3 §6.
Chapters: Ch 21 -
[BDGR06] Florent Bouchez, Alain Darte, Christophe Guillon, and Fabrice Rastello. Register Allocation: What Does the NP-Completeness Proof of Chaitin et al. Really Prove?. LCPC 2006 (LNCS, published 2007), 2006. doi:10.1007/978-3-540-72521-3_21
Why and when: Chaitin's reduction relies on critical edges and copies; without them (SSA, no spilling) the colouring problem is easy. Read after Theorem 22.3.6 and Lesson 22.6.
Chapters: Ch 22 -
[BDMS05] Philip Brisk, Foad Dabiri, Jamie Macbeth, and Majid Sarrafzadeh. Polynomial-Time Graph Coloring Register Allocation. International Workshop on Logic and Synthesis (IWLS 2005), pp. 447–454, 2005.
Why and when: An independent proof that SSA interference graphs are chordal, from high-level synthesis; cited with Theorem 22.6.5.
Note: Workshop paper (Lake Arrowhead, CA, June 2005); indexed by ResearchGate and the ACM Digital Library.
Chapters: Ch 22 -
[BDR+09] Benoit Boissinot, Alain Darte, Fabrice Rastello, Benoît Dupont de Dinechin, and Christophe Guillon. Revisiting Out-of-SSA Translation for Correctness, Code Quality, and Efficiency. Proc. 7th IEEE/ACM International Symposium on Code Generation and Optimization (CGO 2009), 2009. doi:10.1109/CGO.2009.19
Why and when: Core reading. The modern recipe of Lesson 16.7: isolate phis with parallel copies (Sreedhar's Method I made parallel), coalesce aggressively with value-based interference, check interference without an interference graph using dominance order and fast liveness, and sequentialize parallel copies with the minimum number of moves. Read it after Lesson 16.7.
Chapters: Ch 16, Ch 22 -
[BDR07] Florent Bouchez, Alain Darte, and Fabrice Rastello. On the Complexity of Register Coalescing. CGO 2007, pp. 102–114, 2007. doi:10.1109/CGO.2007.26
Why and when: Aggressive, conservative, incremental and optimistic coalescing classified by complexity (Theorem 22.4.11); incremental conservative coalescing on chordal graphs is polynomial. Read the summary table first.
Chapters: Ch 22 -
[BDR07b] Florent Bouchez, Alain Darte, and Fabrice Rastello. On the Complexity of Spill Everywhere under SSA Form. LCTES 2007, 2007. doi:10.1145/1273444.1254782 · pdf
Why and when: Spilling stays NP-complete on SSA and on interval graphs, with the polynomial special cases (Theorems 22.6.11 and 22.9.11). Read the introduction and the summary of results.
Chapters: Ch 22 -
[BDR08] Florent Bouchez, Alain Darte, and Fabrice Rastello. Advanced Conservative and Optimistic Register Coalescing. CASES 2008, 2008. doi:10.1145/1450095.1450119
Why and when: Stronger conservative tests and better de-coalescing; read after Lesson 22.4 §6 if you want to go beyond Briggs and George.
Chapters: Ch 22 -
[Bea82] John C. Beatty. On the relationship between the LL(1) and LR(1) grammars. Journal of the ACM 29(4), 1007–1022, 1982. doi:10.1145/322344.322350
Why and when: Every p-reduced LL(1) grammar is LALR(1), and every ε-free LL(1) grammar is SLR(1): the precise boundary behind Proposition 3.3.14's counterexample (which is not p-reduced).
Chapters: Ch 3 -
[BEH91] David G. Bradlee, Susan J. Eggers, and Robert R. Henry. Integrating Register Allocation and Instruction Scheduling for RISCs. ASPLOS IV (ACM SIGPLAN Notices 26(4)), pp. 122–131, 1991.
Why and when: An empirical comparison of postpass, IPS and a fully integrated strategy; the evidence that a pressure-aware prepass scheduler gets most of the benefit (Lesson 23.8 §1, §8).
Note: In the ASPLOS IV proceedings, 1991.
Chapters: Ch 23 -
[Bel66] Laszlo A. Belady. A Study of Replacement Algorithms for a Virtual-Storage Computer. IBM Systems Journal 5(2), pp. 78–101, 1966. doi:10.1147/sj.52.0078
Why and when: Core reading. The furthest-next-use rule (MIN) as the optimum of page replacement; Lesson 22.2 applies it to the registers of one block. Read the description of MIN; the simulations are of historical interest only.
Chapters: Ch 22 -
[Bel73] James R. Bell. Threaded Code. Communications of the ACM 16(6), pp. 370–372, 1973. doi:10.1145/362248.362270
Why and when: Core reading. Three pages that introduce threaded code: the program as a list of routine addresses, each routine jumping to the next. The origin of Definition 0.2.8's direct threading.
Chapters: Ch 0 -
[Ber66] A. J. Bernstein. Analysis of Programs for Parallel Processing. IEEE Transactions on Electronic Computers EC-15(5), pp. 757–763, 1966. doi:10.1109/PGEC.1966.264565
Why and when: Bernstein's conditions: two operations may run in parallel when neither writes what the other reads or writes. They are Definition 23.2.2's three register dependences in their original form.
Chapters: Ch 23 -
[Ber85] Robert L. Bernstein. Producing Good Code for the Case Statement. Software—Practice and Experience 15(10), 1985.
Why and when: The classic heuristic: split a sparse switch into dense jump tables joined by a comparison tree. The starting point of Lesson 11.3 §6 and of Kannan and Proebsting's correction.
Note: Wiley journal; no DOI was re-resolved from the course container — find it by title.
Chapters: Ch 11 -
[Ber86] Robert Bernstein. Multiplication by Integer Constants. Software: Practice and Experience 16(7), pp. 641–652, 1986.
Why and when: The search for the cheapest shift/add/subtract sequence for x * C that compilers adapted (Lesson 13.7 §1, §6). Read after Algorithm 13.7.2.
Note: Wiley Online Library.
Chapters: Ch 13 -
[BF87] Michael G. Burke and Gerald A. Fisher. A practical method for LR and LL syntactic error diagnosis and recovery. ACM TOPLAS 9(2), 164–197, 1987. doi:10.1145/22719.22720
Why and when: Bounded-window repair that tries edits near the error and keeps the one that parses furthest: the practical compromise between local and global repair (Lesson 2.7 §5–6).
Chapters: Ch 2, Ch 3 -
[BGG+89] David Bernstein, Martin C. Golumbic, Yishay Mansour, Ron Y. Pinter, Dina Q. Goldin, Hugo Krawczyk, and Itai Nahshon. Spill Code Minimization Techniques for Optimizing Compilers. PLDI 1989 (SIGPLAN Notices 24(7)), pp. 258–263, 1989. doi:10.1145/73141.74841
Why and when: Best-of-three spill heuristics (cost/degree, cost/degree², area-based) and cleaning of spill code; the refinements of Chaitin's metric in Lessons 22.3 §6 and 22.9 §6.
Chapters: Ch 22 -
[BGKRTW08] Adam L. Buchsbaum, Loukas Georgiadis, Haim Kaplan, Anne Rogers, Robert E. Tarjan, and Jeffery R. Westbrook. Linear-Time Algorithms for Dominators and Other Path-Evaluation Problems. SIAM Journal on Computing 38(4), pp. 1533-1573, 2008. doi:10.1137/070693217
Why and when: A simpler linear-time dominator algorithm (and a correction of earlier claims); §1-2 give the clearest survey of the dominator-algorithm landscape after Lesson 15.1.
Chapters: Ch 15 -
[BGS00] Rastislav Bodík, Rajiv Gupta, and Vivek Sarkar. ABCD: Eliminating Array Bounds Checks on Demand. Proc. ACM SIGPLAN PLDI 2000, 2000.
Why and when: e-SSA (extended SSA): pi assignments after conditional branches, used to prove array bounds checks redundant on demand. LLVM's PredicateInfo implements the same idea.
Note: Look it up by title in the ACM Digital Library (DOI not re-checked from the course container).
Chapters: Ch 16, Ch 18, Ch 24 -
[BH09] Matthias Braun and Sebastian Hack. Register Spilling and Live-Range Splitting for SSA-Form Programs. CC 2009 (LNCS), 2009. doi:10.1007/978-3-642-00722-4_13
Why and when: Belady's rule made global: next-use distances over the CFG, loops counted as far away, and coupling at block borders; the spiller of libFirm and of Lesson 22.6's decoupled spilling.
Chapters: Ch 22 -
[BHG+08] Benoit Boissinot, Sebastian Hack, Daniel Grund, Benoît Dupont de Dinechin, and Fabrice Rastello. Fast Liveness Checking for SSA-Form Programs. CGO 2008, pp. 35-44, 2008. doi:10.1145/1356058.1356064
Why and when: Answering "is v live at p?" without computing sets, from the dominator tree and loop structure (Lessons 14.3 and 14.6 §6). Useful before Ch 16's SSA destruction.
Chapters: Ch 14, Ch 16, Ch 22 -
[BHRS08] Uday Bondhugula, Albert Hartono, J. Ramanujam, and P. Sadayappan. A Practical Automatic Polyhedral Parallelizer and Locality Optimizer. PLDI 2008, pp. 101-113, 2008. doi:10.1145/1375581.1375595
Why and when: Pluto: choose tiling hyperplanes that minimize dependence distances; the scheduler behind the skew isl found in Lesson 18.7's box.
Chapters: Ch 18 -
[BK73] Walter A. Burkhard and Robert M. Keller. Some approaches to best-match file searching. Communications of the ACM 16(4), 230–236, 1973. doi:10.1145/362003.362025
Why and when: BK-trees (Algorithm 5.8.7): metric-space indexing with the triangle inequality, and why the distance must be a metric (Theorem 5.8.12, Lemma 5.8.11). Read §2 after Lesson 5.8 §2.
Chapters: Ch 5 -
[BL89] Manuel E. Bermudez and George Logothetis. Simple computation of LALR(1) lookahead sets. Information Processing Letters 31(5), 233–238, 1989. doi:10.1016/0020-0190(89)90079-3
Why and when: LALR(1) lookaheads as ordinary FOLLOW sets of a transformed grammar: a variant of DeRemer–Pennello (Lesson 3.3 §6) that reuses your Chapter 2 FOLLOW code.
Chapters: Ch 3 -
[BL94] Thomas Ball and James R. Larus. Optimally Profiling and Tracing Programs. ACM TOPLAS 16(4), pp. 1319–1360, 1994. doi:10.1145/183432.183527
Why and when: Counter placement on the complement of a (maximum-weight) spanning tree, its optimality, and edge profiling vs tracing. Read §2–3 after Lesson 12.3 §2 (Theorem 12.3.12).
Chapters: Ch 12, Ch 20 -
[BMC20] Marcel Böhme, Valentin J. M. Manès, and Sang Kil Cha. Boosting Fuzzer Efficiency: An Information Theoretic Perspective. ESEC/FSE 2020, pp. 678–689, 2020. doi:10.1145/3368089.3409748
Why and when: Entropic, the power schedule libFuzzer uses by default (its start-up log says "Running with entropic power schedule"; Lesson 12.6's box filters that line out). Read §3 after Lesson 12.6.
Chapters: Ch 12 -
[BMO90] Robert A. Ballance, Arthur B. Maccabe, and Karl J. Ottenstein. The Program Dependence Web: A Representation Supporting Control-, Data-, and Demand-Driven Interpretation of Imperative Languages. Proc. ACM SIGPLAN PLDI 1990, 1990.
Why and when: The origin of gated SSA: gamma, mu and eta gating functions that make the controlling predicate of a merge explicit. Lesson 16.8's gated-SSA section follows its definitions.
Note: Look it up by title in the ACM Digital Library (DOI not re-checked from the course container).
Chapters: Ch 16 -
[BOSW98] Gilad Bracha, Martin Odersky, David Stoutamire, and Philip Wadler. Making the Future Safe for the Past: Adding Genericity to the Java Programming Language. OOPSLA 1998, 183–200, 1998. doi:10.1145/286936.286957
Why and when: GJ, the design Java 5 adopted: generics compiled by erasure with bridge methods and casts inserted by the compiler. Read §2–3 after Lesson 6.9's erasure section and find thecheckcasts of the javap box in its translation scheme.
Chapters: Ch 6 -
[Bou93] François Bourdoncle. Efficient chaotic iteration strategies with widenings. Formal Methods in Programming and Their Applications (FMPA), LNCS 735, pp. 128-141, 1993. doi:10.1007/BFb0039704
Why and when: Weak topological orders: iterate strongly connected components recursively and widen only at component heads. The order behind Clang's WTODataflowWorklist (Lessons 14.4 and 14.7 §6).
Chapters: Ch 14 -
[BPR16] Marcel Böhme, Van-Thuan Pham, and Abhik Roychoudhury. Coverage-based Greybox Fuzzing as Markov Chain. CCS 2016, pp. 1032–1043, 2016. doi:10.1145/2976749.2978428
Why and when: AFLFast: power schedules that spend more mutations on inputs exercising rare paths. Read after Lesson 12.6 §6 for the theory behind choosing which corpus input to mutate.
Chapters: Ch 12 -
[BR86] François Bancilhon and Raghu Ramakrishnan. An Amateur's Introduction to Recursive Query Processing Strategies. SIGMOD 1986, pp. 16-52, 1986. doi:10.1145/16894.16859
Why and when: Naive and semi-naive evaluation and their costs (Lesson 14.8, Algorithms 14.8.3 and 14.8.4); the algorithm of lab requirement L3. Read the semi-naive section before writing your evaluator.
Chapters: Ch 14 -
[BR91] David Bernstein and Michael Rodeh. Global Instruction Scheduling for Superscalar Machines. PLDI 1991, pp. 241–255, 1991. doi:10.1145/113445.113466
Why and when: Scheduling over acyclic regions with useful and speculative motion, the design behind GCC'ssched-rgn.cc(Lesson 23.4 §6–7).
Chapters: Ch 23 -
[BR95] Vasanth Bala and Norman Rubin. Efficient Instruction Scheduling Using Finite State Automata. MICRO-28, pp. 46–56, 1995. link
Why and when: Extends the pipeline automaton with reverse automata and factoring, the ideas behind GCC'sdefine_automatonsplit (Lesson 23.1 §6). Read §3–4 if you care about VLIW packers.
Chapters: Ch 23 -
[Bra61] Harvey Bratman. An Alternate Form of the "UNCOL Diagram". Communications of the ACM 4(3), p. 142, 1961. doi:10.1145/366199.366249
Why and when: One page that introduces the T-shaped diagram for compilers (source, target, implementation language) — the notation of Lesson 0.5.
Chapters: Ch 0 -
[Bre74] Richard P. Brent. The Parallel Evaluation of General Arithmetic Expressions. Journal of the ACM 21(2), pp. 201–206, 1974.
Why and when: Any expression with n operations can be evaluated in O(log n) parallel steps using distributivity too (Lesson 13.6 §6). Read after Corollary 13.6.11.
Note: ACM Digital Library.
Chapters: Ch 13 -
[Brz62] Janusz A. Brzozowski. Canonical regular expressions and minimal state graphs for definite events. Mathematical Theory of Automata, Polytechnic Institute of Brooklyn Symposia Series 12, pp. 529–561, 1962.
Why and when: The origin of minimization by double reversal (Algorithm 1.4.6, Theorem 1.4.13). Hard to obtain; the proof in Lesson 1.4 §4 is complete, so read this only for the history.
Note: Symposium proceedings (Polytechnic Press); no DOI. The double-reversal theorem is usually cited from here.
Chapters: Ch 1 -
[Brz64] Janusz A. Brzozowski. Derivatives of regular expressions. Journal of the ACM 11(4), pp. 481–494, 1964. doi:10.1145/321239.321249
Why and when: Core reading. Defines the derivative of a regular expression and proves that dissimilar derivatives are finitely many (Theorem 1.3.12, his Theorem 5.2). Read §2–5 alongside Lesson 1.3 §2 and §4.
Chapters: Ch 1 -
[BS09] Martin Bravenboer and Yannis Smaragdakis. Strictly Declarative Specification of Sophisticated Points-to Analyses. OOPSLA 2009, pp. 243-262, 2009. doi:10.1145/1640089.1640108
Why and when: Core reading. Doop: a complete Java points-to analysis in Datalog, faster than the hand-written framework it was compared with (Lesson 14.8 §5). Read §2–3 for how an analysis becomes rules.
Chapters: Ch 14, Ch 19 -
[BS76] John Bruno and Ravi Sethi. Code Generation for a One-Register Machine. Journal of the ACM 23(3), pp. 502–510, 1976. doi:10.1145/321958.321971
Why and when: Optimal code for expression DAGs is NP-complete even with one register: the first of the hardness results behind Lesson 21.4 §1. Read the introduction and the reduction outline.
Chapters: Ch 21 -
[BS86] Gérard Berry and Ravi Sethi. From regular expressions to deterministic automata. Theoretical Computer Science 48, pp. 117–126, 1986. doi:10.1016/0304-3975(86)90088-5
Why and when: Derives the position automaton (Glushkov/McNaughton–Yamada) from derivatives of linearized expressions and proves the local-language characterization of Lemma 1.1.11. Short; read after Lesson 1.3.
Chapters: Ch 1 -
[BS96] David F. Bacon and Peter F. Sweeney. Fast Static Analysis of C++ Virtual Function Calls. OOPSLA 1996, pp. 324–341, 1996. doi:10.1145/236337.236371
Why and when: Rapid type analysis: CHA restricted to classes instantiated in reachable code, and its evaluation on C++ programs. Read §3–5 after Lesson 20.1's RTA and compare with the lab's measurement table.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[BTCGS91] Val Breazu-Tannen, Thierry Coquand, Carl A. Gunter, and Andre Scedrov. Inheritance as Implicit Coercion. Information and Computation 93(1), 172–221, 1991. doi:10.1016/0890-5401(91)90055-7
Why and when: The coercion semantics of subtyping: every derivation of S <: T denotes a conversion function, and coherence (all derivations give the same function) is the theorem to prove. Read the introduction after Lesson 6.3 §6 and Lesson 6.5's "subtyping vs coercion".
Chapters: Ch 6 -
[BU73] Alexander Birman and Jeffrey D. Ullman. Parsing algorithms with backtrack. Information and Control 23(1), 1–34, 1973. doi:10.1016/S0019-9958(73)90851-6
Why and when: TDPL/GTDPL: the formal model of backtracking parsers with ordered choice and the tabular (memoized) linear-time algorithm that packrat parsing revived (Lesson 2.5 §1).
Chapters: Ch 2, Ch 4 -
[BWZ94] Olaf Bachmann, Paul S. Wang, and Eugene V. Zima. Chains of Recurrences — a Method to Expedite the Evaluation of Closed-Form Functions. ISSAC 1994, pp. 242-249, 1994. doi:10.1145/190347.190423
Why and when: The origin of chains of recurrences and their algebra (Lesson 18.3, Lemmas 18.3.2–18.3.5), from symbolic computation rather than compilers.
Chapters: Ch 18 -
[BZB11] Sebastian Buchwald, Andreas Zwinkau, and Thomas Bersch. SSA-Based Register Allocation with PBQP. CC 2011 (LNCS), 2011. doi:10.1007/978-3-642-19861-8_4
Why and when: PBQP on chordal SSA graphs, reducing along a perfect elimination order; a variant in Lesson 22.7 §6 that joins Lessons 22.6 and 22.7.
Chapters: Ch 22 -
[CACCHM81] Gregory J. Chaitin, Marc A. Auslander, Ashok K. Chandra, John Cocke, Martin E. Hopkins, and Peter W. Markstein. Register Allocation via Coloring. Computer Languages 6(1), pp. 47–57, 1981. link
Why and when: Core reading. The origin of register allocation as graph colouring and of the definition of interference used in Lesson 22.1 ("a value interferes with everything live where it is defined"). Short; read it after Lesson 22.1 §2, then the NP-completeness argument that Lesson 22.3 revisits.
Chapters: Ch 22 -
[Can62] David G. Cantor. On the ambiguity problem of Backus systems. Journal of the ACM 9(4), 477–479, 1962. doi:10.1145/321138.321145
Why and when: One of the three independent 1962 proofs that ambiguity of context-free grammars is undecidable. Three pages; read it after Theorem 2.1.12 to see the original reduction.
Chapters: Ch 2 -
[Car88] Luca Cardelli. A Semantics of Multiple Inheritance. Information and Computation 76(2–3), 138–164, 1988. doi:10.1016/0890-5401(88)90007-7
Why and when: Where structural record subtyping (width and depth) and the contravariant function rule come from. Read the typing rules for records and functions after Lesson 6.5 §2.
Chapters: Ch 6 -
[Cat80] Roderic G. G. Cattell. Automatic Derivation of Code Generators from Machine Descriptions. ACM TOPLAS 2(2), pp. 173–190, 1980. doi:10.1145/357094.357097
Why and when: Top-down, largest-pattern-first matching of trees against a machine description: the origin of maximal munch as a technique (Lesson 21.1 §1, Algorithm 21.1.8).
Chapters: Ch 21 -
[CC76] Patrick Cousot and Radhia Cousot. Static Determination of Dynamic Properties of Programs. Proceedings of the 2nd International Symposium on Programming, Paris, Dunod, pp. 106-130, 1976.
Why and when: The first interval analysis, with widening and narrowing: the domain of exercise E6 and of Lesson 14.7's worked example.
Note: Conference proceedings without DOI; the authors' PDF is on Patrick Cousot's publication page.
Chapters: Ch 14 -
[CC77] Patrick Cousot and Radhia Cousot. Abstract Interpretation: A Unified Lattice Model for Static Analysis of Programs by Construction or Approximation of Fixpoints. POPL 1977, pp. 238-252, 1977. doi:10.1145/512950.512973
Why and when: Core reading. The founding paper of abstract interpretation: collecting semantics, abstraction and concretization, widening and narrowing (Lesson 14.7, Definitions 14.7.1–14.7.9 and Theorem 14.7.10). Read after Lesson 14.7 §2.
Chapters: Ch 14 -
[CC79] Patrick Cousot and Radhia Cousot. Systematic Design of Program Analysis Frameworks. POPL 1979, pp. 269-282, 1979. doi:10.1145/567752.567778
Why and when: Core reading. Galois connections as the design method, best transformers and the reduced product of domains (Lesson 14.7, Lemma 14.7.3 and §6). Read after Lesson 14.7 §4.
Chapters: Ch 14 -
[CC79b] Patrick Cousot and Radhia Cousot. Constructive versions of Tarski's fixed point theorems. Pacific Journal of Mathematics 82(1), pp. 43-57, 1979. doi:10.2140/pjm.1979.82.43
Why and when: Fixed points as limits of (transfinite) iteration sequences: the constructive side of Theorem 14.1.14 (Kleene iteration). Optional mathematical background for Lesson 14.1 §4.
Chapters: Ch 14 -
[CC92] Patrick Cousot and Radhia Cousot. Abstract Interpretation Frameworks. Journal of Logic and Computation 2(4), pp. 511-547, 1992. doi:10.1093/logcom/2.4.511
Why and when: Frameworks without a best abstraction (concretization only), and when widening is needed; the reference for Lesson 14.7 §6's first variant.
Chapters: Ch 14 -
[CC95] Cliff Click and Keith D. Cooper. Combining Analyses, Combining Optimizations. ACM TOPLAS 17(2), pp. 181–196, 1995.
Why and when: Why solving constant propagation, unreachable code and value numbering together beats any fixed order of the separate passes: the theory behind Lessons 17.1 §4 and 17.8. Read §2–4 after Lesson 17.8 §1.
Note: ACM Digital Library; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[CCBS19] Roberto Castañeda Lozano, Mats Carlsson, Gabriel Hjort Blindell, and Christian Schulte. Combinatorial Register Allocation and Instruction Scheduling. ACM TOPLAS 41(3), 2019. link
Why and when: Unison: allocation and scheduling together as a constraint problem, solved to optimality for most functions of MediaBench and SPEC; the state of the art of the exact approaches in Lesson 22.7 §6.
Chapters: Ch 22 -
[CCF91] Jong-Deok Choi, Ron Cytron, and Jeanne Ferrante. Automatic Construction of Sparse Data Flow Evaluation Graphs. POPL 1991, pp. 55–66, 1991. doi:10.1145/99583.99594
Why and when: The origin of pruned SSA (phis only for live variables), the dead-parameter pruning step of Lesson 8.4 §3. Read the introduction.
Chapters: Ch 8, Ch 14, Ch 15, Ch 16 -
[CCK+97] Fred Chow, Sun Chan, Robert Kennedy, Shin-Ming Liu, Raymond Lo, and Peng Tu. A New Algorithm for Partial Redundancy Elimination based on SSA Form. PLDI 1997, pp. 273–286, 1997.
Why and when: SSAPRE: PRE on SSA form expression by expression, via Φ-insertion, renaming, DownSafety, WillBeAvail, Finalize and CodeMotion. Lesson 17.6 §2 (SSAPRE) follows its six steps.
Note: ACM Digital Library; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[CCKT86] David Callahan, Keith D. Cooper, Ken Kennedy, and Linda Torczon. Interprocedural Constant Propagation. SIGPLAN '86 Symposium on Compiler Construction, pp. 152–161, 1986. doi:10.1145/12276.13327
Why and when: Jump functions and return functions for interprocedural constants, the design GCC's ipa-cp still follows. Read §2–3 with Lesson 20.5's IPSCCP section.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[CCL+96] Fred Chow, Sun Chan, Shin-Ming Liu, Raymond Lo, and Mark Streich. Effective Representation of Aliases and Indirect Memory Operations in SSA Form. Compiler Construction (CC 1996), LNCS 1060, 1996. doi:10.1007/3-540-61053-7_66
Why and when: Hashed SSA (HSSA): virtual variables, mu and chi operators for may-uses and may-defs, and hashing of expressions into a global value table; developed at SGI.
Chapters: Ch 16 -
[CDOY09] Cristiano Calcagno, Dino Distefano, Peter O'Hearn, and Hongseok Yang. Compositional Shape Analysis by Means of Bi-Abduction. POPL 2009, pp. 289–300, 2009. doi:10.1145/1480881.1480917
Why and when: Per-procedure separation-logic summaries inferred bottom-up; the analysis inside Facebook Infer's biabduction checker (Lesson 19.9 §7).
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[CFRWZ91] Ron Cytron, Jeanne Ferrante, Barry K. Rosen, Mark N. Wegman, and F. Kenneth Zadeck. Efficiently Computing Static Single Assignment Form and the Control Dependence Graph. ACM TOPLAS 13(4), pp. 451–490, 1991. doi:10.1145/115372.115320
Why and when: Core reading. The SSA paper: definitions, phi placement at iterated dominance frontiers and renaming, plus control dependence. Lesson 8.4 uses its definitions and Lesson 8.5 its control dependence; the construction is taught in Ch 16.
Chapters: Ch 8, Ch 9, Ch 10, Ch 11, Ch 13, Ch 14, Ch 15, Ch 16, Ch 17, Ch 24 -
[CFS90] Ron Cytron, Jeanne Ferrante, and Vivek Sarkar. Compact Representations for Control Dependence. Proc. ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI), pp. 337-351, 1990. doi:10.1145/93548.93592
Why and when: Factors control dependence into regions to shrink PDGs; the "compact representation" variant of Lesson 15.4 §6. Optional.
Chapters: Ch 15 -
[CFT03] Larry Carter, Jeanne Ferrante, and Clark Thomborson. Folklore Confirmed: Reducible Flow Graphs Are Exponentially Larger. Proc. 30th ACM Symposium on Principles of Programming Languages (POPL), pp. 106-114, 2003. doi:10.1145/604131.604141
Why and when: Proves the exponential lower bound behind Proposition 15.6.15 (node splitting can blow up); read the introduction and the construction.
Chapters: Ch 15 -
[CG72] E. G. Coffman Jr. and R. L. Graham. Optimal Scheduling for Two-Processor Systems. Acta Informatica 1(3), pp. 200–213, 1972. doi:10.1007/BF00288685
Why and when: Optimal scheduling of unit-time DAGs on two processors by lexicographic labeling, the polynomial boundary case of Theorem 23.3.4.
Chapters: Ch 23 -
[CH78] Patrick Cousot and Nicolas Halbwachs. Automatic Discovery of Linear Restraints Among Variables of a Program. POPL 1978, pp. 84-96, 1978. doi:10.1145/512760.512770
Why and when: The convex-polyhedra domain with its widening (Lesson 14.7, Definition 14.7.6); the invariant j = 2i of the islpy box is the kind of result it computes.
Chapters: Ch 14 -
[CH90] Fred C. Chow and John L. Hennessy. The Priority-Based Coloring Approach to Register Allocation. ACM TOPLAS 12(4), pp. 501–536, 1990. doi:10.1145/88616.88621
Why and when: Colour live ranges by priority (savings per unit of size) and split instead of spilling; the ancestor of LLVM greedy's priority queue and splitting (Lessons 22.3 §6 and 22.8).
Chapters: Ch 22 -
[Cha12] Arthur Charguéraud. The locally nameless representation. Journal of Automated Reasoning 49(3), 363–408, 2012. doi:10.1007/s10817-011-9225-2
Why and when: The reference treatment of locally nameless syntax: opening, closing, local closure and the lemmas that make proofs go through. Read §2–4 after Lesson 5.2 §6 if you want to see why Lean and Coq developments use it.
Chapters: Ch 5 -
[Cha82] Gregory J. Chaitin. Register Allocation & Spilling via Graph Coloring. Proc. SIGPLAN '82 Symposium on Compiler Construction (SIGPLAN Notices 17(6)), pp. 98–105, 1982. doi:10.1145/872726.806984 · pdf
Why and when: Core reading. The allocator of Lesson 22.3: build, coalesce, simplify, spill with cost/degree, select, and iterate after inserting spill code. Eight pages; the spill-cost definition is Definition 22.3.2 and the loop-depth weight \(10^d\) used by the lab comes from here.
Chapters: Ch 22 -
[Cha87] David R. Chase. An Improvement to Bottom-up Tree Pattern Matching. POPL 1987, 1987. doi:10.1145/41625.41640
Why and when: Per-child index maps that shrink bottom-up matching tables, the compression every BURS table generator uses (Lesson 21.3, Definition 21.3.9 and Algorithm 21.3.10).
Chapters: Ch 21 -
[CHK01] Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy. A Simple, Fast Dominance Algorithm. Software Practice & Experience 4 (also Rice University TR-06-33870), 2001. pdf
Why and when: Core reading. The origin of the CHK algorithm Pebble implements (Figure 3 = Algorithm 15.1.12) and of the runner algorithm for dominance frontiers (Algorithm 15.3.8). Read §2-4 after Lesson 15.1 §2; the timing section backs the "CHK beats Lengauer-Tarjan on normal CFGs" claim.
Chapters: Ch 15 -
[CHK93] Keith D. Cooper, Mary W. Hall, and Ken Kennedy. A Methodology for Procedure Cloning. Computer Languages 19(2), pp. 105–117, 1993. doi:10.1016/0096-0551(93)90005-L
Why and when: Procedure cloning driven by interprocedural facts (constants reaching each call site), with a partitioning algorithm that bounds the number of clones. Read after Lesson 20.4 §2.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 20 -
[Cho56] Noam Chomsky. Three models for the description of language. IRE Transactions on Information Theory 2(3), 113–124, 1956. doi:10.1109/TIT.1956.1056813
Why and when: Where phrase-structure (context-free) grammars enter the literature, as the middle of three models of language. Read the section on phrase-structure grammar after Lesson 2.1 §1 for the historical framing; the linguistics can be skimmed.
Chapters: Ch 2 -
[Cho59] Noam Chomsky. On certain formal properties of grammars. Information and Control 2(2), 137–167, 1959. doi:10.1016/S0019-9958(59)90362-6
Why and when: The hierarchy of grammar types 0–3 by production shape (Definition 2.1.4) and the proofs that the inclusions are strict. Read the definitions of the four types; the rest is background for the Chomsky-hierarchy quiz question.
Chapters: Ch 2 -
[Cho88] Fred C. Chow. Minimizing Register Usage Penalty at Procedure Calls. PLDI 1988, 1988. doi:10.1145/53990.53999
Why and when: The origin of shrink-wrapping: place callee-saved register saves and restores around the region that uses them. Read §4 with Lesson 21.9 (Algorithm 21.9.10).
Chapters: Ch 21, Ch 22 -
[Cho99] Jong-Deok Choi, Manish Gupta, Mauricio Serrano, Vugranam C. Sreedhar, and Sam Midkiff. Escape Analysis for Java. OOPSLA 1999, pp. 1–19, 1999. doi:10.1145/320384.320386
Why and when: Connection graphs with escape states (NoEscape, ArgEscape, GlobalEscape), used for stack allocation and lock elision; HotSpot's C2 escape analysis follows it. Read §3–4 after Lesson 19.9 §2.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[Cic80] Richard J. Cichelli. Minimal perfect hash functions made simple. Communications of the ACM 23(1), pp. 17–19, 1980. doi:10.1145/358808.358813
Why and when: Minimal perfect hashing of Pascal's reserved words from length, first and last letter, by backtracking search: the ancestor of gperf (Algorithm 1.8.6). Three pages; read after Lesson 1.8 §2.
Chapters: Ch 1 -
[CK88] Keith D. Cooper and Ken Kennedy. Interprocedural Side-Effect Analysis in Linear Time. PLDI 1988, pp. 57–66, 1988. doi:10.1145/53990.53996
Why and when: Side effects in linear time by solving on the call graph's SCCs — the same bottom-up SCC structure as Algorithm 20.6.5. Read after Lesson 20.6 §4.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[CK91] David Callahan and Brian Koblenz. Register Allocation via Hierarchical Graph Coloring. PLDI 1991 (SIGPLAN Notices 26(6)), pp. 192–203, 1991. link
Why and when: Colour a tree of tiles (loops, conditionals) bottom-up and place spill code at tile boundaries in cold code; the regional variant mentioned in Lessons 22.3 §6 and 22.9 §6.
Chapters: Ch 22 -
[CL95] Martin C. Carlisle and Errol L. Lloyd. On the k-Coloring of Intervals. Discrete Applied Mathematics 59, pp. 225–235, 1995. link · pdf
Why and when: Maximum k-colourable subsets of interval graphs; why "spill the interval that ends last" is optimal for unit weights and why weights break it (Lesson 22.5 §6).
Chapters: Ch 22 -
[CL97] Keith D. Cooper and John Lu. Register Promotion in C Programs. PLDI 1997, pp. 308-319, 1997. doi:10.1145/258915.258943
Why and when: Scalar (register) promotion of memory references in loops, with measurements on C programs; the motivation and conditions of Lesson 18.1's promotion section.
Chapters: Ch 18 -
[Cli95] Cliff Click. Global Code Motion / Global Value Numbering. PLDI 1995, pp. 246–257, 1995. doi:10.1145/207110.207154
Why and when: GCM (schedule early, schedule late, choose the least loop depth) and hash-based GVN on the sea of nodes: Algorithm 8.5.3 and its proof. Read §2–3 after Lesson 8.5 §2.
Chapters: Ch 8, Ch 17 -
[CLM16] Dehao Chen, David Xinliang Li, and Tipp Moseley. AutoFDO: Automatic Feedback-Directed Optimization for Warehouse-Scale Applications. CGO 2016, pp. 12–23, 2016. doi:10.1145/2854038.2854044
Why and when: Sampling-based FDO from production perf profiles mapped to source lines, and its deployment at Google. Read §3–4 with Lesson 20.10's sampling PGO.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[CM69] John Cocke and Raymond E. Miller. Some Analysis Techniques for Optimizing Computer Programs. Proc. 2nd Hawaii International Conference on System Sciences, pp. 143-146, 1969.
Why and when: Where node splitting (Algorithm 15.6.9) is attributed; read HU74 and JC97 instead for the modern treatment.
Note: Conference proceedings without a DOI; cited for the origin of node splitting.
Chapters: Ch 15 -
[Coc70] John Cocke. Global common subexpression elimination. SIGPLAN Notices 5(7), pp. 20-24 (Symposium on Compiler Optimization), 1970. doi:10.1145/390013.808480
Why and when: Available expressions as a global bit-vector problem, the optimization behind Lesson 14.3's Algorithm 14.3.11. Short; read with Lesson 14.3 §1.
Chapters: Ch 14 -
[Col60] George E. Collins. A Method for Overlapping and Erasure of Lists. Communications of the ACM 3(12), pp. 655–657, 1960. doi:10.1145/367487.367501
Why and when: Core reading. The origin of reference counting, three pages; read it to see that the cycle problem was visible from the start (Lesson 24.5 §1).
Chapters: Ch 24 -
[Con63] Melvin E. Conway. Design of a separable transition-diagram compiler. Communications of the ACM 6(7), 396–408, 1963. doi:10.1145/366663.366704
Why and when: Transition diagrams as coroutines for a COBOL compiler: the other early source of recursive descent. Read the design of the syntax analyzer; the coroutine idea is famous in its own right.
Chapters: Ch 2 -
[CP95] Cliff Click and Michael Paleczny. A Simple Graph-Based Intermediate Representation. ACM SIGPLAN Workshop on Intermediate Representations (IR '95), SIGPLAN Notices 30(3), pp. 35–49, 1995.
Why and when: Core reading. The sea-of-nodes IR: control and data in one graph, pinned and floating nodes. The origin of Lesson 8.5's first technique; read all of it (it is short).
Note: Published in the IR '95 workshop issue of SIGPLAN Notices (ACM Digital Library).
Chapters: Ch 8 -
[CPN98] David G. Clarke, John M. Potter, and James Noble. Ownership Types for Flexible Alias Protection. OOPSLA 1998, pp. 48–64, 1998. doi:10.1145/286936.286947
Why and when: Core reading. Ownership as a type discipline that restricts aliasing; the ancestor of Rust's model (Lesson 24.5 §1). Read §2–3 for the ownership contexts, then RustBelt for the modern form.
Chapters: Ch 24 -
[CR02] Cliff Click and John Rose. Fast Subtype Checking in the HotSpot JVM. Joint ACM-ISCOPE Conference on Java Grande (JGI 2002), 96–107, 2002. doi:10.1145/583810.583821
Why and when: How a nominal subtype test (Algorithm 6.5.9) becomes one load and compare at run time: a display of primary superclasses at fixed depths plus a cached secondary-supers search. Read §2–3 after Lesson 6.5 §5.
Chapters: Ch 6 -
[CS63] Noam Chomsky and Marcel-Paul Schützenberger. The algebraic theory of context-free languages. In P. Braffort and D. Hirschberg (eds.), Computer Programming and Formal Systems, North-Holland, 118–161, 1963.
Why and when: Context-free languages as solutions of algebraic (power-series) equations, the viewpoint behind "L(G) is the least solution of its equations" in Lesson 2.4 (Theorem 2.4.7). Also contains an undecidability proof for ambiguity. For the mathematically curious.
Note: Book chapter; available in university libraries (Studies in Logic and the Foundations of Mathematics series).
Chapters: Ch 2 -
[CSS99] Keith D. Cooper, Philip J. Schielke, and Devika Subramanian. Optimizing for Reduced Code Space using Genetic Algorithms. LCTES 1999, pp. 1–9, 1999. doi:10.1145/314403.314414
Why and when: Genetic search over optimization sequences for code size, beating the fixed sequence. Read after Lesson 12.2 §6.
Chapters: Ch 12, Ch 24 -
[CSV01] Keith D. Cooper, L. Taylor Simpson, and Christopher A. Vick. Operator Strength Reduction. ACM TOPLAS 23(5), pp. 603-625, 2001. doi:10.1145/504709.504710
Why and when: Core reading. OSR on SSA (Algorithm 18.4.6) — the algorithm E3'spebble-osrimplements. Read §3 with the lesson's worked example; §4 covers LFTR.
Chapters: Ch 18 -
[CW85] Luca Cardelli and Peter Wegner. On Understanding Types, Data Abstraction, and Polymorphism. ACM Computing Surveys 17(4), 471–523, 1985. doi:10.1145/6041.6042
Why and when: The classic taxonomy of polymorphism (parametric, inclusion, overloading, coercion) that Lessons 6.3, 6.5 and 6.9 use to separate overloading and coercions from subtyping and generics. Read §1.3 (kinds of polymorphism) after Lesson 6.2 and §3 (subtyping) with Lesson 6.5.
Chapters: Ch 6 -
[CZ02] Jean-Marc Champarnaud and Djelloul Ziadi. Canonical derivatives, partial derivatives and finite automaton constructions. Theoretical Computer Science 289(1), pp. 137–163, 2002.
Why and when: Shows that the partial-derivative automaton is a quotient of the position automaton, the relation stated in Lesson 1.3 §6. Optional, for readers who want the connection proved.
Note: Elsevier journal article.
Chapters: Ch 1 -
[Dam64] Fred J. Damerau. A technique for computer detection and correction of spelling errors. Communications of the ACM 7(3), 171–176, 1964. doi:10.1145/363958.363994
Why and when: The observation that most misspellings are one insertion, deletion, substitution or transposition of adjacent letters: why GCC and rustc use OSA. Read after Lesson 5.8 §2.
Chapters: Ch 5 -
[Das00] Manuvir Das. Unification-based Pointer Analysis with Directional Assignments. PLDI 2000, pp. 35–46, 2000. doi:10.1145/349299.349309
Why and when: One-level flow: inclusion only at the top level of each assignment, unification below, with the empirical claim that this recovers most of Andersen's precision at nearly Steensgaard's cost. Read §3–4 after Lesson 19.5 §2.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[dB72] Nicolaas G. de Bruijn. Lambda calculus notation with nameless dummies, a tool for automatic formula manipulation, with application to the Church–Rosser theorem. Indagationes Mathematicae 75(5), 381–392, 1972. doi:10.1016/1385-7258(72)90034-0
Why and when: Core reading. The origin of de Bruijn indices (Definition 5.2.8) and the shifting of free indices under substitution (Lemma 5.2.13). Read §1–3 after Lesson 5.2 §4; the notation differs but the counting rule is the same.
Chapters: Ch 5 -
[DB76] L. Peter Deutsch and Daniel G. Bobrow. An Efficient, Incremental, Automatic Garbage Collector. Communications of the ACM 19(9), pp. 522–526, 1976. doi:10.1145/360336.360345
Why and when: Deferred reference counting: do not count stack references, reconcile periodically; the variant of Lesson 24.5 §6 that every fast counting runtime uses in some form.
Chapters: Ch 24 -
[DDH84] Peter Dencker, Karl Dürre, and Johannes Heuft. Optimization of parser tables for portable compilers. ACM TOPLAS 6(4), 546–572, 1984. doi:10.1145/1780.1802
Why and when: Measured comparison of LR table compression schemes (Lesson 3.1 §6). Skim the results tables.
Chapters: Ch 3 -
[DeR71] Frank DeRemer. Simple LR(k) grammars. Communications of the ACM 14(7), 453–460, 1971. doi:10.1145/362619.362625
Why and when: Core reading. The origin of SLR(k): the LR(0) automaton plus FOLLOW sets. Short and readable; read it with Lesson 3.2 and compare its examples with the running example's SLR conflict.
Chapters: Ch 3 -
[DF80] Jack W. Davidson and Christopher W. Fraser. The Design and Application of a Retargetable Peephole Optimizer. ACM TOPLAS 2(2), pp. 191–202, 1980.
Why and when: Peephole rules derived from a machine description and applied to register transfers, the ancestor of GCC's combiner. Read after Lesson 13.2 §6 for the retargetable variant.
Note: ACM Digital Library.
Chapters: Ch 13, Ch 21 -
[DF84] Jack W. Davidson and Christopher W. Fraser. Code Selection through Object Code Optimization. ACM TOPLAS 6(4), pp. 505–526, 1984. doi:10.1145/1780.1783
Why and when: "Expand naively, then combine" as a complete selection strategy (the PO/YC compilers). Read after Lesson 21.1 §3 to see the combiner reach the running example's cost 5.
Chapters: Ch 21 -
[DF92] Olivier Danvy and Andrzej Filinski. Representing Control: A Study of the CPS Transformation. Mathematical Structures in Computer Science 2(4), pp. 361–391, 1992. doi:10.1017/S0960129500001535
Why and when: The one-pass CPS transform that produces no administrative redexes by using meta-level continuations: Algorithm 8.6.3. Read the part on the one-pass transform.
Chapters: Ch 8 -
[DG84] William F. Dowling and Jean H. Gallier. Linear-time algorithms for testing the satisfiability of propositional Horn formulae. Journal of Logic Programming 1(3), 267–284, 1984. doi:10.1016/0743-1066(84)90014-1
Why and when: The counter-per-clause algorithm that Bison's nullable computation instantiates (Algorithm 2.2.8): nullable is Horn-clause satisfiability. Read the linear-time algorithm with one counter per clause.
Chapters: Ch 2 -
[DGC95] Jeffrey Dean, David Grove, and Craig Chambers. Optimization of Object-Oriented Programs Using Static Class Hierarchy Analysis. ECOOP 1995, LNCS 952, pp. 77–101, 1995. doi:10.1007/3-540-49538-X_5
Why and when: The origin of class hierarchy analysis: resolve a message send to the overrides below the receiver's static class. Read §2–3 with Lesson 20.1's CHA (Algorithm 20.1.5).
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[DH92] Jack W. Davidson and Anne M. Holler. Subprogram Inlining: A Study of Its Effects on Program Execution Time. IEEE Transactions on Software Engineering 18(2), pp. 89–102, 1992. doi:10.1109/32.121752
Why and when: A measurement study of when inlining helps and when it hurts (register pressure, cache effects). Read after Lesson 20.3 §5 for why a cost model needs a size term.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 20 -
[DHB89] James C. Dehnert, Peter Y.-T. Hsu, and Joseph P. Bratt. Overlapped Loop Support in the Cydra 5. ASPLOS III, pp. 26–38, 1989. doi:10.1145/68182.68185
Why and when: Rotating registers and predicated stages in hardware: the machine support the lab's toy machine imitates (SPEC §6.4, Algorithm 23.6.12).
Chapters: Ch 23 -
[DHB92] R. Kent Dybvig, Robert Hieb, and Carl Bruggeman. Syntactic abstraction in Scheme. Lisp and Symbolic Computation 5(4), 295–326, 1992. doi:10.1007/BF01806308
Why and when:syntax-casewith lazily applied marks: hygiene in linear time instead of the quadratic eager renaming (Lesson 4.8 §5). Read §3 on marks and substitutions.
Chapters: Ch 4, Ch 5 -
[DK13] Jana Dunfield and Neelakantan R. Krishnaswami. Complete and Easy Bidirectional Typechecking for Higher-Rank Polymorphism. ICFP 2013, Proceedings of the 18th ACM SIGPLAN International Conference on Functional Programming, 429–442, 2013. doi:10.1145/2500365.2500582
Why and when: A complete bidirectional algorithm for System F-style higher-rank types with an ordered context of existential variables. Read §1–3 after Lesson 6.4 §6 for how bidirectional checking extends to polymorphism; the context-based algorithm is the bridge to Chapter 7.
Chapters: Ch 6, Ch 7 -
[DM10] Joel E. Denny and Brian A. Malloy. The IELR(1) algorithm for generating minimal LR(1) parser tables for non-LR(1) grammars with conflict resolution. Science of Computer Programming 75(11), 943–979, 2010. doi:10.1016/j.scico.2009.08.001
Why and when: Core reading. IELR(1) as implemented in Bison: annotations, compatibility, state splitting, and why LALR and Pager differ from canonical LR(1) in the presence of precedence declarations. Read §1–3 after Lesson 3.4; §4 has the proofs behind Theorem 3.4.10.
Chapters: Ch 3 -
[DM82] Luis Damas and Robin Milner. Principal Type-Schemes for Functional Programs. POPL 1982, 9th ACM Symposium on Principles of Programming Languages, 207–212, 1982. doi:10.1145/582153.582176
Why and when: Core reading. The declarative HM rules (Definition 7.2.4) and the statements of soundness and completeness of W (Theorem 7.2.11). Six pages; read all of it after Lesson 7.2 §4.
Chapters: Ch 7 -
[DMH92] Amer Diwan, Eliot Moss, and Richard Hudson. Compiler Support for Garbage Collection in a Statically Typed Language. PLDI 1992, pp. 273–282, 1992. doi:10.1145/143095.143140
Why and when: Core reading. Stack maps at safepoints and derived pointers in an optimizing compiler: the origin of Algorithm 24.5.6 and of the (base, derived) pairs. Read §3–4 after Lesson 24.5 §2.
Chapters: Ch 24 -
[DMM98] Amer Diwan, Kathryn S. McKinley, and J. Eliot B. Moss. Type-Based Alias Analysis. PLDI 1998, pp. 106–117, 1998. doi:10.1145/277650.277670
Why and when: Core reading. Type compatibility, field-name disambiguation and SMFieldTypeRefs for Modula-3, with the finding that simple type-based rules capture most of the benefit. The origin of Lesson 19.3's TBAA; read §2–3.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[DP82] Frank DeRemer and Thomas Pennello. Efficient computation of LALR(1) look-ahead sets. ACM TOPLAS 4(4), 615–649, 1982. doi:10.1145/69622.357187
Why and when: Core reading. The Digraph algorithm for "set = direct ∪ union over a relation" equations (Algorithm 2.2.9 and Theorem 2.2.14). Read the description of Digraph now and the LALR part in Ch 3.
Chapters: Ch 2, Ch 3 -
[DR05] Dibyendu Das and U. Ramakrishna. A Practical and Fast Iterative Algorithm for φ-Function Computation Using DJ Graphs. ACM TOPLAS 27(3), pp. 426-440, 2005. doi:10.1145/1065887.1065890
Why and when: Merge sets: precompute DF+({X}) per node once and answer DF+(S) as a union; the variant of Lesson 15.3 §6 that trades quadratic space for fast repeated queries.
Chapters: Ch 15 -
[DS02] Olivier Danvy and Ulrik P. Schultz. Lambda-Lifting in Quadratic Time. FLOPS 2002, LNCS 2441, 2002.
Why and when: Computes the extra parameters with a graph algorithm in quadratic time and describes lambda dropping, the inverse; the complexity row of Lesson 11.8 §5.
Note: Springer LNCS; no DOI was re-resolved from the course container — find it by title.
Chapters: Ch 11 -
[DS84] L. Peter Deutsch and Allan M. Schiffman. Efficient Implementation of the Smalltalk-80 System. POPL 1984, pp. 297–302, 1984. doi:10.1145/800017.800542
Why and when: Dynamic translation of Smalltalk bytecode to native code on first use, and inline caches: the origin of the method JIT in Lesson 0.3.
Chapters: Ch 0, Ch 24 -
[DS88] Karl-Heinz Drechsler and Manfred P. Stadel. A Solution to a Problem with Morel and Renvoise's "Global Optimization by Suppression of Partial Redundancies". ACM TOPLAS 10(4), pp. 635–640, 1988.
Why and when: Morel–Renvoise can miss insertions that need a new block on a critical edge; inserting on edges fixes it. Read after Lesson 17.6 §6.
Note: ACM Digital Library; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[DS93] Karl-Heinz Drechsler and Manfred P. Stadel. A Variation of Knoop, Rüthing, and Steffen's Lazy Code Motion. ACM SIGPLAN Notices 28(5), pp. 29–38, 1993.
Why and when: LCM on basic blocks with insertions on edges (EARLIEST, LATER, LATERIN, INSERT, DELETE): the formulation of Algorithm 17.6.6, the drilllcm-setsand the ★ lab.
Note: ACM Digital Library; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[DSST89] James R. Driscoll, Neil Sarnak, Daniel D. Sleator, and Robert E. Tarjan. Making data structures persistent. Journal of Computer and System Sciences 38(1), 86–124, 1989. doi:10.1016/0022-0000(89)90034-2
Why and when: Core reading. The theory of persistence behind Algorithm 5.2.7: path copying (§2) and the node-copying technique that makes updates amortized \(O(1)\) space. Read §1–2 after Lesson 5.2 §3.
Chapters: Ch 5 -
[DSTP75] Edward S. Davidson, Leonard E. Shar, A. Thampy Thomas, and Janak H. Patel. Effective Control for Pipelined Computers. IEEE COMPCON Spring 1975, pp. 181–184, 1975.
Why and when: The origin of reservation tables, forbidden latencies and collision vectors (Lesson 23.1 §1). Four pages; read it after Definition 23.1.5 to see the hardware controller the compiler's hazard recognizer imitates.
Note: Conference digest paper without a DOI; widely reprinted in pipeline-design course readers.
Chapters: Ch 23 -
[DT20] Lukas Diekmann and Laurence Tratt. Don't Panic! Better, Fewer, Syntax Errors for LR Parsers. ECOOP 2020, LIPIcs 166, 6:1–6:32, 2020. doi:10.4230/LIPIcs.ECOOP.2020.6
Why and when: CPCT+: all minimum-cost repair sequences within a time budget, in the grmtools Rust LR library — the modern successor of Burke–Fisher (Lesson 3.7 §6).
Chapters: Ch 3 -
[Ear70] Jay Earley. An efficient context-free parsing algorithm. Communications of the ACM 13(2), 94–102, 1970. doi:10.1145/362007.362035
Why and when: Core reading. The origin of Earley parsing (Algorithm 4.3.3) and its \(O(n^3)\)/\(O(n^2)\)/linear bounds (Theorem 4.3.11). Read the algorithm section with Lesson 4.3 §2 open.
Chapters: Ch 4 -
[EBSKWK08] Dietmar Ebner, Florian Brandner, Bernhard Scholz, Andreas Krall, Peter Wiedermann, and Albrecht Kadlec. Generalized Instruction Selection Using SSA-Graphs. LCTES 2008, pp. 31–40, 2008. doi:10.1145/1375657.1375663 · pdf
Why and when: PBQP selection with multi-output (DAG) patterns in an LLVM prototype. Read §3 and the evaluation after Lesson 21.4 §2 and the PBQP box of §7.
Chapters: Ch 21 -
[EG03] M. Anton Ertl and David Gregg. The Structure and Performance of Efficient Interpreters. Journal of Instruction-Level Parallelism 5, 2003. pdf
Why and when: Core reading. Measures how indirect-branch mispredictions dominate interpreter time and why threaded code predicts better than switch dispatch — the model of Definition 0.2.9. Read after Lesson 0.2 §3's dispatch trace.
Chapters: Ch 0 -
[EG03b] M. Anton Ertl and David Gregg. Optimizing Indirect Branch Prediction Accuracy in Virtual Machine Interpreters. PLDI 2003, 2003. doi:10.1145/781131.781162
Why and when: Replicated handlers and superinstructions to improve prediction (Lesson 0.2 §6). Read after the lab: try replicating theloadhandler and measure.
Chapters: Ch 0 -
[EGS+16] Josef Eisl, Matthias Grimmer, Doug Simon, Thomas Würthinger, and Hanspeter Mössenböck. Trace-based Register Allocation in a JIT Compiler. PPPJ 2016, 2016. doi:10.1145/2972206.2972211
Why and when: Allocate hot traces with linear scan and cold ones with cheaper strategies (Graal); a variant in Lesson 22.5 §6.
Chapters: Ch 22 -
[EH07] Torbjörn Ekman and Görel Hedin. The JastAdd extensible Java compiler. OOPSLA 2007, 1–18, 2007. doi:10.1145/1297027.1297029
Why and when: A full Java 1.⅘ front end written as a reference attribute grammar, with name analysis, type analysis and definite assignment as modules. Read §3–4 after the JastAdd box of Lesson 5.5; the performance numbers are in §6.
Chapters: Ch 5 -
[EKL10] Javier Esparza, Stefan Kiefer, and Michael Luttenberger. Newtonian program analysis. Journal of the ACM 57(6), Article 33, 2010. doi:10.1145/1857914.1857917
Why and when: Newton's method instead of Kleene iteration on semiring equation systems; further reading after Lesson 14.5 §6 for the algebraic view of interprocedural analysis.
Chapters: Ch 14 -
[EKS03] Erik Eckstein, Oliver König, and Bernhard Scholz. Code Instruction Selection Based on SSA-Graphs. SCOPES 2003, LNCS 2826, pp. 49–65, 2003. doi:10.1007/978-3-540-39920-9_5
Why and when: Whole-function selection on the SSA graph as a PBQP (Definition 21.4.11). Read §3–4 after Lesson 21.4 §2.
Chapters: Ch 21 -
[Ers58] Andrei P. Ershov. On Programming of Arithmetic Operations. Communications of the ACM 1(8), pp. 3–6, 1958. doi:10.1145/368892.368907
Why and when: Origin of the numbering that gives the minimum number of registers (or stack slots) to evaluate an expression tree — Theorem 0.2.14.
Chapters: Ch 0, Ch 8, Ch 10 -
[Ert99] M. Anton Ertl. Optimal Code Selection in DAGs. POPL 1999, 1999. doi:10.1145/292540.292562
Why and when: For grammars with a checkable property, running the tree DP on a DAG is already optimal. Read after Lesson 21.4 §6 to see when the NP-hardness does not bite.
Chapters: Ch 21 -
[ES70] Jay Earley and Howard Sturgis. A Formalism for Translator Interactions. Communications of the ACM 13(10), pp. 607–617, 1970. doi:10.1145/355598.362740
Why and when: Extends T-diagrams to interpreters and machines and gives composition rules — the algebra of Theorems 0.5.4 and 0.5.5.
Chapters: Ch 0 -
[FCL00] Martin Farach-Colton and Vincenzo Liberatore. On Local Register Allocation. Journal of Algorithms 37(1), pp. 37–65, 2000. doi:10.1006/jagm.2000.1095
Why and when: Local allocation with store (write-back) costs is NP-hard, and a 2-approximation exists (Proposition 22.2.7, Theorem 22.9.11). Read the introduction and Theorem 1's statement; the reduction is optional.
Chapters: Ch 22 -
[Fea91] Paul Feautrier. Dataflow Analysis of Array and Scalar References. International Journal of Parallel Programming 20(1), pp. 23-53, 1991. doi:10.1007/BF01407931
Why and when: Core reading. Exact array dataflow by parametric integer programming (Algorithm 18.7.11), which isl'scompute_flowin the real-world box performs.
Chapters: Ch 18 -
[Fea92] Paul Feautrier. Some Efficient Solutions to the Affine Scheduling Problem. I. One-dimensional Time. International Journal of Parallel Programming 21(5), pp. 313-347, 1992. doi:10.1007/BF01407835
Why and when: Affine scheduling with the Farkas lemma (Algorithm 18.7.13, Theorem 18.7.17). Part II (multidimensional time) handles programs without one-dimensional schedules.
Chapters: Ch 18 -
[FG65] Delbert R. Fulkerson and Oliver A. Gross. Incidence Matrices and Interval Graphs. Pacific Journal of Mathematics 15(3), pp. 835–855, 1965. doi:10.2140/pjm.1965.15.835
Why and when: Chordal graphs are exactly the graphs with a perfect elimination order (Definition 22.6.1, Theorem 22.6.2). Read the characterization; the interval-graph recognition is optional.
Chapters: Ch 22 -
[FH06] Richard A. Frost and Rahmatullah Hafiz. A new top-down parsing algorithm to accommodate ambiguity and left recursion in polynomial time. SIGPLAN Notices 41(5), 46–54, 2006. doi:10.1145/1149982.1149988
Why and when: The depth bound |N|·(n+1) that makes a backtracking parser detect left recursion (Lemma 2.5.12) and curtailment for left-recursive memoized parsing (Lesson 2.5 §6).
Chapters: Ch 2, Ch 4 -
[FHP92a] Christopher W. Fraser, Robert R. Henry, and Todd A. Proebsting. BURG: Fast Optimal Instruction Selection and Tree Parsing. ACM SIGPLAN Notices 27(4), pp. 68–76, 1992. doi:10.1145/131080.131089
Why and when: The BURG tool: a grammar in, a hard-coded BURS labeler out. The input format is the one of the lab's rules files (labs/ch21-isel, E4). Read with Lesson 21.3 §7.
Chapters: Ch 21 -
[FHP92b] Christopher W. Fraser, David R. Hanson, and Todd A. Proebsting. Engineering a Simple, Efficient Code-Generator Generator. ACM LOPLAS 1(3), pp. 213–226, 1992. doi:10.1145/151640.151642
Why and when: Core reading. iburg: the DP labeler of Algorithm 21.2.11 generated as C, with dynamic costs. Twelve pages and the clearest description of a tree-grammar generator; read after Lesson 21.2 §2.
Chapters: Ch 21 -
[Fis81] Joseph A. Fisher. Trace Scheduling: A Technique for Global Microcode Compaction. IEEE Transactions on Computers C-30(7), pp. 478–490, 1981. doi:10.1109/TC.1981.1675827
Why and when: Core reading. The origin of trace scheduling and compensation code (Algorithm 23.4.5). Read the trace selection and bookkeeping sections after Lesson 23.4 §2; the correctness argument is informal but complete.
Chapters: Ch 23 -
[FKS00] Stephen J. Fink, Kathleen Knobe, and Vivek Sarkar. Unified Analysis of Array and Object References in Strongly Typed Languages. Static Analysis Symposium (SAS 2000), LNCS 1824, 2000.
Why and when: Heap Array SSA in the Jikes RVM optimizing compiler: one heap array per field or array type, used for redundant load elimination. The production use in Lesson 16.8's real-world box.
Note: Look it up by title in the SpringerLink (DOI not re-checked from the course container).
Chapters: Ch 16 -
[FKS84] Michael L. Fredman, János Komlós, and Endre Szemerédi. Storing a sparse table with O(1) worst case access time. Journal of the ACM 31(3), pp. 538–544, 1984. doi:10.1145/828.1884
Why and when: Two-level perfect hashing with O(1) worst-case lookups for arbitrary static sets: the theoretical counterpart of gperf, mentioned in Lesson 1.8 §6. Optional.
Chapters: Ch 1 -
[FL87] Marc Feeley and Guy Lapalme. Using Closures for Code Generation. Computer Languages 12(1), pp. 47–66, 1987. doi:10.1016/0096-0551(87)90012-9
Why and when: The origin of closure compilation: each syntax-tree node is turned once into a host-language closure that calls its children's closures, removing the per-node dispatch of a tree walker (Lesson 0.2 §6). Read §2–3 after Lesson 0.2's tree-walker section.
Chapters: Ch 0 -
[Fla16] Matthew Flatt. Binding as sets of scopes. POPL 2016, 705–717, 2016. doi:10.1145/2837614.2837620
Why and when: Racket's reformulation of hygiene: identifiers carry sets of scopes, and resolution picks the binding whose set is the largest subset (Lesson 4.8 §4 and §6). Read §2–3.
Chapters: Ch 4, Ch 5 -
[Flo62] Robert W. Floyd. On ambiguity in phrase structure languages. Communications of the ACM 5(10), 526 and 534, 1962. doi:10.1145/368959.368993
Why and when: Floyd's short note proving the same undecidability result; historically interesting because it was written for programming-language designers. Optional after Theorem 2.1.12.
Chapters: Ch 2 -
[Flo63] Robert W. Floyd. Syntactic analysis and operator precedence. Journal of the ACM 10(3), 316–333, 1963. doi:10.1145/321172.321179
Why and when: Core reading. The origin of operator-precedence relations and parsing (Lesson 3.5) and a precursor of bounded-context and LR methods. Read the definitions of the three relations and the parsing algorithm.
Chapters: Ch 3 -
[FMQ80] Charles N. Fischer, Donn R. Milton, and Sam B. Quiring. Efficient LL(1) error correction and recovery using only insertions. Acta Informatica 13(2), 141–154, 1980.
Why and when: Insert-only LL(1) repair with precomputed cheapest insertion strings (Lesson 2.7 §6). Read the definition of insert-correctable grammars.
Note: Springer, Acta Informatica 13(2); available through university libraries.
Chapters: Ch 2 -
[FMW84] Christopher W. Fraser, Eugene W. Myers, and Alan L. Wendt. Analyzing and Compressing Assembly Code. SIGPLAN '84 Symposium on Compiler Construction, pp. 117–121, 1984. doi:10.1145/502874.502886
Why and when: Procedural abstraction with suffix trees: find repeated instruction sequences and replace them by calls — the idea behind LLVM's MachineOutliner. Read with Lesson 20.4's outlining.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[For02] Bryan Ford. Packrat parsing: simple, powerful, lazy, linear time. ICFP 2002, 36–47, 2002. doi:10.1145/581478.581483
Why and when: Memoizing (rule, position) to make backtracking linear, the idea of Algorithm 2.5.7. Read the introduction and the packrat construction now, the rest with Ch 4.
Chapters: Ch 2, Ch 4 -
[For04] Bryan Ford. Parsing expression grammars: a recognition-based syntactic foundation. POPL 2004, 111–122, 2004. doi:10.1145/964001.964011
Why and when: Ordered choice as a grammar formalism; explains why PEG is not "backtracking CFG parsing" (the S → a | a b pitfall in Lesson 2.5 §4). Read the definition of PEGs; Ch 4 covers PEG in depth.
Chapters: Ch 2, Ch 4 -
[FOW87] Jeanne Ferrante, Karl J. Ottenstein, and Joe D. Warren. The Program Dependence Graph and Its Use in Optimization. ACM TOPLAS 9(3), pp. 319–349, 1987. doi:10.1145/24039.24041
Why and when: Core reading. The PDG: control dependence from post-dominance plus data dependence, and the post-dominator-tree walk of Algorithm 8.5.6. Read §2–3 with Lesson 8.5.
Chapters: Ch 8, Ch 15, Ch 17, Ch 23 -
[Fre60] Edward Fredkin. Trie memory. Communications of the ACM 3(9), pp. 490–499, 1960. doi:10.1145/367390.367400
Why and when: Names and introduces the trie (Definition 1.8.3). Historical; Lesson 1.8 §2 is all you need to implement keyword tries.
Chapters: Ch 1 -
[FSDF93] Cormac Flanagan, Amr Sabry, Bruce F. Duba, and Matthias Felleisen. The Essence of Compiling with Continuations. PLDI 1993, pp. 237–247, 1993. doi:10.1145/155090.155113
Why and when: Core reading. A-normal form: CPS followed by administrative reduction and un-CPS equals direct A-normalization (Theorem 8.6.10). The origin of Lesson 8.6's ANF; read all of it.
Chapters: Ch 8 -
[Fut71] Yoshihiko Futamura. Partial Evaluation of Computation Process — An Approach to a Compiler-Compiler. Systems, Computers, Controls 2(5), pp. 45–50; reprinted in Higher-Order and Symbolic Computation 12(4), 1999, pp. 381–391, 1971. doi:10.1023/A:1010095604496
Why and when: Core reading. The three projections relating interpreters, compilers and compiler generators through a partial evaluator (Theorem 0.3.15). The DOI is the 1999 reprint; read it after Lesson 0.3 §4.
Chapters: Ch 0 -
[GA96] Lal George and Andrew W. Appel. Iterated Register Coalescing. ACM TOPLAS 18(3), pp. 300–324, 1996. doi:10.1145/229542.229546
Why and when: Core reading. The George test and the worklist algorithm of Lesson 22.4 (Algorithm 22.4.6), with the argument that interleaving coalescing and simplification removes most copies without new spills. Implement E2 from its pseudo-code.
Chapters: Ch 22 -
[Gal+09] Andreas Gal, Brendan Eich, Mike Shaver, David Anderson, David Mandelin, Mohammad R. Haghighat, Blake Kaplan, Graydon Hoare, Boris Zbarsky, Jason Orendorff, Jesse Ruderman, Edwin W. Smith, Rick Reitmaier, Michael Bebenita, Mason Chang, and Michael Franz. Trace-based Just-in-Time Type Specialization for Dynamic Languages. PLDI 2009, pp. 465–478, 2009. doi:10.1145/1542476.1542528
Why and when: TraceMonkey: recording type-specialized traces with guards and trace trees in a JavaScript engine — Algorithm 0.3.5 in production.
Chapters: Ch 0 -
[Gar02] Karthik Gargi. A Sparse Algorithm for Predicated Global Value Numbering. PLDI 2002, pp. 45–56, 2002.
Why and when: Complete optimistic GVN with value inference and predicates, touching only instructions whose inputs changed: the design LLVM's NewGVN implements (Lesson 17.5 §2). Read §3–5.
Note: ACM Digital Library; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[Gar04] Jacques Garrigue. Relaxing the Value Restriction. FLOPS 2004, Functional and Logic Programming, LNCS 2998, 196–213, 2004.
Why and when: OCaml's relaxed value restriction (generalize covariant variables of expansive expressions). Read after Lesson 7.3 §6 to understand OCaml's'_weakvariables.
Note: Springer LNCS 2998; the author's copy is on his Nagoya University home page.
Chapters: Ch 7 -
[Gav72] Fănică Gavril. Algorithms for Minimum Coloring, Maximum Clique, Minimum Covering by Cliques, and Maximum Independent Set of a Chordal Graph. SIAM Journal on Computing 1(2), pp. 180–187, 1972. doi:10.1137/0201013
Why and when: Optimal colouring of chordal graphs along a perfect elimination order (Theorem 22.6.2). Two pages of the paper are enough.
Chapters: Ch 22 -
[GC01] David Grove and Craig Chambers. A Framework for Call Graph Construction Algorithms. ACM TOPLAS 23(6), pp. 685–746, 2001. doi:10.1145/506315.506316
Why and when: Core reading. One lattice-based framework in which CHA, RTA, XTA-style propagation, 0-CFA and k-CFA are instances, with a large experimental comparison. Read §2–4 after Lesson 20.1 §2 to see the precision chain of Theorem 20.1.14 as an ordering of framework instances.
Note: DOI recorded from the journal; not re-resolved from the course container (doi.org is blocked there).
Chapters: Ch 20 -
[GG78] R. Steven Glanville and Susan L. Graham. A New Method for Compiler Code Generation. POPL 1978, 1978. doi:10.1145/512760.512785
Why and when: Instruction selection as LR parsing of a linearized tree, with conflicts resolved toward the longest match (maximal munch). The variant discussed in Lesson 21.1 §6.
Chapters: Ch 21 -
[GGL12] Tobias Grosser, Armin Größlinger, and Christian Lengauer. Polly — Performing Polyhedral Optimizations on a Low-Level Intermediate Representation. Parallel Processing Letters 22(4), 1250010, 2012. doi:10.1142/S0129626412500107
Why and when: How Polly detects SCoPs in LLVM IR and applies isl schedules; read with Lesson 18.7 §7 since Polly is not in this course's LLVM build.
Chapters: Ch 18 -
[GH88] James R. Goodman and Wei-Chung Hsu. Code Scheduling and Register Allocation in Large Basic Blocks. ICS 1988, pp. 442–452, 1988. doi:10.1145/55364.55407
Why and when: Core reading. Integrated prepass scheduling: latency-first until registers run short, then pressure-first. The origin of Algorithm 23.3.10 and Algorithm 23.8.4, and of the lab's ★pressurealgorithm.
Chapters: Ch 23 -
[GILS16] Loukas Georgiadis, Giuseppe F. Italiano, Luigi Laura, and Federico Santaroni. An Experimental Study of Dynamic Dominators. arXiv:1604.02711 (conference version ESA 2012, LNCS 7501), 2016. link
Why and when: Core reading. The paper LLVM's updater implements ("[2]" in GenericDomTreeConstruction.h): Lemma 2.5 (insertion, Lemma 15.2.3 here), Lemma 2.6 (deletion, Lemma 15.2.5), the proper-support test (p. 3) and the measurements. Read §2-3 alongside Lesson 15.2.
Chapters: Ch 15 -
[GJTV11] Sumit Gulwani, Susmit Jha, Ashish Tiwari, and Ramarathnam Venkatesan. Synthesis of Loop-free Programs. PLDI 2011, pp. 62–73, 2011.
Why and when: Component-based synthesis with an SMT solver and counterexample-guided refinement, the technique Souper's synthesis builds on (Algorithm 13.3.6). Read §3 after Lesson 13.3.
Note: ACM Digital Library (PLDI '11).
Chapters: Ch 13 -
[GK92] Torbjörn Granlund and Richard Kenner. Eliminating Branches using a Superoptimizer and the GNU C Compiler. PLDI 1992, pp. 341–352, 1992.
Why and when: The GNU superoptimizer and how its branch-free sequences went into GCC's code generator. Read after Lesson 13.3 §6; the tool is the one run in the Lesson 13.3 box.
Note: ACM Digital Library (PLDI '92).
Chapters: Ch 13 -
[GKT91] Gina Goff, Ken Kennedy, and Chau-Wen Tseng. Practical Dependence Testing. PLDI 1991, pp. 15-29, 1991. doi:10.1145/113445.113448
Why and when: Core reading. ZIV/SIV/MIV classification, exact SIV tests and the Delta test; the paper LLVM's DependenceAnalysis says it implements. Read with Lesson 18.6's SIV section.
Chapters: Ch 18 -
[Glu61] Victor M. Glushkov. The abstract theory of automata. Russian Mathematical Surveys 16(5), pp. 1–53, 1961.
Why and when: The other origin of the position ("Glushkov") automaton of Lesson 1.1: states are the symbol occurrences of the expression, no ε-edges. Only the construction section is needed; the paper is a broad survey of automata theory as of 1961.
Note: English translation of the 1961 Uspekhi Mat. Nauk article.
Chapters: Ch 1 -
[GM86] Philip B. Gibbons and Steven S. Muchnick. Efficient Instruction Scheduling for a Pipelined Architecture. SIGPLAN '86 Symposium on Compiler Construction, pp. 11–16, 1986. doi:10.1145/12276.13312
Why and when: Core reading. The table-driven backward DAG construction (Algorithm 23.2.6) and a top-down list scheduler with lookahead-free priorities, in six pages. The model for most RISC-era schedulers; read it right after Lesson 23.2.
Chapters: Ch 23 -
[GM94] Torbjörn Granlund and Peter L. Montgomery. Division by Invariant Integers using Multiplication. PLDI 1994, pp. 61–72, 1994. doi:10.1145/178243.178249
Why and when: Division by any constant with a multiply-high and shifts, including the signed rounding correction — the general case of Lesson 12.3's power-of-two sequence. Read §4–5 after Lesson 12.3.
Chapters: Ch 12, Ch 13 -
[GN04] Sumit Gulwani and George C. Necula. A Polynomial-Time Algorithm for Global Value Numbering. SAS 2004, LNCS 3148, pp. 212–227, 2004.
Why and when: What "complete" GVN means (Herbrand equivalence over all paths) and how to reach it in polynomial time; Lesson 17.5 §4 uses their definition to place AWZ and hash-based GVN.
Note: SpringerLink; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[Gol76] Martin Charles Golumbic. Combinatorial Merging. IEEE Transactions on Computers C-25(11), pp. 1164–1167, 1976.
Why and when: Merging with a max-plus cost, the setting of the greedy proof of Theorem 13.6.10. Optional background for Lesson 13.6 §4.
Note: IEEE Xplore.
Chapters: Ch 13 -
[GR75] Susan L. Graham and Steven P. Rhodes. Practical syntactic error recovery. Communications of the ACM 18(11), 639–650, 1975.
Why and when: Phrase-level recovery made systematic: local corrections chosen by context (Lesson 2.7 §1). Read the description of the two recovery phases.
Note: CACM 18(11); in the ACM Digital Library.
Chapters: Ch 2 -
[Gra66] R. L. Graham. Bounds for Certain Multiprocessing Anomalies. Bell System Technical Journal 45(9), pp. 1563–1581, 1966. doi:10.1002/j.1538-7305.1966.tb01709.x
Why and when: The first proof that any list schedule is within a factor 2 − 1/m of the optimum on m identical processors (Theorem 23.3.3). The argument is two pages; read it after the lesson's proof.
Chapters: Ch 23 -
[Gra69] R. L. Graham. Bounds on Multiprocessing Timing Anomalies. SIAM Journal on Applied Mathematics 17(2), pp. 416–429, 1969. doi:10.1137/0117039
Why and when: The anomalies (more processors, shorter tasks or fewer edges can lengthen a list schedule) and the tightness of the bound. Read §2 for the examples behind Lesson 23.3 §4's pitfall.
Chapters: Ch 23 -
[Gra89] Philippe Granger. Static Analysis of Arithmetical Congruences. International Journal of Computer Mathematics 30(3-4), pp. 165-190, 1989. doi:10.1080/00207168908803778
Why and when: The congruence domain aZ + b (Lesson 14.7, Definition 14.7.5); LLVM's KnownBits is its power-of-two special case.
Chapters: Ch 14 -
[Gre65] Sheila A. Greibach. A new normal-form theorem for context-free phrase structure grammars. Journal of the ACM 12(1), 42–52, 1965. doi:10.1145/321250.321254
Why and when: Greibach normal form, whose construction contains direct and indirect left-recursion removal (Lesson 2.4). Read the construction's lemmas; the normal form itself is optional.
Chapters: Ch 2 -
[Gri17] Radu Grigore. Java Generics are Turing Complete. POPL 2017, 44th ACM SIGPLAN Symposium on Principles of Programming Languages, 73–85, 2017. doi:10.1145/3009837.3009871
Why and when: Subtyping with Java's wildcards can simulate a Turing machine, so a type checker that decides it may not terminate. Read the introduction after Lesson 6.4 §5: it is why local inference stays deliberately weak and why variance (Lesson 6.5) must be designed with care.
Chapters: Ch 6 -
[Gri73] David Gries. Describing an algorithm by Hopcroft. Acta Informatica 2(2), pp. 97–109, 1973. doi:10.1007/BF00264025
Why and when: A structured re-derivation of Hopcroft's algorithm with a careful correctness proof; the best companion to Lesson 1.4 §4 (Lemma 1.4.11) if the proof sketch there feels too quick.
Note: Springer journal article.
Chapters: Ch 1 -
[GSW95] Michael P. Gerlek, Eric Stoltz, and Michael Wolfe. Beyond Induction Variables: Detecting and Classifying Sequences Using a Demand-Driven SSA Form. ACM TOPLAS 17(1), pp. 85-122, 1995. doi:10.1145/200994.201003
Why and when: The journal version with the full classification (polynomial, geometric, wrap-around, periodic, monotonic) that Lesson 18.2's Definition 18.2.5 uses.
Chapters: Ch 18 -
[Gup90] Rajiv Gupta. A Fresh Look at Optimizing Array Bound Checking. PLDI 1990, pp. 272–282, 1990. doi:10.1145/93542.93581
Why and when: Core reading. Bounds checks as redundancy: a check is removable when a dominating check or a loop invariant implies it. The origin of static check elimination (Algorithm 24.2.3); read §3–4.
Chapters: Ch 24 -
[Gup93] Rajiv Gupta. Optimizing Array Bound Checks Using Flow Analysis. ACM Letters on Programming Languages and Systems 2(1-4), pp. 135-150, 1993. doi:10.1145/176454.176507
Why and when: Range checks eliminated and hoisted by dataflow analysis; the pre-SSA view of Lesson 18.9's first technique.
Chapters: Ch 18 -
[GW76] Susan L. Graham and Mark Wegman. A Fast and Usually Linear Algorithm for Global Flow Analysis. Journal of the ACM 23(1), pp. 172-202, 1976. doi:10.1145/321921.321939
Why and when: An O(e log e) elimination algorithm for a broad class of frameworks on reducible graphs; the variant listed in Lesson 14.5 §6.
Chapters: Ch 14 -
[GW96] David W. Goodwin and Kent D. Wilken. Optimal and Near-optimal Global Register Allocation Using 0-1 Integer Programming. Software: Practice and Experience 26(8), pp. 929–965, 1996.
Why and when: The first ILP formulation of global allocation with spill placement, copies and rematerialization, solved to optimality on real functions (Lesson 22.7).
Note: Wiley; Software—Practice and Experience, vol. 26, no. 8 (August 1996).
Chapters: Ch 22 -
[Han70] Kenneth V. Hanford. Automatic Generation of Test Cases. IBM Systems Journal 9(4), pp. 242–257, 1970. doi:10.1147/sj.94.0242
Why and when: The "syntax machine": random programs from a grammar to test PL/I compilers — grammar-based fuzzing forty years before the word. Skim it for history after Lesson 12.6 §1.
Chapters: Ch 12 -
[Han90] David R. Hanson. Fast allocation and deallocation of memory based on object lifetimes. Software: Practice and Experience 20(1), 5–12, 1990. doi:10.1002/spe.4380200104
Why and when: Arenas: allocate by bumping a pointer, free everything of one lifetime at once — the design of Algorithm 4.7.6 and of every compiler AST arena. Eight pages; read after Lesson 4.7 §2.
Chapters: Ch 4 -
[Hav97] Paul Havlak. Nesting of Reducible and Irreducible Loops. ACM TOPLAS 19(4), pp. 557-567, 1997. doi:10.1145/262004.262005
Why and when: Core reading. Havlak's loop nesting forest (Algorithm 15.5.9, the definition LLVM's CycleInfo implements); read Figure 3 and §3 with Lesson 15.5, then Ram99 for the complexity fix.
Chapters: Ch 15 -
[HBC98] William A. Havanki, Sanjeev Banerjia, and Thomas M. Conte. Treegion Scheduling for Wide Issue Processors. HPCA-4, 1998, 1998. link
Why and when: Tree-shaped regions that need no join compensation (Definition 23.4.8, Proposition 23.4.12), with heuristics compared against traces and superblocks.
Chapters: Ch 23 -
[HCU92] Urs Hölzle, Craig Chambers, and David Ungar. Debugging Optimized Code with Dynamic Deoptimization. PLDI 1992, pp. 32–43, 1992. doi:10.1145/143095.143114
Why and when: Introduces deoptimization (reconstructing unoptimized frames from optimized ones) in Self — the mechanism behind Definition 0.3.6 and Theorem 0.3.13.
Chapters: Ch 0, Ch 24 -
[Hed00] Görel Hedin. Reference attributed grammars. Informatica (Slovenia) 24(3), 301–317, 2000.
Why and when: Attributes whose values are references to other tree nodes, so thatdecl()can point at a declaration (Lesson 5.5 §6). Read §2–4 before the JastAdd box of Lesson 5.5.
Note: No DOI; the journal's archive and the author's Lund University page host the PDF.
Chapters: Ch 5 -
[HG83] John L. Hennessy and Thomas Gross. Postpass Code Optimization of Pipeline Constraints. ACM TOPLAS 5(3), pp. 422–448, 1983. doi:10.1145/2166.357217
Why and when: Scheduling for the MIPS pipeline without interlocks, with an NP-completeness proof for pipelines with delays. Read it for the phase-ordering discussion that Lesson 23.8 picks up.
Chapters: Ch 23 -
[HGG06] Sebastian Hack, Daniel Grund, and Gerhard Goos. Register Allocation for Programs in SSA-Form. CC 2006 (LNCS), 2006. doi:10.1007/11688839_20
Why and when: Core reading. SSA interference graphs are chordal; colour in dominance order with MaxLive colours and spill beforehand (Theorems 22.6.5 and 22.6.7). The shortest route to Lesson 22.6.
Chapters: Ch 22 -
[HHPW96] Cordelia V. Hall, Kevin Hammond, Simon L. Peyton Jones, and Philip L. Wadler. Type Classes in Haskell. ACM Transactions on Programming Languages and Systems 18(2), 109–138, 1996. doi:10.1145/227699.227700
Why and when: The complete static semantics of Haskell's classes and their dictionary translation, the reference for Theorem 7.7.9. Read §3–5 after Lesson 7.7 §2.
Chapters: Ch 7 -
[HHZ12] Christian Holler, Kim Herzig, and Andreas Zeller. Fuzzing with Code Fragments. USENIX Security 2012, pp. 445–458, 2012. link
Why and when: LangFuzz: grammar-based fuzzing of JavaScript engines that recombines fragments of existing test programs. Read after Lesson 12.6 as the practical refinement of random derivation.
Chapters: Ch 12 -
[Hin69] J. Roger Hindley. The Principal Type-Scheme of an Object in Combinatory Logic. Transactions of the American Mathematical Society 146, 29–60, 1969.
Why and when: The first principal-type theorem, for combinatory logic, which Milner's work rediscovered for ML. Historical background for Lesson 7.2 §1; skim the introduction.
Note: Available through JSTOR and the AMS journal archive.
Chapters: Ch 7 -
[HKMW66] L. P. Horwitz, Richard M. Karp, Raymond E. Miller, and Shmuel Winograd. Index Register Allocation. Journal of the ACM 13(1), pp. 43–61, 1966.
Why and when: Optimal register allocation for straight-line code with store costs, by an exact exponential search; the compiler-side ancestor of Lesson 22.2's MIN and of Proposition 22.2.7's dirty values. Skim the problem statement and the pruning rules.
Note: In the ACM Digital Library under Journal of the ACM, vol. 13, no. 1 (January 1966).
Chapters: Ch 22 -
[HL07] Ben Hardekopf and Calvin Lin. The Ant and the Grasshopper: Fast and Accurate Pointer Analysis for Millions of Lines of Code. PLDI 2007, pp. 290–299, 2007. doi:10.1145/1250734.1250767
Why and when: Core reading. Lazy cycle detection (LCD) and hybrid cycle detection (HCD), and an experimental comparison of every cycle-detection scheme then known. The ★ part of the lab implements LCD; read §3–5 after Lesson 19.4 §6 and compare Table 3 with the lab's stress numbers.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[HL07b] Ben Hardekopf and Calvin Lin. Exploiting Pointer and Location Equivalence to Optimize Pointer Analysis. SAS 2007, LNCS 4634, pp. 265–280, 2007. doi:10.1007/978-3-540-74061-2_17
Why and when: Offline variable substitution (HVN, HRU) that shrinks the constraint graph before solving; GCC's "Detecting pointer and location equivalences" phase in Lesson 19.4's real-world box is this. Read after Lesson 19.4 §6.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[HL11] Ben Hardekopf and Calvin Lin. Flow-Sensitive Pointer Analysis for Millions of Lines of Code. CGO 2011, pp. 289–298, 2011. doi:10.1109/CGO.2011.5764696
Why and when: Staged flow-sensitive analysis (SFS): an auxiliary flow-insensitive analysis builds def-use chains for memory, and the flow-sensitive analysis runs sparsely on them. Read §3–4 after Lesson 19.6 §2.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[HM82] John L. Hennessy and Noah Mendelsohn. Compilation of the Pascal Case Statement. Software—Practice and Experience 12(9), 1982.
Why and when: Binary search over sorted case values and its comparison with tables; read with Lesson 11.3's Algorithm 11.3.4 and Theorem 11.3.5.
Note: Wiley journal; no DOI was re-resolved from the course container — find it by title.
Chapters: Ch 11 -
[HM97] Nevin Heintze and David McAllester. On the Cubic Bottleneck in Subtyping and Flow Analysis. LICS 1997, pp. 342–351, 1997.
Why and when: Shows that a family of inclusion-based analyses is as hard as a problem for which no subcubic algorithm is known — why Proposition 19.4.16's bound is not just an artefact of the worklist. Read the introduction after Lesson 19.4 §5.
Note: Look it up by title in the LICS 1997 proceedings (IEEE); no DOI was checked from the course container.
Chapters: Ch 19 -
[HM98] Graham Hutton and Erik Meijer. Monadic parsing in Haskell. Journal of Functional Programming 8(4), 437–444, 1998. doi:10.1017/S0956796898003050
Why and when: The eight-page version of [HM96]: a complete combinator library and an expression parser. Read it first if you only read one combinator paper.
Chapters: Ch 4 -
[HMC+93] Wen-mei W. Hwu, Scott A. Mahlke, William Y. Chen, Pohua P. Chang, Nancy J. Warter, Roger A. Bringmann, Roland G. Ouellette, Richard E. Hank, Tokuzo Kiyohara, Grant E. Haab, John G. Holm, and Daniel M. Lavery. The Superblock: An Effective Technique for VLIW and Superscalar Compilation. The Journal of Supercomputing 7(1–2), pp. 229–248, 1993. doi:10.1007/BF01205185
Why and when: Core reading. Superblock formation by tail duplication and the superblock optimizations of IMPACT (Algorithm 23.4.6). Shorter and more practical than the trace-scheduling literature; read it right after Lesson 23.4 §2.
Chapters: Ch 23 -
[HO82] Christoph M. Hoffmann and Michael J. O'Donnell. Pattern Matching in Trees. Journal of the ACM 29(1), pp. 68–95, 1982. doi:10.1145/322290.322295
Why and when: Top-down and bottom-up tree pattern matching automata. The bottom-up construction is the matching half of BURS (Lesson 21.3 §1); twig uses the top-down one (Lesson 21.2 §6).
Chapters: Ch 21 -
[Hop71] John E. Hopcroft. An n log n algorithm for minimizing states in a finite automaton. Theory of Machines and Computations (Z. Kohavi, A. Paz, eds.), Academic Press, pp. 189–196, 1971.
Why and when: Core reading. The O(kn log n) minimization algorithm (Algorithm 1.4.5). The original is terse; read [Knu01] or [Gri73] for the proof and come back here for the "smaller half" idea.
Note: Conference proceedings chapter; also Stanford report STAN-CS-71-190.
Chapters: Ch 1 -
[HPHF14] Matthew A. Hammer, Khoo Yit Phang, Michael Hicks, and Jeffrey S. Foster. Adapton: Composable, Demand-Driven Incremental Computation. PLDI 2014, 2014. doi:10.1145/2594291.2594324
Why and when: Demand-driven incremental computation with dependency graphs, the research lineage of salsa and rustc's query system (Lesson 0.1, query-based compilation).
Chapters: Ch 0, Ch 5 -
[HPR88] Susan Horwitz, Jan Prins, and Thomas Reps. On the Adequacy of Program Dependence Graphs for Representing Programs. POPL 1988, pp. 146–157, 1988. doi:10.1145/73560.73573
Why and when: Proves that programs with isomorphic PDGs are equivalent, under restrictions: the full proof behind Theorem 8.5.11.
Chapters: Ch 8 -
[HRS+17] Andreas Haas, Andreas Rossberg, Derek L. Schuff, Ben L. Titzer, Michael Holman, Dan Gohman, Luke Wagner, Alon Zakai, and JF Bastien. Bringing the Web up to Speed with WebAssembly. PLDI 2017, pp. 185–200, 2017. doi:10.1145/3062341.3062363
Why and when: The design of WebAssembly as a validated stack machine with structured control flow; the origin of the structured-stack-code variant in Lesson 8.1 and of its one-pass validation.
Chapters: Ch 8, Ch 9 -
[HS06] Lang Hames and Bernhard Scholz. Nearly Optimal Register Allocation with PBQP. JMLC 2006 (LNCS), 2006. doi:10.1007/11860990_21
Why and when: A better RN heuristic and an evaluation against a branch-and-bound optimum; the design of LLVM's RegAllocPBQP (Lesson 22.7 §7).
Chapters: Ch 22 -
[HT01] Nevin Heintze and Olivier Tardieu. Demand-Driven Pointer Analysis. PLDI 2001, pp. 24–34, 2001. doi:10.1145/378795.378802
Why and when: Answer one query "what may p point to?" by exploring only the constraints that can matter, with caching. Read §3 after Lesson 19.8 §2.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[Hu61] T. C. Hu. Parallel Sequencing and Assembly Line Problems. Operations Research 9(6), pp. 841–848, 1961. doi:10.1287/opre.9.6.841
Why and when: Level (height) priority is optimal for in-trees of unit tasks on any number of processors, the origin of critical-path priority (Theorem 23.3.4's polynomial cases).
Chapters: Ch 23 -
[HU72] Matthew S. Hecht and Jeffrey D. Ullman. Flow Graph Reducibility. SIAM Journal on Computing 1(2), pp. 188-202, 1972. doi:10.1137/0201014
Why and when: Core reading. Defines T1/T2 and proves the result independent of the order of application (Theorem 15.6.3); read §2-3 with Lesson 15.6.
Chapters: Ch 15 -
[HU74] Matthew S. Hecht and Jeffrey D. Ullman. Characterizations of Reducible Flow Graphs. Journal of the ACM 21(3), pp. 367-375, 1974. doi:10.1145/321832.321835
Why and when: Core reading. The equivalences of Theorem 15.6.4: T1/T2, DFS back edges = dominance back edges, acyclic forward graph, and the forbidden () subgraph. Nine pages; read all of it after Lesson 15.6.
Chapters:* Ch 15 -
[HU75] Matthew S. Hecht and Jeffrey D. Ullman. A Simple Algorithm for Global Data Flow Analysis Problems. SIAM Journal on Computing 4(4), pp. 519-532, 1975. doi:10.1137/0204044
Why and when: Round-robin iteration in reverse postorder and its pass bound for reducible graphs, before Kam and Ullman's general version; read with Lesson 14.4 §2.
Chapters: Ch 14 -
[HU94] Urs Hölzle and David Ungar. Optimizing Dynamically-Dispatched Calls with Run-Time Type Feedback. PLDI 1994, 1994. doi:10.1145/178243.178478
Why and when: Type feedback from the running program drives recompilation: the adaptive-optimization core of tiered compilation (Lesson 0.3).
Chapters: Ch 0, Ch 20, Ch 24 -
[HW04] Christian Haack and J. B. Wells. Type Error Slicing in Implicitly Typed Higher-Order Languages. Science of Computer Programming 50(1–3), 189–224, 2004.
Why and when: Error slices as minimal unsatisfiable constraint sets (Definition 7.9.2). Read §1–4 after Lesson 7.9 §2.
Note: Science of Computer Programming (Elsevier), volume 50; an ESOP 2003 version exists.
Chapters: Ch 7 -
[IAS16] Anastasia Izmaylova, Ali Afroozeh, and Tijs van der Storm. Practical, general parser combinators. PEPM 2016, 1–12, 2016. doi:10.1145/2847538.2847539
Why and when: Combinators on top of GLL: all CFGs, left recursion and a parse forest in cubic worst case (Lesson 4.5 §6). Read after Lesson 4.4's GLL part.
Chapters: Ch 4 -
[IdFC05] Roberto Ierusalimschy, Luiz Henrique de Figueiredo, and Waldemar Celes. The Implementation of Lua 5.0. Journal of Universal Computer Science 11(7), pp. 1159–1176, 2005. pdf
Why and when: Why Lua moved from a stack VM to a register VM, with the instruction formats; the most readable production register-VM design (Lesson 0.2). Read §7 on the virtual machine.
Chapters: Ch 0, Ch 8 -
[Ier09] Roberto Ierusalimschy. A text pattern-matching tool based on parsing expression grammars. Software: Practice and Experience 39(3), 221–258, 2009. doi:10.1002/spe.892
Why and when: LPeg: PEGs compiled to a small parsing machine instead of memoized recursion (Lesson 4.2 §6). Read §4–5 for the machine.
Chapters: Ch 4 -
[IM15] Chinawat Isradisaikul and Andrew C. Myers. Finding counterexamples from parsing conflicts. PLDI 2015, 555–564, 2015. doi:10.1145/2737924.2737961
Why and when: Unifying and nonunifying counterexamples for LR conflicts, the algorithm behind Bison's -Wcounterexamples (Lesson 3.5). Read §2–3 for the definitions and the search.
Chapters: Ch 3 -
[IPW01] Atsushi Igarashi, Benjamin C. Pierce, and Philip Wadler. Featherweight Java: A Minimal Core Calculus for Java and GJ. ACM Transactions on Programming Languages and Systems 23(3), 396–450, 2001. doi:10.1145/503502.503505
Why and when: Nominal subtyping in a calculus small enough to prove sound on one page, with casts as the one place a well-typed program may fail. Read §2 after Lesson 6.5's nominal/structural section and compare itsextends-based subtyping with Definition 6.5.2.
Chapters: Ch 6 -
[Iro61] Edgar T. Irons. A Syntax Directed Compiler for ALGOL 60. Communications of the ACM 4(1), pp. 51–55, 1961. doi:10.1145/366062.366083
Why and when: The origin of attaching a translation to each grammar rule and producing code in one walk, the scheme of Lesson 11.1's Algorithm 11.1.3. Five pages; read it for the idea, not the ALGOL details.
Note: DOI recorded from the journal; not re-resolved from the course container (doi.org is blocked there).
Chapters: Ch 11 -
[Iro63] Edgar T. Irons. An error-correcting parse algorithm. Communications of the ACM 6(11), 669–673, 1963.
Why and when: The first error-correcting parser: repair the input and continue. Historical origin of Lesson 2.7's third family.
Note: CACM 6(11); in the ACM Digital Library.
Chapters: Ch 2 -
[IT88] François Irigoin and Rémi Triolet. Supernode Partitioning. POPL 1988, pp. 319-329, 1988. doi:10.1145/73560.73588
Why and when: The legality condition for tiling (Theorem 18.7.16); read §2–3 after Lesson 18.7's tiling section.
Chapters: Ch 18 -
[IV02] Atsushi Igarashi and Mirko Viroli. On Variance-Based Subtyping for Parametric Types. ECOOP 2002, LNCS 2374, 441–469, 2002. doi:10.1007/3-540-47993-7_19
Why and when: Use-site variance annotations on parametric types, the direct ancestor of Java wildcards. Read §2 after Lesson 6.5's variance section.
Chapters: Ch 6 -
[JAL17] Teresa Johnson, Mehdi Amini, and Xinliang David Li. ThinLTO: Scalable and Incremental LTO. CGO 2017, pp. 111–121, 2017. doi:10.1109/CGO.2017.7863733
Why and when: Core reading. Summaries, the thin link, importing and the parallel backends, with measurements against full LTO. Read §3–4 with Lesson 20.9 and §5 for the numbers its "At scale" paragraph cites.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[JC97] Johan Janssen and Henk Corporaal. Making Graphs Reducible with Controlled Node Splitting. ACM TOPLAS 19(6), pp. 1031-1052, 1997. doi:10.1145/267959.269971
Why and when: Chooses split nodes to keep the copies small; the controlled variant of Lesson 15.6 §6 and the best description of node splitting as an algorithm.
Chapters: Ch 15 -
[Jef03] Clinton L. Jeffery. Generating LR syntax error messages from examples. ACM TOPLAS 25(5), 631–640, 2003. doi:10.1145/937563.937566
Why and when: merr: per-state error messages derived from example erroneous inputs, the idea Menhir's .messages files systematize (Lesson 3.7).
Chapters: Ch 3 -
[JJKD17] Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers, and Derek Dreyer. RustBelt: Securing the Foundations of the Rust Programming Language. Proceedings of the ACM on Programming Languages 2 (POPL 2018), article 66, 2017. doi:10.1145/3158154
Why and when: The machine-checked proof that Rust's ownership and borrowing guarantee memory safety for a core calculus, and how unsafe code fits. The full proof behind Theorem 24.5.13's sketch.
Chapters: Ch 24 -
[JJKD18] Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers, and Derek Dreyer. RustBelt: Securing the Foundations of the Rust Programming Language. Proceedings of the ACM on Programming Languages 2(POPL), Article 66, 2018. doi:10.1145/3158154
Why and when: A semantic soundness proof for a core of Rust's ownership and borrowing, including libraries built onunsafe. Read §1–2 after Lesson 6.8 §4 for what "the borrow checker is sound" means and why it is not a syntactic progress-and-preservation proof.
Chapters: Ch 6 -
[JM03] Neil Johnson and Alan Mycroft. Combined Code Motion and Register Allocation Using the Value State Dependence Graph. CC 2003, LNCS 2622, pp. 1–16, 2003. doi:10.1007/3-540-36579-6_1
Why and when: The VSDG: value and state edges, γ and θ nodes. The origin of Definition 8.5.5's non-hierarchical version.
Chapters: Ch 8 -
[JMG+02] Trevor Jim, Greg Morrisett, Dan Grossman, Michael Hicks, James Cheney, and Yanling Wang. Cyclone: A Safe Dialect of C. USENIX Annual Technical Conference 2002, pp. 275–288, 2002. link
Why and when: Unique pointers and region types in a C dialect: the bridge between Tofte–Talpin regions, ownership types and Rust. Read §3 (regions) and §5 after Lesson 24.5 §6.
Chapters: Ch 24 -
[JNR02] Rajeev Joshi, Greg Nelson, and Keith Randall. Denali: A Goal-directed Superoptimizer. PLDI 2002, 2002. doi:10.1145/512529.512566
Why and when: The first e-graph-based instruction selector: saturate with axioms, then ask a SAT solver for the shortest program. Read §2–3 before Lesson 21.7's e-graph section.
Chapters: Ch 21 -
[Joh85] Thomas Johnsson. Lambda Lifting: Transforming Programs to Recursive Equations. FPCA 1985, LNCS 201, pp. 190–203, 1985. doi:10.1007/3-540-15975-4_37
Why and when: Lambda lifting: pass free variables as extra parameters and move local functions to the top level, with the fixed point over mutually recursive functions of Algorithm 11.8.4.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 11 -
[JOR75] Mehdi Jazayeri, William F. Ogden, and William C. Rounds. The intrinsically exponential complexity of the circularity problem for attribute grammars. Communications of the ACM 18(12), 697–706, 1975. doi:10.1145/361227.361231
Why and when: The lower bound behind Theorem 5.5.16: deciding circularity takes exponential time. Read §1–2 for the statement and skim the encoding in §3–5 after Lesson 5.5 §5.
Chapters: Ch 5 -
[JPL12] Jacques-Henri Jourdan, François Pottier, and Xavier Leroy. Validating LR(1) parsers. European Symposium on Programming (ESOP 2012), LNCS 7211, 397–416, 2012. doi:10.1007/978-3-642-28869-2_20
Why and when: A Coq validator certifies that a Menhir-generated LR(1) automaton is correct for its grammar; used for CompCert's C parser (Lessons 3.7–3.8).
Chapters: Ch 3 -
[JSS16] Herbert Jordan, Bernhard Scholz, and Pavle Subotić. Soufflé: On Synthesis of Program Analyzers. CAV 2016, LNCS 9780, pp. 422-430, 2016. doi:10.1007/978-3-319-41540-6_23
Why and when: Core reading. Compiling Datalog to parallel C++ with specialized indexes: why declarative analyses can be fast (Lesson 14.8's Soufflé boxes). A short tool paper; read it all.
Chapters: Ch 14, Ch 19 -
[Kas80] Uwe Kastens. Ordered attributed grammars. Acta Informatica 13(3), 229–256, 1980. doi:10.1007/BF00288644
Why and when: Ordered AGs: a polynomial-time test and visit sequences computed at generation time (Definition 5.5.9, Proposition 5.5.17). Read §3–4 after Lesson 5.5 §5; the evaluator generators LIGA and Eli use it.
Chapters: Ch 5 -
[KB70] Donald E. Knuth and Peter B. Bendix. Simple Word Problems in Universal Algebras. In J. Leech (ed.), Computational Problems in Abstract Algebra, Pergamon Press, pp. 263–297, 1970.
Why and when: Critical pairs and the completion procedure (Algorithm 13.4.5). Read after Lesson 13.4 §2 if you want the original; [BN98, Ch. 6–7] is the modern treatment.
Note: Book chapter; reprinted in later collections of Knuth's papers.
Chapters: Ch 13 -
[KCL+99] Robert Kennedy, Sun Chan, Shin-Ming Liu, Raymond Lo, Peng Tu, and Fred Chow. Partial Redundancy Elimination in SSA Form. ACM TOPLAS 21(3), pp. 627–676, 1999.
Why and when: The journal version of [CCK+97] with the correctness and optimality proofs and the extensions (speculation, strength reduction). Theorem 17.6.16 points here for the full proof.
Note: ACM Digital Library; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[KD94] Uday P. Khedker and Dhananjay M. Dhamdhere. A Generalized Theory of Bit Vector Data Flow Analysis. ACM TOPLAS 16(5), pp. 1472-1511, 1994. doi:10.1145/186025.186043
Why and when: Bidirectional bit-vector frameworks and their iteration complexity (Lesson 14.2 §6). Read if the unidirectional theory of Lesson 14.4 leaves you wondering what PRE's equations cost.
Chapters: Ch 14 -
[Kel95] Richard A. Kelsey. A Correspondence between Continuation Passing Style and Static Single Assignment Form. ACM SIGPLAN Workshop on Intermediate Representations (IR '95), SIGPLAN Notices 30(3), pp. 13–22, 1995.
Why and when: Core reading. Translations in both directions between SSA and CPS with non-escaping continuations, nesting blocks by the dominator tree: Algorithm 8.6.7 and Theorem 8.6.12.
Note: Published in the IR '95 workshop issue of SIGPLAN Notices (ACM Digital Library).
Chapters: Ch 8, Ch 16 -
[Ken07] Andrew Kennedy. Compiling with Continuations, Continued. ICFP 2007, pp. 177–190, 2007. doi:10.1145/1291151.1291179
Why and when: Argues for CPS with second-class continuations (letcont) over ANF, which duplicates code at joins; the source of Lesson 8.6's pathological family and join-point discussion.
Chapters: Ch 8 -
[KFFD86] Eugene Kohlbecker, Daniel P. Friedman, Matthias Felleisen, and Bruce Duba. Hygienic macro expansion. LFP 1986, 151–161, 1986. doi:10.1145/319838.319859
Why and when: Core reading. The origin of hygiene: the hygiene condition of Definition 4.8.5 and the time-stamping expansion algorithm behind Algorithm 4.8.6. Read after Lesson 4.8 §2.
Chapters: Ch 4, Ch 5 -
[KG08] David Ryan Koes and Seth Copen Goldstein. Near-Optimal Instruction Selection on DAGs. CGO 2008, pp. 45–54, 2008. doi:10.1145/1356058.1356065 · pdf
Why and when: Core reading. NOLTIS (Algorithm 21.4.9): tile the DAG as if it were a tree, then fix shared nodes whose duplication costs more than sharing. Implemented in LLVM and compared with an ILP optimum. Read §3–5 with Lesson 21.4.
Chapters: Ch 21 -
[Kil73] Gary A. Kildall. A unified approach to global program optimization. POPL 1973, 194–206, 1973. doi:10.1145/512927.512945
Why and when: Iterating monotone equations from the bottom of a finite lattice until nothing changes: the same argument as Lesson 2.2's round-robin proof, in its dataflow setting. Read after Lesson 2.2 §4 to see why Ch 14 will feel familiar.
Chapters: Ch 2, Ch 14, Ch 17 -
[KL21] John Keiser and Daniel Lemire. Validating UTF-8 in less than one instruction per byte. Software—Practice and Experience 51(5), pp. 950–964, 2021. doi:10.1002/spe.2920
Why and when: SIMD UTF-8 validation with nibble lookups, the fast version of Algorithm 1.9.8. Read after Lesson 1.9 if you want to vectorize the decoder.
Note: Wiley journal article; preprint arXiv:2010.03090.
Chapters: Ch 1 -
[Kle56] Stephen C. Kleene. Representation of events in nerve nets and finite automata. Automata Studies (C. E. Shannon, J. McCarthy, eds.), Annals of Mathematics Studies 34, Princeton University Press, pp. 3–41, 1956.
Why and when: Core reading. The origin of regular expressions ("regular events") and of the theorem that they describe exactly what finite automata recognize (Theorem 1.1.13). Historical reading after Lesson 1.1; the modern proof in [HMU07 §3.2] is easier to follow than the original notation.
Note: Based on RAND memorandum RM-704 (1951). Reprinted in the De Gruyter edition of Automata Studies.
Chapters: Ch 1 -
[KM93] Ken Kennedy and Kathryn S. McKinley. Maximizing Loop Parallelism and Improving Data Locality via Loop Fusion and Distribution. Languages and Compilers for Parallel Computing (LCPC 1993), LNCS 768, 1993. doi:10.1007/3-540-57659-2_18
Why and when: Fusion and distribution as graph problems, and the NP-hardness of fusion for locality cited in Lesson 18.7 §5.
Chapters: Ch 18 -
[KMRS88] Anna R. Karlin, Mark S. Manasse, Larry Rudolph, and Daniel D. Sleator. Competitive Snoopy Caching. Algorithmica 3, pp. 79–119, 1988. doi:10.1007/BF01762111
Why and when: The competitive analysis behind the rent-or-buy (ski-rental) argument; Theorem 0.3.14 applies it to "interpret or compile". Read the rent-or-buy part only.
Chapters: Ch 0 -
[Knu01] Timo Knuutila. Re-describing an algorithm by Hopcroft. Theoretical Computer Science 250(1–2), pp. 333–363, 2001. doi:10.1016/S0304-3975(99)00150-4
Why and when: Modern invariants and the complete O(kn log n) accounting for Hopcroft's algorithm (Theorem 1.4.12 and Proposition 1.4.15 cite it). Read §4–5 after Lesson 1.4.
Note: Elsevier journal article.
Chapters: Ch 1 -
[Knu65] Donald E. Knuth. On the translation of languages from left to right. Information and Control 8(6), 607–639, 1965. doi:10.1016/S0019-9958(65)90426-2
Why and when: LR(k) parsing; cited here because an LR(k) grammar is unambiguous, one of the sufficient conditions for unambiguity in Lesson 2.1 (Corollary 2.1.13). The full treatment is Ch 3.
Chapters: Ch 2, Ch 3 -
[Knu68] Donald E. Knuth. Semantics of context-free languages. Mathematical Systems Theory 2(2), 127–145, 1968. doi:10.1007/BF01692511
Why and when: Core reading. The origin of attribute grammars: synthesized and inherited attributes, dependency graphs, and a circularity test (Definitions 5.5.1–5.5.4 and 5.5.7). Read §1–3 after Lesson 5.5 §2; the binary numerals example is the classic first AG.
Chapters: Ch 5 -
[Knu71] Donald E. Knuth. Top-down syntax analysis. Acta Informatica 1(2), 79–110, 1971. doi:10.1007/BF00289517
Why and when: Core reading. Knuth's survey-with-proofs of top-down parsing: LL(1) characterized by FIRST and FOLLOW, the parsing-machine view of recursive descent, and left-recursion elimination. The best single companion to Lessons 2.2–2.5; read the parts on LL(1) and on recursive descent.
Chapters: Ch 2, Ch 3 -
[Knu71c] Donald E. Knuth. Semantics of context-free languages: correction. Mathematical Systems Theory 5(1), 95–96, 1971. doi:10.1007/BF01702865
Why and when: Two pages that fix the 1968 circularity test: keep a set of IO graphs per nonterminal, not their union — exactly the point of Algorithm 5.5.8 and Theorem 5.5.15. Read right after the proof sketch of Theorem 5.5.15.
Chapters: Ch 5 -
[KP94] Sampath Kannan and Todd A. Proebsting. Correction to 'Producing Good Code for the Case Statement'. Software—Practice and Experience 24(2), 1994.
Why and when: Core reading. The dynamic program that partitions sorted cases into the fewest dense clusters, which LLVM'sfindJumpTablesimplements (with a score). Read after Lesson 11.3 §2 (Algorithm 11.3.7, Theorem 11.3.8).
Note: Wiley journal; no DOI was re-resolved from the course container — find it by title.
Chapters: Ch 11 -
[KRS92] Jens Knoop, Oliver Rüthing, and Bernhard Steffen. Lazy Code Motion. PLDI 1992, pp. 224-234, 1992. doi:10.1145/143095.143136
Why and when: PRE decomposed into unidirectional bit-vector problems (down-safety = anticipability, earliest, latest); the modern form of Lesson 14.3's very busy expressions. Ch 17 builds on it.
Chapters: Ch 14, Ch 17, Ch 18 -
[KRS94] Jens Knoop, Oliver Rüthing, and Bernhard Steffen. Optimal Code Motion: Theory and Practice. ACM TOPLAS 16(4), pp. 1117–1155, 1994.
Why and when: The journal version of [KRS92] with full proofs of computational and lifetime optimality; Lemma 17.6.12 and Theorems 17.6.13–17.6.14 cite it for the complete arguments.
Note: ACM Digital Library; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[KRS94b] Jens Knoop, Oliver Rüthing, and Bernhard Steffen. Partial Dead Code Elimination. PLDI 1994, pp. 147-158, 1994. doi:10.1145/178243.178256
Why and when: Sinking generalized: move assignments to where they are live. Read after Lesson 18.1's sinking section for the dataflow framework behind it.
Chapters: Ch 18 -
[KS01] Andrew Kennedy and Don Syme. Design and Implementation of Generics for the .NET Common Language Runtime. PLDI 2001, ACM SIGPLAN Conference on Programming Language Design and Implementation, 1–12, 2001. doi:10.1145/378795.378797
Why and when: The alternative to erasure: reified generics with code shared across reference types and specialized at load time for value types. Read §3–4 after Lesson 6.9 §6.
Chapters: Ch 6 -
[KS73] Donald E. Knuth and Francis R. Stevenson. Optimal Measurement Points for Program Frequency Counts. BIT Numerical Mathematics 13(3), pp. 313–322, 1973. doi:10.1007/BF01951942
Why and when: Counting only the edges outside a spanning tree and recovering the rest by flow conservation — the counter placement of LLVM's IR PGO (Lesson 20.10, Ch 12).
Note: DOI recorded from the journal; not re-resolved from the course container. Cited in the header of LLVM's PGOInstrumentation.cpp.
Chapters: Ch 20 -
[KS98] Kathleen Knobe and Vivek Sarkar. Array SSA Form and Its Use in Parallelization. Proc. 25th ACM POPL, 1998. doi:10.1145/268946.268956
Why and when: Array SSA: element-level def-use through @ timestamps, definition phis after every array store and control phis at joins. Lesson 16.8's Array SSA section.
Chapters: Ch 16 -
[KTU90] A. J. Kfoury, J. Tiuryn, and P. Urzyczyn. ML Typability is DEXPTIME-Complete. CAAP '90, 15th Colloquium on Trees in Algebra and Programming, LNCS 431, 206–220, 1990.
Why and when: The independent proof of the same bound as [Mai90], by a different encoding. Consult it if Mairson's construction is hard to follow.
Note: Springer LNCS 431.
Chapters: Ch 7 -
[KU76] John B. Kam and Jeffrey D. Ullman. Global Data Flow Analysis and Iterative Algorithms. Journal of the ACM 23(1), pp. 158-171, 1976. doi:10.1145/321921.321938
Why and when: Core reading. Rapid frameworks and the d(G) + 2 pass bound for round-robin iteration in reverse postorder (Theorem 14.4.6). Read §3–4 after Lesson 14.4 §2; the definition of loop connectedness is theirs.
Chapters: Ch 14, Ch 15 -
[KU77] John B. Kam and Jeffrey D. Ullman. Monotone Data Flow Analysis Frameworks. Acta Informatica 7(3), pp. 305-317, 1977. doi:10.1007/BF00290339
Why and when: MFP versus MOP in monotone frameworks; definite assignment is distributive, so its MFP solution equals the all-paths meaning (Theorem 5.7.8). Read after Lesson 5.7 §4; Chapter 14 covers the full theory.
Chapters: Ch 5, Ch 14 -
[Kur69] Reino Kurki-Suonio. Notes on top-down languages. BIT Numerical Mathematics 9(3), 225–238, 1969.
Why and when: The strict hierarchy LL(k) ⊊ LL(k+1) of languages, quoted in Lesson 2.6 §4. Read the statement and the witness family; the proof is optional.
Note: Springer, BIT 9(3); available through university libraries.
Chapters: Ch 2 -
[KW76] Ken Kennedy and Scott K. Warren. Automatic generation of efficient evaluators for attribute grammars. POPL 1976, 32–49, 1976. doi:10.1145/800168.811538
Why and when: Strongly (absolutely) non-circular grammars: one merged IO graph per nonterminal, a polynomial test and static evaluation plans. Read after Lesson 5.5 §6.
Chapters: Ch 5 -
[KW95] Priyadarshan Kolte and Michael Wolfe. Elimination of Redundant Array Subscript Range Checks. PLDI 1995 (SIGPLAN Notices 30(6)), pp. 270-278, 1995. doi:10.1145/223428.207160
Why and when: Range checks on induction variables in SSA form, the idea behind Theorem 18.9.2.
Chapters: Ch 18 -
[KWM+08] Thomas Kotzmann, Christian Wimmer, Hanspeter Mössenböck, Thomas Rodriguez, Kenneth Russell, and David Cox. Design of the Java HotSpot Client Compiler for Java 6. ACM Transactions on Architecture and Code Optimization 5(1), Article 7, 2008. doi:10.1145/1369396.1370017
Why and when: HotSpot's C1, the fast lower tier (levels 1–3 in-XX:+PrintCompilation), with its SSA-based HIR and linear-scan register allocation.
Chapters: Ch 0 -
[KWTD06] Prasad A. Kulkarni, David B. Whalley, Gary S. Tyson, and Jack W. Davidson. Exhaustive Optimization Phase Order Space Exploration. CGO 2006, pp. 306–318, 2006. link · pdf
Why and when: Enumerating all distinct function instances reachable by phase orders, made feasible by detecting identical instances. Read after Lesson 12.2 §2 (Algorithm 12.2.7).
Chapters: Ch 12, Ch 24 -
[LA00] Samuel Larsen and Saman Amarasinghe. Exploiting Superword Level Parallelism with Multimedia Instruction Sets. PLDI 2000, pp. 145-156, 2000. doi:10.1145/349299.349320
Why and when: SLP vectorization: packing isomorphic statements of a basic block (Definition 18.8.6).
Chapters: Ch 18 -
[LA04] Chris Lattner and Vikram Adve. LLVM: A Compilation Framework for Lifelong Program Analysis & Transformation. CGO 2004, pp. 75–86, 2004. doi:10.1109/CGO.2004.1281665
Why and when: Core reading. The original LLVM paper: a typed SSA IR shared across compile, link and run time. Read §2–3 after Lesson 0.4 to see which design goals of 2004 survive in LLVM 23.
Chapters: Ch 0, Ch 8, Ch 9, Ch 10, Ch 20 -
[LAB+21] Chris Lattner, Mehdi Amini, Uday Bondhugula, Albert Cohen, Andy Davis, Jacques Pienaar, River Riddle, Tatiana Shpeisman, Nicolas Vasilache, and Oleksandr Zinenko. MLIR: Scaling Compiler Infrastructure for Domain Specific Computation. CGO 2021, pp. 2–14, 2021. doi:10.1109/CGO51591.2021.9370308
Why and when: Core reading. The MLIR paper: dialects, operations with regions, progressive lowering and the rationale for a multi-level IR. The origin of the multi-level IR shape in Lesson 0.1.
Chapters: Ch 0, Ch 8, Ch 9, Ch 24 -
[Lam88] Monica Lam. Software Pipelining: An Effective Scheduling Technique for VLIW Machines. PLDI 1988, pp. 318–328, 1988. doi:10.1145/53990.54022
Why and when: Software pipelining in a real compiler (Warp): modulo variable expansion and hierarchical reduction of conditionals. Read it after Algorithm 23.6.12 to compare MVE with rotating registers.
Chapters: Ch 23 -
[Lan64] Peter J. Landin. The Mechanical Evaluation of Expressions. The Computer Journal 6(4), pp. 308–320, 1964. doi:10.1093/comjnl/6.4.308
Why and when: The SECD machine, whose closures pair code with the environment of definition; the idea Lesson 11.8's closure conversion makes explicit.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 11 -
[Lan74] Bernard Lang. Deterministic techniques for efficient non-deterministic parsers. ICALP 1974, LNCS 14, 255–269, 1974. doi:10.1007/978-3-662-21545-6_18
Why and when: The first shared-stack simulation of a nondeterministic LR parser, the idea Tomita made practical (Lesson 3.6 §1). For historical depth.
Chapters: Ch 3 -
[LAS14] Vu Le, Mehrdad Afshari, and Zhendong Su. Compiler Validation via Equivalence Modulo Inputs. PLDI 2014, pp. 216–226, 2014. doi:10.1145/2594291.2594334
Why and when: EMI and the Orion tool: prune statements that did not execute on an input and compare; 147 confirmed bugs in GCC and LLVM in eleven months. Read §2–3 after Lesson 12.6 §2.
Chapters: Ch 12 -
[LBR20] Vsevolod Livinskii, Dmitry Babokin, and John Regehr. Random Testing for C and C++ Compilers with YARPGen. Proc. ACM Program. Lang. 4 (OOPSLA), Article 196, 2020. doi:10.1145/3428264
Why and when: YARPGen: UB avoidance by evaluating every expression during generation, and generation policies that steer programs toward optimization-triggering patterns. Read §3 after Lesson 12.5; compare its design choices with Csmith's.
Chapters: Ch 12 -
[Lee02] Lillian Lee. Fast context-free grammar parsing requires fast Boolean matrix multiplication. Journal of the ACM 49(1), 1–15, 2002. doi:10.1145/505241.505242
Why and when: The converse of Valiant's result: faster CFG parsing would give faster matrix multiplication. Read the introduction after Theorem 4.4.10.
Chapters: Ch 4 -
[Leo91] Joop M. I. M. Leo. A general context-free parsing algorithm running in linear time on every LR(k) grammar without using lookahead. Theoretical Computer Science 82(1), 165–176, 1991. doi:10.1016/0304-3975(91)90180-A
Why and when: Core reading. Deterministic reduction paths and transitive items (Definition 4.3.5, Algorithm 4.3.6), with the linear-time proof for LR-regular grammars. Read after Lesson 4.3 §4.
Chapters: Ch 4 -
[Ler03] Xavier Leroy. Java Bytecode Verification: Algorithms and Formalizations. Journal of Automated Reasoning 30(3–4), pp. 235–269, 2003. doi:10.1023/A:1025055424017
Why and when: The JVM verifier as dataflow over stack and local types, the trouble with subroutines, and the move to checking stack maps. Read it after Algorithm 8.1.6 to see the typed version of height consistency.
Chapters: Ch 8 -
[Ler09] Xavier Leroy. Formal Verification of a Realistic Compiler. Communications of the ACM 52(7), pp. 107–115, 2009. doi:10.1145/1538788.1538814
Why and when: Core reading. CompCert: a C compiler proven correct in Coq, semantic preservation as simulation, and what is (and is not) in the trusted base; its CSE pass is the superlocal value numbering of Lesson 13.1. Read it after Lesson 13.9 §2 (Theorem 13.9.12).
Chapters: Ch 13, Ch 24 -
[Lev66] Vladimir I. Levenshtein. Binary codes capable of correcting deletions, insertions, and reversals. Soviet Physics Doklady 10(8), 707–710, 1966.
Why and when: Core reading. The origin of the edit distance of Definition 5.8.5 (insertions, deletions, substitutions). Read the definitions on the first two pages after Lesson 5.8 §2.
Note: English translation of the 1965 Russian paper (Doklady Akademii Nauk SSSR 163(4)); no DOI.
Chapters: Ch 5 -
[LFK+93] P. Geoffrey Lowney, Stefan M. Freudenberger, Thomas J. Karzes, W. D. Lichtenstein, Robert P. Nix, John S. O'Donnell, and John C. Ruttenberg. The Multiflow Trace Scheduling Compiler. The Journal of Supercomputing 7(1–2), pp. 51–142, 1993. doi:10.1007/BF01205182
Why and when: Ninety pages on the only commercial trace-scheduling compiler: what worked, what compensation code cost, and how the machine model shaped the compiler. Read selectively after Lesson 23.4.
Chapters: Ch 23 -
[LGA00] Guei-Yuan Lueh, Thomas Gross, and Ali-Reza Adl-Tabatabai. Fusion-Based Register Allocation. ACM TOPLAS 22(3), pp. 431–470, 2000. doi:10.1145/353926.353929
Why and when: Allocate regions separately and fuse them along the hottest edges, so that shuffle and spill code lands on cold edges; a placement-aware alternative to global colouring (Lesson 22.9 §6).
Chapters: Ch 22 -
[LGAV96] Josep Llosa, Antonio González, Eduard Ayguadé, and Mateo Valero. Swing Modulo Scheduling: A Lifetime-Sensitive Approach. PACT 1996, pp. 80–86, 1996. link
Why and when: Core reading. SMS (Algorithm 23.6.10): the node ordering that avoids backtracking and keeps lifetimes short, implemented by LLVM's MachinePipeliner and GCC'smodulo-sched.cc.
Chapters: Ch 23 -
[LH03] Ondřej Lhoták and Laurie Hendren. Scaling Java Points-to Analysis Using Spark. CC 2003, LNCS 2622, pp. 153–169, 2003. doi:10.1007/3-540-36579-6_12
Why and when: Soot's Spark: points-to analysis with on-the-fly call-graph construction, and the options (rta, vta, on-fly-cg) the Lesson 20.1 boxes use. Read §2–3 after Lesson 20.1's points-to-based call graphs.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[LH06] Ondřej Lhoták and Laurie Hendren. Context-Sensitive Points-to Analysis: Is It Worth It?. CC 2006, LNCS 3923, pp. 47–64, 2006. doi:10.1007/11688839_5
Why and when: A measured comparison of call-site, object and ZCWL cloning sensitivity on Java: object sensitivity wins for OO clients. Read §5 for the numbers quoted in Lesson 19.7 §8.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[LHJ+18] Juneyoung Lee, Chung-Kil Hur, Ralf Jung, Zhengyang Liu, John Regehr, and Nuno P. Lopes. Reconciling High-Level Optimizations and Low-Level Code in LLVM. Proc. ACM Program. Lang. 2 (OOPSLA), Article 125, 2018. doi:10.1145/3276495
Why and when: A memory model for LLVM IR with pointer provenance and the "twin allocation" semantics for integer-pointer casts: why inttoptr(ptrtoint p) is not simply p, and why GEP, not integer arithmetic, should compute addresses (Lesson 9.4, casts). Read after Lesson 9.4.
Chapters: Ch 9 -
[LHK+17] Juneyoung Lee, Yoonseung Kim, Youngju Song, Chung-Kil Hur, Sanjoy Das, David Majnemer, John Regehr, and Nuno P. Lopes. Taming Undefined Behavior in LLVM. PLDI 2017, pp. 633–647, 2017. doi:10.1145/3062341.3062343
Why and when: Core reading. Shows that LLVM's old combination of undef and poison was inconsistent (optimizations that are each "obviously" right miscompile together), proposes poison-only deferred UB plus the freeze instruction, and measures the cost. The source of Lesson 9.7's Definitions 9.7.2–9.7.6 and Proposition 9.7.14; read §2–4 after the lesson.
Chapters: Ch 9, Ch 13 -
[LL09] Martin Lange and Hans Leiß. To CNF or not to CNF? An efficient yet presentable version of the CYK algorithm. Informatica Didactica 8, 2009. link
Why and when: CYK over a binary normal form with nullable and unit-closure precomputations, avoiding the grammar blow-up of full CNF (Lesson 4.4 §6). Read after Algorithm 4.4.2.
Chapters: Ch 4 -
[LL19] Geoff Langdale and Daniel Lemire. Parsing gigabytes of JSON per second. The VLDB Journal 28(6), pp. 941–960, 2019. doi:10.1007/s00778-019-00578-5
Why and when: simdjson's two-stage design: SIMD classification of structural characters and string regions (Algorithm 1.5.10's approach), then a scalar walk. Read §3–4 after Lesson 1.5 for the bit-manipulation tricks.
Chapters: Ch 1 -
[LLH+21] Nuno P. Lopes, Juneyoung Lee, Chung-Kil Hur, Zhengyang Liu, and John Regehr. Alive2: Bounded Translation Validation for LLVM. PLDI 2021, pp. 65–79, 2021. doi:10.1145/3453483.3454030
Why and when: Core reading. Refinement for whole LLVM functions with undef, poison, memory and bounded loops, and the experience of running it over LLVM's test suite. Read §2–4 after Lesson 12.8.
Chapters: Ch 12, Ch 24 -
[LLH71] Wilf R. LaLonde, E. S. Lee, and James J. Horning. An LALR(k) parser generator. Proceedings of IFIP Congress 71, 513–518, North-Holland, 1971.
Why and when: One of the first practical LALR generators, computing lookaheads on the LR(0) automaton without building LR(1) (Lesson 3.3 §1). Of historical interest.
Note: IFIP Congress proceedings (North-Holland, 1972); no DOI; available in university libraries.
Chapters: Ch 3 -
[LLM+21] Nuno P. Lopes, Juneyoung Lee, Chung-Kil Hur, Zhengyang Liu, and John Regehr. Alive2: Bounded Translation Validation for LLVM. PLDI 2021, pp. 65–79, 2021. doi:10.1145/3453483.3454030
Why and when: Core reading. Refinement (Definition 9.7.8) for whole LLVM functions, with undef, poison, memory and loops (bounded), checked by SMT; the tool behind the alive2.llvm.org links in InstCombine tests. Read §2–3 after Lesson 9.7; Chapter 13 uses it in practice.
Chapters: Ch 9, Ch 13 -
[LM69] Edward S. Lowry and C. W. Medlock. Object Code Optimization. Communications of the ACM 12(1), pp. 13-22, 1969. doi:10.1145/362835.362838
Why and when: Core reading. The FORTRAN H optimizer: "predominators" by iterating set equations, loops found from them, code moved into a landing pad (the preheader), and postdominators by running the same code backwards. Read after Lessons 15.1 and 15.7 to see how much of the chapter was already there.
Chapters: Ch 15, Ch 18 -
[LMNR15] Nuno P. Lopes, David Menendez, Santosh Nagarakatte, and John Regehr. Provably Correct Peephole Optimizations with Alive. PLDI 2015, pp. 22–32, 2015. doi:10.1145/2737924.2737965
Why and when: The DSL and SMT-based checker for InstCombine rules, including the automatic inference of which nsw/nuw/exact flags a rewrite may keep, the question of theflagsdrill (Algorithm 9.7.10 does it by enumeration). Read §3 after Lesson 9.7.
Chapters: Ch 9, Ch 12, Ch 13 -
[LRS74] Philip M. Lewis, Daniel J. Rosenkrantz, and Richard E. Stearns. Attributed translations. Journal of Computer and System Sciences 9(3), 279–307, 1974. doi:10.1016/S0022-0000(74)80045-0
Why and when: L-attributed translations, evaluable during a single left-to-right parse (Definition 5.5.4, Theorem 5.5.13). Read §2 after Lesson 5.5 §3 for the formal definition behind one-pass compilers.
Chapters: Ch 5 -
[LS68] Philip M. Lewis II and Richard E. Stearns. Syntax-directed transduction. Journal of the ACM 15(3), 465–488, 1968. doi:10.1145/321466.321477
Why and when: Core reading. The origin of LL(k) grammars and of the top-down (predictive) translation that Lessons 2.3, 2.5 and 2.6 study. Read the definitions of LL(k) and of the top-down translator; the transduction results are optional.
Chapters: Ch 2 -
[LT79] Thomas Lengauer and Robert Endre Tarjan. A Fast Algorithm for Finding Dominators in a Flowgraph. ACM TOPLAS 1(1), pp. 121-141, 1979. doi:10.1145/357062.357071
Why and when: Core reading. The origin of semidominators, EVAL/LINK and the two-phase algorithm of Lesson 15.1. Read §2 (Theorems 1-4 and Corollary 1, which Theorem 15.1.15 and Corollary 15.1.16 restate), then the pseudo-code of §3 and the appendix (sophisticated LINK). The complexity analysis of §4 can wait.
Chapters: Ch 15 -
[Luc61] Peter Lucas. Die Strukturanalyse von Formelübersetzern. Elektronische Rechenanlagen 3(4), 159–167, 1961.
Why and when: One of the first descriptions of recursive descent: one recursive procedure per syntactic category. Historical; cited in Lesson 2.5 §1 for the origin.
Note: In German; Oldenbourg journal, available through university libraries.
Chapters: Ch 2 -
[LY98] Oukseh Lee and Kwangkeun Yi. Proofs about a Folklore Let-Polymorphic Type Inference Algorithm. ACM Transactions on Programming Languages and Systems 20(4), 707–723, 1998. doi:10.1145/291891.291892
Why and when: Algorithm M (Algorithm 7.2.9): top-down inference, proved sound and complete, and shown to fail earlier than W. Read §2–4 after Lesson 7.2 §3; the lab's L3 is this algorithm.
Chapters: Ch 7 -
[Mai90] Harry G. Mairson. Deciding ML Typability is Complete for Deterministic Exponential Time. POPL 1990, 17th ACM Symposium on Principles of Programming Languages, 382–401, 1990. doi:10.1145/96709.96748
Why and when: The DEXPTIME lower bound of Theorem 7.3.11 by simulating Turing machines with nested lets. Read §1–2 for the type-doubling construction; the full encoding is optional.
Chapters: Ch 7 -
[Mak03] Vladimir N. Makarov. The Finite State Automaton Based Pipeline Hazard Recognizer and Instruction Scheduler in GCC. GCC Developers' Summit 2003, pp. 135–150, 2003. link
Why and when: How GCC'sgenautomataturnsdefine_insn_reservationdescriptions into factored automata and howhaifa-schedqueries them. Read after Lesson 23.1 §7 alongside the.mdfiles of a GCC target.
Chapters: Ch 23 -
[Mas87] Henry Massalin. Superoptimizer: A Look at the Smallest Program. ASPLOS II (SIGPLAN Notices 22(10)), pp. 122–126, 1987.
Why and when: Core reading. The origin of superoptimization: exhaustive search over 68020 instruction sequences, pruned and tested on sample inputs, with the famous branch-free signum. Read it with Lesson 13.3 §1 and compare its results with the GNU superoptimizer box.
Note: ACM Digital Library (ASPLOS II proceedings).
Chapters: Ch 13 -
[May89] Cathy May. The Parallel Assignment Problem Redefined. IEEE Transactions on Software Engineering 15(6), 1989.
Why and when: The parallel assignment problem and its solution with a minimum number of moves, earlier than the SSA literature; background for Theorem 16.7.6.
Note: Look it up by title in the IEEE Xplore (DOI not re-checked from the course container).
Chapters: Ch 16 -
[McA03] David McAllester. A Logical Algorithm for ML Type Inference. RTA 2003, Rewriting Techniques and Applications, LNCS 2706, 436–451, 2003.
Why and when: Why ML inference is fast in practice: nearly linear time when let-depth and type size are bounded (Lesson 7.3 §5). Read the introduction and the main theorem.
Note: Springer LNCS 2706.
Chapters: Ch 7 -
[McA98] Bruce J. McAdam. On the Unification of Substitutions in Type Inference. IFL '98, Implementation of Functional Languages, LNCS 1595, 137–152, 1998.
Why and when: The left-to-right bias of W's error reports and a symmetric alternative (Lesson 7.9). Read §1–3.
Note: Springer LNCS 1595; also an Edinburgh technical report.
Chapters: Ch 7 -
[McC60] John McCarthy. Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I. Communications of the ACM 3(4), pp. 184–195, 1960. doi:10.1145/367177.367199
Why and when: LISP and itseval: the first tree-walking interpreter, defined as a program over the program's own syntax. Origin of the tree-walking technique in Lesson 0.2.
Chapters: Ch 0, Ch 24 -
[McK65] William M. McKeeman. Peephole Optimization. Communications of the ACM 8(7), pp. 443–444, 1965.
Why and when: Names the peephole idea: look at a small window of generated code and replace it. Read it in five minutes before Lesson 13.2 to see how little the definition has changed.
Note: Two pages in CACM, July 1965; available in the ACM Digital Library.
Chapters: Ch 13, Ch 21 -
[McK98] William M. McKeeman. Differential Testing for Software. Digital Technical Journal 10(1), pp. 100–107, 1998. link
Why and when: Core reading. The origin of differential testing for compilers: run the same program through several C compilers and treat disagreement as a bug report, with a hierarchy of generated-test "quality levels" from random bytes to well-defined programs. Read it before Lesson 12.5 §2; its discussion of undefined behavior is the problem Csmith later solved.
Note: No DOI. The URL is HP Labs' archive of the Digital Technical Journal (vol. 10, no. 1, article 9); if it moves, the Internet Archive keeps copies of that path.
Chapters: Ch 12 -
[MDAJ17] Luke Maurer, Paul Downen, Zena M. Ariola, and Simon Peyton Jones. Compiling without Continuations. PLDI 2017, pp. 482–494, 2017. doi:10.1145/3062341.3062380
Why and when: Join points in GHC's direct-style Core: ANF plus second-class local functions, which is the lab'sjoin/loop/jump. Read §2–3 with Lesson 8.6 and the GHC boxes.
Chapters: Ch 8 -
[ME92] Soo-Mook Moon and Kemal Ebcioğlu. An Efficient Resource-Constrained Global Scheduling Technique for Superscalar and VLIW Processors. MICRO-25, pp. 55–71, 1992.
Why and when: Selective scheduling: moving operations upward through the CFG with renaming and bookkeeping, the algorithm of GCC'ssel-sched.cc(Lesson 23.4 §6).
Note: Also IBM Research Report RC 17962, 1992.
Chapters: Ch 23 -
[Mer03] Jason Merrill. GENERIC and GIMPLE: A New Tree Representation for Entire Functions. Proceedings of the GCC Developers' Summit 2003, 2003.
Why and when: The origin of GIMPLE: GENERIC as the language-independent tree form, GIMPLE as its three-address lowering (derived from McCAT's SIMPLE). Read before Lesson 9.8's GIMPLE box for the design motivation.
Note: Published in the 2003 GCC Summit proceedings (linked from the GCC wiki); the URL could not be checked from the authoring environment. GCC's own GIMPLE documentation [GCC-GIMPLE] covers the same design and is the version-pinned reference.
Chapters: Ch 9 -
[MGST70] Richard L. Mattson, Jan Gecsei, Donald R. Slutz, and Irving L. Traiger. Evaluation Techniques for Storage Hierarchies. IBM Systems Journal 9(2), pp. 78–117, 1970. pdf
Why and when: Stack algorithms and a proof that Belady's MIN is optimal; background for Theorem 22.2.6 if you want the original argument rather than the exchange proof in the lesson.
Chapters: Ch 22 -
[MH07] Eva Magnusson and Görel Hedin. Circular reference attributed grammars — their evaluation and applications. Science of Computer Programming 68(1), 21–37, 2007. doi:10.1016/j.scico.2005.06.005
Why and when: Circular attributes evaluated to a fixed point over a finite-height lattice (Algorithm 5.5.11), with nullability and definite assignment as examples. Read §3 after Lesson 5.5 §6.
Chapters: Ch 5 -
[MHM+95] Scott A. Mahlke, Richard E. Hank, James E. McCormick, David I. August, and Wen-mei W. Hwu. A Comparison of Full and Partial Predicated Execution Support for ILP Processors. ISCA 1995, pp. 138–150, 1995. doi:10.1145/223982.225965
Why and when: Full predication versus conditional moves only: how much of the benefit selects keep. The background for LLVM'sEarlyIfConversiondesign (Lesson 23.5 §6–7).
Chapters: Ch 23 -
[Mil78] Robin Milner. A Theory of Type Polymorphism in Programming. Journal of Computer and System Sciences 17(3), 348–375, 1978. doi:10.1016/0022-0000(78)90014-4
Why and when: Core reading. The origin of "well-typed programs cannot go wrong": §3 defines a denotational semantics in which "wrong" is a value and proves that well-typed expressions never denote it. Read §1–3 after Lesson 6.1 §1 to see the semantic route to soundness that Wright and Felleisen later replaced by a syntactic one; the inference half (Algorithm W) is Chapter 7's.
Chapters: Ch 6, Ch 7 -
[Min06] Antoine Miné. The Octagon Abstract Domain. Higher-Order and Symbolic Computation 19(1), pp. 31-100, 2006. doi:10.1007/s10990-006-8609-1
Why and when: Core reading. Octagons, difference-bound matrices, strong closure (Algorithm 14.7.7), widening, and their use in Astrée. Read the closure and widening sections after Lesson 14.7 §2.
Chapters: Ch 14 -
[MLC+92] Scott A. Mahlke, David C. Lin, William Y. Chen, Richard E. Hank, and Roger A. Bringmann. Effective Compiler Support for Predicated Execution Using the Hyperblock. MICRO-25, pp. 45–54, 1992. link
Why and when: Core reading. Hyperblocks: select blocks by frequency, size and hazards, tail-duplicate, then if-convert (Algorithm 23.5.6). Read it after Lesson 23.5 §2.
Chapters: Ch 23 -
[MM04] Conor McBride and James McKinna. Functional pearl: I am not a number—I am a free variable. Haskell Workshop 2004, 1–9, 2004. doi:10.1145/1017472.1017477
Why and when: Locally nameless terms in practice: bound variables as indices, free ones as names, withabstractandinstantiateas the only operations that cross the boundary. Read after Lesson 5.2 §6.
Chapters: Ch 5 -
[MM82] Alberto Martelli and Ugo Montanari. An Efficient Unification Algorithm. ACM Transactions on Programming Languages and Systems 4(2), 258–282, 1982. doi:10.1145/357162.357169
Why and when: Core reading. Unification as rewriting a set of equations to solved form (Algorithm 7.1.8) and the termination measure of Theorem 7.1.15. Read §2 after Lesson 7.1 §4; §3–5 develop the efficient multi-equation algorithm mentioned in §6.
Chapters: Ch 7 -
[MMH96] Yasuhiko Minamide, Greg Morrisett, and Robert Harper. Typed Closure Conversion. POPL 1996, pp. 271–283, 1996. doi:10.1145/237721.237791
Why and when: Closure conversion for typed languages, with environments as existential types and a correctness proof by logical relations; the full proof behind Theorem 11.8.3.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 11 -
[MMI14] Sérgio Medeiros, Fabio Mascarenhas, and Roberto Ierusalimschy. Left recursion in parsing expression grammars. Science of Computer Programming 96(2), 177–190, 2014. doi:10.1016/j.scico.2014.01.013
Why and when: Bounded left recursion: a formal semantics for left-recursive PEGs that agrees with seed growing on direct recursion. Read after Theorem 4.2.9 for the precise definition.
Chapters: Ch 4 -
[MMP18] Andrey Mokhov, Neil Mitchell, and Simon Peyton Jones. Build Systems à la Carte. Proc. ACM Program. Lang. 2 (ICFP), Article 79, 2018. doi:10.1145/3236774
Why and when: A precise framework for build systems (and, by extension, query-based compilers): verifying traces and early cutoff are exactly Algorithm 0.1.12 and Theorem 0.1.19. Read §3–4 after the lesson's query section.
Chapters: Ch 0 -
[MMY10] Kota Mizushima, Atusi Maeda, and Yoshinori Yamaguchi. Packrat parsers can handle practical grammars in mostly constant space. PASTE 2010, 29–36, 2010. doi:10.1145/1806672.1806679
Why and when: Cut operators that let a packrat parser discard its memo table, answering the memory cost of Theorem 4.2.10. Read after Lesson 4.2 §5.
Chapters: Ch 4 -
[MN04] Scott McPeak and George C. Necula. Elkhound: A fast, practical GLR parser generator. Compiler Construction (CC 2004), LNCS 2985, 73–88, 2004. doi:10.1007/978-3-540-24723-4_6
Why and when: A deterministic LR core that switches to GLR only at conflicts, and a C++ front end built on it: the engineering answer to "GLR is slow" (Lesson 3.6 §6–7).
Chapters: Ch 3 -
[MN17] David Menendez and Santosh Nagarakatte. Alive-Infer: Data-Driven Precondition Inference for Peephole Optimizations in LLVM. PLDI 2017, pp. 49–63, 2017.
Why and when: Learns weakest-like preconditions for Alive rules from positive and negative examples and verifies them (Algorithm 13.3.8). Read after Lesson 13.3 §6.
Note: ACM Digital Library (PLDI '17).
Chapters: Ch 13 -
[MNG16] David Menendez, Santosh Nagarakatte, and Aarti Gupta. Alive-FP: Automated Verification of Floating Point Based Peephole Optimizations in LLVM. Static Analysis Symposium (SAS) 2016, LNCS 9837, pp. 317–337, 2016.
Why and when: Extends Alive to floating point and fast-math flags, including the treatment of signed zeros and NaN. Read after Lesson 13.8 §2 (Definition 13.8.8) and Lesson 13.9 §7.
Note: Springer LNCS 9837.
Chapters: Ch 13 -
[Moo00] Robert C. Moore. Removing left recursion from context-free grammars. NAACL 2000, 249–255, 2000. link
Why and when: Names Paull's algorithm, measures how the variants blow up grammars, and gives a left-corner-based improvement (Lesson 2.4 §5–6). Read it after Lesson 2.4; the measurements are the point.
Chapters: Ch 2 -
[Moo56] Edward F. Moore. Gedanken-experiments on sequential machines. Automata Studies (C. E. Shannon, J. McCarthy, eds.), Annals of Mathematics Studies 34, Princeton University Press, pp. 129–153, 1956.
Why and when: The origin of state equivalence by experiments, and of the partition refinement now called Moore's algorithm (Algorithm 1.4.4). Read the sections on distinguishable states after Lesson 1.4 §2.
Note: Same volume as [Kle56].
Chapters: Ch 1 -
[Mos70] Joel Moses. The function of FUNCTION in LISP, or why the FUNARG problem should be called the environment problem. ACM SIGSAM Bulletin 15, 13–27 (also MIT AI Memo 199), 1970. doi:10.1145/1093410.1093411
Why and when: Names the funarg problem that Lesson 5.1 §3 reproduces: a function passed as an argument sees the wrong binding under dynamic scope. Read §1–3 after Theorem 5.1.10.
Chapters: Ch 5 -
[MR05] Laurent Mauborgne and Xavier Rival. Trace Partitioning in Abstract Interpretation Based Static Analyzers. ESOP 2005, LNCS 3444, pp. 5-20, 2005. doi:10.1007/978-3-540-31987-0_2
Why and when: Keeping some paths apart instead of joining them: a controlled step from MFP towards MOP (Lesson 14.2 §6).
Chapters: Ch 14 -
[MR24] Manasij Mukherjee and John Regehr. Hydra: Generalizing Peephole Optimizations with Program Synthesis. Proc. ACM Program. Lang. 8 (OOPSLA1), 2024.
Why and when: Turns Souper's concrete findings into rules with symbolic constants and synthesized preconditions, and emits compiler code. Read after Lesson 13.3 to see the whole pipeline "superoptimize, generalize, verify, implement".
Note: ACM Digital Library (OOPSLA 2024).
Chapters: Ch 13 -
[MR79] Etienne Morel and Claude Renvoise. Global optimization by suppression of partial redundancies. Communications of the ACM 22(2), pp. 96-103, 1979. doi:10.1145/359060.359069
Why and when: Partial-redundancy elimination: availability and anticipability (very busy expressions) combined in a bidirectional bit-vector system. Read after Lesson 14.3 §6; Ch 17 treats PRE in full.
Chapters: Ch 14, Ch 17, Ch 18 -
[MRR05] Ana Milanova, Atanas Rountev, and Barbara G. Ryder. Parameterized Object Sensitivity for Points-to Analysis for Java. ACM TOSEM 14(1), pp. 1–41, 2005. doi:10.1145/1044834.1044835
Why and when: Object sensitivity: a method is analysed separately per receiver object (allocation site), not per call site. Read §3 after Lesson 19.7 §2.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 19 -
[MY60] Robert McNaughton and Hisao Yamada. Regular expressions and state graphs for automata. IRE Transactions on Electronic Computers EC-9(1), pp. 39–47, 1960. doi:10.1109/TEC.1960.5221603
Why and when: Constructs automata from regular expressions via marked positions: one origin of the position automaton (Algorithm 1.1.8) and the "M-Y" in the Dragon book's McNaughton–Yamada–Thompson construction. Read after Lesson 1.1 §2.
Chapters: Ch 1 -
[Nau60] Peter Naur (ed.), John W. Backus, and et al.. Report on the algorithmic language ALGOL 60. Communications of the ACM 3(5), 299–314, 1960. doi:10.1145/367236.367262
Why and when: Core reading. BNF's debut and the first language defined by a context-free grammar. §3.3.1 is the layered arithmetic-expression grammar (term, factor) that Lesson 2.1 generalizes into Algorithm 2.1.9; §4.5 shows how ALGOL avoided the dangling else by syntax (Lesson 2.3).
Chapters: Ch 2, Ch 4 -
[Nau63] Peter Naur (ed.), John W. Backus, and et al.. Revised report on the algorithmic language ALGOL 60. Communications of the ACM 6(1), 1–17, 1963. doi:10.1145/366193.366201
Why and when: The origin of block structure and static scoping: §4.1.3 (blocks and the locality of identifiers) and §5 (declarations). Read those two pages after Lesson 5.1 §1; Definition 5.1.2 is their modern form.
Chapters: Ch 5 -
[Nec00] George C. Necula. Translation Validation for an Optimizing Compiler. PLDI 2000, pp. 83–94, 2000. doi:10.1145/349299.349314
Why and when: Translation validation for GCC's optimizer by symbolic evaluation and inferred simulation relations between source and target. Read after Lesson 12.8 §2 (Algorithm 12.8.6 follows its structure).
Chapters: Ch 12, Ch 13 -
[New42] Maxwell H. A. Newman. On Theories with a Combinatorial Definition of "Equivalence". Annals of Mathematics 43(2), pp. 223–243, 1942.
Why and when: The origin of Newman's lemma (Theorem 13.4.7). Historical; read the proof in Lesson 13.4 or [BN98, Ch. 2] instead.
Note: JSTOR.
Chapters: Ch 13 -
[NF91] Rahman Nozohoor-Farshi. GLR parsing for ε-grammars. In M. Tomita (ed.), Generalized LR Parsing, Kluwer, 61–75, 1991.
Why and when: The fix for Tomita's algorithm on grammars with ε-rules and hidden left recursion (Lesson 3.6 §1 and §6).
Note: Chapter of the edited volume [Tom91]; no DOI.
Chapters: Ch 3 -
[Nij82] Anton Nijholt. On the relationship between the LL(k) and LR(k) grammars. Information Processing Letters 15(3), 97–101, 1982. doi:10.1016/0020-0190(82)90038-2
Why and when: A short proof that every LL(k) grammar is LR(k), via Beatty's left-part theorem: the full proof of Theorem 3.2.14.
Chapters: Ch 3 -
[NO80] Greg Nelson and Derek C. Oppen. Fast Decision Procedures Based on Congruence Closure. Journal of the ACM 27(2), pp. 356–364, 1980. doi:10.1145/322186.322198
Why and when: Congruence closure with union-find, the data structure an e-graph is (Definition 8.5.7 and its congruence invariant). Read after Lesson 8.5 §2.
Chapters: Ch 8, Ch 17 -
[Nov07] Diego Novillo. Memory SSA — A Unified Approach for Sparsely Representing Memory Operations. Proceedings of the GCC Developers' Summit 2007, 2007.
Why and when: Memory SSA as implemented in GCC: virtual operands (VDEF/VUSE) that version memory, with memory partitions. LLVM's MemorySSA documentation points to this paper and notes that GCC later moved to a single memory name, as LLVM uses. Read it with Lesson 16.8.
Note: In the printed GCC Developers' Summit 2007 proceedings; the GCC wiki (MemorySSA page) links the paper.
Chapters: Ch 16, Ch 19 -
[NP20] Andy Newell and Sergey Pupyrev. Improved Basic Block Reordering. IEEE Transactions on Computers 69(12), 2020. pdf
Why and when: Core reading. The ext-TSP model and its greedy chain-merging algorithm (Definition 23.9.5, Algorithm 23.9.6), with the NP-hardness proof and measurements on large binaries.
Chapters: Ch 23 -
[NP93] Cindy Norris and Lori L. Pollock. A Scheduler-Sensitive Global Register Allocator. Supercomputing '93, pp. 804–813, 1993.
Why and when: Adds scheduling edges to a Chaitin-style allocator and removes them before spilling (Algorithm 23.8.7).
Note: In the proceedings of Supercomputing '93 (ACM/IEEE).
Chapters: Ch 23 -
[NRZ06] Dorit Nuzman, Ira Rosen, and Ayal Zaks. Auto-Vectorization of Interleaved Data for SIMD. PLDI 2006, pp. 132-143, 2006. doi:10.1145/1133981.1133997
Why and when: Interleaved and strided accesses in GCC's vectorizer; read for Lesson 18.8 §6's interleave groups.
Chapters: Ch 18 -
[NS94] Esko Nuutila and Eljas Soisalon-Soininen. On finding the strongly connected components in a directed graph. Information Processing Letters 49(1), pp. 9–14, 1994. doi:10.1016/0020-0190(94)90047-7
Why and when: A Tarjan variant that does not push single-node SCCs, which dominate call graphs. Short; read after Lesson 20.2 §6.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 20 -
[NTVW15] Pierre Néron, Andrew Tolmach, Eelco Visser, and Guido Wachsmuth. A theory of name resolution. ESOP 2015, LNCS 9032, 205–231, 2015. doi:10.1007/978-3-662-46669-8_9
Why and when: Core reading. Scope graphs: declarations, references, scopes and labeled P/I edges, resolution as well-formed minimal paths (Definitions 5.3.5–5.3.6). Read §2–3 before the ★ part of the lab and §4 for the resolution calculus behind Algorithm 5.3.7.
Chapters: Ch 5 -
[OL96] Martin Odersky and Konstantin Läufer. Putting Type Annotations to Work. POPL 1996, 23rd ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, 54–67, 1996. doi:10.1145/237721.237729
Why and when: Rank-N polymorphism with annotations on top of HM (Lesson 7.8 §1). Read §1–3.
Chapters: Ch 7 -
[OM17] Guilherme Ottoni and Bertrand Maher. Optimizing Function Placement for Large-Scale Data-Center Applications. CGO 2017, pp. 233–244, 2017.
Why and when: hfsort / C³: call-graph clustering for function order, used by BOLT and linkers (Lessons 23.9 §6 and 23.10 §7).
Note: In the CGO 2017 proceedings (IEEE/ACM).
Chapters: Ch 23 -
[ORT09] Scott Owens, John Reppy, and Aaron Turon. Regular-expression derivatives re-examined. Journal of Functional Programming 19(2), pp. 173–190, 2009. doi:10.1017/S0956796808007090
Why and when: Core reading. Revives Brzozowski derivatives for practice: similarity and smart constructors (Definition 1.3.4), derivative classes for large alphabets (Definition 1.3.6), regular vectors for lexer specifications (Algorithm 1.3.10), and an evaluation in ml-ulex. The paper behind Lesson 1.3; read it all.
Chapters: Ch 1 -
[OSW99] Martin Odersky, Martin Sulzmann, and Martin Wehr. Type Inference with Constrained Types. Theory and Practice of Object Systems 5(1), 35–55, 1999.
Why and when: Core reading. HM(X): Hindley–Milner parameterized by a constraint system, with soundness for every X and principal types when X has principal solutions (Theorems 7.4.7, 7.4.9). Read §2–5 after Lesson 7.4 §2.
Note: Wiley journal TAPOS 5(1); preprints circulate from the authors' pages.
Chapters: Ch 7 -
[P0088] Axel Naumann. Variant: a type-safe union for C++17 (P0088R3). ISO/IEC JTC1/SC22/WG21 paper P0088R3, 2016. link
Why and when: The proposal that became std::variant and std::visit (Lesson 10.4): the design rationale for the index-plus-storage representation and for compile-time exhaustiveness of visitation.
Note: Also reachable as https://wg21.link/P0088R3. open-std.org was not reachable from the authoring container; the number, title and meeting (2016-06, Oulu) were checked against libc++'s libcxx/docs/Status/Cxx17Papers.csv at llvmorg-23.1.2.
Chapters: Ch 10 -
[P0323] Vicente J. Botet Escribá, JF Bastien, and Jonathan Wakely. std::expected (P0323R12). ISO/IEC JTC1/SC22/WG21 paper P0323R12, 2022. link
Why and when: The C++23 value-or-error type the Pebble code uses (Lesson 10.7). Read the design section on why expected has no "must check" state, and compare with llvm::Expected's checked bit.
Note: Also reachable as https://wg21.link/P0323R12. open-std.org was not reachable from the authoring container; the number, title and meeting (2022-02, virtual) were checked against libc++'s libcxx/docs/Status/Cxx23Papers.csv at llvmorg-23.1.2.
Chapters: Ch 10 -
[Pag77] David Pager. A practical general method for constructing LR(k) parsers. Acta Informatica 7(3), 249–268, 1977. doi:10.1007/BF00290336
Why and when: Core reading. Weak compatibility and the PGM construction of Lesson 3.4, with the proof that merging weakly compatible states preserves LR(1)-ness (Theorem 3.4.8). Read the definitions and the main theorem.
Chapters: Ch 3 -
[PAN+19] Maksim Panchenko, Rafael Auler, Bill Nell, and Guilherme Ottoni. BOLT: A Practical Binary Optimizer for Data Centers and Beyond. CGO 2019, 2019. doi:10.1109/CGO.2019.8661201 · pdf
Why and when: Post-link optimization of the linked binary from sampled profiles: CFG reconstruction, block reordering, function splitting and ordering. Read §3–5 after Lesson 20.10.
Chapters: Ch 20, Ch 23 -
[PB09] Fernando Magno Quintão Pereira and Daniel Berlin. Wave Propagation and Deep Propagation for Pointer Analysis. CGO 2009, pp. 126–135, 2009. doi:10.1109/CGO.2009.9
Why and when: Replaces the worklist by rounds of "collapse cycles, propagate once in topological order, add complex edges" (wave) or by a depth-first push from each changed node (deep). Algorithm 19.4.9 is wave propagation; read §3–4 after Lesson 19.4 §2.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[PB97] Keshav Pingali and Gianfranco Bilardi. Optimal Control Dependence Computation and the Roman Chariots Problem. ACM TOPLAS 19(3), pp. 462-491, 1997. doi:10.1145/256167.256217
Why and when: The APT structure answers control-dependence queries in time proportional to the answer, avoiding the quadratic output of Lesson 15.4 §5; read §1-3 for the idea.
Chapters: Ch 15 -
[PCC85] Joseph C. H. Park, K. M. Choe, and C. H. Chang. A new analysis of LALR formalisms. ACM TOPLAS 7(1), 159–175, 1985.
Why and when: An alternative relational formulation of LALR lookaheads, compared in Lesson 3.3 §6. Optional.
Note: ACM TOPLAS 7(1), 1985; available from the ACM Digital Library.
Chapters: Ch 3 -
[PCS05] Sebastian Pop, Albert Cohen, and Georges-André Silber. Induction Variable Analysis with Delayed Abstractions. HiPEAC 2005, LNCS 3793, pp. 218-232, 2005. doi:10.1007/11587514_15
Why and when: The design of GCC's scalar evolution analysis ("chrecs"); the closest paper to what LLVM's ScalarEvolution does, read after Lesson 18.3.
Chapters: Ch 18 -
[Pea16] David J. Pearce. A space-efficient algorithm for finding strongly connected components. Information Processing Letters 116(1), pp. 47–52, 2016. doi:10.1016/j.ipl.2015.08.010
Why and when: Tarjan's algorithm with one integer per node instead of index, lowlink and an on-stack flag, in the same visiting order. Read after Lesson 20.2 §6.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 20 -
[Pen86] Thomas J. Pennello. Very fast LR parsing. SIGPLAN '86 Symposium on Compiler Construction, SIGPLAN Notices 21(7), 145–151, 1986. doi:10.1145/12276.13326
Why and when: Compiling LR tables into machine code (recursive ascent style), the speed argument of Lesson 3.1 §6. Optional.
Chapters: Ch 3 -
[PF11] Terence Parr and Kathleen Fisher. LL(): the foundation of the ANTLR parser generator.* PLDI 2011, 425–436, 2011. doi:10.1145/1993498.1993548
Why and when: Core reading. Lookahead DFAs built by subset construction over the grammar's ATN (Algorithm 2.6.8) and the fallback to backtracking. Read the LL() analysis sections after Lesson 2.6 §2.
Chapters:* Ch 2 -
[PF94] Todd A. Proebsting and Christopher W. Fraser. Detecting Pipeline Structural Hazards Quickly. POPL 1994, pp. 280–286, 1994. doi:10.1145/174675.177904
Why and when: Compiles reservation tables into a finite automaton so a scheduler's "does it fit?" is one table lookup (Proposition 23.1.7). Short and clear; read it after Lesson 23.1 §2.
Chapters: Ch 23 -
[PG88] Eduardo Pelegrí-Llopart and Susan L. Graham. Optimal Code Generation for Expression Trees: An Application of BURS Theory. POPL 1988, pp. 294–308, 1988. doi:10.1145/73560.73586
Why and when: Core reading. The origin of BURS: relative costs folded into automaton states, so optimal selection needs no cost arithmetic at compile time. Read §3–4 with Lesson 21.3 §2.
Chapters: Ch 21 -
[PH90] Karl Pettis and Robert C. Hansen. Profile Guided Code Positioning. PLDI 1990, 1990. doi:10.1145/93542.93550
Why and when: Profile-driven layout of functions and basic blocks: the classic profile-guided AOT optimization (Algorithm 0.3.2).
Chapters: Ch 0, Ch 20, Ch 23 -
[PHF14] Terence Parr, Sam Harwell, and Kathleen Fisher. Adaptive LL() parsing: the power of dynamic analysis.* OOPSLA 2014, 579–598, 2014. doi:10.1145/2660193.2660202
Why and when: Core reading. The ALL() algorithm of ANTLR 4: SLL simulation, full-LL fallback, DFA caching, the O(n⁴) bound and the linear-in-practice measurements quoted in Lesson 2.6 §5. Readable and precise; read all of it after Lesson 2.6, then open [ANTLR4-PATN].
Chapters:* Ch 2 -
[Pik87] Rob Pike. The text editor sam. Software—Practice and Experience 17(11), pp. 813–845, 1987.
Why and when: The editor whose regular-expression engine tracked submatches per NFA thread: the origin of the "Pike VM" of Lesson 1.2. Only the regular-expression section matters here; [Cox09] explains the engine in detail.
Note: Wiley journal article.
Chapters: Ch 1 -
[Pin93] Shlomit S. Pinter. Register Allocation with Instruction Scheduling: A New Approach. PLDI 1993, pp. 248–257, 1993. doi:10.1145/173262.155114
Why and when: The parallelizable interference graph (Definition 23.8.5, Theorem 23.8.6): a coloring that introduces no restricting false dependence.
Chapters: Ch 23 -
[PJVWS07] Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, and Mark Shields. Practical Type Inference for Arbitrary-Rank Types. Journal of Functional Programming 17(1), 1–82, 2007. doi:10.1017/S0956796806006034
Why and when: GHC'sRankNTypes: bidirectional checking, subsumption and skolemization, with a complete implementation in the appendix (Lesson 7.8). Read §1–6.
Chapters: Ch 7 -
[PKH03] David J. Pearce, Paul H. J. Kelly, and Chris Hankin. Online Cycle Detection and Difference Propagation for Pointer Analysis. SCAM 2003 (Third IEEE International Workshop on Source Code Analysis and Manipulation), pp. 3–12, 2003. doi:10.1109/SCAM.2003.1238030
Why and when: Cycle detection during solving by maintaining a topological order of the constraint graph (the Marchetti-Spaccamela / Pearce-Kelly dynamic ordering), plus difference propagation. The source of Lesson 19.4's "online" cycle detection; read §3–4 after Lesson 19.4 §6.
Note: DOI recorded from the proceedings; not re-resolved from the course container (doi.org is blocked there).
Chapters: Ch 19 -
[PKH07] David J. Pearce, Paul H. J. Kelly, and Chris Hankin. Efficient Field-Sensitive Pointer Analysis of C. ACM TOPLAS 30(1), article 4, 2007. doi:10.1145/1290520.1290524
Why and when: Field sensitivity for C with pointer arithmetic, modelled as constraints with offsets ("Pearce's model", Lesson 19.6), and the cycle and positive-weight-cycle problems it creates. Read §3–5 after Lesson 19.6 §2.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 19 -
[PKW14] Zvonimir Pavlinovic, Tim King, and Thomas Wies. Finding Minimum Type Error Sources. OOPSLA 2014, ACM International Conference on Object-Oriented Programming, Systems, Languages & Applications, 525–542, 2014. doi:10.1145/2660193.2660230
Why and when: Minimum error sources computed with a MaxSMT solver, with timings on OCaml programs (Lesson 7.9 §5). Read §1–4.
Chapters: Ch 7 -
[Plo75] Gordon D. Plotkin. Call-by-Name, Call-by-Value and the λ-Calculus. Theoretical Computer Science 1(2), pp. 125–159, 1975. doi:10.1016/0304-3975(75)90017-1
Why and when: The CPS transform and its correctness (simulation) theorems; the naive transform of Definition 8.6.2. Read the sections on the call-by-value CPS translation.
Chapters: Ch 8 -
[PM04] Jinpyo Park and Soo-Mook Moon. Optimistic Register Coalescing. ACM TOPLAS 26(4), 2004. doi:10.1145/1011508.1011512
Why and when: Coalesce aggressively and undo it for nodes that become actual spills; the alternative to conservative tests in Lesson 22.4 §6.
Chapters: Ch 22 -
[PM72] Paul W. Purdom Jr. and Edward F. Moore. Immediate Predominators in a Directed Graph. Communications of the ACM 15(8), pp. 777-778, 1972. doi:10.1145/361532.361566
Why and when: The "delete d and see what becomes unreachable" definition of dominance (Proposition 15.1.4) turned into an O(n·m) algorithm; the course's Python oracle dominators_by_removal is this idea. Two pages; read with Lesson 15.1 §6.
Chapters: Ch 15 -
[Pos46] Emil L. Post. A variant of a recursively unsolvable problem. Bulletin of the American Mathematical Society 52(4), 264–268, 1946. doi:10.1090/S0002-9904-1946-08555-9
Why and when: Post's correspondence problem, the undecidable problem that Theorem 2.1.12 reduces to grammar ambiguity. Read the problem statement only; the proof of its undecidability is covered more accessibly in [Sip12, §5.2].
Chapters: Ch 2 -
[Pot16] François Pottier. Reachability and error diagnosis in LR(1) parsers. Compiler Construction (CC 2016), 88–98, 2016. doi:10.1145/2892208.2892224
Why and when: Core reading. The algorithm behind menhir --list-errors: which error states are reachable and by which shortest inputs (Theorem 3.7.11). Read §1–3; the ✗ rows of Lesson 3.7 §3 are its motivating problem.
Chapters: Ch 3 -
[PP05] Fernando Magno Quintão Pereira and Jens Palsberg. Register Allocation via Coloring of Chordal Graphs. APLAS 2005 (LNCS), 2005. doi:10.1007/11575467_21
Why and when: Most interference graphs of Java methods are chordal even before SSA; a chordal-colouring allocator for JoeQ. Background for Lesson 22.6 §1.
Chapters: Ch 22 -
[PQ95] Terence J. Parr and Russell W. Quong. ANTLR: A predicated-LL(k) parser generator. Software: Practice and Experience 25(7), 789–810, 1995. doi:10.1002/spe.4380250705
Why and when: Syntactic and semantic predicates as a way out of LL(k) conflicts (Lesson 2.3 §6, Lesson 2.6 §6). Read the sections on predicates to see how they change what "the grammar" means.
Chapters: Ch 2 -
[Pra73] Vaughan R. Pratt. Top down operator precedence. POPL 1973, 41–51, 1973. doi:10.1145/512927.512931
Why and when: Binding powers instead of one nonterminal per precedence level: the hand-written alternative to layering (Lesson 2.1 §6, Lesson 2.5 §6), taught in full in Ch 4.
Chapters: Ch 2, Ch 4 -
[Pro59] Reese T. Prosser. Applications of Boolean Matrices to the Analysis of Flow Diagrams. Proc. Eastern Joint IRE-AIEE-ACM Computer Conference (1959), pp. 133-138, 1959. doi:10.1145/1460299.1460314
Why and when: Where "dominance" first appears, as a property of connectivity matrices of flow diagrams. Worth a skim after Lesson 15.1 §1 for history only; nothing in the chapter depends on it.
Chapters: Ch 15 -
[Pro92] Todd A. Proebsting. Simple and Efficient BURS Table Generation. PLDI 1992, 1992. doi:10.1145/143095.143145
Why and when: The worklist state construction with cost normalization and chain closure that Algorithm 21.3.5 and the lab's ch21-burg follow. Read §3 with Lesson 21.3 §2.
Chapters: Ch 21 -
[Pro95] Todd A. Proebsting. BURS Automata Generation. ACM TOPLAS 17(3), pp. 461–486, 1995. doi:10.1145/203095.203098
Why and when: The journal version: state trimming, representer states and the table sizes of real grammars (Proposition 21.3.11). Read §4–6 after Lesson 21.3 §5.
Chapters: Ch 21 -
[Pro98] Todd A. Proebsting. Least-Cost Instruction Selection in DAGs is NP-Complete. Unpublished note, Microsoft Research, 1998.
Why and when: The short SAT reduction behind Theorem 21.4.4. Read it (or [KG08, §2]) after Lesson 21.4 §2 and compare with the lesson's 3-SAT gadgets.
Note: Published only as a web page (research.microsoft.com/~toddpro/papers/proof.htm, now offline; archived copies exist). Koes and Goldstein [KG08] restate the reduction.
Chapters: Ch 21 -
[PS99] Massimiliano Poletto and Vivek Sarkar. Linear Scan Register Allocation. ACM TOPLAS 21(5), 1999. doi:10.1145/330249.330250
Why and when: Core reading. Algorithm 22.5.3 and its spill-furthest-end heuristic, with measurements against colouring. Short; implement E3 from §2.
Chapters: Ch 22 -
[PSS98] Amir Pnueli, Michael Siegel, and Eli Singerman. Translation Validation. TACAS 1998, LNCS 1384, pp. 151–166, 1998. doi:10.1007/BFb0054170
Why and when: Core reading. The idea of validating each compiler run instead of verifying the compiler, applied to the SIGNAL-to-C translator. Read §1–3 before Lesson 12.8 §2.
Chapters: Ch 12, Ch 13 -
[PT00] Benjamin C. Pierce and David N. Turner. Local Type Inference. ACM Transactions on Programming Languages and Systems 22(1), 1–44, 2000. doi:10.1145/345099.345100
Why and when: Core reading. Bidirectional checking ("local type propagation") plus local synthesis of type arguments, the design behind Scala and the target typing of Java and C#. Read §1–3 after Lesson 6.4 §1: the rules of §3 are the checking/synthesis split of Figure 6.4.2; §4 infers type arguments of polymorphic applications locally.
Chapters: Ch 6 -
[PTBD16] Phitchaya Mangpo Phothilimthana, Aditya Thakur, Rastislav Bodik, and Dinakar Dhurjati. Scaling up Superoptimization. ASPLOS 2016, pp. 297–310, 2016.
Why and when: Combines enumerative, stochastic and symbolic search with a "lens" that prunes by equivalence classes. Optional, after Lesson 13.3 §6.
Note: ACM Digital Library (ASPLOS '16).
Chapters: Ch 13 -
[Pug91] William Pugh. The Omega Test: a Fast and Practical Integer Programming Algorithm for Dependence Analysis. Supercomputing '91 (ACM/IEEE Conference on Supercomputing), 1991. doi:10.1145/125826.125848
Why and when: The Omega test: exact integer feasibility by extended Fourier–Motzkin elimination (Lesson 18.6, Algorithm 18.6.14).
Chapters: Ch 18 -
[Pug92] William Pugh. A Practical Algorithm for Exact Array Dependence Analysis. Communications of the ACM 35(8), pp. 102-114, 1992. doi:10.1145/135226.135233
Why and when: The journal presentation of the Omega test with dark and grey shadows; the more readable of the two for Lesson 18.6.
Chapters: Ch 18 -
[Pur72] Paul Purdom. A Sentence Generator for Testing Parsers. BIT Numerical Mathematics 12(3), pp. 366–375, 1972. doi:10.1007/BF01932308
Why and when: Generating a small set of sentences that together use every production of a grammar; the systematic counterpart of random derivation (Lesson 12.6 §6).
Chapters: Ch 12 -
[PVC01] Michael Paleczny, Christopher Vick, and Cliff Click. The Java HotSpot Server Compiler. USENIX Java Virtual Machine Research and Technology Symposium (JVM '01), 2001. pdf
Why and when: HotSpot's C2: an optimizing JIT with speculation and uncommon traps — the top tier in the HotSpot box of Lesson 0.3.
Chapters: Ch 0 -
[PW78] Michael S. Paterson and Mark N. Wegman. Linear Unification. Journal of Computer and System Sciences 16(2), 158–167, 1978.
Why and when: The strictly linear-time unification algorithm of Lesson 7.1 §6. Read it after the union-find algorithm to see what the last \(\alpha(n)\) factor costs to remove.
Note: Journal of Computer and System Sciences (Elsevier), volume 16, issue 2.
Chapters: Ch 7 -
[Ram02] G. Ramalingam. On Loops, Dominators, and Dominance Frontiers. ACM TOPLAS 24(5), pp. 455-490, 2002. doi:10.1145/570886.570887
Why and when: Core reading. The general definition of a loop nesting forest (Definition 15.5.6) and a comparison of Tarjan's, Havlak's, Steensgaard's and Sreedhar-Gao-Lee's forests; the best single paper to read after Lesson 15.5.
Chapters: Ch 15 -
[Ram22] Norman Ramsey. Beyond Relooper: Recursive Translation of Unstructured Control Flow to Structured Control Flow (Functional Pearl). Proc. ACM Program. Lang. 6 (ICFP), Article 90, 2022. doi:10.1145/3547621
Why and when: How to turn a reducible CFG into Wasm's block/loop/br nesting without duplicating code, driven by the dominator tree: the constructive half of Proposition 9.8.11. Read after Lesson 9.8 and Chapter 15.
Chapters: Ch 9 -
[Ram99] G. Ramalingam. Identifying Loops in Almost Linear Time. ACM TOPLAS 21(2), pp. 175-188, 1999. doi:10.1145/316686.316687
Why and when: Shows Havlak's bookkeeping can be quadratic (the pathological family of Lesson 15.5 §5) and restores the almost-linear bound; read §3.
Chapters: Ch 15 -
[Rau94] B. Ramakrishna Rau. Iterative Modulo Scheduling: An Algorithm for Software Pipelining Loops. MICRO-27, pp. 63–74, 1994. doi:10.1145/192724.192731
Why and when: Core reading. The algorithm the lab implements (Algorithm 23.6.9): HeightR priority, the MRT, eviction and the budget, with measurements on over 1300 loops. Read it before E4.
Chapters: Ch 23 -
[RC00] Atanas Rountev and Satish Chandra. Off-line Variable Substitution for Scaling Points-to Analysis. PLDI 2000, pp. 47–56, 2000. doi:10.1145/349299.349310
Why and when: The first offline pre-pass that merges pointer-equivalent variables before solving (Lesson 19.4 §6); [HL07b] generalizes it.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[RCC+12] John Regehr, Yang Chen, Pascal Cuoq, Eric Eide, Chucky Ellison, and Xuejun Yang. Test-Case Reduction for C Compiler Bugs. PLDI 2012, pp. 335–346, 2012. doi:10.1145/2254064.2254104
Why and when: C-Reduce: domain-specific transformation passes iterated to a fixpoint, compared with delta debugging, and the problem of reductions that introduce undefined behavior. Read after Lesson 12.7 §2.
Chapters: Ch 12 -
[Rei60] George W. Reitwiesner. Binary Arithmetic. Advances in Computers, vol. 1, Academic Press, pp. 231–308, 1960.
Why and when: Introduces the non-adjacent form of signed-digit representations (Definition 13.7.1). Historical; Proposition 13.7.8 contains what the lesson needs.
Note: Book chapter in Advances in Computers 1.
Chapters: Ch 13 -
[Rep98] Thomas Reps. "Maximal-munch" tokenization in linear time. ACM Transactions on Programming Languages and Systems 20(2), pp. 259–273, 1998. doi:10.1145/276393.276394
Why and when: Core reading. Shows that naive maximal munch is quadratic in the worst case and gives the memoized linear-time algorithm (Algorithm 1.6.7, Theorem 1.6.10). Short and readable; read §2–3 after Lesson 1.6.
Chapters: Ch 1 -
[Rey02] John C. Reynolds. Separation Logic: A Logic for Shared Mutable Data Structures. LICS 2002, pp. 55–74, 2002. doi:10.1109/LICS.2002.1029817
Why and when: The separating conjunction and list-segment predicates behind separation-logic shape analyses (Infer). Read §1–3 after Lesson 19.9 §6.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[RG81] B. R. Rau and C. D. Glaeser. Some Scheduling Techniques and an Easily Schedulable Horizontal Architecture for High Performance Scientific Computing. 14th Annual Workshop on Microprogramming (MICRO-14), pp. 183–198, 1981.
Why and when: The first modulo scheduler and the resource bound ResMII (Definition 23.6.3), with the polycyclic architecture it targeted.
Note: In the MICRO-14 proceedings (ACM/IEEE), 1981.
Chapters: Ch 23 -
[RHS95] Thomas Reps, Susan Horwitz, and Mooly Sagiv. Precise Interprocedural Dataflow Analysis via Graph Reachability. POPL 1995, pp. 49-61, 1995. doi:10.1145/199448.199462
Why and when: Core reading. IFDS: exploded supergraphs, realizable paths and the tabulation algorithm (Lesson 14.8, Definitions 14.8.6–14.8.7, Algorithm 14.8.8, Theorem 14.8.9). Read §2–4.
Chapters: Ch 14, Ch 20 -
[RL70] Daniel J. Rosenkrantz and Philip M. Lewis II. Deterministic left corner parsing. IEEE Conference Record of the 11th Annual Symposium on Switching and Automata Theory, 139–152, 1970.
Why and when: The left-corner transform, the polynomial-size alternative to Paull's algorithm mentioned in Lesson 2.4 §6. Background reading.
Note: IEEE SWAT 1970 proceedings; available in IEEE Xplore.
Chapters: Ch 2 -
[RL77] John H. Reif and Harry R. Lewis. Symbolic Evaluation and the Global Value Graph. POPL 1977, pp. 104–118, 1977.
Why and when: Sparse constant propagation over def-use ("global value graph") edges instead of program points: the "sparse simple constant" algorithm of Lesson 17.1 §2. Read §2 for the graph, skip the symbolic-evaluation generalization on a first pass.
Note: ACM Digital Library; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[RL86] John H. Reif and Harry R. Lewis. Efficient Symbolic Analysis of Programs. Journal of Computer and System Sciences 32(3), pp. 280–314, 1986.
Why and when: The journal version of [RL77] with the complexity analysis quoted in Lesson 17.1 §5; optional reading.
Note: ScienceDirect; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[RMBS20] Nico Reissmann, Jan Christian Meyer, Helge Bahmann, and Magnus Själander. RVSDG: An Intermediate Representation for Optimizing Compilers. ACM Transactions on Embedded Computing Systems 19(6), Article 49, 2020. doi:10.1145/3391902
Why and when: Core reading. The regionalized VSDG: γ/θ/λ/δ/φ nodes with acyclic regions, construction from a CFG with restructuring, and simple optimizations on it. Read the definitions with Lesson 8.5 §2 and the construction section for the restructuring cost.
Chapters: Ch 8 -
[Rob65] J. A. Robinson. A Machine-Oriented Logic Based on the Resolution Principle. Journal of the ACM 12(1), 23–41, 1965. doi:10.1145/321250.321253
Why and when: Core reading. The origin of unification and of the most general unifier. Read §5 (the unification algorithm and its theorem) after Lesson 7.1 §2; the resolution part is optional for this chapter.
Chapters: Ch 7 -
[RR94] G. Ramalingam and Thomas Reps. An Incremental Algorithm for Maintaining the Dominator Tree of a Reducible Flowgraph. Proc. 21st ACM Symposium on Principles of Programming Languages (POPL), pp. 287-296, 1994. doi:10.1145/174675.177905
Why and when: The first incremental dominator algorithm, restricted to reducible flowgraphs; its insertion lemma is the ancestor of Lemma 15.2.3. Read §3 after Lesson 15.2 for the history.
Chapters: Ch 15 -
[RS59] Michael O. Rabin and Dana Scott. Finite automata and their decision problems. IBM Journal of Research and Development 3(2), pp. 114–125, 1959. doi:10.1147/rd.32.0114
Why and when: Core reading. Introduces nondeterministic automata and the subset construction (Algorithm 1.2.5, Theorem 1.2.10). Read §4–5 after Lesson 1.2 §2; the rest (decision problems, two-way automata) is optional.
Chapters: Ch 1 -
[RS70] Daniel J. Rosenkrantz and Richard E. Stearns. Properties of deterministic top-down grammars. Information and Control 17(3), 226–256, 1970. doi:10.1016/S0019-9958(70)90446-8
Why and when: Core reading. The standard reference for LL(k) theory: strong LL(k) versus LL(k) (Theorem 2.6.12), the local-follow-set tables of full LL(k) (Algorithm 2.6.6), and the equivalence of LL(1) with conflict-free tables (Theorem 2.3.8). Read it after Lesson 2.6, starting with the definitions and the strong-vs-full example.
Chapters: Ch 2 -
[RSL08] Laurence Rideau, Bernard Paul Serpette, and Xavier Leroy. Tilting at Windmills with Coq: Formal Verification of a Compilation Algorithm for Parallel Moves. Journal of Automated Reasoning 40(4), 2008.
Why and when: A mechanically verified parallel-move sequentializer (the one CompCert uses) and the "windmill" picture of copy graphs behind Lesson 16.7's algorithm; read it for the algorithm and its invariant.
Note: Look it up by title in the SpringerLink (DOI not re-checked from the course container).
Chapters: Ch 16 -
[RSS15] Erven Rohou, Bharath Narasimha Swamy, and André Seznec. Branch Prediction and the Performance of Interpreters — Don't Trust Folklore. CGO 2015, pp. 103–114, 2015. doi:10.1109/CGO.2015.7054191
Why and when: Shows that modern predictors (ITTAGE-like, with global history) predict switch dispatch far better than the last-target model of Definition 0.2.9 assumes; a necessary correction to 2000s folklore. Read after measuring the lab's switch vs threaded VMs.
Chapters: Ch 0 -
[RTD83] Thomas Reps, Tim Teitelbaum, and Alan Demers. Incremental context-dependent analysis for language-based editors. ACM TOPLAS 5(3), 449–477, 1983. doi:10.1145/2166.357218
Why and when: Optimal incremental attribute evaluation after a subtree replacement: the ancestor of red–green marking and early cutoff (Lesson 5.6 §4). Read §1–3 after Lesson 5.6.
Chapters: Ch 5 -
[RvAPKV20] Arjen Rouvoet, Hendrik van Antwerpen, Casper Bach Poulsen, Robbert Krebbers, and Eelco Visser. Knowing when to ask: sound scheduling of name resolution in type checkers derived from declarative specifications. Proc. ACM Program. Lang. 4 (OOPSLA), Article 180, 2020. doi:10.1145/3428248
Why and when: When is a scope-graph query's answer final while the graph is still being built? Critical edges answer it, the principled version of the "undetermined import" of Algorithm 5.3.4. Read §2–3 after Lesson 5.3 §6.
Chapters: Ch 5 -
[RWZ88] Barry K. Rosen, Mark N. Wegman, and F. Kenneth Zadeck. Global Value Numbers and Redundant Computations. POPL 1988, pp. 12–27, 1988. doi:10.1145/73560.73562
Why and when: The companion paper to [AWZ88]: SSA names and phi functions as the basis of global redundancy elimination. Historical background for Lesson 8.4.
Chapters: Ch 8, Ch 16, Ch 17 -
[Sal81] Arthur Sale. The Implementation of Case Statements in Pascal. Software—Practice and Experience 11(9), 1981.
Why and when: When a jump table is worth its space for Pascalcasestatements; the density argument of Lesson 11.3 §1 and Algorithm 11.3.3.
Note: Wiley journal; no DOI was re-resolved from the course container — find it by title in the journal's 1981 volume.
Chapters: Ch 11 -
[SB06] Manu Sridharan and Rastislav Bodík. Refinement-Based Context-Sensitive Points-to Analysis for Java. PLDI 2006, pp. 387–400, 2006. doi:10.1145/1133981.1134027
Why and when: Points-to as CFL reachability (matched field and call parentheses), answered on demand and refined only where the client needs more precision, under a budget. Read §3–4 after Lesson 19.8 §2.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[SBL11] Yannis Smaragdakis, Martin Bravenboer, and Ondřej Lhoták. Pick Your Contexts Well: Understanding Object-Sensitivity. POPL 2011, pp. 17–30, 2011. doi:10.1145/1926385.1926390
Why and when: A uniform model of context sensitivity that explains object sensitivity and introduces type sensitivity (contexts are the classes enclosing allocation sites). Read §3–5 after Lesson 19.7.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[SCC+17] Raimondas Sasnauskas, Yang Chen, Peter Collingbourne, Jeroen Ketema, Gratian Lup, Jubi Taneja, and John Regehr. Souper: A Synthesizing Superoptimizer. arXiv:1711.04422, 2017. link
Why and when: Core reading. How Souper extracts dataflow fragments from LLVM IR and synthesizes cheaper refinements with an SMT solver, and which missing LLVM optimizations it found. Read §2–4 after Lesson 13.3; the README of the Souper repository points to this paper.
Chapters: Ch 13 -
[Sch07] Sylvain Schmitz. Conservative ambiguity detection in context-free grammars. ICALP 2007, LNCS 4596, 692–703, 2007. doi:10.1007/978-3-540-73420-8_60
Why and when: The approximation approach to ambiguity detection (always terminates, may report false positives), the variant contrasted with bounded search in Lesson 2.1 §6. Read the introduction and the definition of the approximation.
Chapters: Ch 2 -
[Sch77] Robert W. Scheifler. An Analysis of Inline Substitution for a Structured Programming Language. Communications of the ACM 20(9), pp. 647–654, 1977. doi:10.1145/359810.359830
Why and when: Inlining under a size budget as a knapsack-like optimization problem, with a greedy heuristic. Read §2–3 after Lesson 20.3 §2 (Definition 20.3.3 and Theorem 20.3.4).
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 20 -
[Sch90] Douglas C. Schmidt. GPERF: A Perfect Hash Function Generator. Proceedings of the 2nd C++ Conference (USENIX), San Francisco, pp. 87–102, 1990. pdf
Why and when: Core reading. The design of gperf: key positions, associated values, the search, and the generated lookup code (Definition 1.8.2, Algorithm 1.8.6). Read §2–4 while looking at the gperf output in Lesson 1.8's real-world box.
Chapters: Ch 1 -
[Sco08] Elizabeth Scott. SPPF-style parsing from Earley recognisers. Electronic Notes in Theoretical Computer Science 203(2), 53–67, 2008. doi:10.1016/j.entcs.2008.03.044
Why and when: Shared packed parse forests: one polynomial-size structure for all parse trees of an ambiguous sentence (Lesson 2.1 §6). Read the SPPF definition; the Earley part belongs to Ch 4.
Chapters: Ch 2, Ch 4 -
[SD96] S. Doaitse Swierstra and Luc Duponcheel. Deterministic, error-correcting combinator parsers. Advanced Functional Programming 1996, LNCS 1129, 184–207, 1996. doi:10.1007/3-540-61628-4_7
Why and when: Applicative combinators that can be analyzed before running, with error correction (Lesson 4.5 §6). Read after Lesson 4.5 to see what giving up>>=buys.
Chapters: Ch 4 -
[SE02] Bernhard Scholz and Erik Eckstein. Register Allocation for Irregular Architectures. LCTES/SCOPES 2002, pp. 139–148, 2002. doi:10.1145/513829.513854
Why and when: Core reading. PBQP as a model of register allocation and the R0/RI/RII/RN reduction solver (Algorithm 22.7.3). Read §3–4 with the drillpbqp.
Chapters: Ch 22 -
[Ser16] Kostya Serebryany. Continuous Fuzzing with libFuzzer and AddressSanitizer. IEEE Cybersecurity Development (SecDev) 2016, p. 157, 2016. doi:10.1109/SecDev.2016.043
Why and when: libFuzzer's author on in-process, coverage-guided fuzzing combined with sanitizers as a continuous service. Short; read with Lesson 12.6 §7.
Chapters: Ch 12 -
[Set75] Ravi Sethi. Complete Register Allocation Problems. SIAM Journal on Computing 4(3), pp. 226–248, 1975. doi:10.1137/0204020
Why and when: Minimizing registers for a DAG's evaluation order is NP-complete (Lesson 23.3 §4): why pressure-aware schedulers are heuristics.
Chapters: Ch 23 -
[SG95] Vugranam C. Sreedhar and Guang R. Gao. A Linear Time Algorithm for Placing φ-Nodes. Proc. 22nd ACM Symposium on Principles of Programming Languages (POPL), pp. 62-73, 1995. doi:10.1145/199448.199464
Why and when: The linear-time DF+ computation behind LLVM's IDFCalculator, whichmem2regcalls; read it if Lesson 11.1 §5's cost of phi placement needs justifying.
Chapters: Ch 11, Ch 15, Ch 16 -
[SGBE05] Yunhe Shi, David Gregg, Andrew Beatty, and M. Anton Ertl. Virtual Machine Showdown: Stack Versus Registers. VEE 2005, pp. 153–163, 2005. doi:10.1145/1064979.1065001 · pdf
Why and when: Translates JVM stack code to register code; the abstract reports that more than 47% of executed VM instructions are eliminated, code grows by roughly 25%, and execution time with switch dispatch on a Pentium 4 drops by 32.3% — the empirical basis of Lesson 0.2's register-VM comparison (the 2008 TACO journal version reports 46% and 26%). Read the abstract and the dynamic instruction counts in the evaluation.
Chapters: Ch 0, Ch 8 -
[SGL96] Vugranam C. Sreedhar, Guang R. Gao, and Yong-Fong Lee. Identifying Loops Using DJ Graphs. ACM TOPLAS 18(6), pp. 649-658, 1996. doi:10.1145/236114.236115
Why and when: Uses the DJ graph of Lesson 15.3 to find reducible and irreducible loops in one framework; read with Lesson 15.5 §6 as the bridge between frontiers and loop forests.
Chapters: Ch 15 -
[SGL97] Vugranam C. Sreedhar, Guang R. Gao, and Yong-Fong Lee. Incremental Computation of Dominator Trees. ACM TOPLAS 19(2), pp. 239-252, 1997. doi:10.1145/244795.244799
Why and when: Updates dominator trees and DJ graphs together under edge insertions and deletions, using dominance frontiers to find affected nodes; the alternative Lesson 15.2 §6 compares with DBS.
Chapters: Ch 15 -
[Sha80] Micha Sharir. Structural analysis: A new approach to flow analysis in optimizing compilers. Computer Languages 5(3-4), pp. 141-153, 1980. doi:10.1016/0096-0551(80)90007-7
Why and when: The origin of structural analysis (Lesson 14.5, Algorithm 14.5.9): region schemas, the control tree, summaries per schema.
Chapters: Ch 14 -
[Sha81] Micha Sharir. A strong-connectivity algorithm and its applications in data flow analysis. Computers & Mathematics with Applications 7(1), pp. 67–72, 1981. doi:10.1016/0898-1221(81)90008-0
Why and when: The two-pass (Kosaraju–Sharir) SCC algorithm, which emits SCCs in topological order. Read after Lesson 20.2 §6 for the contrast with Tarjan's bottom-up order.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 20 -
[Shi88] Olin Shivers. Control-Flow Analysis in Scheme. PLDI 1988, pp. 164–174, 1988. doi:10.1145/53990.54007
Why and when: k-CFA: contexts as the last k call sites. The name and the parameter k of Lesson 19.7's call-string sensitivity come from here.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[SHPJV20] Alejandro Serrano, Jurriaan Hage, Simon Peyton Jones, and Dimitrios Vytiniotis. A Quick Look at Impredicativity. Proceedings of the ACM on Programming Languages 4 (ICFP 2020), Article 89, 2020. doi:10.1145/3408971
Why and when: Quick Look (Algorithm 7.8.4), GHC's impredicative instantiation since 9.2, with the soundness and conservativity results of Theorem 7.8.7a. Read §1–4.
Chapters: Ch 7 -
[SHR+00] Vijay Sundaresan, Laurie Hendren, Chrislain Razafimahefa, Raja Vallée-Rai, Patrick Lam, Étienne Gagnon, and Charles Godin. Practical Virtual Method Call Resolution for Java. OOPSLA 2000, pp. 264–280, 2000. doi:10.1145/353171.353189
Why and when: Variable type analysis (VTA) and declared type analysis in Soot: a type propagation graph over variables. Read §3 with Lesson 20.1's VTA and the Soot box of §7.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[SJ06] Elizabeth Scott and Adrian Johnstone. Right nulled GLR parsers. ACM TOPLAS 28(4), 577–618, 2006. doi:10.1145/1146809.1146810
Why and when: Core reading. RNGLR: right-nullable reductions make Tomita's algorithm correct for all context-free grammars (Theorem 3.6.9). Read §2–4.
Chapters: Ch 3 -
[SJ10] Elizabeth Scott and Adrian Johnstone. GLL parsing. Electronic Notes in Theoretical Computer Science 253(7), 177–189, 2010. doi:10.1016/j.entcs.2010.08.041
Why and when: Core reading. The origin of generalized LL parsing: descriptors, the GSS and the popped set of Definition 4.4.4 and Algorithm 4.4.5. Read §3–4 after Lesson 4.4 §2.
Chapters: Ch 4 -
[SJ13] Elizabeth Scott and Adrian Johnstone. GLL parse-tree generation. Science of Computer Programming 78(10), 1828–1844, 2013. doi:10.1016/j.scico.2012.03.005
Why and when: GLL with binarized SPPF construction and the cubic bound of Theorem 4.4.11. Read after the recognizer paper [SJ10].
Chapters: Ch 4 -
[SJE07] Elizabeth Scott, Adrian Johnstone, and Rob Economopoulos. BRNGLR: a cubic Tomita-style GLR parsing algorithm. Acta Informatica 44(6), 427–461, 2007. doi:10.1007/s00236-007-0054-z
Why and when: Binarized reductions bring GLR's worst case to O(n^3) (Theorem 3.6.9, Lesson 3.6 §5). Read the introduction and the complexity section.
Chapters: Ch 3 -
[SJGS99] Vugranam C. Sreedhar, Roy Dz-Ching Ju, David M. Gillies, and Vatsa Santhanam. Translating Out of Static Single Assignment Form. Static Analysis Symposium (SAS 1999), LNCS 1694, 1999. doi:10.1007/3-540-48294-6_13
Why and when: Core reading. Conventional SSA, phi congruence classes, and three methods to reach CSSA before dropping the phis: I (copy everything), II (copy where interference graphs say so), III (copy only where live ranges really interfere). Lesson 16.6 §2-4 follows its definitions.
Chapters: Ch 16 -
[SL14] Martin Sulzmann and Kenny Zhuo Ming Lu. POSIX regular expression parsing with derivatives. Functional and Logic Programming (FLOPS 2014), LNCS 8475, Springer, pp. 203–220, 2014.
Why and when: Uses derivatives to compute POSIX (longest-leftmost) parse trees: the connection between maximal munch (Lesson 1.6) and regular-expression parsing. Further reading after Lessons 1.3 and 1.6.
Note: Springer LNCS conference paper.
Chapters: Ch 1 -
[SP81] Micha Sharir and Amir Pnueli. Two Approaches to Interprocedural Data Flow Analysis. In S. Muchnick and N. Jones (eds.), Program Flow Analysis: Theory and Applications, Prentice-Hall, pp. 189–234, 1981.
Why and when: The call-string and functional (summary) approaches to interprocedural analysis, the two poles of Lesson 19.7. Read §3 (call strings) and §4 (functional approach).
Note: A book chapter; no DOI. Available in university libraries.
Chapters: Ch 19, Ch 20 -
[Spe88] David Spector. Efficient full LR(1) parser generation. ACM SIGPLAN Notices 23(12), 143–150, 1988.
Why and when: Splitting LALR states on demand where conflicts appear — a simpler predecessor of IELR (Lesson 3.4 §6). Optional.
Note: SIGPLAN Notices 23(12), 1988; ACM Digital Library.
Chapters: Ch 3 -
[SPL+23] Han Shen, Krzysztof Pszeniczny, Rahman Lavaee, Snehasish Kumar, Sriraman Tallam, and Xinliang David Li. Propeller: A Profile Guided, Relinking Optimizer for Warehouse-Scale Applications. ASPLOS 2023, pp. 617–631, 2023. doi:10.1145/3575693.3575727
Why and when: Post-link layout moved into the compiler and linker with basic-block sections, designed for distributed builds. Read §3–4 with Lesson 20.10's basic-block-sections box.
Chapters: Ch 20, Ch 23 -
[SRH04] Michael D. Smith, Norman Ramsey, and Glenn Holloway. A Generalized Algorithm for Graph-Coloring Register Allocation. PLDI 2004, pp. 277–288, 2004. doi:10.1145/996841.996875 · pdf
Why and when: Colouring for irregular register files with aliasing and pairs: generalizes the degree test by counting how many registers each neighbour can block (Lesson 22.1 §6, Lesson 22.3 §6).
Chapters: Ch 22 -
[SRH96] Mooly Sagiv, Thomas Reps, and Susan Horwitz. Precise Interprocedural Dataflow Analysis with Applications to Constant Propagation. Theoretical Computer Science 167(1-2), pp. 131-170, 1996. doi:10.1016/0304-3975(96)00072-2
Why and when: IDE: environment transformers with micro-functions on exploded edges, linear constant propagation (Lesson 14.8, Definition 14.8.10). Read after RHS95.
Chapters: Ch 14, Ch 20 -
[SRW02] Mooly Sagiv, Thomas Reps, and Reinhard Wilhelm. Parametric Shape Analysis via 3-Valued Logic. ACM TOPLAS 24(3), pp. 217–298, 2002. doi:10.1145/514188.514190
Why and when: Shape analysis with three-valued logical structures, summary nodes and focus/blur (TVLA). Read §2–4 after Lesson 19.9 §2; the rest is for specialists.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 19 -
[SSA13] Eric Schkufza, Rahul Sharma, and Alex Aiken. Stochastic Superoptimization. ASPLOS 2013, pp. 305–316, 2013.
Why and when: STOKE: Metropolis–Hastings search over x86-64 programs with a cost of correctness plus performance (Algorithm 13.3.5, Theorem 13.3.10). Read §3 (the cost function and the proposal distribution) after Lesson 13.3.
Note: ACM Digital Library (ASPLOS '13).
Chapters: Ch 13 -
[ST06] Jeremy G. Siek and Walid Taha. Gradual Typing for Functional Languages. Scheme and Functional Programming Workshop 2006, 81–92, 2006. link
Why and when: Core reading. The origin of gradual typing: the dynamic type ?, the consistency relation and compilation to a cast calculus. Read it after Lesson 6.7 §2: Definition 6.7.2 and Algorithm 6.7.4 are its consistency relation and cast insertion, for a smaller language.
Chapters: Ch 6 -
[ST85] Daniel D. Sleator and Robert E. Tarjan. Amortized Efficiency of List Update and Paging Rules. Communications of the ACM 28(2), pp. 202–208, 1985. doi:10.1145/2786.2793
Why and when: Competitive analysis of paging: LRU is K-competitive and no deterministic online rule does better. Read the paging section after Lesson 22.2 §6 to see why local allocators that cannot look ahead lose to MIN.
Chapters: Ch 22 -
[Ste77] Guy Lewis Steele Jr.. Debunking the "Expensive Procedure Call" Myth, or, Procedure Call Implementations Considered Harmful, or, LAMBDA: The Ultimate GOTO. Proceedings of the 1977 ACM Annual Conference, pp. 153–162, 1977. doi:10.1145/800179.810196
Why and when: Tail calls as jumps that pass arguments, and why a compiler should compile them so. Read §1–3 with Lesson 20.8's tail-call elimination.
Note: DOI recorded from the proceedings; not re-resolved from the course container. Also MIT AI Memo 443.
Chapters: Ch 20 -
[Ste96] Bjarne Steensgaard. Points-to Analysis in Almost Linear Time. POPL 1996, pp. 32–41, 1996. doi:10.1145/237721.237727
Why and when: Core reading. The origin of unification-based points-to analysis: a type system whose inference is union-find, with conditional joins for non-pointers and λ types for functions. Read §3–5 after Lesson 19.5 §2; the lab's signatures for indirect calls are its λ types.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[Str00] Christopher Strachey. Fundamental Concepts in Programming Languages. Higher-Order and Symbolic Computation 13(1–2), pp. 11–49 (lecture notes from 1967), 2000. doi:10.1023/A:1010000313106
Why and when: Where L-values and R-values come from: an expression denotes a location or its contents, and the left of an assignment is evaluated for its location. Read §3.3 with Lesson 11.4 §1.
Note: DOI recorded from the journal; not re-resolved from the course container.
Chapters: Ch 11 -
[SU70] Ravi Sethi and Jeffrey D. Ullman. The Generation of Optimal Code for Arithmetic Expressions. Journal of the ACM 17(4), pp. 715–728, 1970. doi:10.1145/321607.321620
Why and when: Proves optimality of Ershov-style evaluation order for register machines; the rigorous background of Theorem 0.2.14 (and of instruction selection in Ch 21).
Chapters: Ch 0, Ch 21, Ch 23 -
[SVCB15] Jeremy G. Siek, Michael M. Vitousek, Matteo Cimini, and John Tang Boyland. Refined Criteria for Gradual Typing. SNAPL 2015, LIPIcs 32, 274–293, 2015. doi:10.4230/LIPIcs.SNAPL.2015.274
Why and when: The gradual guarantee (static and dynamic) of Theorem 6.7.7, which the lab tests on its corpus. Read §4 after Lesson 6.7 §4.
Chapters: Ch 6 -
[SVE17] Nigel Stephens, Stuart Biles, Matthias Boettcher, Jacob Eapen, Mbou Eyole, Giacomo Gabrielli, Matt Horsnell, Grigorios Magklis, Alejandro Martinez, Nathanael Premillieu, Alastair Reid, Alejandro Rico, and Paul Walker. The ARM Scalable Vector Extension. IEEE Micro 37(2), pp. 26-39, 2017. doi:10.1109/MM.2017.35
Why and when: Vector-length-agnostic code, predicates andwhilelo: the hardware behind Lesson 18.8's scalable-vector box.
Chapters: Ch 18 -
[SWT+58] J. Strong, J. Wegstein, A. Tritter, J. Olsztyn, O. Mock, and T. Steel. The Problem of Programming Communication with Changing Machines: A Proposed Solution. Communications of the ACM 1(8), pp. 12–18, 1958. doi:10.1145/368892.368915
Why and when: The UNCOL proposal: one universal intermediate language turns m × n translators into m + n (Theorem 0.4.2). A historical read for Lesson 0.4 §1.
Chapters: Ch 0 -
[SX16] Yulei Sui and Jingling Xue. SVF: Interprocedural Static Value-Flow Analysis in LLVM. CC 2016, pp. 265–266, 2016. doi:10.1145/2892208.2892235
Why and when: The SVF framework whose Andersen (wave, diff), flow-sensitive and demand-driven solvers Lessons 19.4, 19.6 and 19.8 quote. A two-page tool paper; the SVF wiki has the details.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[Szy78] Thomas G. Szymanski. Assembling Code for Machines with Span-Dependent Instructions. Communications of the ACM 21(4), pp. 300–308, 1978. doi:10.1145/359460.359474
Why and when: Span-dependent instructions: an efficient optimal algorithm for label operands and an NP-completeness proof for general expressions (Theorem 21.10.7, Proposition 21.10.8). Read it after Lesson 21.10 §2.
Chapters: Ch 21 -
[Tar55] Alfred Tarski. A lattice-theoretical fixpoint theorem and its applications. Pacific Journal of Mathematics 5(2), 285–309, 1955. doi:10.2140/pjm.1955.5.285
Why and when: The Knaster–Tarski theorem: a monotone function on a complete lattice has a least fixed point. Lesson 2.2 uses it (Theorem 2.2.4) to say that nullable, FIRST and FOLLOW are well defined. Read the statement of Theorem 1; Ch 14 uses it again.
Chapters: Ch 2, Ch 14 -
[Tar72] Robert E. Tarjan. Depth-first search and linear graph algorithms. SIAM Journal on Computing 1(2), 146–160, 1972. doi:10.1137/0201010
Why and when: Strongly connected components in one depth-first search, the engine of the digraph algorithm (Algorithm 2.2.9). Read the SCC section; Ch 15 reuses the paper for dominators.
Chapters: Ch 2, Ch 3, Ch 8, Ch 15, Ch 18, Ch 20 -
[Tar74] Robert Endre Tarjan. Testing Flow Graph Reducibility. Journal of Computer and System Sciences 9(3), pp. 355-365, 1974. doi:10.1016/S0022-0000(74)80049-8
Why and when: Core reading. The almost-linear loop-nesting / reducibility test with union-find (Algorithm 15.5.8) that Havlak later extended; read §2-3 after Lesson 15.5 §2.
Chapters: Ch 15 -
[Tar75] Robert Endre Tarjan. Efficiency of a Good But Not Linear Set Union Algorithm. Journal of the ACM 22(2), 215–225, 1975. doi:10.1145/321879.321884
Why and when: The inverse-Ackermann bound for union by rank with path compression that Lesson 7.1 §5 uses for union-find unification. Read the statement of the main theorem; the proof is optional.
Chapters: Ch 7, Ch 19 -
[Tar81a] Robert Endre Tarjan. A Unified Approach to Path Problems. Journal of the ACM 28(3), pp. 577-593, 1981. doi:10.1145/322261.322272
Why and when: Core reading. Path expressions and their interpretation in an algebra (Lesson 14.5, Definition 14.5.10 and Theorem 14.5.12): one framework for shortest paths, reachability and dataflow.
Chapters: Ch 14 -
[Tar81b] Robert Endre Tarjan. Fast Algorithms for Solving Path Problems. Journal of the ACM 28(3), pp. 594-614, 1981. doi:10.1145/322261.322273
Why and when: Computing path expressions in O(e α(e, n)) on reducible graphs through the dominator tree; the best elimination bound quoted in Lesson 14.5 §5.
Chapters: Ch 14 -
[TFGNVF16] Asumu Takikawa, Daniel Feltey, Ben Greenman, Max S. New, Jan Vitek, and Matthias Felleisen. Is Sound Gradual Typing Dead?. POPL 2016, 43rd ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, 456–468, 2016. doi:10.1145/2837614.2837630
Why and when: The performance lattice method and its sobering result for Typed Racket: some partially typed configurations run orders of magnitude slower than untyped ones. Read §2 and §5 after Lesson 6.7 §5; it is the source of the whole-program cost in the lesson's §5 and §8.
Chapters: Ch 6 -
[THEAG04] Mads Torgersen, Christian Plesner Hansen, Erik Ernst, Peter von der Ahé, Gilad Bracha, and Neal Gafter. Adding Wildcards to the Java Programming Language. SAC 2004, ACM Symposium on Applied Computing, 1289–1296, 2004. doi:10.1145/967900.968162
Why and when: The design of? extends/? superand wildcard capture as it shipped in Java 5. Read it after the javac box of Lesson 6.5; the "CAP#1" in that output is its capture conversion.
Chapters: Ch 6 -
[THF08] Sam Tobin-Hochstadt and Matthias Felleisen. The Design and Implementation of Typed Scheme. POPL 2008, 35th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, 395–406, 2008. doi:10.1145/1328438.1328486
Why and when: Occurrence typing: the type of a variable depends on the predicates that guard its occurrence. Read §3 (the formal system with latent predicates) after Lesson 6.6 §2.
Chapters: Ch 6 -
[THF10] Sam Tobin-Hochstadt and Matthias Felleisen. Logical Types for Untyped Languages. ICFP 2010, 15th ACM SIGPLAN International Conference on Functional Programming, 117–128, 2010. doi:10.1145/1863543.1863561
Why and when: Occurrence typing recast with propositions: every expression carries "then" and "else" propositions, combined byand/or/notexactly as Algorithm 6.6.3 combines the (true, false) states. Read §3–4 after Lesson 6.6 §4.
Chapters: Ch 6 -
[Tho68] Ken Thompson. Programming Techniques: Regular expression search algorithm. Communications of the ACM 11(6), pp. 419–422, 1968. doi:10.1145/363347.363387
Why and when: Core reading. Four pages that introduce both Thompson's construction (Algorithm 1.1.6) and the simulation of all NFA states at once (Algorithm 1.2.4), compiled to IBM 7094 code for the QED editor. Read after Lesson 1.2 §2; the code is dated, the idea is not.
Chapters: Ch 1 -
[Tho84] Ken Thompson. Reflections on Trusting Trust. Communications of the ACM 27(8), pp. 761–763, 1984. doi:10.1145/358198.358210
Why and when: Core reading. The Turing Award lecture describing a compiler binary that backdoorsloginand reinserts itself when compiling the compiler (Definition 0.5.9). Three pages; read it in full.
Chapters: Ch 0 -
[THS98] Omri Traub, Glenn Holloway, and Michael D. Smith. Quality and Speed in Linear-scan Register Allocation. PLDI 1998, 1998. doi:10.1145/277650.277714
Why and when: Second-chance binpacking: pack into lifetime holes, give spilled values a register again at the next use, and resolve locations on edges (Algorithm 22.5.7). Read §3–4.
Chapters: Ch 22 -
[Tof90] Mads Tofte. Type Inference for Polymorphic References. Information and Computation 89(1), 1–34, 1990.
Why and when: Imperative type variables, the SML '90 solution that the value restriction replaced (Lesson 7.3 §6). Read §1–2 for the counterexample of Proposition 7.3.9.
Note: Information and Computation (Elsevier), volume 89, issue 1.
Chapters: Ch 7 -
[TP00] Frank Tip and Jens Palsberg. Scalable Propagation-Based Call Graph Construction Algorithms. OOPSLA 2000, pp. 281–293, 2000. doi:10.1145/353171.353190
Why and when: The family CTA, MTA, FTA and XTA between RTA and 0-CFA: one type set per method, field or class. Read §3 with Lesson 20.1's XTA (Algorithm 20.1.8), the lab's ★ milestone.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 20 -
[TP95] Peng Tu and David Padua. Efficient Building and Placing of Gating Functions. Proc. ACM SIGPLAN PLDI 1995, 1995.
Why and when: Builds gating functions for arbitrary reducible CFGs with gating path expressions; Lesson 16.8's Algorithm 16.8.6 is the structured special case. Read it for the general construction.
Note: Look it up by title in the ACM Digital Library (DOI not re-checked from the course container).
Chapters: Ch 16 -
[TQB+21] Mircea Trofin, Yundi Qian, Eugene Brevdo, Zinan Lin, Krzysztof Choromanski, and David Li. MLGO: a Machine Learning Guided Compiler Optimizations Framework. arXiv preprint 2101.04808, 2021. link
Why and when: Learned heuristics inside a fixed pipeline (the inliner's decision, register eviction) as opposed to learned pass orders; the variant of Lesson 24.1 §6. Read §3 to see what stays fixed.
Chapters: Ch 24 -
[TQY+21] Mircea Trofin, Yundi Qian, Eugene Brevdo, Zinan Lin, Krzysztof Choromanski, and David Li. MLGO: a Machine Learning Guided Compiler Optimizations Framework. arXiv preprint 2101.04808, 2021. link
Why and when: The design of LLVM's learned inlining-for-size policy: features, the reward (native size), evolution strategies and reinforcement learning, and deployment in LLVM. Read §3–5 after Lesson 20.3's MLGO section.
Chapters: Ch 20 -
[TSTL09] Ross Tate, Michael Stepp, Zachary Tatlock, and Sorin Lerner. Equality Saturation: A New Approach to Optimization. POPL 2009, pp. 264–276, 2009. doi:10.1145/1480881.1480915
Why and when: The origin of equality saturation as an optimizer: apply rules non-destructively, then extract. Read §1–3 with Lesson 8.5; Ch 17 implements it.
Chapters: Ch 8, Ch 17, Ch 21 -
[TT94] Mads Tofte and Jean-Pierre Talpin. Implementation of the Typed Call-by-Value λ-calculus using a Stack of Regions. POPL 1994, pp. 188–201, 1994. doi:10.1145/174675.177855
Why and when: Core reading. Region inference: allocate every value in a lexically scoped region and free regions as a whole. The origin of Definition 24.5.9; read §2–3, and the later ML Kit papers for the space-leak fix.
Chapters: Ch 24 -
[TY79] Robert Endre Tarjan and Andrew Chi-Chih Yao. Storing a sparse table. Communications of the ACM 22(11), 606–611, 1979. doi:10.1145/359168.359175
Why and when: Row displacement for sparse tables with O(1) lookup: how generated LL (and LR) tables are compressed (Lesson 2.3 §5–6). Read the row-displacement scheme.
Chapters: Ch 2, Ch 3 -
[Ukk83] Esko Ukkonen. Lower bounds on the size of deterministic parsers. Journal of Computer and System Sciences 26(2), 153–170, 1983. doi:10.1016/0022-0000(83)90010-7
Why and when: Families of LR(0) and LL(2) grammars whose deterministic parsers must be exponentially larger than the grammar; the theory behind Proposition 3.1.21's blow-up. Skim the statements of the main theorems.
Chapters: Ch 3 -
[Ull73] Jeffrey D. Ullman. Fast algorithms for the elimination of common subexpressions. Acta Informatica 2(3), pp. 191-213, 1973. doi:10.1007/BF00289078
Why and when: An O(e log e) elimination algorithm for available expressions on reducible graphs; the historical context for Lessons 14.3 and 14.5.
Chapters: Ch 14 -
[Ull75] J. D. Ullman. NP-Complete Scheduling Problems. Journal of Computer and System Sciences 10(3), pp. 384–393, 1975. doi:10.1016/S0022-0000(75)80008-0
Why and when: NP-completeness of precedence-constrained scheduling of unit tasks, the reduction behind Theorem 23.3.4. Read §2 for the construction.
Chapters: Ch 23 -
[UM02] Sebastian Unger and Frank Mueller. Handling Irreducible Loops: Optimized Node Splitting versus DJ-Graphs. ACM TOPLAS 24(4), pp. 299-333, 2002. doi:10.1145/567097.567098
Why and when: Measures node splitting against analyzing irreducible loops directly; read §1 and the results after Lesson 15.6 when deciding between transforming and analyzing.
Chapters: Ch 15 -
[Val75] Leslie G. Valiant. General context-free recognition in less than cubic time. Journal of Computer and System Sciences 10(2), 308–315, 1975. doi:10.1016/S0022-0000(75)80046-8
Why and when: CFL recognition in Boolean matrix multiplication time (Theorem 4.4.10). Read the idea after Lesson 4.4 §4; the construction is intricate and not needed for the exercises.
Chapters: Ch 4 -
[vAPRV18] Hendrik van Antwerpen, Casper Bach Poulsen, Arjen Rouvoet, and Eelco Visser. Scopes as types. Proc. ACM Program. Lang. 2 (OOPSLA), Article 114, 2018. doi:10.1145/3276484
Why and when: Statix: type checkers specified as constraints over scope graphs, with regular path expressions and label orders as query parameters. Read §2–4 after Lesson 5.3 §6.
Chapters: Ch 5 -
[vEn01] Robert A. van Engelen. Efficient Symbolic Analysis for Optimizing Compilers. Compiler Construction (CC 2001), LNCS 2027, pp. 118-132, 2001. doi:10.1007/3-540-45306-7_9
Why and when: Brings CRs into compilers for induction-variable analysis; read after Lesson 18.3 §2 to see the CR rewrite rules applied to loops.
Chapters: Ch 18 -
[Ver10] Sven Verdoolaege. isl: An Integer Set Library for the Polyhedral Model. Mathematical Software – ICMS 2010, LNCS 6327, pp. 299-302, 2010. doi:10.1007/978-3-642-15582-6_49
Why and when: The library used in the Omega and polyhedral real-world boxes (via islpy), inside Polly and GCC Graphite. Short; read it before running Lesson 18.7's isl box.
Chapters: Ch 18 -
[VH04] Thomas VanDrunen and Antony L. Hosking. Value-Based Partial Redundancy Elimination. Compiler Construction (CC 2004), LNCS 2985, pp. 167–184, 2004.
Why and when: GVN-PRE: anticipation and availability over value numbers, with phi-translation, so PRE also removes redundancies that are not lexically identical. GCC's tree PRE is built on it (Lesson 17.6 §7).
Note: SpringerLink; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[VNLBS21] Alexa VanHattum, Rachit Nigam, Vincent T. Lee, James Bornholt, and Adrian Sampson. Vectorization for Digital Signal Processors via Equality Saturation. ASPLOS 2021, 2021. doi:10.1145/3445814.3446707
Why and when: Diospyros: selecting DSP vector instructions by equality saturation and extraction, a concrete e-graph selector (Lesson 21.7 §6).
Chapters: Ch 21 -
[VPF+24] Alexa VanHattum, Monica Pardeshi, Chris Fallin, Adrian Sampson, and Fraser Brown. Lightweight, Modular Verification for WebAssembly-to-Native Instruction Selection. ASPLOS 2024, 2024. doi:10.1145/3617232.3624862
Why and when: Verifies Cranelift's ISLE lowering rules with an SMT solver; the full version of Theorem 0.4.10's argument that rule-based lowering is correct when each rule is. Read after Lesson 0.4's Cranelift section.
Chapters: Ch 0 -
[VPFSB24] Alexa VanHattum, Monica Pardeshi, Chris Fallin, Adrian Sampson, and Fraser Brown. Lightweight, Modular Verification for WebAssembly-to-Native Instruction Selection. ASPLOS 2024, 2024. doi:10.1145/3617232.3624862
Why and when: Crocus: SMT verification of Cranelift's ISLE lowering rules, which found real bugs. Read §2–4 after Lesson 21.7 §4 to see why a rule DSL makes selectors verifiable.
Chapters: Ch 21 -
[VPJS10] Dimitrios Vytiniotis, Simon Peyton Jones, and Tom Schrijvers. Let Should Not Be Generalised. TLDI 2010, 5th ACM Workshop on Types in Language Design and Implementation, 39–50, 2010.
Why and when: The argument for MonoLocalBinds (Lesson 7.2 §6, Lesson 7.4 §6), with measurements of how rarely Haskell code needs generalized local lets. Short; read after Lesson 7.4.
Note: ACM TLDI 2010 proceedings; also on the Microsoft Research site.
Chapters: Ch 7 -
[VPJSS11] Dimitrios Vytiniotis, Simon Peyton Jones, Tom Schrijvers, and Martin Sulzmann. OutsideIn(X): Modular Type Inference with Local Assumptions. Journal of Functional Programming 21(4–5), 333–412, 2011. doi:10.1017/S0956796811000098
Why and when: Core reading. GHC's inference algorithm: implication constraints, touchable variables, and why guessing is forbidden (Lesson 7.4). Read §1–5; §7 is the concrete solver.
Chapters: Ch 7 -
[WACL05] John Whaley, Dzintars Avots, Michael Carbin, and Monica S. Lam. Using Datalog with Binary Decision Diagrams for Program Analysis. APLAS 2005, LNCS 3780, pp. 97–118, 2005. doi:10.1007/11575467_8
Why and when: bddbddb: Datalog compiled to BDD operations, with variable-ordering search. Read §2–3 after Lesson 19.8 §6.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[Wad85] Philip Wadler. How to replace failure by a list of successes. FPCA 1985, LNCS 201, 113–128, 1985. doi:10.1007/3-540-15975-4_42
Why and when: Returning every successful end position instead of committing: the formulation of full backtracking in Algorithm 2.5.6 and lab exercise L3.
Chapters: Ch 2, Ch 4 -
[Wad98] Philip Wadler. The expression problem. Message to the java-genericity mailing list, 12 November 1998, 1998. link
Why and when: The name and statement of the trade-off between sum types and class hierarchies (adding cases vs adding operations) discussed in Lesson 4.7 §1 and §6. One page.
Chapters: Ch 4 -
[War90] Henry S. Warren Jr.. Instruction Scheduling for the IBM RISC System/6000 Processor. IBM Journal of Research and Development 34(1), pp. 85–92, 1990. doi:10.1147/rd.341.0085
Why and when: A production list scheduler with a precise priority list for a superscalar processor; a good second example after [GM86] (Lesson 23.3 §7).
Chapters: Ch 23 -
[WB89] Philip Wadler and Stephen Blott. How to Make Ad-hoc Polymorphism Less Ad Hoc. POPL 1989, 16th ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, 60–76, 1989. doi:10.1145/75277.75283
Why and when: Type classes and their translation to dictionary passing: every class constraint becomes an extra argument holding the methods. Read §1–4 after Lesson 6.9 §2; the GHC Core in the lesson's box is this translation.
Chapters: Ch 6, Ch 7 -
[WCES94] Daniel Weise, Roger F. Crew, Michael Ernst, and Bjarne Steensgaard. Value Dependence Graphs: Representation Without Taxation. POPL 1994, pp. 297–310, 1994. doi:10.1145/174675.177907
Why and when: The VDG, a demand-driven dependence representation without a CFG; the step from the PDG to the VSDG in Lesson 8.5.
Chapters: Ch 8 -
[WDM08] Alessandro Warth, James R. Douglass, and Todd Millstein. Packrat parsers can support left recursion. PEPM 2008, 103–110, 2008. doi:10.1145/1328408.1328424
Why and when: Seed growing for left recursion in packrat parsers, the technique CPython's pegen uses (memoize_left_rec); a variant in Lesson 2.4 §6 and Lesson 2.5 §6.
Chapters: Ch 2, Ch 4 -
[Weg75] Ben Wegbreit. Property Extraction in Well-Founded Property Sets. IEEE Transactions on Software Engineering SE-1(3), pp. 270–285, 1975.
Why and when: The origin of conditional constant propagation on dense dataflow: only edges whose branch condition allows them contribute (the CC algorithm of [WZ91]). Read after Lesson 17.1 §6 for the dense ancestor of SCCP.
Note: IEEE Xplore; DOI not re-checked from the course container (look it up by title).
Chapters: Ch 17 -
[Wel99] J. B. Wells. Typability and Type Checking in System F Are Equivalent and Undecidable. Annals of Pure and Applied Logic 98(1–3), 111–156, 1999.
Why and when: The undecidability of System F inference (Theorem 7.8.7b) by reduction from semi-unification. Read the introduction for the statement and its history.
Note: Annals of Pure and Applied Logic (Elsevier), volume 98.
Chapters: Ch 7 -
[WF09] Philip Wadler and Robert Bruce Findler. Well-Typed Programs Can't Be Blamed. ESOP 2009, LNCS 5502, 1–16, 2009. doi:10.1007/978-3-642-00590-9_1
Why and when: The blame calculus: casts carry labels with polarity, and the Blame Theorem says a cast failure is never the fault of the more precisely typed side. Read §2–3 after Lesson 6.7 §4 (Theorem 6.7.8) and compare its positive/negative blame with the lab's single labels.
Chapters: Ch 6 -
[WF10] Christian Wimmer and Michael Franz. Linear Scan Register Allocation on SSA Form. CGO 2010, 2010. doi:10.1145/1772954.1772979
Why and when: Build lifetime intervals in one backward pass over SSA with contiguous loops, and destroy SSA during resolution (Algorithm 22.5.10, Theorem 22.5.11).
Chapters: Ch 22 -
[WF74] Robert A. Wagner and Michael J. Fischer. The string-to-string correction problem. Journal of the ACM 21(1), 168–173, 1974. doi:10.1145/321796.321811
Why and when: The dynamic program for edit distance (Algorithm 5.8.6) with its correctness proof. Six pages; read after Lesson 5.8 §2 and compare withllvm::ComputeEditDistance.
Chapters: Ch 5 -
[WF94] Andrew K. Wright and Matthias Felleisen. A Syntactic Approach to Type Soundness. Information and Computation 115(1), 38–94, 1994. doi:10.1006/inco.1994.1093
Why and when: Core reading. The progress-and-preservation ("subject reduction") method of Lesson 6.1 §4, applied to ML-like languages with references and exceptions. Read §1–4 after Corollary 6.1.17; §5 shows why the method scales where the denotational proof of [Mil78] does not.
Chapters: Ch 6 -
[WG98] Tim A. Wagner and Susan L. Graham. Efficient and flexible incremental parsing. ACM Transactions on Programming Languages and Systems 20(5), pp. 980–1013, 1998. doi:10.1145/293677.293678
Why and when: Core reading. Incremental lexing and parsing with lookahead-based invalidation (Algorithm 1.10.8), the design tree-sitter follows. Read the lexing sections after Lesson 1.10.
Chapters: Ch 1, Ch 4 -
[Whe05] David A. Wheeler. Countering Trusting Trust through Diverse Double-Compiling. Annual Computer Security Applications Conference (ACSAC 2005), 2005. doi:10.1109/CSAC.2005.17
Why and when: Introduces diverse double-compiling and demonstrates it on the Tiny C Compiler — the experiment the Lesson 0.5 box reproduces with gcc and clang.
Chapters: Ch 0 -
[Wir71] Niklaus Wirth. The Design of a PASCAL Compiler. Software: Practice and Experience 1(4), pp. 309–333, 1971. doi:10.1002/spe.4380010403
Why and when: Wirth's one-pass Pascal compiler and the language-design choices (declare before use) that make one-pass compilation possible — Definition 0.1.9. Read after Lesson 0.1 §2.
Chapters: Ch 0 -
[Wir77] Niklaus Wirth. What can we do about the unnecessary diversity of notation for syntactic definitions?. Communications of the ACM 20(11), 822–823, 1977. doi:10.1145/359863.359883
Why and when: The one-page proposal of EBNF ({ } for repetition), the notation behind loop-shaped recursive descent (Lesson 2.4 §6, Lesson 2.5 exercise L2).
Chapters: Ch 2 -
[WL04] John Whaley and Monica S. Lam. Cloning-Based Context-Sensitive Pointer Alias Analysis Using Binary Decision Diagrams. PLDI 2004, pp. 131-144, 2004. doi:10.1145/996841.996859
Why and when: bddbddb: Datalog over BDDs made context-sensitive points-to analysis practical (Lesson 14.8 §1 and §6).
Chapters: Ch 14, Ch 19 -
[WL91] Michael E. Wolf and Monica S. Lam. A Data Locality Optimizing Algorithm. PLDI 1991, pp. 30-44, 1991. doi:10.1145/113445.113449
Why and when: Unimodular transformations (interchange, reversal, skewing) plus tiling, and the skewing that makes a band fully permutable (Lemma 18.7.8).
Chapters: Ch 18 -
[WM05] Christian Wimmer and Hanspeter Mössenböck. Optimized Interval Splitting in a Linear Scan Register Allocator. VEE 2005, 2005. doi:10.1145/1064979.1064998
Why and when: Core reading. The linear scan of HotSpot C1 and Graal: free-until and next-use positions, split at optimal positions, spill-slot resolution (Algorithm 22.5.8). The pseudo-code maps line by line onto c1_LinearScan.cpp.
Chapters: Ch 22 -
[WMZC07] Tao Wei, Jian Mao, Wei Zou, and Yu Chen. A New Algorithm for Identifying Loops in Decompilation. Static Analysis Symposium (SAS 2007), LNCS 4634, pp. 170-183, 2007. doi:10.1007/978-3-540-74061-2_11
Why and when: A one-pass loop-nesting algorithm designed for decompilers; the Havlak variant listed in Lesson 15.5 §6. Optional.
Chapters: Ch 15 -
[WNW+21] Max Willsey, Chandrakana Nandi, Yisu Remy Wang, Oliver Flatt, Zachary Tatlock, and Pavel Panchekha. egg: Fast and Extensible Equality Saturation. Proc. ACM on Programming Languages 5 (POPL), Article 23, 2021. doi:10.1145/3434304
Why and when: Core reading. Rebuilding (deferred congruence repair, §3) and e-class analyses (§4): Algorithm 8.5.8 and the egg library of the real-world box. Read §2–4.
Chapters: Ch 8, Ch 17, Ch 21 -
[Wol92] Michael Wolfe. Beyond Induction Variables. PLDI 1992, pp. 162-174, 1992. doi:10.1145/143095.143131
Why and when: Core reading. Induction variables as SCCs of the SSA graph (Algorithm 18.2.6). Read §2–3 after Lesson 18.2 §2; E2'sprint<pebble-iv>follows its classification.
Chapters: Ch 18 -
[Wri95] Andrew K. Wright. Simple Imperative Polymorphism. Lisp and Symbolic Computation 8(4), 343–355, 1995.
Why and when: Core reading. The value restriction (Definition 7.3.3) and its soundness argument, with the observation that it rejects few real programs. Short; read it after Lesson 7.3 §4.
Note: Lisp and Symbolic Computation (Kluwer), volume 8, issue 4.
Chapters: Ch 7 -
[WS97] Deborah L. Whitfield and Mary Lou Soffa. An Approach for Exploring Code Improving Transformations. ACM TOPLAS 19(6), pp. 1053–1084, 1997. doi:10.1145/267959.267961
Why and when: Core reading. Pre- and postconditions of transformations, the enabling and disabling relations between them, and a framework (Genesis) for exploring orders. The source of Definition 24.1.2; read §2–3 after Lesson 24.1 §2, and the interaction tables in §4 with the enabling graph of the drill.
Chapters: Ch 24 -
[WW66] Niklaus Wirth and Helmut Weber. EULER: a generalization of ALGOL, and its formal definition: Part I. Communications of the ACM 9(1), 13–25, 1966. doi:10.1145/365153.365162
Why and when: Simple precedence parsing (relations between all grammar symbols), the variant of Floyd's method in Lessons 3.1 §6 and 3.5 §6. Read the parsing section.
Chapters: Ch 3 -
[WWH+17] Thomas Würthinger, Christian Wimmer, Christian Humer, Andreas Wöß, Lukas Stadler, Chris Seaton, Gilles Duboscq, Doug Simon, and Matthias Grimmer. Practical Partial Evaluation for High-Performance Dynamic Language Runtimes. PLDI 2017, 2017. doi:10.1145/3062341.3062381
Why and when: Truffle/Graal: self-specializing AST interpreters turned into machine code by partial evaluation at run time, with deoptimization. The first Futamura projection in production (Lessons 0.2 §6 and 0.3).
Chapters: Ch 0 -
[WWM07] Thomas Würthinger, Christian Wimmer, and Hanspeter Mössenböck. Array Bounds Check Elimination for the Java HotSpot Client Compiler. PPPJ 2007, pp. 125-133, 2007. doi:10.1145/1294325.1294343
Why and when: BCE in a production JIT with deoptimization; read after Lesson 18.9 for loop-invariant check hoisting in practice.
Chapters: Ch 18 -
[WZ91] Mark N. Wegman and F. Kenneth Zadeck. Constant Propagation with Conditional Branches. ACM TOPLAS 13(2), pp. 181-210, 1991. doi:10.1145/103135.103136
Why and when: Sparse conditional constant propagation, the global extension of constant folding mentioned in Lesson 13.1 §6; taught in full in Chapter 14.
Chapters: Ch 13, Ch 14, Ch 17, Ch 20 -
[YCER11] Xuejun Yang, Yang Chen, Eric Eide, and John Regehr. Finding and Understanding Bugs in C Compilers. PLDI 2011, pp. 283–294, 2011. doi:10.1145/1993498.1993532
Why and when: Core reading. Csmith: generating C programs free of undefined behavior (safe math, points-to and effect analysis during generation) and running them differentially; more than 325 bugs reported in GCC and LLVM. Read §2 (generation) after Lesson 12.5 §2 and §3 for the bug statistics.
Chapters: Ch 12, Ch 13, Ch 24 -
[You67] Daniel H. Younger. Recognition and parsing of context-free languages in time \(n^3\). Information and Control 10(2), 189–208, 1967. doi:10.1016/S0019-9958(67)80007-X
Why and when: The other origin of CYK, with the cubic bound of Proposition 4.4.9. Read §2 after Lesson 4.4 §2.
Chapters: Ch 4 -
[Zak11] Alon Zakai. Emscripten: An LLVM-to-JavaScript Compiler. SPLASH '11 Companion (OOPSLA), pp. 301–312, 2011. doi:10.1145/2048147.2048224
Why and when: Transpiling LLVM IR to JavaScript, including the relooper that rebuilds structured control flow from a CFG — a transpiler whose target lacksgoto(Lesson 0.3).
Chapters: Ch 0 -
[ZH02] Andreas Zeller and Ralf Hildebrandt. Simplifying and Isolating Failure-Inducing Input. IEEE Transactions on Software Engineering 28(2), pp. 183–200, 2002. doi:10.1109/32.988498
Why and when: Core reading. The ddmin algorithm, 1-minimality and its complexity analysis, and the isolation variant dd. Read §3–4 alongside Lesson 12.7 §2 and §4 before implementing Part B of the lab.
Chapters: Ch 12 -
[ZM14] Danfeng Zhang and Andrew C. Myers. Toward General Diagnosis of Static Errors. POPL 2014, 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages, 569–581, 2014. doi:10.1145/2535838.2535870
Why and when: SHErrLoc: likelihood-ranked error locations over a general constraint language (Lesson 7.9 §6). Read §1–3 and the evaluation.
Chapters: Ch 7 -
[ZNMZ12] Jianzhou Zhao, Santosh Nagarakatte, Milo M. K. Martin, and Steve Zdancewic. Formalizing the LLVM Intermediate Representation for Verified Program Transformations. POPL 2012, pp. 427–440, 2012. doi:10.1145/2103656.2103709
Why and when: Vellvm: LLVM IR's syntax, well-formedness (including the SSA dominance property of Theorem 9.3.5) and semantics in Coq, with machine-checked proofs about SSA-based passes. Read §3–4 after Lesson 9.3 to see Definition 9.3.4 made fully formal.
Chapters: Ch 9
Textbooks and monographs¶
-
[AHV95] Serge Abiteboul, Richard Hull, and Victor Vianu. Foundations of Databases. Addison-Wesley, 1995. Read: Part D: Ch. 12 (Datalog), Ch. 13 (Evaluation of Datalog), Ch. 15 (Negation in Datalog).
Why and when: The textbook semantics of Datalog: least models, the immediate-consequence operator, semi-naive evaluation and stratified negation (Lesson 14.8, Definition 14.8.2).
Chapters: Ch 14 -
[AK02] Randy Allen and Ken Kennedy. Optimizing Compilers for Modern Architectures: A Dependence-Based Approach. Morgan Kaufmann, 2002. Read: Ch. 2–3 (dependence theory and testing), Ch. 4 (preliminary transformations, induction-variable substitution), Ch. 5–6 (vectorization, loop distribution, interchange, fusion).
Why and when: Core reading. The standard reference for Lessons 18.6–18.8: dependence vectors, the testing hierarchy of GCD/Banerjee/SIV, and the Allen–Kennedy distribution and vectorization algorithms. Read Ch. 2 before Lesson 18.6 if distance and direction vectors are new.
Chapters: Ch 18 -
[ALSU07] Alfred V. Aho, Monica S. Lam, Ravi Sethi, and Jeffrey D. Ullman. Compilers: Principles, Techniques, and Tools, 2nd ed.. Addison-Wesley, 2007. Read: §4.1.3–4.1.4 (error-recovery strategies), §4.2 (context-free grammars), §4.3 (writing a grammar: ambiguity, dangling else, left recursion, Algorithm 4.19, left factoring), §4.4 (top-down parsing: FIRST/FOLLOW, LL(1), predictive parsing, §4.4.5 error recovery).
Why and when: Core reading. The classical presentation this chapter follows for FIRST/FOLLOW, the LL(1) table and panic mode. Read §4.2–4.4 alongside Lessons 2.1–2.5; its exercises are good extra drill.
Chapters: Ch 2, Ch 3, Ch 4, Ch 5, Ch 6, Ch 11 -
[App92] Andrew W. Appel. Compiling with Continuations. Cambridge University Press, 1992. Read: Ch. 1–2 (overview, continuation-passing style), Ch. 5 (conversion into CPS).
Why and when: How SML/NJ compiled through CPS: the CPS datatype that Lesson 8.6's real-world pointer shows (cexp) and the conversion algorithm. Read Ch. 2 before Lesson 8.6 §2 if CPS is new.
Chapters: Ch 8 -
[Appel] Andrew W. Appel. Modern Compiler Implementation in ML. Cambridge University Press, 1998. Read: §7.1–7.2 (translation to intermediate trees: Ex, Nx and Cx, conditionals), §19.1 (converting to SSA form).
Why and when: Represents a condition as a function from two labels to code (Cx), a clean formulation of Lesson 11.2's jumping code; read §7.2 with Algorithm 11.2.2. The C and Java editions share the numbering.
Chapters: Ch 11, Ch 15, Ch 16, Ch 21, Ch 22 -
[ASU86] Alfred V. Aho, Ravi Sethi, and Jeffrey D. Ullman. Compilers: Principles, Techniques, and Tools, 1st ed.. Addison-Wesley, 1986. Read: §4.6 (operator-precedence parsing), §4.7 (LR parsers), §4.8 (using ambiguous grammars).
Why and when: The first edition keeps operator-precedence parsing (dropped in the 2nd edition): the textbook proof behind Theorem 3.5.11 and the precedence-function variant.
Chapters: Ch 3 -
[AU72] Alfred V. Aho and Jeffrey D. Ullman. The Theory of Parsing, Translation, and Compiling, Vol. 1: Parsing. Prentice Hall, 1972. Read: §2.4 (context-free grammars), §5.1 (LL(k) grammars, strong LL(k), LL(k) parsing tables).
Why and when: The rigorous textbook treatment behind Lesson 2.6's definitions and proofs (FIRST_k, ⊕_k, local follow sets, table construction). Use §5.1 when a proof in Lesson 2.6 is only sketched.
Chapters: Ch 2, Ch 3 -
[Ban88] Utpal Banerjee. Dependence Analysis for Supercomputing. Kluwer Academic Publishers, 1988. Read: the chapters on the GCD test and the bounds (Banerjee's inequalities) under direction vectors.
Why and when: The origin of the inequalities of Lemma 18.6.7 and Theorem 18.6.8 with direction vectors. Consult it for the general (trapezoidal) bounds that the lesson's rectangular case simplifies.
Chapters: Ch 18 -
[Bli16] Gabriel Hjort Blindell. Instruction Selection: Principles, Methods, and Applications. Springer, 2016. Read: Ch. 2 (Macro expansion), Ch. 3 (Tree covering), Ch. 4 (DAG covering), Ch. 5 (Graph covering); an earlier version is the survey arXiv:1306.4898.
Why and when: Core reading. The survey of the whole field this chapter compresses: every technique of Lessons 21.1–21.4 and 21.7 with its history. Read the chapter matching each lesson afterwards.
Chapters: Ch 21 -
[BN98] Franz Baader and Tobias Nipkow. Term Rewriting and All That. Cambridge University Press, 1998. Read: Ch. 2 (abstract reduction systems, Newman's lemma), Ch. 5 (termination), Ch. 6 (confluence and critical pairs), Ch. 7 (Knuth–Bendix completion).
Why and when: The standard textbook for Lesson 13.4: read Ch. 2 for Theorem 13.4.7 and Ch. 6 for the critical-pair lemma (Theorem 13.4.8) before designing your own rule set.
Chapters: Ch 13 -
[BS01] Franz Baader and Wayne Snyder. Unification Theory (chapter 8 of the Handbook of Automated Reasoning). Elsevier and MIT Press, 2001. Read: §2 (syntactic unification: substitutions, MGUs), §3 (algorithms: Robinson, Martelli–Montanari rules, the union-find algorithm and its complexity), §4–5 (E-unification).
Why and when: The best single survey of unification: the three algorithms of Lesson 7.1 with proofs, the exponential example of §5 and the extensions of §6. Read §2–3 alongside Lesson 7.1.
Chapters: Ch 7 -
[CLRS4] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms, 4th ed.. MIT Press, 2022. Read: Ch. 11 (Hash Tables), §11.3 (hash functions, universal hashing) and §11.4 (open addressing).
Why and when: Expected-time analysis of hash tables with universal hashing and open addressing, behind the interning table of Lesson 1.8 (Algorithm 1.8.5). Read §11.3–11.4 if the expected O(1) probe bound is unfamiliar.
Chapters: Ch 1, Ch 10 -
[Col25] Quentin Colombet. LLVM Code Generation: A deep dive into compiler backend development. Packt, 2025. Read: Ch. 3 (Compiler Basics and How They Map to LLVM APIs), Ch. 4 (Writing Your First Optimization), Ch. 7 (Understanding LLVM IR); code: github.com/PacktPublishing/LLVM-Code-Generation.
Why and when: By the architect of GlobalISel; Ch. 3 walks through the same Value/Use/IRBuilder APIs with a backend developer's eye and Ch. 4 writes a first pass with them. Written against LLVM 20. Useful after Lesson 10.2 and as a bridge to the back-end chapters (Ch 21).
Chapters: Ch 10, Ch 21 -
[Cro07] Douglas Crockford. Top down operator precedence, in: Beautiful Code (A. Oram, G. Wilson, eds.). O'Reilly, 2007. Read: Ch. 9 (Top down operator precedence). link
Why and when: The chapter that revived Pratt parsing by writing JSLint's JavaScript parser with it. Read it for the style of nud/led tables after Lesson 4.1's Algorithm 4.1.8.
Chapters: Ch 4 -
[Dragon2] Alfred V. Aho, Monica S. Lam, Ravi Sethi, and Jeffrey D. Ullman. Compilers: Principles, Techniques, and Tools, 2nd ed.. Addison-Wesley, 2006. Read: §1.1–1.2 (language processors, the structure of a compiler), §2.8 (intermediate code generation), §8.10 (optimal code generation for expressions: Ershov numbers).
Why and when: Core reading. The classical picture of a compiler as a sequence of phases, which Lesson 0.1 starts from; §2.8 introduces stack and three-address code (Lesson 0.2) and §8.10 proves the Ershov-number optimality result behind Theorem 0.2.14. Read §1.2 before Lesson 0.1.
Chapters: Ch 0, Ch 1, Ch 8, Ch 13, Ch 14, Ch 15, Ch 18, Ch 19, Ch 21, Ch 23 -
[EaC3] Keith D. Cooper and Linda Torczon. Engineering a Compiler, 3rd ed.. Morgan Kaufmann, 2022. Read: Ch. 1 (Overview of compilation).
Why and when: A gentler overview of front end, optimizer and back end than the Dragon book, with the engineering trade-offs this chapter's comparison tables are about; read Ch. 1 alongside the chapter README before the lessons.
Chapters: Ch 0, Ch 1, Ch 2, Ch 3, Ch 5, Ch 8, Ch 9, Ch 13, Ch 14, Ch 15, Ch 16, Ch 17, Ch 18, Ch 21, Ch 22, Ch 23 -
[ES90] Margaret A. Ellis and Bjarne Stroustrup. The Annotated C++ Reference Manual. Addison-Wesley, 1990. Read: §13.2 (argument matching), with the annotations on ambiguity.
Why and when: Where the C++ overload-resolution rules (Algorithm 5.4.3, the ranks of Definition 5.4.1) were first written down with the rationale. Read §13.2 after Lesson 5.4 §2.
Chapters: Ch 5 -
[FB-Grammar] Andreas Zeller, Rahul Gopinath, Marcel Böhme, Gordon Fraser, and Christian Holler. The Fuzzing Book. CISPA Helmholtz Center for Information Security (online book; Python package fuzzingbook 1.2.2), 2024. Read: Chapters "Fuzzing with Grammars" and "Efficient Grammar Fuzzing" (GrammarFuzzer), "Coverage", "Reducing Failure-Inducing Inputs". link
Why and when: Executable chapters on grammar fuzzing (the three-phase GrammarFuzzer of Algorithm 12.6.2), greybox fuzzing and delta debugging. Run the notebooks alongside Lessons 12.6–12.7.
Chapters: Ch 12 -
[FH95] Christopher W. Fraser and David R. Hanson. A Retargetable C Compiler: Design and Implementation. Addison-Wesley, 1995. Read: Ch. 14 (selecting and emitting instructions with lburg), Ch. 16–18 (the MIPS, SPARC and x86 code generators).
Why and when: lcc's code generators and lburg explained with the full source (Lesson 21.2 §7 and Lesson 21.8 §2). Read Ch. 14 with the lcc box of Lesson 21.8.
Chapters: Ch 21 -
[GJ08] Dick Grune and Ceriel J. H. Jacobs. Parsing Techniques: A Practical Guide, 2nd ed.. Springer, 2008. Read: ch. 3 (introduction to parsing, ambiguity), ch. 6 (general directional top-down parsing, backtracking), ch. 8 (deterministic top-down parsing: LL(1), LL(k), strong LL(k)), ch. 16 (error handling).
Why and when: Core reading. The most complete survey of parsing there is, with an enormous annotated bibliography. Use ch. 8 for every LL variant this chapter mentions and ch. 16 for error handling; dip into it whenever you want a second explanation.
Chapters: Ch 2, Ch 3 -
[GJ79] Michael R. Garey and David S. Johnson. Computers and Intractability: A Guide to the Theory of NP-Completeness. W. H. Freeman, 1979. Read: Appendix A1.3 (vertex ordering, including optimal linear arrangement), Appendix A6 (mathematical programming, including knapsack).
Why and when: The NP-hardness facts behind Proposition 20.10.8 (weighted linear arrangement) and the knapsack view of inlining (Theorem 20.3.4). Use as a lookup, not a read.
Chapters: Ch 20, Ch 22, Ch 23 -
[GoF94] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994. Read: Visitor, pp. 331–344.
Why and when: The classic (virtual, double-dispatch) visitor pattern; Lesson 10.4 contrasts it with LLVM's static CRTP InstVisitor and its delegation chain.
Chapters: Ch 10 -
[Gus97] Dan Gusfield. Algorithms on Strings, Trees, and Sequences: Computer Science and Computational Biology. Cambridge University Press, 1997. Read: Ch. 5 (suffix trees), Ch. 6 (Ukkonen's linear-time construction), Ch. 7 (first applications: repeated substrings).
Why and when: The full proofs behind the outliner's repeated-sequence search (Lesson 20.4 §4 cites Ch. 7). Read Ch. 5–6 only if you want to implement suffix trees yourself.
Chapters: Ch 20 -
[HD2] Henry S. Warren Jr.. Hacker's Delight, 2nd ed.. Addison-Wesley, 2012. Read: Ch. 10 (Integer Division by Constants), §10-1 (Signed Division by a Known Power of 2).
Why and when: The bias trick of Theorem 12.3.9 and its variants for every width, then division by arbitrary constants. Read §10-1 with Lesson 12.3 §2.
Chapters: Ch 12 -
[Hec77] Matthew S. Hecht. Flow Analysis of Computer Programs. Elsevier North-Holland, 1977. Read: the chapters on flow-graph reducibility and node splitting (section numbers not verified for this course).
Why and when: The monograph that systematized T1/T2, intervals and node splitting; use it as a reference for the proofs Lesson 15.6 sketches if your library has it.
Chapters: Ch 15 -
[HMU07] John E. Hopcroft, Rajeev Motwani, and Jeffrey D. Ullman. Introduction to Automata Theory, Languages, and Computation, 3rd ed.. Pearson / Addison-Wesley, 2007. Read: Ch. 2 (§2.3–2.5 NFA, ε-NFA, subset construction), Ch. 3 (§3.2 Kleene's theorem, state elimination), Ch. 4 (§4.1 pumping lemma, §4.2 closure incl. inverse homomorphisms, §4.4 table-filling minimization).
Why and when: The full proofs behind Lessons 1.1 and 1.4: Kleene's theorem (Theorem 1.1.13), closure under inverse homomorphism (Corollary 1.1.17), and the table-filling algorithm. Read when a proof sketch in the lessons needs more detail.
Chapters: Ch 1, Ch 4 -
[HP6] John L. Hennessy and David A. Patterson. Computer Architecture: A Quantitative Approach, 6th ed.. Morgan Kaufmann, 2017. Read: Ch. 3 (Instruction-Level Parallelism and Its Exploitation), Appendix H (Hardware and Software for VLIW and EPIC).
Why and when: The hardware side of this chapter: pipelines, dynamic scheduling (why out-of-order cores forgive bad schedules) and the VLIW/EPIC support (predication, rotating registers) that Lessons 23.5–23.6 compile for.
Chapters: Ch 23 -
[HU79] John E. Hopcroft and Jeffrey D. Ullman. Introduction to Automata Theory, Languages, and Computation. Addison-Wesley, 1979. Read: §4.6 (Greibach normal form: Lemmas 4.3–4.4, substitution and left-recursion elimination), Ch. 8 (Post's correspondence problem and the undecidable questions about CFGs, including ambiguity).
Why and when: The textbook proofs behind Lesson 2.4 (the substitution lemma and direct removal preserve the language) and behind Theorem 2.1.12 (ambiguity is undecidable). Open it when a proof in those lessons is only sketched.
Chapters: Ch 2 -
[JGS93] Neil D. Jones, Carsten K. Gomard, and Peter Sestoft. Partial Evaluation and Automatic Program Generation. Prentice Hall, 1993. Read: Ch. 1 (Introduction: specializers, interpreters, compilers and the Futamura projections), Ch. 4 (Partial evaluation for a flow chart language). link
Why and when: The standard text on partial evaluation, freely available. Ch. 1 states the Futamura projections exactly as Theorem 0.3.15 and discusses when the compiled programs are actually fast; Ch. 4 builds a self-applicable specializer. Read after Lesson 0.3 §4.
Chapters: Ch 0 -
[JHM11] Richard Jones, Antony Hosking, and Eliot Moss. The Garbage Collection Handbook: The Art of Automatic Memory Management. Chapman & Hall/CRC, 2011. Read: Ch. 5 (reference counting: deferred and coalesced), Ch. 11 (run-time interface: stack maps, safepoints, derived pointers), Ch. 4 (mark–sweep basics).
Why and when: The reference for everything Lesson 24.5 compresses: read Ch. 11 when the stack-map and base/derived discussion feels thin, Ch. 5 for the counting variants of §6.
Chapters: Ch 24 -
[Jon94] Mark P. Jones. Qualified Types: Theory and Practice. Cambridge University Press, 1994. Read: Ch. 2 (predicates and entailment), Ch. 3 (type inference with qualified types), Ch. 5 (evidence and the translation to dictionaries).
Why and when: The theory of type classes as HM with predicates, including coherence of the evidence translation. Read Ch. 3 and 5 after Lesson 7.7 §4.
Chapters: Ch 7 -
[Knu98] Donald E. Knuth. The Art of Computer Programming, Volume 3: Sorting and Searching, 2nd ed.. Addison-Wesley, 1998. Read: §6.2.3 (balanced trees: the AVL height bound), §6.4 (hashing).
Why and when: The height bound \(1.44 \log_2(n+2)\) used in Proposition 5.2.10 and the analysis of chained hashing behind the scope stack. Read §6.2.3 if the AVL rotations of the lab are new.
Chapters: Ch 5 -
[Kog81] Peter M. Kogge. The Architecture of Pipelined Computers. McGraw-Hill, 1981. Read: the chapters on static pipeline control: reservation tables, forbidden latencies, collision vectors and the state diagram of a pipeline controller.
Why and when: The textbook collection of the reservation-table theory of Lesson 23.1 (collision vectors, greedy cycles, minimum average latency). Useful if Lemma 23.1.6 and the automaton of Proposition 23.1.7 feel too compressed.
Chapters: Ch 23 -
[KT06] Jon Kleinberg and Éva Tardos. Algorithm Design. Addison-Wesley, 2006. Read: §4.3 (Optimal Caching: A More Complex Exchange Argument).
Why and when: The textbook exchange-argument proof that furthest-in-future is optimal; compare it with the proof of Theorem 22.2.6.
Chapters: Ch 22 -
[Lat11] Chris Lattner. LLVM, in: The Architecture of Open Source Applications, Vol. 1 (A. Brown, G. Wilson, eds.). aosabook.org (lulu.com), 2011. Read: §11.1 (classical compiler design), §11.3 (LLVM IR), §11.4 (LLVM's implementation of the three-phase design). link
Why and when: Lattner's own account of the three-phase design and of why LLVM IR is the only interface between front end, optimizer and back end. The best short companion to Lesson 0.4; read it right after the lesson's §1.
Chapters: Ch 0, Ch 10 -
[Lev00] John R. Levine. Linkers and Loaders. Morgan Kaufmann, 2000. Read: Ch. 3 (Object files), Ch. 5 (Symbol management), Ch. 7 (Relocation), Ch. 10 (Dynamic linking and loading).
Why and when: The standard book on the tools of Lesson 0.6. Ch. 5 and 7 are the long versions of Algorithm 0.6.6 (resolution, relocation); Ch. 10 explains PLT/GOT and lazy binding.
Chapters: Ch 0, Ch 11, Ch 21 -
[McC62] John McCarthy, Paul W. Abrahams, Daniel J. Edwards, Timothy P. Hart, and Michael I. Levin. LISP 1.5 Programmer's Manual. MIT Press, 1962. Read: Ch. 1 (the LISP language), Appendix B (the LISP interpreter: eval, apply and the association list).
Why and when: Dynamic scoping as it was first implemented:evallooks names up in the association list of the calling context. Read the interpreter in Appendix B after Lesson 5.1 §2 and find where deep binding (Algorithm 5.1.7) happens.
Chapters: Ch 5 -
[ModernML] Andrew W. Appel. Modern Compiler Implementation in ML. Cambridge University Press, 1998. Read: Ch. 4 (abstract syntax: datatypes for syntax trees, positions).
Why and when: Abstract syntax as ML datatypes, the sum-type design of Lesson 4.7; read Ch. 4 to see a whole compiler's AST written that way.
Chapters: Ch 4 -
[Muchnick] Steven S. Muchnick. Advanced Compiler Design and Implementation. Morgan Kaufmann, 1997. Read: Ch. 7 (Control-Flow Analysis: §7.6 interval analysis and control trees, §7.7 structural analysis), Ch. 8 (Data-Flow Analysis: iterative, lattices of flow functions, control-tree-based methods).
Why and when: Full pseudo-code for interval and structural analysis (Lesson 14.5) and for flow-function lattices (Definition 14.5.1).
Chapters: Ch 14, Ch 15, Ch 17, Ch 18, Ch 20, Ch 21, Ch 22, Ch 23 -
[Nac24] Kai Nacke and Amy Kwan. Learn LLVM 17: A beginner's guide to learning LLVM compiler tools and core libraries with C++, 2nd ed.. Packt, 2024. Read: Ch. 4–6 (generating IR with IRBuilder for a small language, tinylang), Ch. 9 (JIT compilation with LLJIT); code: github.com/PacktPublishing/Learn-LLVM-17.
Why and when: A book-length tutorial through the same APIs as this chapter (IRBuilder, the object model, LLJIT) on a complete small compiler. Written against LLVM 17: expect to adapt insertion points (iterators, debug records) and the pass plugin header. Read alongside Labs 10.1 and 10.3.
Chapters: Ch 10 -
[NNH] Flemming Nielson, Hanne Riis Nielson, and Chris Hankin. Principles of Program Analysis. Springer, 1999. Read: Ch. 2 (Data Flow Analysis: the four classics, monotone frameworks, MFP and MOP), Ch. 4 (Abstract Interpretation: widening, narrowing, Galois connections), Ch. 6 (Algorithms: worklists, reverse postorder, strong components), Appendix A (partially ordered sets and fixed points).
Why and when: Core reading. The rigorous reference for Lessons 14.1, 14.2, 14.4 and 14.7; its Chapter 6 covers the solver orders of Lesson 14.4 in more depth than any compiler textbook.
Chapters: Ch 14 -
[Nys21] Robert Nystrom. Crafting Interpreters. Genever Benning, 2021. Read: Part II, ch. 4–13 (a tree-walk interpreter, jlox); Part III, ch. 14–30 (a bytecode virtual machine, clox). link
Why and when: A book-length build of exactly the two interpreter designs of Lesson 0.2 (tree walker, then stack VM with a switch loop), freely readable online. Useful while doing lab milestones L2–L4.
Chapters: Ch 0 -
[Oka98] Chris Okasaki. Purely Functional Data Structures. Cambridge University Press, 1998. Read: Ch. 2 (persistence: lists and binary search trees with path copying), §3.3 (red-black trees).
Why and when: Persistent trees the functional way: Ch. 2 is Algorithm 5.2.7 in twenty lines of ML. Read it before the L2 milestone of the lab.
Chapters: Ch 5 -
[Pes24] Slava Pestov. Compiling Swift Generics. The Swift Project (swiftlang/swift, docs/Generics; PDF at download.swift.org), 2024. Read: Ch. 1 (introduction: generic calling convention, type metadata and witness tables), Ch. 7 (conformances and their witness tables).
Why and when: The Swift compiler's own book on generics: dictionary passing through witness tables plus type metadata, and when the optimizer specializes instead. Read Ch. 1 after Lesson 6.9 §2.
Chapters: Ch 6 -
[PFPL] Robert Harper. Practical Foundations for Programming Languages, 2nd ed.. Cambridge University Press, 2016. Read: Ch. 2–3 (inductive and hypothetical judgments), Ch. 4 (statics), Ch. 5 (dynamics), Ch. 6 (type safety), Ch. 22 (dynamic typing), Ch. 23 (hybrid typing), Ch. 24 (structural subtyping).
Why and when: A more rigorous treatment of judgments, rule induction and safety than [TAPL]; Ch. 22–23 are the principled view of "dynamic typing as static typing with one type" behind Lessons 6.2 and 6.7. Read Ch. 4–6 if Lesson 6.1's proofs feel too compressed.
Chapters: Ch 6 -
[PR05] François Pottier and Didier Rémy. The Essence of ML Type Inference (chapter 10 of Advanced Topics in Types and Programming Languages, B. C. Pierce, ed.). MIT Press, 2005. Read: §10.1 (let-polymorphism, let-expansion), §10.2–10.4 (constraints and constraint generation), §10.5–10.6 (constraint solving by rewriting, with let-constraints).
Why and when: Core reading. The generate-then-solve presentation of HM(X) that Lesson 7.4's Algorithm 7.4.4 follows, with complete proofs. The best reading for Lessons 7.3–7.4; long but rewarding.
Chapters: Ch 7 -
[Sch86] Alexander Schrijver. Theory of Linear and Integer Programming. Wiley, 1986. Read: Ch. 7 (Farkas' lemma and its variants, including the affine form, Corollary 7.1h).
Why and when: The mathematical background for Lesson 18.7's Theorem 18.7.12; read Ch. 7 if you want the duality proof in full generality.
Chapters: Ch 18 -
[Sip12] Michael Sipser. Introduction to the Theory of Computation, 3rd ed.. Cengage Learning, 2012. Read: §2.1 (context-free grammars, ambiguity), §5.2 (Post's correspondence problem), Problem 5.21 (ambiguity is undecidable).
Why and when: The gentlest complete proof path for Theorem 2.1.12: PCP's undecidability in §5.2, and the reduction to ambiguity as a guided problem. Read after Lesson 2.1 §4.
Chapters: Ch 2 -
[SPA] Anders Møller and Michael I. Schwartzbach. Static Program Analysis. Aarhus University (online lecture notes), 2024. Read: Ch. 4 (Lattice Theory), Ch. 5 (Dataflow Analysis with Monotone Frameworks), Ch. 6 (Widening), Ch. 9 (Distributive Interprocedural Analysis: IFDS), Ch. 12 (Abstract Interpretation) — chapter numbers of the 2024 edition. link
Why and when: Free, concise and precise; the best first reading for Lessons 14.1, 14.2 and 14.7, with the TIP teaching language (github.com/cs-au-dk/TIP) as a companion implementation.
Note: Unverified: chapter numbers follow the 2024 edition's table of contents as recalled by the author and reviewer; cs.au.dk was unreachable from the course container, so check them against the current PDF (the notes are revised yearly and chapters get renumbered).
Chapters: Ch 14, Ch 19 -
[SSAB] Fabrice Rastello and Florent Bouchez Tichadou. SSA-based Compiler Design. Springer, 2022. Read: Ch. 2 Properties and Flavors (strict SSA and the dominance property). doi:10.1007/978-3-030-80515-9
Why and when: The SSA properties the verifier enforces: strict SSA is exactly the dominance property of Theorem 9.3.5, and the chapter compares SSA flavors. Read Ch. 2 after Lesson 9.3.
Chapters: Ch 9, Ch 14, Ch 15, Ch 16, Ch 17, Ch 19 -
[SSAbook] Fabrice Rastello and Florent Bouchez Tichadou. SSA-based Compiler Design. Springer, 2022. Read: Part I, Ch. 1–3 (introduction, properties and flavours, construction and destruction); Ch. 6 (functional representations of SSA). doi:10.1007/978-3-030-80515-9
Why and when: The reference on SSA. Chapters 1–3 back Lesson 8.4 (minimal, pruned and strict SSA); the chapter on functional representations states the SSA/CPS/ANF correspondence of Lesson 8.6 with the dominator-tree nesting in full.
Chapters: Ch 8 -
[Str94] Bjarne Stroustrup. The Design and Evolution of C++. Addison-Wesley, 1994. Read: §11.2 (overload resolution: the rules and their rationale), Ch. 15 (templates and their instantiation).
Why and when: Why C++ overload resolution ranks conversions the way it does, and why templates were designed for compile-time instantiation (monomorphization). Read §11.2 with Lesson 6.3 and Ch. 15 with Lesson 6.9.
Chapters: Ch 6, Ch 10 -
[TAOCP1] Donald E. Knuth. The Art of Computer Programming, Vol. 1: Fundamental Algorithms, 3rd ed.. Addison-Wesley, 1997. Read: §2.2.5 (doubly linked lists), pp. 280–298.
Why and when: Doubly linked lists with a sentinel and O(1) insertion and deletion at a known node, the structure behind LLVM's ilist (Lesson 10.1, Definition 10.1.6 and Lemma 10.1.13).
Chapters: Ch 10 -
[TAOCP3] Donald E. Knuth. The Art of Computer Programming, Vol. 3: Sorting and Searching, 2nd ed.. Addison-Wesley, 1998. Read: §6.4 (hashing): Algorithm L (linear probing), Algorithm R (deletion with linear probing), Theorem K (expected probes), pp. 513–558.
Why and when: Core reading. The source of LLVM 23's DenseMap design: linear probing and deletion by backward shifting (Algorithm R), which the DenseMap.h header comment cites. Theorem K gives the probe counts used in Lesson 10.6's Proposition 10.6.16; read after Lesson 10.6 §2.
Chapters: Ch 10 -
[TAPL] Benjamin C. Pierce. Types and Programming Languages. MIT Press, 2002. Read: Ch. 5 (the untyped lambda calculus: free variables, substitution), Ch. 6 (nameless representation of terms: shifting and substitution), Ch. 7 (an ML implementation).
Why and when: The standard textbook account of de Bruijn indices, shifting and substitution (Lemma 5.2.13). Read Ch. 6 after Lesson 5.2 §4; Ch. 7 is a working implementation.
Chapters: Ch 5, Ch 6, Ch 7 -
[Tom85] Masaru Tomita. Efficient Parsing for Natural Language: A Fast Algorithm for Practical Systems. Kluwer Academic Publishers, 1985. Read: the chapters presenting the algorithm, the graph-structured stack and the shared packed forest (the first half of the book).
Why and when: The origin of GLR with a graph-structured stack and packed forests (Lesson 3.6). Read the algorithm description with the worked example of Lesson 3.6 §3 at hand.
Chapters: Ch 3 -
[Tom91] Masaru Tomita. Generalized LR Parsing. Kluwer Academic Publishers (edited volume), 1991. Read: ch. 1 (Tomita and Ng, the GLR algorithm), the chapter by Nozohoor-Farshi on ε-grammars.
Why and when: The standard reference collection on GLR; its first chapter restates the algorithm used in Theorem 3.6.7, and Nozohoor-Farshi's chapter [NF91] treats ε-rules.
Chapters: Ch 3 -
[War13] Henry S. Warren and Jr.. Hacker's Delight, 2nd ed.. Addison-Wesley, 2013. Read: Ch. 10 (Integer Division by Constants), including Figure 10-1 (signed magic numbers); Ch. 8 (Multiplication).
Why and when: Core reading. The algorithms LLVM's DivisionByConstantInfo cites, with proofs for signed and unsigned division by constants (Lesson 13.7, Theorem 13.7.10 and the magic-division drill). Read Ch. 10 with Lesson 13.7.
Chapters: Ch 13 -
[Wir76] Niklaus Wirth. Algorithms + Data Structures = Programs. Prentice Hall, 1976. Read: §5.9 (syntax error recovery in a recursive-descent parser, with stop-symbol sets).
Why and when: Panic mode in recursive descent by passing "stop symbol" sets down the calls, the origin of FOLLOW-based synchronization (Lesson 2.7 §1). Short and concrete; read after Algorithm 2.7.3.
Chapters: Ch 2, Ch 4 -
[Wol96] Michael Wolfe. High Performance Compilers for Parallel Computing. Addison-Wesley, 1996. Read: the chapters on data dependence, dependence testing (extreme-value / Banerjee test) and loop restructuring (interchange, skewing, tiling, peeling).
Why and when: Wolfe's book presents Banerjee's inequalities as the "extreme value test" and treats loop restructuring as a catalogue with legality conditions; a second view of Lessons 18.5–18.7.
Chapters: Ch 18 -
[WPF] Andreas Zeller. Why Programs Fail: A Guide to Systematic Debugging, 2nd ed.. Morgan Kaufmann, 2009. Read: Ch. 5 (Simplifying Problems: ddmin), Ch. 14 (Isolating Failure Causes).
Why and when: The textbook presentation of delta debugging with worked examples and code; easier than the paper. Read Ch. 5 before Lesson 12.7 if the proofs feel dense.
Chapters: Ch 12
Surveys and tutorials¶
-
[Aho90] Alfred V. Aho. Algorithms for finding patterns in strings. Handbook of Theoretical Computer Science, Vol. A (J. van Leeuwen, ed.), Elsevier, pp. 255–300, 1990.
Why and when: A survey of regular-expression matching as used in Unix tools, including egrep's construction of DFA states on demand (the lazy DFA of Lesson 1.2). Read §3 for the history of automata-based search tools.
Note: Handbook chapter.
Chapters: Ch 1 -
[AJ74] Alfred V. Aho and Stephen C. Johnson. LR parsing. ACM Computing Surveys 6(2), 99–124, 1974. doi:10.1145/356628.356629
Why and when: Core reading. The tutorial that taught a generation LR(0) items, SLR and LALR, conflict resolution and table compression, written by yacc's author. Read it as a second explanation of Lessons 3.1–3.3 and 3.5.
Chapters: Ch 3 -
[Ayc03] John Aycock. A Brief History of Just-In-Time. ACM Computing Surveys 35(2), pp. 97–113, 2003. doi:10.1145/857076.857077
Why and when: Survey of JIT compilation from the 1960s to Java: method JITs, mixed-mode execution, and the terminology of Lesson 0.3. Read before the lesson for the history.
Chapters: Ch 0 -
[Car96] Luca Cardelli. Type Systems. CRC Handbook of Computer Science and Engineering, ch. 103 (A. B. Tucker, ed.), CRC Press, 1996. link
Why and when: Core reading. The best short survey of the whole chapter: judgments and rules (§3), type safety and the trapped/untrapped errors behind "strong" and "weak" typing (§1), subtyping (§6) and equivalence (§8). Read §1–3 before Lesson 6.1 and §1 again with Lesson 6.2, whose definitions follow it.
Chapters: Ch 6 -
[CPS+20] Junjie Chen, Jibesh Patra, Michael Pradel, Yingfei Xiong, Hongyu Zhang, Dan Hao, and Lu Zhang. A Survey of Compiler Testing. ACM Computing Surveys 53(1), Article 4, 2020. doi:10.1145/3363562
Why and when: The map of the field: program generation, test oracles (differential, metamorphic/EMI), reduction, prioritization, and the empirical record. Read it after Lesson 12.5 to place every technique of Lessons 12.5–12.8.
Chapters: Ch 12 -
[DK21] Jana Dunfield and Neel Krishnaswami. Bidirectional Typing. ACM Computing Surveys 54(5), Article 98, 2021. doi:10.1145/3450952
Why and when: Core reading. The survey Lesson 6.4 follows: mode-correctness, the Pfenning recipe (introduction forms check, elimination forms synthesize), annotatability and the subsumption rule. Read §2–4 alongside Lesson 6.4 §2–4; §7 surveys variants (spines, polarized systems).
Chapters: Ch 6, Ch 7 -
[GTW06] Loukas Georgiadis, Robert E. Tarjan, and Renato F. Werneck. Finding Dominators in Practice. Journal of Graph Algorithms and Applications 10(1), pp. 69-94, 2006. doi:10.7155/jgaa.00119
Why and when: Core reading. The experimental comparison of iterative, Lengauer-Tarjan and Semi-NCA on real CFGs and adversarial families (the ladder of Lesson 15.1 §5 among them) behind LLVM's choice of Semi-NCA. Read §4-5 before running the comparison lab.
Chapters: Ch 15 -
[Hin01] Michael Hind. Pointer Analysis: Haven't We Solved This Problem Yet?. PASTE 2001, pp. 54–61, 2001. doi:10.1145/379605.379665
Why and when: Core reading. The map of the design space (flow, context, field sensitivity; heap naming; aggregate modelling) and a sober look at what precision buys clients. Read it first, before the lessons, and again after Lesson 19.7.
Note: DOI recorded from the proceedings; not re-resolved from the course container.
Chapters: Ch 19 -
[Ken81] Ken Kennedy. A survey of data flow analysis techniques. In S. S. Muchnick and N. D. Jones (eds.), Program Flow Analysis: Theory and Applications, Prentice-Hall, pp. 5-54, 1981.
Why and when: The survey of the pre-SSA era: iterative, interval and elimination methods, def-use chains and the classic problems side by side. Read after Lessons 14.3–14.5 for the historical map.
Note: A book chapter; no DOI. Found in university libraries.
Chapters: Ch 14 -
[LDSM80] David Landskov, Scott Davidson, Bruce Shriver, and Patrick W. Mallett. Local Microcode Compaction Techniques. ACM Computing Surveys 12(3), pp. 261–294, 1980. doi:10.1145/356819.356822
Why and when: Core reading. The survey that turned dependence graphs and list scheduling into compiler techniques (for horizontal microcode). Read its DAG construction and list-scheduling sections after Lessons 23.2–23.3: the algorithms are recognizably the ones in LLVM today.
Chapters: Ch 23 -
[RP86] Barbara G. Ryder and Marvin C. Paull. Elimination Algorithms for Data Flow Analysis. ACM Computing Surveys 18(3), pp. 277-316, 1986. doi:10.1145/27632.27649
Why and when: The comparative survey of Allen–Cocke, Hecht–Ullman, Graham–Wegman and Tarjan elimination methods with complexity tables; read after Lesson 14.5 to see all of them side by side.
Chapters: Ch 14
Theses and technical reports¶
-
[AC72] Frances E. Allen and John Cocke. Graph-Theoretic Constructs for Program Control Flow Analysis. IBM Research Report RC 3923, IBM T. J. Watson Research Center, 1972.
Why and when: The set-based formulation of dominators (Dom(n) = {n} ∪ ⋂ Dom(p)) that Lesson 15.1's Algorithm 15.1.11 iterates, together with intervals and the derived sequence of Lesson 15.6.
Note: No DOI; the report circulates as a scanned copy (Frances Allen's papers). Cited for history.
Chapters: Ch 15 -
[AL96] Stephen Alstrup and Peter W. Lauridsen. A Simple Dynamic Algorithm for Maintaining a Dominator Tree. Technical Report 96-3, Department of Computer Science, University of Copenhagen, 1996.
Why and when: The depth-based insertion search that GILS16 turned into DBS (Algorithm 15.2.4); read GILS16 instead unless you want the original argument.
Note: Technical report without a DOI; GILS16 summarizes it.
Chapters: Ch 15 -
[Ana99] C. Scott Ananian. The Static Single Information Form. Master's thesis, Massachusetts Institute of Technology (MIT-LCS-TR-801), 1999.
Why and when: SSI: sigma-functions at branches so that branch-refined facts become sparse too (Lesson 14.6 §6), the idea behind LLVM's PredicateInfo.
Note: MIT technical report; no DOI.
Chapters: Ch 14, Ch 16 -
[And94] Lars Ole Andersen. Program Analysis and Specialization for the C Programming Language. PhD thesis, DIKU, University of Copenhagen (DIKU report 94/19), 1994. link
Why and when: Core reading. The origin of inclusion-based ("Andersen-style") points-to analysis: Ch. 4 states the subset constraints for C and solves them. Read Ch. 4 after Lesson 19.4 §2; the lesson's four constraint forms are a simplification of Andersen's type-directed rules.
Note: The Cornell course copy of the thesis; not re-fetched from the course container.
Chapters: Ch 19 -
[Bag01] Phil Bagwell. Ideal hash trees. EPFL, Technical Report (LAMP), 2001. link
Why and when: Hash array mapped tries: a persistent map with one popcount per level, used by Clojure, Scala and rust-analyzer-era persistent collections. Read §2–3 for the stretch goal of the lab (a HAMT environment) after Lesson 5.2 §6.
Chapters: Ch 5 -
[BBD+11] Florian Brandner, Benoit Boissinot, Alain Darte, Benoît Dupont de Dinechin, and Fabrice Rastello. Computing Liveness Sets for SSA-Form Programs. INRIA Research Report RR-7503, 2011. link
Why and when: Path exploration versus iterative liveness on SSA, with measurements; the algorithm of the lab's sparse liveness (Algorithm 14.6.4). Read §2–3 before starting lab requirement L1.
Chapters: Ch 14 -
[Che09] Xin Chen. Measuring and extending LR(1) parser generation. PhD thesis, University of Hawaii, 2009.
Why and when: Implements and measures Pager's PGM and lane-tracing (Hyacc); useful state-count data for Lesson 3.4's comparison. Skim the experimental chapter.
Note: University of Hawaii at Manoa, 2009; the Hyacc parser generator implements its algorithms.
Chapters: Ch 3 -
[CHK04] Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy. Iterative Data-flow Analysis, Revisited. Rice University, Department of Computer Science, technical report TR04-432 (March 2004), 2004. link
Why and when: Theory and measurements of the iterative algorithm: the role of reducibility in the Kam–Ullman bound, and experiments showing that round-robin and worklist variants behave very differently (a careful worklist wins; implementation mistakes reverse that). Read after Lesson 14.4; cited in Lesson 14.5 for why production compilers iterate. It does not benchmark elimination methods.
Note: Report number and date from the Rice repository record (handle 1911/96324); the repository was not reachable from the review container, so the number was checked via its search-index entry only.
Chapters: Ch 14 -
[Cla86] Keith Clarke. The top-down parsing of expressions. Queen Mary College, Department of Computer Science, Research Report 383, 1986. link
Why and when: The report that describes precedence climbing (Algorithm 4.1.6) as an efficient replacement for one function per level. Short; read it after Lesson 4.1 §2.
Chapters: Ch 4 -
[Cli95t] Clifford Noel Click Jr.. Combining Analyses, Combining Optimizations. PhD thesis, Rice University, 1995.
Why and when: The long form of the sea-of-nodes design and of combining optimizations; background for Lesson 8.5 when [CP95] and [Cli95] are too terse.
Note: Rice University Ph.D. thesis (also a Rice CS technical report); available from Rice's repository.
Chapters: Ch 8, Ch 17 -
[CS70] John Cocke and Jacob T. Schwartz. Programming Languages and Their Compilers: Preliminary Notes. Courant Institute of Mathematical Sciences, New York University (2nd revised version), 1970.
Why and when: The early source usually credited with local value numbering over basic blocks. Cited in Lesson 8.3 for history; the algorithm is taught from [Dragon2] and [EaC3].
Note: Technical notes; scanned copies circulate in university libraries and archives.
Chapters: Ch 8, Ch 13 -
[Dam85] Luis Damas. Type Assignment in Programming Languages. PhD thesis, University of Edinburgh (report CST-33-85), 1985.
Why and when: The full proofs of W's soundness and completeness that [DM82] only states. Consult it for the Let case of Theorem 7.2.11's proof.
Note: Edinburgh Research Archive; scanned copies circulate under the report number CST-33-85.
Chapters: Ch 7 -
[DeR69] Franklin L. DeRemer. Practical translators for LR(k) languages. PhD thesis, MIT (Project MAC TR-65), 1969.
Why and when: Separates the LR(0) automaton (the characteristic finite-state machine) from the lookahead computation and defines LALR(k) as merged LR(k) states — the origin of Lessons 3.1 and 3.3.
Note: MIT Project MAC Technical Report MAC-TR-65; scanned copies are in MIT's DSpace.
Chapters: Ch 3 -
[Dij61] Edsger W. Dijkstra. Algol 60 translation: an Algol 60 translator for the X1 and making a translator for Algol 60. Mathematisch Centrum, Amsterdam, Report MR 35/61, 1961.
Why and when: Where the shunting-yard algorithm (Algorithm 4.1.9) first appears, as part of a complete ALGOL 60 translator. Of historical interest; read Lesson 4.1's trace first.
Note: Scans circulate via the E. W. Dijkstra Archive and CWI's repository.
Chapters: Ch 4 -
[Ell85] John R. Ellis. Bulldog: A Compiler for VLIW Architectures. Yale University, PhD thesis (Research Report YALEU/DCS/RR-364); MIT Press, 1986, 1985.
Why and when: The engineering of a trace-scheduling compiler: the full bookkeeping rules, memory disambiguation and code generation for a VLIW. Read the trace-scheduling chapters for the cases Theorem 23.4.10's sketch skips.
Note: Published as a book by MIT Press (ACM Doctoral Dissertation Award series), 1986.
Chapters: Ch 23 -
[Geo05] Loukas Georgiadis. Linear-Time Algorithms for Dominators and Related Problems. PhD thesis, Princeton University (TR-737-05), 2005. link
Why and when: Core reading. Semi-NCA (pp. 21-23) and the proof that idom(w) = NCA(parent(w), sdom(w)) (Lemma 15.1.18). This is the reference LLVM's GenericDomTreeConstruction.h cites; read the Semi-NCA pages after Lesson 15.1 §4, then compare with SemiNCAInfo::runSemiNCA.
Chapters: Ch 15 -
[Hack07] Sebastian Hack. Register Allocation for Programs in SSA Form. PhD thesis, Universität Karlsruhe (TH), 2007.
Why and when: SSA interference graphs are chordal, so SSA programs can be register-allocated before leaving SSA; spilling and coalescing on SSA. The preview in Lesson 16.7 §6 and the SSA-based allocator of Ch 22 start here.
Note: Published by Universitätsverlag Karlsruhe; the KIT library repository hosts the PDF.
Chapters: Ch 16, Ch 22 -
[HM96] Graham Hutton and Erik Meijer. Monadic parser combinators. University of Nottingham, Technical Report NOTTCS-TR-96-4, 1996. link
Why and when: The long tutorial on monadic combinators:>>=, choice,many, and the space leaks of backtracking. Read §2–4 alongside Algorithm 4.5.3.
Note: Also archived as Nottingham ePrints 237 (https://eprints.nottingham.ac.uk/237/).
Chapters: Ch 4 -
[Hue76] Gérard Huet. Résolution d'équations dans des langages d'ordre 1, 2, …, ω. Thèse de doctorat d'État, Université Paris VII, 1976.
Why and when: Where union-find unification over term graphs and rational-tree unification come from (Lesson 7.1, Algorithm 7.1.10 and Definition 7.1.11). Most readers should read [BS01]'s account instead; cite Huet for the origin.
Note: Not online in a stable place; the union-find algorithm is presented in English in [BS01, §3].
Chapters: Ch 7 -
[Joh75] Stephen C. Johnson. Yacc: Yet Another Compiler-Compiler. Bell Laboratories Computing Science Technical Report 32, 1975.
Why and when: The origin of %left/%right precedence declarations and of "shift beats reduce" for the dangling else (Lesson 2.3 §1 and the Bison real-world boxes). Read the sections on ambiguity and conflicts and on precedence.
Note: Bell Labs CSTR 32; reprinted in the Unix Programmer's Manual (7th ed.), vol. 2B.
Chapters: Ch 2, Ch 3, Ch 4 -
[Kas65] Tadao Kasami. An efficient recognition and syntax-analysis algorithm for context-free languages. Air Force Cambridge Research Laboratory, Bedford MA, Scientific Report AFCRL-65-758, 1965. link
Why and when: One of the two independent origins of CYK (Algorithm 4.4.3). Hard to obtain; the textbook treatment in [HMU07 §7.4] is the practical reading.
Note: A DTIC-distributed technical report that few libraries hold (the URL is its catalog record); the textbook treatment in HMU07 §7.4.4 is the practical source.
Chapters: Ch 4 -
[Lat02] Chris Lattner. LLVM: An Infrastructure for Multi-Stage Optimization. Master's thesis, Department of Computer Science, University of Illinois at Urbana-Champaign, 2002. link
Why and when: The longer original description of LLVM, with the argument for a persistent, self-contained program representation that is the module of Lesson 9.1. Optional; skim the representation chapter after Lesson 9.1 §1.
Chapters: Ch 9, Ch 10 -
[LM01] Daan Leijen and Erik Meijer. Parsec: direct style monadic parser combinators for the real world. Utrecht University, Technical Report UU-CS-2001-35, 2001. link
Why and when: Committed choice with consumed/empty replies andtry(Definition 4.5.4, Algorithm 4.5.5), and why it fixes the space leak and the error messages of backtracking. Read §3 and §5.1.
Note: The Microsoft Research page carries the PDF of the Utrecht report.
Chapters: Ch 4 -
[Par93] Terence J. Parr. Obtaining practical variants of LL(k) and LR(k) for k > 1 by splitting the atomic k-tuple. PhD thesis, Purdue University, 1993.
Why and when: Linear-approximate lookahead (k sets of tokens instead of sets of k-strings), the ANTLR 2 variant of strong LL(k) in Lesson 2.6 §6. Read the chapter on linear approximate lookahead for the idea and the cost argument.
Note: Purdue University thesis; available from the author's publication list and ProQuest.
Chapters: Ch 2 -
[PS91] Joseph C. H. Park and Michael S. Schlansker. On Predicated Execution. Hewlett-Packard Laboratories, Technical Report HPL-91-58, 1991. pdf
Why and when: The RK algorithm: predicates from control dependence, one per predicate class (Definition 23.5.4, Proposition 23.5.10). Read it after Lesson 23.5 §2.
Chapters: Ch 23 -
[Rek92] Jan Rekers. Parser Generation for Interactive Environments. PhD thesis, University of Amsterdam, 1992.
Why and when: A careful GLR with shared packed parse forests and ε-handling, and a proof of correctness (Theorem 3.6.7). Read ch. 1 after Lesson 3.6.
Note: University of Amsterdam, 1992; the basis of the SGLR parser of ASF+SDF and Spoofax.
Chapters: Ch 3 -
[Rem92] Didier Rémy. Extending ML Type System with a Sorted Equational Theory. INRIA Research Report 1766, 1992.
Why and when: Introduces the ranks (levels) of type variables that make generalization a level comparison (Algorithm 7.3.2). Read the part on efficient generalization after Lesson 7.3 §2; [Kis13] is the gentler account.
Note: INRIA HAL repository, report RR-1766.
Chapters: Ch 7 -
[Sim96] L. Taylor Simpson. Value-Driven Redundancy Elimination. PhD thesis, Rice University, 1996.
Why and when: SCC-based value numbering (the optimistic RPO algorithm NewGVN's header cites) and value-based code motion. Read Ch. 3–4 after Lesson 17.5 §6.
Note: Rice University Ph.D. thesis (also a Rice CS technical report).
Chapters: Ch 17 -
[SS75] Gerald Jay Sussman and Guy L. Steele Jr.. Scheme: an interpreter for extended lambda calculus. MIT Artificial Intelligence Laboratory, AI Memo 349, 1975. link
Why and when: The memo that brought static scoping and closures to Lisp. Read the interpreter's treatment of environments after Lesson 5.1 §1; it is the static counterpart of [McC62]'s a-list.
Chapters: Ch 5 -
[Ste78] Guy L. Steele Jr.. Rabbit: A Compiler for Scheme. MIT Artificial Intelligence Laboratory, Technical Report AI-TR-474 (Master's thesis), 1978.
Why and when: The first compiler to use CPS as its intermediate representation. Historical background for Lesson 8.6 §1.
Note: MIT AI Lab technical report AI-TR-474; scanned in MIT's DSpace repository.
Chapters: Ch 8 -
[Ste93] Bjarne Steensgaard. Sequentializing Program Dependence Graphs for Irreducible Programs. Technical Report MSR-TR-93-14, Microsoft Research, 1993.
Why and when: The SCC-based loop forest with header sets (Algorithm 15.5.10); read the loop-forest section only, after Lesson 15.5, or the summary in Ram02 §3.
Note: Microsoft Research technical report without a DOI; listed on Microsoft Research's publications site.
Chapters: Ch 15 -
[Whe09] David A. Wheeler. Fully Countering Trusting Trust through Diverse Double-Compiling. PhD dissertation, George Mason University, 2009. link
Why and when: Core reading. The formal proof of DDC (Theorem 0.5.16) with all assumptions made explicit, and demonstrations on four compilers (a small C compiler, a small Lisp compiler, a trojaned Lisp compiler, GCC). Also arXiv:1004.5534. Read the introduction and the proof's assumptions after Lesson 0.5.
Chapters: Ch 0
Source code (pinned versions)¶
-
[Alive2] Alive2's standalone validator, opt/clang plugin and Alive DSL tool —
tools/alive-tv.cppinAliveToolkit/alive2at01a5ec45c8152995755f7331827407a9de19f262. Symbols:TransformVerify,tv/tv.cpp,tools/alive.cpp.
Why and when: The commit built for Lesson 12.8's boxes (the last one compatible with LLVM 23.1.2's TargetLibraryInfo API). The README explains building against LLVM with RTTI.
Chapters: Ch 12, Ch 24 -
[ALIVE2-src] Alive2's translation validator (the commit built against LLVM 23.1.2 for this chapter) —
tools/alive-tv.cppinAliveToolkit/alive2at01a5ec4. Symbols:alive-tv,alive.
Why and when: Build instructions: README.md; this commit is the last before an LLVM API change. The tool behind every alive-tv box of Lessons 13.3, 13.8 and 13.9.
Chapters: Ch 13 -
[ANTLR3-NFAToDFA] ANTLR 3's LL() lookahead-DFA construction —
tool/src/main/java/org/antlr/analysis/NFAToDFAConverter.javainantlr/antlr3at3.5.2. Symbols:NFAToDFAConverter.convert,reach.
Why and when:* The static subset construction of Algorithm 2.6.8 with recursion limits and the fallback to predicates (Lesson 2.6 §7).
Chapters: Ch 2 -
[ANTLR4-ErrorStrategy] ANTLR 4's default error strategy —
runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.javainantlr/antlr4at4.13.2. Symbols:recoverInline,singleTokenDeletion,singleTokenInsertion,recover,sync,getErrorRecoverySet.
Why and when: Single-token deletion and insertion with a panic-mode fallback: Algorithm 2.7.5 in production. Read it after Lesson 2.7 §2 and compare with the real-world box there.
Chapters: Ch 2 -
[ANTLR4-Interp] ANTLR 4's grammar interpreter (parsing without generated code) —
runtime/Java/src/org/antlr/v4/runtime/ParserInterpreter.javainantlr/antlr4at4.13.2. Symbols:ParserInterpreter.parse,visitState.
Why and when: Walks the grammar's ATN with an explicit stack of rule invocations: the data-driven counterpart of Algorithm 2.5.4 thatorg.antlr.v4.gui.Interpreterruns in Lesson 2.5's real-world box. ReadparseandvisitState.
Chapters: Ch 2 -
[ANTLR4-LeftRec] ANTLR 4's rewriting of directly left-recursive rules —
tool/src/org/antlr/v4/analysis/LeftRecursiveRuleTransformer.javainantlr/antlr4at4.13.2. Symbols:translateLeftRecursiveRules.
Why and when: How a tool removes direct left recursion for you by turning the rule into a precedence loop (Lesson 2.4 §7); indirect left recursion is error 119 intool/src/org/antlr/v4/tool/ErrorType.java.
Chapters: Ch 2 -
[ANTLR4-LL1Analyzer] ANTLR 4's LL(1) lookahead-set computation on the ATN —
runtime/Java/src/org/antlr/v4/runtime/atn/LL1Analyzer.javainantlr/antlr4at4.13.2. Symbols:getDecisionLookahead,LOOK.
Why and when: FIRST/FOLLOW-style sets computed by a depth-first walk of the grammar's ATN (Lessons 2.2 and 2.3, §7).
Chapters: Ch 2 -
[ANTLR4-PATN] ANTLR 4's ALL() prediction engine —
runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.javainantlr/antlr4at4.13.2. Symbols:adaptivePredict,execATN,execATNWithFullContext,computeReachSet,closure,reportAttemptingFullContext,reportAmbiguity.
Why and when:* The production implementation of Algorithm 2.6.9: SLL simulation with a DFA cache and the full-context fallback. Read the long class comment first; then followadaptivePredict.
Chapters: Ch 2 -
[ANTLR4-PredictionMode] ANTLR 4's prediction modes and conflict tests —
runtime/Java/src/org/antlr/v4/runtime/atn/PredictionMode.javainantlr/antlr4at4.13.2. Symbols:SLL,LL,LL_EXACT_AMBIG_DETECTION,hasSLLConflictTerminatingPrediction,resolvesToJustOneViableAlt.
Why and when: The SLL/LL distinction (Definition 2.6.7) and "the minimum alternative wins" (Lesson 2.3 §7). The comments are an excellent explanation of SLL conflicts.
Chapters: Ch 2 -
[BISON-src] Bison's counting nullable computation (with relation.c and closure.c) —
src/nullable.cinakimd/bisonatv3.8.2. Symbols:nullable_compute.
Why and when: Algorithm 2.2.8 in C (rcount,squeue);src/relation.c—relation_digraphis DeRemer–Pennello's Digraph (Algorithm 2.2.9);src/closure.c—set_firstsis FIRST by reflexive–transitive closure.
Chapters: Ch 2, Ch 3 -
[BRICS-Min] dk.brics.automaton's three minimizers —
src/dk/brics/automaton/MinimizationOperations.javaincs-au-dk/dk.brics.automatonat582d8f3502b71185749c691aac91206619d36baf. Symbols:MinimizationOperations.minimizeBrzozowski,MinimizationOperations.minimizeHopcroft,MinimizationOperations.minimizeHuffman.
Why and when: Brzozowski's double reversal in two lines, next to Hopcroft and table filling (Huffman): compare all three after Lesson 1.4.
Chapters: Ch 1 -
[CHUMSKY] chumsky's error-recovery strategies —
src/recovery.rsinzesterer/chumskyat0.10. Symbols:via_parser,skip_then_retry_until,nested_delimiters.
Why and when: Recovery inside a combinator library (Algorithm 4.5.7). Read after Lesson 4.5 §2.
Chapters: Ch 4 -
[CIL-PTA] CIL's points-to analyses (olf.ml one-level flow, steensgaard.ml, golf.ml) —
src/ext/pta/olf.mlincil-project/cilatcil-1.7.3. Symbols:leq_int,unify_int,add_toplev_constraint.
Why and when: Lesson 19.5's production implementations of Steensgaard and Das's one-level flow, in OCaml;steensgaard.mlin the same directory is the unification analysis.
Chapters: Ch 19 -
[CIR-Src] ClangIR code generation from the Clang AST —
clang/lib/CIR/CodeGen/CIRGenStmt.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CIRGenFunction::emitForStmt.
Why and when: ClangIR, the MLIR dialect between Clang's AST and LLVM IR (Lesson 8.7); compare withclang/lib/CodeGen/CGStmt.cpp, which emits LLVM IR directly.
Chapters: Ch 8 -
[CL-Arith] Cranelift's arithmetic rewrite rules (ISLE) —
cranelift/codegen/src/opts/arithmetic.isleinbytecodealliance/wasmtimeatv37.0.2. Symbols:simplify.
Why and when: What an aegraph rule looks like in production; compare with the lab's rules files (Lesson 17.8 §7).
Chapters: Ch 17 -
[CL-DFG] Cranelift's data-flow graph (arenas and value aliases) —
cranelift/codegen/src/ir/dfg.rsinbytecodealliance/wasmtimeatv37.0.2. Symbols:DataFlowGraph,DataFlowGraph::change_to_alias,DataFlowGraph::resolve_aliases.
Why and when: Instructions in a PrimaryMap, order in Layout, and value aliases instead of use lists: the contrast case for Lessons 10.1 and 10.2.
Chapters: Ch 10 -
[CL-Egraph] Cranelift's aegraph mid-end —
cranelift/codegen/src/egraph.rsinbytecodealliance/wasmtimeatv37.0.2. Symbols:EgraphPass.
Why and when: A production acyclic e-graph with elaboration back into a CFG (Lesson 8.5 §6); its rewrite rules are ISLE files undercranelift/codegen/src/opts/.
Chapters: Ch 8, Ch 17, Ch 21 -
[CL-Entity] Cranelift's entity arenas —
cranelift/entity/src/lib.rsinbytecodealliance/wasmtimeatv37.0.2. Symbols:PrimaryMap,SecondaryMap,EntityList,EntityRef.
Why and when: The index-based alternative to LLVM's ownership tree (Lesson 10.1, Definition 10.1.9); the module comment explains the design in a page.
Chapters: Ch 10 -
[CL-IR] Cranelift IR reference (block parameters) —
cranelift/docs/ir.mdinbytecodealliance/wasmtimeatv37.0.2. Symbols:Basic blocks.
Why and when: Cranelift's definition of block parameters and of branch arguments; read with the Cranelift box of Lessons 16.3 and 16.5.
Chapters: Ch 16 -
[CL-IR-Docs] Cranelift IR reference —
cranelift/docs/ir.mdinbytecodealliance/wasmtimeatv37.0.2. Symbols:Static single assignment form.
Why and when: "Cranelift does not have phi instructions but uses BB parameters instead": the definition behind Lesson 8.4's Cranelift box.
Chapters: Ch 8 -
[CL-ISLE-Src] The ISLE compiler's overlap checker (and the aarch64 lowering rules) —
cranelift/isle/isle/src/overlap.rsinbytecodealliance/wasmtimeatv37.0.2.
Why and when: Proposition 21.7.7's check in code; the rules themselves are in cranelift/codegen/src/isa/aarch64/lower.isle.
Chapters: Ch 21 -
[CL-MachBuffer] Cranelift's MachBuffer (single-pass emission with islands and veneers) —
cranelift/codegen/src/machinst/buffer.rsinbytecodealliance/wasmtimeatv37.0.2. Symbols:MachBuffer::island_needed,MachBuffer::emit_island.
Why and when: The alternative to fixpoint relaxation in Lesson 21.10 §6; the module comment explains deadlines, islands and veneers in two pages.
Chapters: Ch 21 -
[CL-Src] Cranelift's x86-64 lowering rules in ISLE —
cranelift/codegen/src/isa/x64/lower.isleinbytecodealliance/wasmtimeatv37.0.2. Symbols:iadd_base_case_32_or_64_lea.
Why and when: Real ISLE rules with priorities (Algorithm 0.4.7);cranelift/codegen/src/egraph.rs(EgraphPass) is the e-graph mid-end.
Chapters: Ch 0 -
[CL-SSA] Cranelift's SSA construction (Braun et al.) for its front-end helper —
cranelift/frontend/src/ssa.rsinbytecodealliance/wasmtimeatv37.0.2. Symbols:SSABuilder.
Why and when: How a producer of block-argument SSA builds it on the fly from variables; compare with Algorithm 8.4.7 and with Ch 16.
Chapters: Ch 8, Ch 11, Ch 16 -
[CLANG-AArch64ABI] Clang's AAPCS64 argument classification —
clang/lib/CodeGen/Targets/AArch64.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:AArch64ABIInfo::classifyArgumentType.
Why and when: Homogeneous floating-point aggregates,[2 x i64]coercion and indirect passing by caller copy on AArch64; the macOS side of Lesson 11.5.
Chapters: Ch 11 -
[CLANG-ABW] Clang's CFG-based warnings (falling off the end of a function) —
clang/lib/Sema/AnalysisBasedWarnings.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CheckFallThroughForBody,CheckFallThrough.
Why and when:-Wreturn-typefrom a CFG instead of the syntax-directed rules of Definition 5.7.1. Read after Lesson 5.7 §7 and compare withpebblec's E0305.
Chapters: Ch 5 -
[Clang-AST] Clang's statement AST classes —
clang/include/clang/AST/Stmt.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ForStmt,IfStmt.
Why and when: The typed tree dumped in Lesson 8.3's box; Clang keepsforand+=as distinct nodes.
Chapters: Ch 8 -
[CLANG-BranchOnBool] Clang's jumping code for conditions —
clang/lib/CodeGen/CodeGenFunction.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CodeGenFunction::EmitBranchOnBoolExpr.
Why and when: Recurses through&&,||,!and?:with a true and a false block, exactly Algorithm 11.2.2; read with Lesson 11.2 §7.
Chapters: Ch 11 -
[CLANG-Call] Clang's call emission with ABI-adjusted arguments —
clang/lib/CodeGen/CGCall.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CodeGenFunction::EmitCall,ClangToLLVMArgMapping.
Why and when: Applies the ABI classification to every argument (direct, coerced,sret,byval, indirect); read after Lesson 11.5 §2.
Chapters: Ch 11 -
[CLANG-CGBuilder] Clang's IRBuilder (TargetFolder + a custom inserter) —
clang/lib/CodeGen/CGBuilder.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CGBuilderInserter,CGBuilderBaseTy,CGBuilderTy.
Why and when: A production builder configuration (Lesson 10.3 real-world box); CGBuilderInserter::InsertHelper is defined in clang/lib/CodeGen/CodeGenFunction.cpp.
Chapters: Ch 10 -
[CLANG-CGExpr] Clang's l-value emission, stack slots and trap checks —
clang/lib/CodeGen/CGExpr.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CodeGenFunction::CreateTempAlloca,CodeGenFunction::EmitLValue,CodeGenFunction::EmitTrapCheck.
Why and when: Three techniques of the chapter in one file: one alloca per local (Lesson 11.1), places (EmitLValue, Lesson 11.4) and trap blocks for-fsanitize-trap(Lesson 11.6).
Chapters: Ch 11 -
[CLANG-Deduce] Clang's template argument deduction and
autodeduction —clang/lib/Sema/SemaTemplateDeduction.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DeduceTemplateArgumentsByTypeMatch,checkDeducedTemplateArguments,Sema::DeduceAutoType.
Why and when: One-sided unification of parameter and argument types (Lesson 7.1 §7) and deduction ofautofrom an initializer (Lesson 7.6 §7). FindTemplateDeductionResult::Inconsistent.
Chapters: Ch 7 -
[CLANG-DFA] Clang's dataflow framework (typed lattice + transfer functions) —
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DataflowAnalysis,runDataflowAnalysis.
Why and when: A modern Kildall framework in C++ (Lessons 14.1 and 14.2); the unchecked-optional-access check is built on it.
Chapters: Ch 14 -
[CLANG-DFW] Clang's worklists ordered by RPO or by a weak topological order —
clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DataflowWorklistBase,ReversePostOrderCompare,ForwardDataflowWorklist,BackwardDataflowWorklist,WTODataflowWorklist.
Why and when: Algorithm 14.4.2's priority discipline in 100 lines (Lesson 14.4).
Chapters: Ch 14 -
[CLANG-DiagSema] Clang's table of semantic diagnostics —
clang/include/clang/Basic/DiagnosticSemaKinds.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:err_undeclared_var_use_suggest,warn_decl_shadow.
Why and when: The TableGen counterpart of Pebble'sDiagnosticKinds.def: every message, its severity and its warning group. Skim after Lesson 5.8.
Chapters: Ch 5 -
[CLANG-Driver] The clang driver — builds the phase graph (-ccc-print-phases) and the jobs (-###) —
clang/lib/Driver/Driver.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Driver::BuildActions,Driver::BuildJobs,Driver::PrintActions.
Why and when: ReadBuildActionsafter Lesson 0.1's first box to see how a command line becomes preprocess/compile/backend/assemble/link actions;clang/lib/Driver/ToolChains/Gnu.cppadds the crt files of Lesson 0.6.
Chapters: Ch 0 -
[CLANG-EH] Clang's landing pads for C++ exceptions —
clang/lib/CodeGen/CGException.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CodeGenFunction::EmitLandingPad.
Why and when: Whereinvoketargets andlandingpadclauses of Lesson 11.7's box come from.
Chapters: Ch 11 -
[CLANG-Expr] Clang's expression nodes, including RecoveryExpr —
clang/include/clang/AST/Expr.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:RecoveryExpr,DeclRefExpr.
Why and when:RecoveryExpris the error symbol of Algorithm 5.8.4: it keeps the broken subexpressions and marks the expression as containing errors so later checks stay quiet. Read after Lesson 5.8 §2.
Chapters: Ch 5 -
[CLANG-ExprClass] Clang's value categories (lvalue, xvalue, prvalue) —
clang/lib/AST/ExprClassification.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ClassifyImpl,Expr::isModifiableLvalue.
Why and when: One function computes the category of every C/C++ expression: the "place vs value" judgment of Definition 6.8.1. Read after Lesson 6.8 §2.
Chapters: Ch 6 -
[CLANG-ExprScalar] Clang's assignment and compound assignment —
clang/lib/CodeGen/CGExprScalar.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ScalarExprEmitter::VisitBinAssign,ScalarExprEmitter::EmitCompoundAssignLValue.
Why and when: The evaluation order of a place and a value in C and C++ assignments; compare with Pebble's rule (Algorithm 11.4.4) after Lesson 11.4 §7.
Chapters: Ch 11 -
[CLANG-GnuLink] The link line Clang's driver builds for GNU ld —
clang/lib/Driver/ToolChains/Gnu.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:tools::gnutools::Linker::ConstructJob.
Why and when: Start-up objects,-pie, the dynamic linker and libgcc/libc after the user's inputs, as in Lesson 11.9'sclang -###box; macOS's isdarwin::Linker::ConstructJobinDarwin.cpp.
Chapters: Ch 11 -
[CLANG-IdentifierTable] Clang's identifier table, seeded with keywords per language mode —
clang/lib/Basic/IdentifierTable.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IdentifierTable::AddKeywords,AddKeyword,getKeywordStatus.
Why and when: Lesson 1.8's interning-table technique: how TokenKinds.def becomes identifier entries with a token kind, and how getKeywordStatus enables keywords per language.
Chapters: Ch 1 -
[CLANG-IdResolver] Clang's per-identifier chains of visible declarations —
clang/lib/Sema/IdentifierResolver.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IdentifierResolver::AddDecl,IdentifierResolver::RemoveDecl,IdentifierResolver::begin.
Why and when: A single table with shadowing chains (Algorithm 5.2.4): each identifier points to its innermost declaration; leaving a scope removes the scope's declarations. Read after Lesson 5.2 §7.
Chapters: Ch 5 -
[CLANG-Lambda] C++ lambdas as closure classes —
clang/lib/Sema/SemaLambda.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Sema::BuildLambdaExpr.
Why and when: Closure conversion in a C++ front end: the lambda becomes a class whose fields are the captures (Lesson 11.8 §7).
Chapters: Ch 11 -
[CLANG-Lex] Clang's numeric-literal parser (lexer side) —
clang/lib/Lex/LiteralSupport.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:NumericLiteralParser::NumericLiteralParser.
Why and when: Reportsinvalid suffix 'x' on integer constant— a lexical error in thephasesdrill;clang/lib/Lex/PPDirectives.cppimplements#include/#define/#if(Lesson 0.6).
Chapters: Ch 0 -
[CLANG-Lexer] Clang's hand-written lexer —
clang/lib/Lex/Lexer.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Lexer::LexTokenInternal,Lexer::SkipBlockComment,Lexer::LexRawStringLiteral,fastParseASCIIIdentifier,Lexer::tryConsumeIdentifierUTF8Char.
Why and when: Core reading. The production example for Lessons 1.5–1.7 and 1.9: the switch in LexTokenInternal, the SIMD fast paths, raw strings, and UTF-8 identifiers. Start at LexTokenInternal and follow one case ('<') to the end.
Chapters: Ch 1 -
[CLANG-LV] Live variables on Clang's CFG —
clang/lib/Analysis/LiveVariables.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LiveVariables::computeLiveness.
Why and when: A backward worklist liveness used by the dead-store checker (Lesson 14.3's analyzer box).
Chapters: Ch 14 -
[CLANG-OpPrec] Clang's table of C/C++ binary-operator precedence levels —
clang/include/clang/Basic/OperatorPrecedence.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:prec::Level,getBinOpPrecedence.
Why and when: The layered grammar of the C standard turned back into a table (Lesson 2.1 §7). Twenty lines; the quiz asks about it.
Chapters: Ch 2, Ch 4 -
[CLANG-ParseExpr] Clang's expression parser (precedence climbing) —
clang/lib/Parse/ParseExpr.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Parser::ParseRHSOfBinaryExpression.
Why and when: Left-recursion removal written as a loop that builds left-nested ASTs, withisRightAssocfor?:and assignment (Lessons 2.1, 2.4). Compare with lab exercise L2.
Chapters: Ch 2, Ch 4 -
[CLANG-Parser] Clang's parser-side replacement for the C lexer hack —
clang/lib/Parse/Parser.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Parser::TryAnnotateTypeOrScopeToken.
Why and when: How Clang asks Sema whether an identifier names a type and annotates the token in place (Algorithm 1.7.12). Read after Lesson 1.7.
Chapters: Ch 1, Ch 2, Ch 3 -
[CLANG-ParseStmt] Clang's statement parser (predictive recursive descent) —
clang/lib/Parse/ParseStmt.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Parser::ParseStatementOrDeclarationAfterAttributes,Parser::ParseIfStatement.
Why and when: Aswitchon the current token that is one row of an LL(1) table;ParseIfStatementis the left-factored if/else with the dangling-else warning. Read after Lesson 2.5 §7.
Chapters: Ch 2 -
[CLANG-ParseTemplate] Clang splits
>>when it closes a template argument list —clang/lib/Parse/ParseTemplate.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Parser::ParseGreaterThanInTemplateList.
Why and when: Algorithm 1.7.9 in production, including>=,>>=and the C++98 fix-it. Read after Lesson 1.7.
Chapters: Ch 1 -
[CLANG-ParseTentative] Clang's tentative (backtracking) parsing for C++ declarations vs expressions —
clang/lib/Parse/ParseTentative.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Parser::isCXXDeclarationStatement,TPResult.
Why and when: Bounded backtracking and arbitrary lookahead at the few places C++ needs them (Lessons 2.5–2.6). Read the file comment first, thenisCXXDeclarationStatement.
Chapters: Ch 2, Ch 3 -
[CLANG-PPMacro] Clang's macro expansion (with TokenLexer.cpp and Preprocessor.cpp) —
clang/lib/Lex/PPMacroExpansion.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Preprocessor::HandleMacroExpandedIdentifier,Token::DisableExpand,TokenLexer::Init,Preprocessor::HandleIdentifier.
Why and when: Algorithm 4.8.2 in production: disabled macros and painted-blue tokens. Read after Lesson 4.8 §2.
Chapters: Ch 4 -
[CLANG-SA] The static analyzer's loop widening (see also ExprEngine.cpp and RangeConstraintManager.cpp) —
clang/lib/StaticAnalyzer/Core/LoopWidening.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:getWidenedLoopState.
Why and when: Widening in a path-sensitive analyzer (Lesson 14.7's last box); ExprEngine.cpp explores paths and RangeConstraintManager.cpp keeps each symbol's range set.
Chapters: Ch 14 -
[CLANG-Scope] Clang's parser-time scope objects —
clang/include/clang/Sema/Scope.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Scope,Scope::AddDecl,Scope::ScopeFlags.
Why and when: The scope marks of Algorithm 5.2.4: eachScoperemembers the declarations made in it so thatActOnPopScopecan remove them. Read with [CLANG-IdResolver] after Lesson 5.2.
Chapters: Ch 5 -
[CLANG-SemaChecking] Clang's -Wconversion family of warnings —
clang/lib/Sema/SemaChecking.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CheckImplicitConversion,DiagnoseImpCast.
Why and when: The heuristics behind-Wconversion,-Wsign-conversionand the literal-conversion warnings of Lesson 6.3's box: the conversions are legal C; the warnings are a separate analysis of value ranges.
Chapters: Ch 6 -
[CLANG-SemaDecl] Clang's semantic analysis of declarations —
clang/lib/Sema/SemaDecl.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Sema::CheckShadow,Sema::ImplicitlyDefineFunction,Sema::ActOnPopScope.
Why and when:-Wshadow(Lesson 5.1), implicit function declarations as a declare-before-use failure (Lesson 5.3) and the scope pop that ends lifetimes of names. Search for the symbols; the file is huge.
Chapters: Ch 5 -
[CLANG-SemaExpr] Clang's semantic analysis of expressions (name uses become DeclRefExprs) —
clang/lib/Sema/SemaExpr.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Sema::BuildDeclRefExpr,Sema::ActOnIdExpression,Sema::DiagnoseEmptyLookup.
Why and when: AST annotation (Lesson 5.6 §2): a resolved name becomes aDeclRefExprpointing at its declaration;DiagnoseEmptyLookupstarts typo correction. Read after Lesson 5.6.
Chapters: Ch 5, Ch 6 -
[CLANG-SemaExprCXX] Clang's insertion of implicit conversions —
clang/lib/Sema/SemaExprCXX.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Sema::PerformImplicitConversion.
Why and when: Where a chosen implicit conversion sequence becomesImplicitCastExprnodes in the AST, the elaboration step of Lesson 6.3 §2. Read after the AST-dump box of Lesson 6.1.
Chapters: Ch 6 -
[CLANG-SemaLookup] Clang's name lookup, ADL and typo correction —
clang/lib/Sema/SemaLookup.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Sema::LookupName,Sema::ArgumentDependentLookup,TypoCorrectionConsumer::addName,Sema::CorrectTypo.
Why and when: Core reading. Unqualified lookup through scopes, ADL's associated namespaces (Algorithm 5.4.5) and the typo-correction rule of Lesson 5.8 (a unique best candidate with \(3d \le\) the typo's length) (addNamerejects whenTypoLen / ED < 3). Read after Lessons 5.4 and 5.8.
Chapters: Ch 5 -
[CLANG-SemaOverload] Clang's overload resolution —
clang/lib/Sema/SemaOverload.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:OverloadCandidateSet::BestViableFunction,isBetterOverloadCandidate,CompareImplicitConversionSequences.
Why and when: The tournament of Algorithm 5.4.3 with the C++ tie-breakers: findBestViableFunction's two loops (pick a winner, then check it beats everyone). Read after Lesson 5.4 §2.
Chapters: Ch 5, Ch 6 -
[CLANG-SemaStmt] Clang's semantic analysis of statements (range-based for) —
clang/lib/Sema/SemaStmt.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Sema::BuildCXXForRangeStmt.
Why and when: A range-basedforkeeps its own AST node but gets implicit__range,__begin,__endvariables — partial desugaring (Lesson 5.6 §5).
Chapters: Ch 5 -
[CLANG-Stmt] Clang's statement/expression base classes (arena-only allocation, kind field) —
clang/include/clang/AST/Stmt.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Stmt::operator new,Stmt::getStmtClass,Expr::classof.
Why and when: The protected plainoperator newand theASTContext&one;Expr::classofinExpr.his the interval test of Theorem 4.7.11. Read after Lesson 4.7 §2.
Chapters: Ch 4 -
[CLANG-StmtNodes] Clang's TableGen list of statement and expression classes —
clang/include/clang/Basic/StmtNodes.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:StmtNode,Expr,BinaryOperator.
Why and when: The node list that generates the kind enum, the ranges and the visitors (Definition 4.7.1, Lesson 4.7 §6). Compare with Pebble'sASTNodes.def.
Chapters: Ch 4 -
[CLANG-TemplateInst] Clang's template instantiation (monomorphization) —
clang/lib/Sema/SemaTemplateInstantiateDecl.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Sema::InstantiateFunctionDefinition.
Why and when: Wherebiggest<int>of Lesson 6.9's box is produced: the template's body is re-checked with the type arguments substituted. Read after Lesson 6.9 §7.
Chapters: Ch 6 -
[CLANG-TextDiag] Clang's textual diagnostic printer (carets, ranges, fix-its) —
clang/lib/Frontend/TextDiagnostic.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TextDiagnostic::emitParseableFixits,TextDiagnostic::emitSnippetAndCaret.
Why and when: How spans become carets and fix-its becomefix-it:lines (Definition 5.8.1). Read after Lesson 5.8 §2 and runclang -fdiagnostics-parseable-fixits.
Chapters: Ch 5 -
[CLANG-Unicode] Clang's Unicode identifier range tables —
clang/lib/Lex/UnicodeCharSets.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:XIDStartRanges,XIDContinueRanges,C11AllowedIDCharRanges,C99AllowedIDCharRanges.
Why and when: The same range-table representation as Pebble's generated XIDTables.inc, plus the frozen C99/C11 lists (Lesson 1.9 §6).
Chapters: Ch 1 -
[CLANG-Uninit] Clang's uninitialized-variables analysis (-Wuninitialized, -Wsometimes-uninitialized) —
clang/lib/Analysis/UninitializedValues.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:runUninitializedVariablesAnalysis,TransferFunctions.
Why and when: A may/must uninitialized analysis over Clang's CFG, a warning rather than definite assignment's error. Read after Lesson 5.7 §4.
Chapters: Ch 5 -
[CLANG-UNINIT] The analysis behind -Wuninitialized and -Wsometimes-uninitialized —
clang/lib/Analysis/UninitializedValues.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:runUninitializedVariablesAnalysis,CFGBlockValues,TransferFunctions.
Why and when: Definite initialization as a forward worklist over packed bit vectors (Lessons 14.3 and 14.4).
Chapters: Ch 14 -
[CLANG-X86ABI] Clang's System V x86-64 classification and coercion —
clang/lib/CodeGen/Targets/X86.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:X86_64ABIInfo::classify,X86_64ABIInfo::GetINTEGERTypeAtOffset,X86_64ABIInfo::GetSSETypeAtOffset,X86_64ABIInfo::classifyArgumentType.
Why and when: Algorithm 11.5.4 in production, including the rule that picksi32ori64for an INTEGER eightbyte; theabi-classifydrill's oracle matches its output. Read after Lesson 11.5 §2.
Chapters: Ch 11 -
[CompCert-Compiler] CompCert's pipeline and its correctness theorem —
driver/Compiler.vinAbsInt/CompCertatv3.15. Symbols:transf_rtl_program,transf_c_program,transf_c_program_correct,c_semantic_preservation.
Why and when: Core reading. Lesson 24.1 §7 readstransf_rtl_programas a staged design withRenumbergates; Lesson 24.7 §3–4 readstransf_c_program_correctand the composition of simulations. Read the pass list first, then the theorem statement, then the proof script's structure.
Chapters: Ch 24 -
[COMPCERT-CSE] CompCert's verified value numbering over extended basic blocks —
backend/CSE.vinAbsInt/CompCertatv3.15. Symbols:transf_function,CSEproof.v transf_program_correct,driver/Compiler.v transf_c_program_correct.
Why and when: A superlocal value-numbering pass with a Coq proof (Lessons 13.1 and 13.9). Read the header comment of CSE.v and the statement of transf_program_correct.
Chapters: Ch 13 -
[COMPCERT-msgs] CompCert's hand-written syntax error messages for its Menhir C parser —
cparser/handcrafted.messagesinAbsInt/CompCertatv3.15. Symbols:error sentences and messages.
Why and when: A real .messages file (Lesson 3.7): sentences from --list-errors with a hand-written message each.
Chapters: Ch 3 -
[CompCert-Smallstep] CompCert's simulation diagrams —
common/Smallstep.vinAbsInt/CompCertatv3.15. Symbols:fsim_properties,forward_simulation,forward_simulation_star,compose_forward_simulations,forward_to_backward_simulation,determinate.
Why and when: Core reading. Definition 24.7.4 verbatim (fsim_properties), the special cases each pass proof picks, and the forward-to-backward theorem that needs determinism.backend/Inliningproof.vshows a proof that usesforward_simulation_star.
Chapters: Ch 24 -
[COMPILERRT-Divti3] compiler-rt's 128-bit signed division helper —
compiler-rt/lib/builtins/divti3.cinllvm/llvm-projectatllvmorg-23.1.2. Symbols:__divti3.
Why and when: A runtime-library function in its smallest form: one file per function, so an archive links only what is used (Lesson 11.9 §3 and §6).
Chapters: Ch 11 -
[CPY-Ceval] CPython's bytecode interpreter loop —
Python/ceval.cinpython/cpythonatv3.11.15. Symbols:_PyEval_EvalFrameDefault,USE_COMPUTED_GOTOS.
Why and when: A production stack VM with token-threaded dispatch throughPython/opcode_targets.hwhen the compiler supports computed goto (Lesson 0.2).
Chapters: Ch 0 -
[CPY-Compile] CPython's bytecode compiler (AST to stack bytecode) —
Python/compile.cinpython/cpythonatv3.11.15.
Why and when: The postorder code generator for CPython's stack bytecode shown bydisin Lesson 8.1;Python/ceval.cis the interpreter.
Chapters: Ch 8 -
[CPY-Gram] CPython's PEG grammar —
Grammar/python.graminpython/cpythonatv3.11.15. Symbols:sum,term,factor,power.
Why and when: A production PEG with left-recursive layered expression rules and(memo)markers (Lessons 4.1 and 4.2 §7). Read the expression section.
Chapters: Ch 4 -
[CPY-pegen] CPython's PEG parser generator (pegen) —
Tools/peg_generator/pegen/parser_generator.pyinpython/cpythonatv3.13.0. Symbols:compute_left_recursives.
Why and when: Left-corner SCCs and "leaders" for left recursion (Lesson 2.4 §7); the generated parsers'memoizeandmemoize_left_reclive inpegen/parser.py(Lesson 2.5 §7) andpegen/first_sets.pyhasFirstSetCalculator(Lesson 2.2 §7).
Chapters: Ch 2, Ch 4 -
[CPY-Spec] CPython 3.11's specializing adaptive interpreter (PEP 659) —
Python/specialize.cinpython/cpythonatv3.11.15. Symbols:_PyCode_Quicken,_Py_Specialize_BinaryOp.
Why and when: Quickening and specialization (BINARY_OP_ADD_INT) seen in Lesson 0.2'sdisbox.
Chapters: Ch 0 -
[CPY-Symtable] CPython's symbol-table pass (local, global, free and cell variables) —
Python/symtable.cinpython/cpythonatv3.13.0. Symbols:analyze_name,symtable_analyze,PySymtable_Build.
Why and when: A separate pass that classifies every name per scope before code generation (LEGB, PEP 227): why assignment anywhere in a function makes a name local. Read after Lesson 5.1 §2.
Chapters: Ch 5 -
[CPY38-pgen] CPython 3.8's LL(1) parser generator pgen —
Parser/pgen/pgen.pyinpython/cpythonatv3.8.0. Symbols:ParserGenerator.addfirstsets,ParserGenerator.calcfirst.
Why and when: FIRST sets over per-rule DFAs and the "rule … is ambiguous" FIRST/FIRST check (Lessons 2.2 and 2.3); the table-driven driver isParser/parser.c,PyParser_AddToken. The last release before the PEG switch.
Chapters: Ch 2 -
[CPYTHON-Lexer] CPython's C tokenizer (INDENT/DEDENT) —
Parser/lexer/lexer.cinpython/cpythonatv3.13.0. Symbols:tok_get_normal_mode.
Why and when: The indentation stack of Algorithm 1.7.10 in the tokenizer the Python compiler actually uses. Search for INDENT and DEDENT after Lesson 1.7.
Chapters: Ch 1 -
[CPYTHON-Tokenize] Python's pure-Python tokenizer built from regex combinators —
Lib/tokenize.pyinpython/cpythonatv3.13.0. Symbols:group,any,maybe,PseudoToken.
Why and when: Lesson 1.5's regex-combinator style: token patterns assembled by small helper functions and run by Python's backtracking engine.
Chapters: Ch 1 -
[Cranelift-Dom] Cranelift's Semi-NCA dominator tree (and its CHK baseline in dominator_tree/simple.rs) —
cranelift/codegen/src/dominator_tree.rsinbytecodealliance/wasmtimeatv36.0.0. Symbols:DominatorTree::compute,SimpleDominatorTree.
Why and when: Semi-NCA for production, CHK kept as a simple baseline; the comment lists Julia, SpiderMonkey and LLVM as other Semi-NCA users.
Chapters: Ch 15 -
[Cranelift-ISLE] Cranelift's mid-end simplification rules in ISLE (and opts/cprop.isle) —
cranelift/codegen/src/opts/arithmetic.isleinbytecodealliance/wasmtimeatv37.0.2. Symbols:(rule (simplify (isub (ty_int ty) x x)) ...),cprop.isle push immediates to the right.
Why and when: A typed term-rewriting DSL applied inside an acyclic e-graph (Lessons 13.2 and 13.4). Read arithmetic.isle and the canonicalization rules of cprop.isle.
Chapters: Ch 13 -
[Cranelift-Loops] Cranelift's natural-loop analysis —
cranelift/codegen/src/loop_analysis.rsinbytecodealliance/wasmtimeatv36.0.0. Symbols:LoopAnalysis::compute,find_loop_headers,discover_loop_blocks.
Why and when: Natural loops in their plainest form ("a block is a loop header if it dominates any of its predecessors"); read after Lesson 15.5 §2.
Chapters: Ch 15 -
[CReduce] C-Reduce's driver and pass modules (Ubuntu 24.04 packages 2.11.0) —
creduce/creduce.inincsmith-project/creduceatmaster. Symbols:pass_lines,pass_clex,clang_delta.
Why and when: Algorithm 12.7.4's fixpoint loop over passes; read pass_lines.pm to see ddmin-style line deletion inside it.
Note: The repository has no 2.11.0 release tag; the pass modules are creduce/pass_.pm and the C++-aware transformations are in clang_delta/.
Chapters:* Ch 12 -
[Csmith] Csmith's random statement generation (see also src/FactPointTo.cpp, runtime/safe_math.m4) —
src/Statement.cppincsmith-project/csmithatcsmith-2.3.0. Symbols:Statement::make_random.
Why and when: Where Algorithm 12.5.6's random choices and safety checks live; safe_math.m4 generates the wrappers.
Chapters: Ch 12 -
[DOTNET-SRM] .NET's derivative-based non-backtracking regex engine —
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/Symbolic/SymbolicRegexNode.csindotnet/runtimeatv8.0.0. Symbols:SymbolicRegexNode.CreateDerivativeWrapper,SymbolicRegexNode.CreateNfaDerivativeWithEffects.
Why and when: Brzozowski derivatives over minterms (derivative classes) with a DFA cache and an NFA mode built from partial derivatives (Lesson 1.3).
Chapters: Ch 1 -
[EGG-Src] The egg e-graph implementation —
src/egraph.rsinegraphs-good/eggatv0.11.0. Symbols:EGraph::add,EGraph::union,EGraph::rebuild.
Why and when: Algorithm 8.5.8'sAdd,MergeandRebuild; theRunnerof the real-world box is insrc/run.rs.
Chapters: Ch 8 -
[Firm-Belady] libFirm's Belady-based spiller for SSA —
ir/be/bespillbelady.cinlibfirm/libfirmatlibfirm-1.22.0. Symbols:be_spill_belady.
Why and when: The global next-use spiller of [BH09] that makes pressure fit before colouring (Lesson 22.6).
Chapters: Ch 22 -
[Firm-Chordal] libFirm's chordal (dominance-order) colouring —
ir/be/bechordal.cinlibfirm/libfirmatlibfirm-1.22.0. Symbols:assign,create_borders.
Why and when: Algorithm 22.6.6 in production: pressure borders per block, colours assigned walking the dominator tree.
Chapters: Ch 22 -
[FLEX-DFA] flex's subset construction ("NFA to DFA") —
src/dfa.cinwestes/flexatv2.6.4. Symbols:ntod.
Why and when: The build-time subset construction over equivalence classes behind every flex scanner; no minimization pass follows (Lesson 1.2 §2).
Chapters: Ch 1 -
[GCC-bbreorder] GCC's basic-block reordering —
gcc/bb-reorder.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:reorder_basic_blocks,find_traces,reorder_basic_blocks_simple.
Why and when: Trace-based ("software trace cache") and simple reordering, and hot/cold partitioning; compare with [LLVM-MBP].
Chapters: Ch 23 -
[GCC-CCP] GCC's conditional constant propagation on SSA —
gcc/tree-ssa-ccp.ccingcc-mirror/gccatreleases/gcc-15. Symbols:ccp_lattice_t.
Why and when: Wegman–Zadeck CCP with a four-level lattice; its header comment is a good summary of Algorithm 14.6.6 (Lessons 14.3 and 14.6).
Chapters: Ch 14, Ch 17 -
[GCC-CDecl] GCC's C front end scopes and bindings —
gcc/c/c-decl.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:bind,pop_scope,warn_if_shadowing,c_binding.
Why and when: A single table with per-name binding chains plus a per-scope list, restored bypop_scope: Algorithm 5.2.4 with an intrusive undo log. Read after Lesson 5.2 §7.
Chapters: Ch 5 -
[GCC-CFGAnal] GCC's DFS orders over the CFG —
gcc/cfganal.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:post_order_compute,pre_and_rev_post_order_compute.
Why and when: Postorder and RPO as GCC computes them (Lesson 8.2 §7).
Chapters: Ch 8 -
[GCC-Cfganal] GCC's CFG analyses (DFS back edges, CHK frontiers, DF+, control dependence) —
gcc/cfganal.ccingcc-mirror/gccatreleases/gcc-15. Symbols:mark_dfs_back_edges,compute_dominance_frontiers,compute_idf,connect_infinite_loops_to_exit,control_dependences::find_control_dependence.
Why and when: One file with four of the chapter's techniques: the runner loop of Algorithm 15.3.8, the worklist of Algorithm 15.3.11, the FOW walk of Algorithm 15.4.10 and DFS_BACK marking.
Chapters: Ch 15 -
[GCC-CH] GCC's loop header copying (rotation) —
gcc/tree-ssa-loop-ch.ccingcc-mirror/gccatreleases/gcc-15.1.0.
Why and when: GCC's form of Lesson 18.5's loop rotation.
Chapters: Ch 18 -
[GCC-Chrec] GCC's chrec algebra —
gcc/tree-chrec.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:chrec_fold_plus,chrec_fold_multiply,chrec_apply.
Why and when: The CR operations of Lemmas 18.3.3–18.3.4 in production code.
Chapters: Ch 18 -
[GCC-Coalesce] GCC's SSA-name coalescing into partitions —
gcc/tree-ssa-coalesce.ccingcc-mirror/gccatreleases/gcc-15. Symbols:build_ssa_conflict_graph,coalesce_partitions,live_track_process_def.
Why and when: Conflict graph with Chaitin's copy exception and a cost-sorted coalesce list; the partitions are Sreedhar's phi congruence classes after coalescing (Lesson 16.6-16.7 boxes).
Chapters: Ch 16 -
[GCC-Combine] GCC's instruction combiner —
gcc/combine.ccingcc-mirror/gccatreleases/gcc-15. Symbols:try_combine,combine_instructions.
Why and when: The descendant of Davidson–Fraser combining (Algorithm 21.1.11): merges two to four linked instructions and keeps the result if recog accepts it. Read the header comment.
Chapters: Ch 21 -
[GCC-CParser] GCC's hand-written recursive-descent C parser —
gcc/c/c-parser.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:c_parser_statement,c_parser_if_statement,c_parser_binary_expression,c_parser_skip_until_found.
Why and when: The same shapes as Clang's parser in another code base: left-factored if (with -Wdangling-else), an operator-precedence stack for binary expressions, and panic mode.
Chapters: Ch 2, Ch 3, Ch 4 -
[GCC-CPCall] GCC's C++ overload resolution —
gcc/cp/call.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:joust,tourney,build_new_function_call,compare_ics.
Why and when:tourneyandjoustare the tournament of Algorithm 5.4.3 by name;compare_icsranks conversion sequences. Read after Lesson 5.4 §2.
Chapters: Ch 5 -
[GCC-CPChangeLog] The GCC C++ ChangeLog entry removing the yacc grammar —
gcc/cp/ChangeLog.3ingcc-mirror/gccatreleases/gcc-3.4.0. Symbols:2002-12-30 parse.y: Remove..
Why and when: Primary evidence for the switch from a yacc-generated to a hand-written C++ parser (Lesson 3.8).
Chapters: Ch 3 -
[GCC-CPP] The GNU C preprocessor manual (Texinfo source) —
gcc/doc/cpp.texiingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:Macro Pitfalls,Operator Precedence Problems,Self-Referential Macros,Argument Prescan.
Why and when: The catalogue of token-macro pitfalls that motivate Lesson 4.8: precedence, duplicated side effects, self-reference, prescan. Read the "Macro Pitfalls" node.
Chapters: Ch 4 -
[GCC-CPParser] GCC's hand-written recursive-descent C++ parser —
gcc/cp/parser.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:cp_parser_statement,cp_parser_parse_tentatively,cp_parser_parse_definitely,cp_parser_simulate_error,cp_parser_skip_to_end_of_statement.
Why and when: Read the long header comment ("Future Improvements" discusses the cost of tentative parsing, quoted in Lesson 2.5 §5) and the tentative-parsing trio.
Chapters: Ch 2, Ch 3 -
[GCC-CPParserBin] GCC's C++ parser, binary expressions —
gcc/cp/parser.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:cp_parser_binary_expression.
Why and when: The C++ front end's version of the same stack-based algorithm, with template-argument complications (>closing a template). Read after [GCC-CParser].
Chapters: Ch 4 -
[GCC-CPROP] GCC's global constant/copy propagation on RTL (dense, available sets) —
gcc/cprop.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:one_cprop_pass.
Why and when: Kildall-style dense propagation over available assignments, still in GCC's RTL pipeline (Lesson 17.1's Kildall box).
Chapters: Ch 17 -
[GCC-DataRef] GCC's data dependence analysis —
gcc/tree-data-ref.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:compute_affine_dependence,analyze_siv_subscript,analyze_miv_subscript.
Why and when: ZIV/SIV/MIV subscript tests (Lesson 18.6) as GCC's vectorizer and loop passes use them.
Chapters: Ch 18 -
[GCC-DCE] GCC's DCE and control-dependence DCE (cddce) —
gcc/tree-ssa-dce.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:find_obviously_necessary_stmts,mark_control_dependent_edges_necessary,perform_tree_ssa_dce.
Why and when: Mark-sweep DCE and its aggressive variant in one file; its finite-loop test is the GCC answer to "may not terminate" (Lesson 17.3 §7).
Chapters: Ch 17 -
[GCC-Devirt] GCC's type inheritance graph, polymorphic call targets and speculative devirtualization —
gcc/ipa-devirt.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:possible_polymorphic_call_targets,type_possibly_instantiated_p,ipa_devirt.
Why and when: CHA with an RTA-like instantiation filter and speculative devirtualization. Read possible_polymorphic_call_targets after Lesson 20.1 §7 and ipa_devirt with Lesson 20.7.
Chapters: Ch 20 -
[GCC-DF] GCC's RTL dataflow framework (problems in gcc/df-problems.cc) —
gcc/df-core.ccingcc-mirror/gccatreleases/gcc-15. Symbols:df_analyze,df_analyze_problem,df_worklist_dataflow,df_worklist_dataflow_doublequeue.
Why and when: A production worklist solver over bitmaps with the live-register and reaching-definitions problems (Lessons 14.2–14.4); the dump boxes show its visit counts.
Chapters: Ch 14 -
[GCC-Distribution] GCC's loop distribution —
gcc/tree-loop-distribution.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:loop_distribution::build_rdg,loop_distribution::classify_partition,loop_distribution::distribute_loop.
Why and when: Distribution over a reduced dependence graph, with memset/memcpy partitions (Lesson 18.7).
Chapters: Ch 18 -
[GCC-Dominance] GCC's Lengauer-Tarjan (balanced) and its CHK-based incremental fix-up —
gcc/dominance.ccingcc-mirror/gccatreleases/gcc-15. Symbols:dom_info::calc_idoms,dom_info::eval,dom_info::compress,dom_info::link_roots,iterate_fix_dominators.
Why and when: Sophisticated-linking Lengauer-Tarjan for full builds and CHK for small affected block sets; read the header comment after Lesson 15.1 and iterate_fix_dominators after Lesson 15.2.
Chapters: Ch 15 -
[GCC-Dwarf2out] GCC's DWARF emitter —
gcc/dwarf2out.ccingcc-mirror/gccatreleases/gcc-15. Symbols:add_location_or_const_value_attribute,loc_list_from_tree,dw_loc_list.
Why and when: The same location-list construction from GCC'svar_loc_list(produced byvar-tracking.cc). Skim after Lesson 24.4 §7 for the comparison; the file is enormous, grep the symbols.
Chapters: Ch 24 -
[GCC-Expand] GCC's expansion from GIMPLE to RTL —
gcc/cfgexpand.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:pass_expand,expand_gimple_basic_block.
Why and when: The GIMPLE → RTL step of GCC's pipeline (Lesson 8.7).
Chapters: Ch 8 -
[GCC-Expmed] GCC's expansion of signed division by a power of two —
gcc/expmed.ccingcc-mirror/gccatreleases/gcc-15. Symbols:expand_sdiv_pow2.
Why and when: The same bias sequence as Theorem 12.3.9, chosen per target cost.
Chapters: Ch 12 -
[GCC-fold-const] GCC's GENERIC constant folder —
gcc/fold-const.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:const_binop,int_const_binop,fold_binary_loc.
Why and when: GCC's counterpart of ConstantFolding.cpp, including the TREE_OVERFLOW marking seen in the Lesson 13.1 box.
Chapters: Ch 13 -
[GCC-GCSE] GCC's RTL global CSE and PRE —
gcc/gcse.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:one_pre_gcse_pass.
Why and when: Its header lists the literature from Morel–Renvoise to lazy code motion; RTL PRE on top of lcm.cc (Lesson 17.6 §7).
Chapters: Ch 17 -
[GCC-genautomata] GCC's pipeline-automaton generator —
gcc/genautomata.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:define_automaton,define_insn_reservation,minimize_DFA.
Why and when: Builds, minimizes and factors the automata of Proposition 23.1.7 from a target's reservation descriptions. The long header comment is the design document; read it after [Mak03].
Chapters: Ch 23 -
[GCC-GimpleH] GIMPLE statement classes —
gcc/gimple.hingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:gassign.
Why and when:gassignholds one operator and its operands: GCC's quadruple (Definition 8.1.2).
Chapters: Ch 8 -
[GCC-Gimplify] GCC's gimplifier (GENERIC to GIMPLE three-address code) —
gcc/gimplify.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:gimplify_function_tree,gimplify_expr.
Why and when: Where GCC produces the TAC of Lesson 8.1's GIMPLE box.
Chapters: Ch 8, Ch 11 -
[GCC-Graphite] GCC Graphite's isl scheduling and tiling —
gcc/graphite-optimize-isl.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:optimize_isl.
Why and when: GCC's polyhedral optimizer (Lesson 18.7's Graphite box); the driver isgcc/graphite.cc.
Chapters: Ch 18 -
[GCC-haifa] GCC's list scheduler (Haifa) —
gcc/haifa-sched.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:schedule_block,priority,rank_for_schedule,model_schedule.
Why and when: A cycle-driven top-down scheduler with a long list of tie-breaks (rank_for_schedule) and the-fsched-pressuremodel. Readpriorityafter Lesson 23.2 andschedule_blockafter Algorithm 23.3.2.
Chapters: Ch 23 -
[GCC-I386] GCC's System V x86-64 argument classification —
gcc/config/i386/i386.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:classify_argument.
Why and when: The same psABI rules as Clang's, applied to RTL modes; read with Algorithm 11.5.4 for a second implementation.
Chapters: Ch 11 -
[GCC-i386md] GCC's x86 machine description (RTL instruction patterns) —
gcc/config/i386/i386.mdingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:*add<mode>_1<nf_name>.
Why and when: The target description GCC's back end is generated from; the add patterns carry the flags clobber visible in Lesson 0.4's RTL dump (which was produced by gcc 13.3, where the pattern is named*add<mode>_1; gcc 15 adds the APX<nf_name>suffix).
Chapters: Ch 0 -
[GCC-ifcvt] GCC's RTL if-converter —
gcc/ifcvt.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:noce_process_if_block,cond_exec_process_if_block.
Why and when: Both flavors in one file: selects/cmov(noce_*) and predication (cond_exec_*). Compare with LLVM's two passes after Lesson 23.5 §7.
Chapters: Ch 23 -
[GCC-Inline] GCC's inliner (priority queue by badness, unit-growth limits) —
gcc/ipa-inline.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:inline_small_functions,edge_badness,want_inline_small_function_p.
Why and when: The greedy benefit/cost inliner of Algorithm 20.3.5. Read edge_badness after Lesson 20.3 §2 and the GCC box of §7.
Chapters: Ch 20 -
[GCC-Interchange] GCC's loop interchange —
gcc/gimple-loop-interchange.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:tree_loop_interchange::valid_data_dependences,should_interchange_loops.
Why and when: Interchange legality and a stride cost model (Lesson 18.7's GCC box).
Chapters: Ch 18 -
[GCC-IntoSSA] GCC's SSA construction —
gcc/tree-into-ssa.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:pass_build_ssa,insert_phi_nodes.
Why and when: Where thePHI <…>nodes of Lesson 8.4's GIMPLE SSA box come from.
Chapters: Ch 8, Ch 16 -
[GCC-IPACP] GCC's interprocedural constant propagation and cloning —
gcc/ipa-cp.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:decide_about_value,create_specialized_node.
Why and when: Jump functions, lattices per parameter and .constprop clones (Lessons 20.4 and 20.5).
Chapters: Ch 20 -
[GCC-IPAPureConst] GCC's nothrow propagation over the call graph —
gcc/ipa-pure-const.ccingcc-mirror/gccatreleases/gcc-15. Symbols:propagate_nothrow,stmt_can_throw_external.
Why and when: The GCC form of Algorithm 24.6.7: acan_throwsummary per function, propagated overipa_reduced_postorder. Readpropagate_nothrowafter Lesson 24.6 §7.
Chapters: Ch 24 -
[GCC-IRA] GCC's integrated register allocator (regional Chaitin–Briggs colouring) —
gcc/ira-color.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:color_allocnos,push_allocnos_to_stack,pop_allocnos_from_stack.
Why and when: Optimistic colouring over a loop tree; the header comment of gcc/ira.cc (same tag) is the best overview of IRA's regions and cost model.
Chapters: Ch 22 -
[GCC-Ivcanon] GCC's complete unrolling and peeling —
gcc/tree-ssa-loop-ivcanon.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:try_peel_loop.
Why and when: Full unrolling and complete peeling of loops with small trip counts (Lesson 18.5).
Chapters: Ch 18 -
[GCC-IVOPTS] GCC's induction-variable optimizations —
gcc/tree-ssa-loop-ivopts.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:find_induction_variables,find_iv_candidates,may_eliminate_iv.
Why and when: Biv/giv detection, strength reduction and IV elimination by cost (Lessons 18.2 and 18.4).
Chapters: Ch 18 -
[GCC-LCM] GCC's generic lazy code motion on edges —
gcc/lcm.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:pre_edge_lcm,compute_antinout_edge,compute_earliest,compute_laterin.
Why and when: Algorithm 17.6.6 as a reusable library: ANTIN/ANTOUT, EARLIEST, LATERIN, INSERT and DELETE over bitmaps, shared by PRE and other placement problems.
Chapters: Ch 17 -
[GCC-LCSSA] GCC's loop-closed SSA rewriting —
gcc/tree-ssa-loop-manip.ccingcc-mirror/gccatreleases/gcc-15. Symbols:rewrite_into_loop_closed_ssa,rewrite_into_loop_closed_ssa_1.
Why and when: The GCC counterpart of LLVM's LCSSA pass (Lesson 15.7 §7); read with the GCC-LoopDoc node.
Chapters: Ch 15 -
[GCC-Lex] GCC's C/C++ lexer (libcpp) —
libcpp/lex.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:_cpp_lex_direct,search_line_sse2,init_vectorized_lexer.
Why and when: The hand-written lexer of GCC with SIMD line scanning chosen at startup (Lesson 1.5).
Chapters: Ch 1 -
[GCC-LIM] GCC's loop invariant motion and store motion —
gcc/tree-ssa-loop-im.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:determine_max_movement,hoist_memory_references,execute_sm.
Why and when: Hoisting to the outermost loop in one step and store motion (Lesson 18.1).
Chapters: Ch 18 -
[GCC-LoopCH] GCC's loop header copying (loop rotation) —
gcc/tree-ssa-loop-ch.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:pass_ch.
Why and when: GCC's rotation of top-tested loops into guarded do-while form (Lesson 11.4, Algorithm 11.4.7).
Chapters: Ch 11 -
[GCC-LoopIV] GCC's RTL induction-variable analysis —
gcc/loop-iv.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:iv_analyze_biv.
Why and when: Classic basic-IV detection on registers (Lesson 18.2's Algorithm 18.2.2).
Chapters: Ch 18 -
[GCC-LoopManip] GCC's loop-closed SSA —
gcc/tree-ssa-loop-manip.ccingcc-mirror/gccatreleases/gcc-15. Symbols:rewrite_into_loop_closed_ssa,verify_loop_closed_ssa.
Why and when: GCC's LCSSA, with a verifier that checks the form after every loop pass: the canonical-form discipline of Lesson 24.1 §7 in GCC.
Chapters: Ch 24 -
[GCC-Loops] GCC's SCC-based irreducible-region marking —
gcc/cfgloopanal.ccingcc-mirror/gccatreleases/gcc-15. Symbols:mark_irreducible_loops.
Why and when: Throws away latch edges and marks blocks and edges inside remaining SCCs (IRREDUCIBLE_LOOP): the Steensgaard-style marking of Lesson 15.5 §7; natural loops are found by flow_loops_find in gcc/cfgloop.cc.
Chapters: Ch 15 -
[GCC-LRA] GCC's local register allocator (constraints, reloads, final substitution) —
gcc/lra.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:lra.
Why and when: GCC's rewriter and constraint solver after IRA; lra-constraints.cc (same tag) splits pseudos and inserts reloads (Lessons 22.5 §7 and 22.8 §7).
Chapters: Ch 22 -
[GCC-LRARemat] GCC LRA's rematerialization sub-pass —
gcc/lra-remat.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:lra_remat.
Why and when: Rematerialization as an availability dataflow problem; the header comment quoted in Lesson 22.9 §7 states the conditions of Definition 22.9.4.
Chapters: Ch 22 -
[GCC-Modref] GCC's mod/ref summaries (ipa-modref) —
gcc/ipa-modref.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:modref_summary,analyze_function,modref_propagate_in_scc.
Why and when: Bottom-up per-function memory summaries propagated over SCCs — Lessons 20.2, 20.5 and 20.6 in one production pass.
Chapters: Ch 20 -
[GCC-MultipleTarget] GCC's function multiversioning (target_clones) —
gcc/multiple_target.ccingcc-mirror/gccatreleases/gcc-15. Symbols:expand_target_clones,create_dispatcher_calls.
Why and when: The origin oftarget_clones: one body per target, a dispatcher resolved through IFUNC. Readexpand_target_clonesafter Lesson 24.2 §7's Clang box.
Chapters: Ch 24 -
[GCC-NameLookup] GCC's C++ name lookup, including ADL —
gcc/cp/name-lookup.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:lookup_arg_dependent,name_lookup::adl_expr.
Why and when: GCC's version of Algorithm 5.4.5: the associated namespaces and classes of each argument type. Read after Lesson 5.4 §3, next to [CLANG-SemaLookup].
Chapters: Ch 5 -
[GCC-Niter] GCC's trip-count computation —
gcc/tree-ssa-loop-niter.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:number_of_iterations_exit,number_of_iterations_ne,number_of_iterations_lt.
Why and when: Trip counts for!=and<exits (Theorems 18.3.13–18.3.14).
Chapters: Ch 18 -
[GCC-Opts] Which -f options each -O level enables in GCC —
gcc/opts.ccingcc-mirror/gccatreleases/gcc-15. Symbols:default_options_table.
Why and when: GCC's counterpart of LLVM's pipeline builders: levels are sets of flags that gate passes.
Chapters: Ch 12 -
[GCC-OutOfSSA] GCC's translation out of SSA (per-edge elimination graphs) —
gcc/tree-outof-ssa.ccingcc-mirror/gccatreleases/gcc-15. Symbols:eliminate_phi,elim_create,insert_partition_copy_on_edge,insert_backedge_copies.
Why and when: Copies on edges between coalesced partitions, ordered by an elimination graph with a temporary for cycles: GCC's parallel-copy sequentializer (Lesson 16.7).
Chapters: Ch 16 -
[GCC-Passes] GCC's pass list (GIMPLE, IPA and RTL passes in order) —
gcc/passes.defingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:pass_build_ssa_passes,pass_expand.
Why and when: GCC's pipeline as data: everyNEXT_PASSline is one pass;pass_expandis the GIMPLE-to-RTL boundary of Lesson 0.4.gcc/passes.ccruns the list.
Chapters: Ch 0, Ch 12 -
[GCC-PassesDef] GCC's pass tree —
gcc/passes.defingcc-mirror/gccatreleases/gcc-15. Symbols:INSERT_PASSES_AFTER,PUSH_INSERT_PASSES_WITHIN,NEXT_PASS.
Why and when: The whole optimization pipeline in one file; count the instances of pass_ccp and pass_fre (Lesson 12.2).
Chapters: Ch 12, Ch 24 -
[GCC-PolyCall] GCC's polymorphic call contexts (dynamic-type tracking) —
gcc/ipa-polymorphic-call.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:ipa_polymorphic_call_context.
Why and when: Flow-sensitive tracking of an object's dynamic type before target lookup — GCC's closest relative of XTA/VTA (Lesson 20.1 §7).
Chapters: Ch 20 -
[GCC-PRE] GCC's tree PRE (GVN-PRE), FRE and code hoisting —
gcc/tree-ssa-pre.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:compute_antic,do_pre_regular_insertion.
Why and when: ANTIC_IN/ANTIC_OUT over value expressions with phi-translation, insertion, and the hoisting pass that shares its sets (Lesson 17.6 §7's box prints them).
Chapters: Ch 17 -
[GCC-RANGER] GCC's on-demand range analysis (Ranger) —
gcc/gimple-range.ccingcc-mirror/gccatreleases/gcc-15. Symbols:gimple_ranger::range_of_stmt.
Why and when: Intervals (multi-ranges) on demand, the engine behind VRP (Lesson 14.7 §7).
Chapters: Ch 14 -
[GCC-reassoc] GCC's rank-based reassociation pass —
gcc/tree-ssa-reassoc.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:get_rank,reassociate_bb.
Why and when: Ranks, linearization, merging of equal operands and constant folding (Lesson 13.6 §7). Read get_rank after the lesson.
Chapters: Ch 13 -
[GCC-regrename] GCC's post-allocation register renaming —
gcc/regrename.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:regrename_analyze,find_rename_reg.
Why and when: Removes false dependences after allocation by renaming chains to free registers (Algorithm 23.8.8); compare with LLVM's anti-dependence breakers.
Chapters: Ch 23 -
[GCC-SCCVN] GCC's value numbering over SSA, in RPO —
gcc/tree-ssa-sccvn.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:do_rpo_vn,run_rpo_vn.
Why and when: Global value numbering in GCC, named for the traversal order of Lesson 8.2; the global big sibling of Lesson 8.3's local value numbering.
Chapters: Ch 8, Ch 17 -
[GCC-sccvn] GCC's value numbering (FRE/PRE) —
gcc/tree-ssa-sccvn.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:do_rpo_vn,visit_nary_op.
Why and when: Value numbering over SSA in RPO, with expression simplification in the table (Lesson 13.5 §7). Optional reading after Lesson 13.5.
Chapters: Ch 13 -
[GCC-SCEV] GCC's scalar evolution analysis —
gcc/tree-scalar-evolution.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:analyze_scalar_evolution,instantiate_scev.
Why and when: Chains of recurrences on GIMPLE SSA ([PCS05]); compare with LLVM's SCEV after Lesson 18.3.
Chapters: Ch 18 -
[GCC-sched-deps] GCC's dependence analysis for the scheduler —
gcc/sched-deps.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:sched_analyze,add_dependence,flush_pending_lists.
Why and when: GCC's counterpart ofbuildSchedGraph, with pending read/write lists capped by--param max-pending-list-length. Compare with [LLVM-SDInstrs] after Lesson 23.2 §7.
Chapters: Ch 23 -
[GCC-sched-rgn] GCC's interblock (region) scheduler —
gcc/sched-rgn.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:find_rgns,add_branch_dependences,compute_trg_info.
Why and when: Region formation over the CFG and speculative interblock motion ([BR91]); also where GCC adds the control edges of Definition 23.2.7. Readfind_rgnsafter Lesson 23.4 §7.
Chapters: Ch 23 -
[GCC-selsched] GCC's selective scheduler —
gcc/sel-sched.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:sel_sched_region,moveup_expr,generate_bookkeeping_insn.
Why and when: A living trace-scheduling descendant that still generates bookkeeping copies (generate_bookkeeping_insn). Read after Theorem 23.4.10 to see compensation in production code.
Chapters: Ch 23 -
[GCC-Sink] GCC's code sinking pass —
gcc/tree-ssa-sink.ccingcc-mirror/gccatreleases/gcc-15.1.0.
Why and when: Sinking statements toward their uses, including out of loops (Lesson 18.1).
Chapters: Ch 18 -
[GCC-SLP] GCC's SLP vectorizer —
gcc/tree-vect-slp.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:vect_build_slp_tree,vect_slp_function.
Why and when: SLP trees for basic blocks and loops (Lesson 18.8's SLP box).
Chapters: Ch 18 -
[GCC-SLSR] GCC's straight-line strength reduction —
gcc/gimple-ssa-strength-reduction.ccingcc-mirror/gccatreleases/gcc-15.1.0.
Why and when: Strength reduction outside loops on related multiplications (Lesson 18.4's OSR box).
Chapters: Ch 18 -
[GCC-sms] GCC's swing modulo scheduler (-fmodulo-sched) —
gcc/modulo-sched.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:sms_schedule,sms_schedule_by_order,res_MII,generate_prolog_epilog.
Why and when: SMS on RTL with MII computation and prologue/epilogue generation; compare with [LLVM-Pipeliner] after Lesson 23.6 §7.
Chapters: Ch 23 -
[GCC-Spellcheck] GCC's spelling suggestions —
gcc/spellcheck.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:get_edit_distance,get_edit_distance_cutoff,best_match.
Why and when: OSA distance with cheaper case changes and a length-dependent cutoff: compare with Clang's rule (Lesson 5.8, Algorithm 5.8.6) after Lesson 5.8 §2.
Chapters: Ch 5 -
[GCC-Split] GCC's function splitting for partial inlining (fnsplit) —
gcc/ipa-split.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:find_split_points,split_function.
Why and when: Chooses a split point by estimated size and time and creates .part functions. Read after Lesson 20.4's partial inlining.
Chapters: Ch 20 -
[GCC-SSA] GCC's SSA verifier —
gcc/tree-ssa.ccingcc-mirror/gccatreleases/gcc-15. Symbols:verify_ssa.
Why and when: GCC's counterpart of LLVM's dominance check (Proposition 9.8.7); compare with Verifier::verifyDominatesUse after Lesson 9.8.
Chapters: Ch 9 -
[GCC-StructAlias] GCC's points-to analysis (field-sensitive Andersen with HVN, HCD and LCD-style cycle collapsing) —
gcc/tree-ssa-structalias.ccingcc-mirror/gccatreleases/gcc-14.2.0. Symbols:solve_constraints,perform_var_substitution,find_indirect_cycles,solve_graph,get_constraint_for_component_ref.
Why and when: The production inclusion-based solver of Lessons 19.4 and 19.6; the phases printed by-fdump-tree-ealias-detailsare these functions. Its comments cite Pearce–Kelly–Hankin, Heintze–Tardieu, Nuutila's SCC algorithm and Hardekopf–Lin (lazy cycle detection, and pointer/location equivalence). GCC 14.2 is the version installed in the course container.
Chapters: Ch 19 -
[GCC-SwitchConv] GCC's switch clustering and decision trees —
gcc/tree-switch-conversion.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:jump_table_cluster::can_be_handled,bit_test_cluster::find_bit_tests,switch_decision_tree::analyze_switch_statement.
Why and when: GCC's version of Algorithm 11.3.7: its own jump-table and bit-test clusters, then a decision tree; compare its dump with LLVM's choice in Lesson 11.3 §7.
Chapters: Ch 11 -
[GCC-Tail] GCC's tail-call marking and tail-recursion elimination —
gcc/tree-tailcall.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:find_tail_calls,process_assignment,eliminate_tail_call.
Why and when: Accumulator recognition (add and mult accumulators) and the loop construction — compare with LLVM's TRE after Lesson 20.8.
Chapters: Ch 20 -
[GCC-tracer] GCC's superblock formation pass (-ftracer) —
gcc/tracer.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:find_trace,tail_duplicate.
Why and when: Trace selection by profile and tail duplication on GIMPLE, a short and readable version of Algorithms 23.4.3 and 23.4.6.
Chapters: Ch 23 -
[GCC-TreeAlias] GCC's alias oracle (the query layer over points-to sets and type-based rules) —
gcc/tree-ssa-alias.ccingcc-mirror/gccatreleases/gcc-14.2.0. Symbols:refs_may_alias_p_1,ptr_derefs_may_alias_p,call_may_clobber_ref_p,ref_maybe_used_by_call_p,aliasing_component_refs_p,same_type_for_tbaa.
Why and when: GCC's counterpart of LLVM's AAResults: reference-reference and call-reference queries that combine points-to sets (tree-ssa-structalias.cc), access-path rules and TBAA alias sets. Read after Lesson 19.1 §7.
Chapters: Ch 19 -
[GCC-TreeCFG] GCC's GIMPLE CFG construction and critical-edge splitting —
gcc/tree-cfg.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:build_gimple_cfg,make_blocks,make_edges,split_critical_edges.
Why and when: GCC's leaders algorithm (make_blocks) and edges (make_edges); compare with Algorithm 8.2.3 and the-fdump-tree-cfgbox of Lesson 8.2.
Chapters: Ch 8 -
[GCC-TreeEH] GCC's GIMPLE exception-handling lowering and cleanup —
gcc/tree-eh.ccingcc-mirror/gccatreleases/gcc-15. Symbols:lower_resx,remove_unreachable_handlers,cleanup_empty_eh,pass_refactor_eh.
Why and when: What GCC does to EH regions between the front end and RTL: loweringRESX, deleting unreachable and empty handlers. The comparison point for SimplifyCFG's pad removal.
Chapters: Ch 24 -
[GCC-TreePass] GCC pass metadata, properties and TODO flags —
gcc/tree-pass.hingcc-mirror/gccatreleases/gcc-15. Symbols:pass_data,opt_pass,PROP_ssa,TODO_update_ssa.
Why and when: Definition 12.1.12 comes straight from this header.
Chapters: Ch 12 -
[GCC-Uninit] GCC's uninitialized-use warnings on SSA form —
gcc/tree-ssa-uninit.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:warn_uninitialized_vars,warn_uninit.
Why and when: Uninitialized uses found on SSA after optimization, so the result depends on-O: the opposite design choice to definite assignment (Lesson 5.7 §6).
Chapters: Ch 5 -
[GCC-UNINIT] GCC's -Wuninitialized and -Wmaybe-uninitialized —
gcc/tree-ssa-uninit.ccingcc-mirror/gccatreleases/gcc-15. Symbols:warn_uninitialized_vars,execute_late_warn_uninitialized.
Why and when: Uninitialized-use warnings on optimized SSA with predicate analysis (Lesson 14.3).
Chapters: Ch 14 -
[GCC-Unswitch] GCC's loop unswitching —
gcc/tree-ssa-loop-unswitch.ccingcc-mirror/gccatreleases/gcc-15.1.0.
Why and when: Unswitching on invariant conditions (Lesson 18.5).
Chapters: Ch 18 -
[GCC-Vect] GCC's loop vectorizer —
gcc/tree-vect-loop.ccingcc-mirror/gccatreleases/gcc-15.1.0. Symbols:vect_analyze_loop,vect_transform_loop.
Why and when: GCC's analysis and transformation of vectorizable loops, including epilogues and fully masked loops (Lesson 18.8).
Chapters: Ch 18 -
[GCC-Versioning] GCC's loop versioning for unit strides —
gcc/gimple-loop-versioning.ccingcc-mirror/gccatreleases/gcc-15.1.0.
Why and when: Versioning on "stride = 1" assumptions (Lesson 18.5 §7).
Chapters: Ch 18 -
[GHC-App] GHC's application checking with Quick Look —
compiler/GHC/Tc/Gen/App.hsinghc/ghcatghc-9.4.7-release. Symbols:tcApp,quickLookArg.
Why and when: Checking applications against expected types, and Quick Look (Lessons 7.2 §6 and 7.8).
Chapters: Ch 7 -
[GHC-Canonical] GHC's canonicalization of equality constraints —
compiler/GHC/Tc/Solver/Canonical.hsinghc/ghcatghc-9.4.7-release. Symbols:canEqNC.
Why and when: Decomposition, conflict and orientation of equalities — Martelli–Montanari's rules in GHC's solver (Lesson 7.1 §7).
Chapters: Ch 7 -
[GHC-Class] GHC's instance lookup for class constraints —
compiler/GHC/Tc/Instance/Class.hsinghc/ghcatghc-9.4.7-release. Symbols:matchGlobalInst.
Why and when: Instance resolution (Algorithm 7.7.4) in GHC. ReadmatchGlobalInstafter Lesson 7.7.
Chapters: Ch 7 -
[GHC-Prep] GHC's CorePrep pass (conversion to A-normal form) —
compiler/GHC/CoreToStg/Prep.hsinghc/ghcatghc-9.4.7-release. Symbols:corePrepPgm.
Why and when: "Convert to A-normal form; that is, function arguments are always variables": the pass behind Lesson 8.6's CorePrep box.
Chapters: Ch 8 -
[GHC-RdrEnv] GHC's renamer environments (persistent maps of local names) —
compiler/GHC/Types/Name/Reader.hsinghc/ghcatghc-9.4.7-release. Symbols:LocalRdrEnv,extendLocalRdrEnv,lookupLocalRdrEnv.
Why and when: A persistent environment (Algorithm 5.2.7) passed down the renamer's recursion; every binder gets a freshUnique. Read after Lesson 5.2 §7.
Chapters: Ch 5 -
[GHC-Solver] GHC's constraint solver entry points (OutsideIn(X)) —
compiler/GHC/Tc/Solver.hsinghc/ghcatghc-9.4.7-release. Symbols:simplifyInfer,solveWanteds,solveImplication,decideMonoTyVars.
Why and when: Generalization with constraints and implication solving (Lessons 7.3–7.4, 7.7). ReadsimplifyInferafter Lesson 7.4.
Chapters: Ch 7 -
[GHC-Specialise] GHC's specialiser (dictionary passing turned into monomorphization) —
compiler/GHC/Core/Opt/Specialise.hsinghc/ghcatghc-9.4.7-release. Symbols:specProgram.
Why and when: The optimization that removes dictionary arguments by cloning overloaded functions at the types they are used at: Lesson 6.9 §6's hybrid. Read the long comment at the top after the GHC box.
Chapters: Ch 6 -
[GHC-TcType] GHC's levels and touchability —
compiler/GHC/Tc/Utils/TcType.hsinghc/ghcatghc-9.4.7-release. Symbols:TcLevel,isTouchableMetaTyVar.
Why and when: Levels as in Lesson 7.3, reused for OutsideIn's touchable variables (Lesson 7.4).
Chapters: Ch 7 -
[GHC-Unify] GHC's eager unifier and skolemization —
compiler/GHC/Tc/Utils/Unify.hsinghc/ghcatghc-9.4.7-release. Symbols:unifyType.
Why and when: The unifier called during constraint generation, with the occurs and skolem-escape checks (Lessons 7.1 and 7.8).
Chapters: Ch 7 -
[GNULIB-DFA] GNU grep's DFA matcher (positions and lazily built states) —
lib/dfa.cincoreutils/gnulibatv1.0. Symbols:dfaanalyze,build_state,dfaexec.
Why and when: The position construction of Lesson 1.1 (nullable/firstpos/lastpos/follows) and the lazy DFA of Lesson 1.2 in one file.
Chapters: Ch 1 -
[GO-Bounds] Go's run-time panics for failed bounds checks —
src/runtime/panic.goingolang/goatgo1.24.7. Symbols:panicIndex.
Why and when: The unwind policy of Lesson 11.6: a failed check calls a panic function that can be recovered; the compiler side isboundsCheckinssagen/ssa.go.
Chapters: Ch 11 -
[GO-Closure] Go's direct closure calls (lambda lifting a called function literal) —
src/cmd/compile/internal/walk/closure.goingolang/goatgo1.24.7. Symbols:directClosureCall.
Why and when: Turns a directly called function literal into a call with its captures as arguments; the quiz's find-in-Go question for Lesson 11.8.
Chapters: Ch 11 -
[GO-Dist] Go's bootstrap driver (toolchain1, toolchain2, toolchain3) —
src/cmd/dist/build.goingolang/goatgo1.24.7. Symbols:cmdbootstrap.
Why and when: The multi-stage self-hosting build of Lesson 0.5 as real code;src/cmd/dist/buildtool.gosetsminBootstrap.
Chapters: Ch 0 -
[Go-Dom] The Go compiler's dominators (Lengauer-Tarjan and CHK side by side) —
src/cmd/compile/internal/ssa/dom.goingolang/goatgo1.25.0. Symbols:dominators,dominatorsLTOrig,evalOrig,linkOrig,dominatorsSimple,intersect.
Why and when: Both algorithms of the comparison lab in one short file, with comments naming the papers; read after Lesson 15.1 §7.
Chapters: Ch 15 -
[Go-Escape] The Go compiler's escape analysis —
src/cmd/compile/internal/escape/escape.goingolang/goatgo1.24.7. Symbols:Batch,escape.go header comment (the "data-flow graph" of locations).
Why and when: Lesson 19.9's Go example: a weighted data-flow graph of locations, whose header comment states the two invariants (no pointer to a stack object is stored in the heap or outlives the object).
Chapters: Ch 19 -
[GO-Info] go/types Info (side tables of the type checker's results) —
src/go/types/api.goingolang/goatgo1.24.7. Symbols:Info,Info.Types,Info.Defs,Info.Uses,Info.Scopes.
Why and when: Side tables in their purest form (Lesson 5.6 §3): maps from AST nodes to objects and types, filled only if the caller asks for them. Read after Lesson 5.6.
Chapters: Ch 5 -
[Go-Loopnest] The Go compiler's loop nest with irreducibility detection —
src/cmd/compile/internal/ssa/likelyadjust.goingolang/goatgo1.25.0. Symbols:loopnestfor.
Why and when: Natural loops from dominated predecessors and a sawIrred flag when a retreating edge is not a dominance back edge (Theorem 15.6.4(b)); Lesson 15.5 §7 and 15.6 §7.
Chapters: Ch 15 -
[GO-ParseBinary] Go's parser, binary expressions —
src/go/parser/parser.goingolang/goatgo1.24.7. Symbols:parser.parseBinaryExpr.
Why and when: Precedence climbing in fifteen lines with Go's five binary levels; compare with Algorithm 4.1.6 after Lesson 4.1 §2.
Chapters: Ch 4 -
[GO-Parser] Go's hand-written recursive-descent parser —
src/go/parser/parser.goingolang/goatgo1.23.0. Symbols:(*parser).advance,(*parser).parseStmt,stmtStart.
Why and when: Panic mode that synchronizes on statement starts and bounds cascades ("avoid an endless parser loop"), quoted in Lesson 2.7 §5–7. A compact, readable production parser.
Chapters: Ch 2 -
[GO-Phi] Go's phi insertion from forward references —
src/cmd/compile/internal/ssagen/phi.goingolang/goatgo1.24.7. Symbols:insertPhis,simplePhiState.
Why and when: Go builds SSA directly with forward-reference placeholders and places phis afterwards; the Go box of Lesson 11.1 §7.
Chapters: Ch 11 -
[Go-Phi] The Go compiler's phi placement (Sreedhar-Gao above 500 blocks) —
src/cmd/compile/internal/ssagen/phi.goingolang/goatgo1.25.0. Symbols:phiState.insertVarPhis,smallBlocks.
Why and when: A second production implementation of Algorithm 15.3.14 with a block-level heap; read after Lesson 15.3 §7.
Chapters: Ch 15 -
[Go-Prove] The Go compiler's prove pass (bounds-check elimination) —
src/cmd/compile/internal/ssa/prove.goingolang/goatgo1.24.7. Symbols:prove,factsTable.update.
Why and when: Fact-based BCE with a poset of SSA values (poset.go) and induction-variable limits (loopbce.go); the Go box of Lesson 18.9 prints its decisions.
Chapters: Ch 18 -
[Go-Regalloc] The Go register allocator's edge shuffles (parallel copies on edges) —
src/cmd/compile/internal/ssa/regalloc.goingolang/goatgo1.24.7. Symbols:edgeState.shuffle,edgeState.processDest,edgeState.findRegFor.
Why and when: Phi arguments become register-to-register moves on each edge, resolved as a parallel copy with a free register for cycles; the parallel-copy real-world box of Lesson 16.7.
Chapters: Ch 16 -
[Go-regalloc] Go's SSA register allocator —
src/cmd/compile/internal/ssa/regalloc.goingolang/goatgo1.24.7. Symbols:regAllocState.allocValToReg,regAllocState.placeSpills,Value.rematerializeable.
Why and when: Furthest-next-use eviction over blocks, rematerialization of cheap values, and spill sinking on the dominator tree (Lessons 22.2 and 22.9); the header comment explains the design.
Chapters: Ch 22 -
[GO-Regexp] Go's Thompson compiler for regular expressions —
src/regexp/syntax/compile.goingolang/goatgo1.24.7. Symbols:Compile,compiler.compile.
Why and when: Algorithm 1.1.6 as an instruction list; its Pike VM ismachine.stepin src/regexp/exec.go. Read after Lesson 1.1's Go box.
Chapters: Ch 1 -
[GO-Rules] Go's lowering rules for amd64 —
src/cmd/compile/internal/ssa/_gen/AMD64.rulesingolang/goatgo1.23.0.
Why and when: A rewrite-rule DSL applied greedily to a fixed point, without priorities: compare with ISLE after Lesson 21.7 §6.
Chapters: Ch 21 -
[GO-Scope] go/types scopes (a map per scope with a parent pointer) —
src/go/types/scope.goingolang/goatgo1.24.7. Symbols:Scope,Scope.Insert,Scope.Lookup,Scope.LookupParent (in scope2.go).
Why and when: The stack of tables of Algorithm 5.2.2 written as a tree of scopes that stays alive after checking, so tools can query it. Read after Lesson 5.2 §7.
Chapters: Ch 5 -
[Go-SSAGen] The Go compiler's phi placement (Braun below 500 blocks, Sreedhar-Gao above) —
src/cmd/compile/internal/ssagen/phi.goingolang/goatgo1.24.7. Symbols:state.insertPhis,phiState.insertPhis,phiState.insertVarPhis,simplePhiState.insertPhis,smallBlocks.
Why and when: Two construction algorithms in one file, chosen by function size; the large-function path considers only variables read before written in some block (semi-pruned SSA). Lessons 16.1 and 16.3 real-world boxes use the Go 1.24.7 toolchain.
Chapters: Ch 16 -
[GO-Switch] Go's switch lowering (binary search and jump tables) —
src/cmd/compile/internal/walk/switch.goingolang/goatgo1.24.7. Symbols:binarySearch,tryJumpTable.
Why and when: Algorithm 11.3.4 and a jump-table heuristic in a compiler without LLVM; read with Lesson 11.3 §7.
Chapters: Ch 11 -
[Graal-LSRA] Graal's linear scan register allocator —
compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScan.javainoracle/graalatvm-24.1.0. Symbols:LinearScan,LinearScan.allocate.
Why and when: The Java successor of C1's allocator, with an SSA variant (Lesson 22.5 §7).
Chapters: Ch 22 -
[GRAAL-SG] Graal's graph IR —
compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/nodes/StructuredGraph.javainoracle/graalatvm-23.1.0. Symbols:StructuredGraph.
Why and when: Graal's sea-of-nodes variant with fixed and floating nodes (Lesson 8.5 §6).
Chapters: Ch 8 -
[GSO-src] The GNU superoptimizer 2.5 (Granlund and Kenner), as maintained by Embecosm —
READMEinembecosm/gnu-superoptat3649aac8bbdaa721f26213e685bd99ccecac7ba6. Symbols:superopt.c,goal.def SGN.
Why and when: Build it in a minute and run the signum search of the Lesson 13.3 box; the README's warning about unverified sequences motivates the full check of Theorem 13.3.9.
Chapters: Ch 13 -
[HotSpot-Dom] HotSpot C2's Lengauer-Tarjan with sophisticated linking —
src/hotspot/share/opto/domgraph.cppinopenjdk/jdkatjdk-25+36. Symbols:PhaseCFG::build_dominator_tree,Tarjan.
Why and when: The balanced LINK/EVAL of Algorithm 15.1.17 with _size and _child fields; read after the balanced-linking trace in Lesson 15.1 §3.
Chapters: Ch 15 -
[HotSpot-EA] HotSpot C2 escape analysis (connection graph after Choi et al.) —
src/hotspot/share/opto/escape.cppinopenjdk/jdk21uatjdk-21.0.10+7. Symbols:ConnectionGraph::compute_escape,ConnectionGraph::find_non_escaped_objects.
Why and when: Lesson 19.9 §7: C2's connection graph, scalar replacement and lock elimination.
Chapters: Ch 19 -
[HotSpot-Loops] HotSpot C2's loop tree ("a modified Vick/Tarjan algorithm") —
src/hotspot/share/opto/loopnode.cppinopenjdk/jdkatjdk-25+36. Symbols:PhaseIdealLoop::build_loop_tree,IdealLoopTree.
Why and when: A Tarjan-style loop nesting that flags irreducible loops instead of stopping; the production relative of Algorithm 15.5.8.
Chapters: Ch 15 -
[HS-ADLC] HotSpot's ADLC generator of C2's DFA labeler —
src/hotspot/share/adlc/dfa.cppinopenjdk/jdkatjdk-21-ga. Symbols:cost_check.
Why and when: Generates the DP labeler from the .ad files (for x86-64, src/hotspot/cpu/x86/x86_64.ad), pruning cost tests with bounds (Lesson 21.2 §6, Lesson 21.8).
Chapters: Ch 21 -
[HS-C1LinearScan] HotSpot C1's linear scan with interval splitting —
src/hotspot/share/c1/c1_LinearScan.cppinopenjdk/jdkatjdk-21+35. Symbols:LinearScanWalker::alloc_free_reg,LinearScanWalker::alloc_locked_reg.
Why and when: Wimmer–Mössenböck in production (Algorithm 22.5.8): free-until and next-use positions, splitting, resolution.
Chapters: Ch 22 -
[HS-Chaitin] HotSpot C2's Chaitin–Briggs allocator —
src/hotspot/share/opto/chaitin.cppinopenjdk/jdkatjdk-21+35. Symbols:PhaseChaitin::Register_Allocate,PhaseChaitin::Simplify,PhaseChaitin::Select,LRG::score.
Why and when: A production Chaitin–Briggs loop with splitting instead of spill-everywhere (Lesson 22.3 §7).
Chapters: Ch 22 -
[HS-Coalesce] HotSpot C2's aggressive and conservative coalescing —
src/hotspot/share/opto/coalesce.cppinopenjdk/jdkatjdk-21+35. Symbols:PhaseAggressiveCoalesce,PhaseConservativeCoalesce.
Why and when: The two coalescing phases of Lesson 22.4 §7, one after the other.
Chapters: Ch 22 -
[HS-GCM] HotSpot C2's global code motion over the sea of nodes —
src/hotspot/share/opto/gcm.cppinopenjdk/jdkatjdk-21-ga. Symbols:PhaseCFG::schedule_early,PhaseCFG::schedule_late,PhaseCFG::global_code_motion.
Why and when: Algorithm 8.5.3 in production; C2'sNodeclass is insrc/hotspot/share/opto/node.hpp.
Chapters: Ch 8 -
[HS-Interp] HotSpot's template interpreter —
src/hotspot/share/interpreter/templateInterpreter.cppinopenjdk/jdkatjdk-21+35.
Why and when: The JVM's stack-bytecode interpreter, whose handlers are machine-code templates generated at VM startup (Lesson 0.2 §7).
Chapters: Ch 0 -
[HS-Matcher] HotSpot C2's matcher —
src/hotspot/share/opto/matcher.cppinopenjdk/jdkatjdk-21-ga. Symbols:Matcher::Label_Root,Matcher::ReduceInst.
Why and when: Labeling and reduction exactly as Algorithms 21.2.3–21.2.4 on C2's sea of nodes.
Chapters: Ch 21 -
[HS-Tiered] HotSpot's tiered compilation policy (tier transitions 0–4, OSR) —
src/hotspot/share/compiler/compilationPolicy.cppinopenjdk/jdkatjdk-21+35. Symbols:CompilationPolicy::event,CompilationPolicy::call_event,CompilationPolicy::common.
Why and when: Where HotSpot decides to move a method between the interpreter, C1 levels and C2 — the policy behind the-XX:+PrintCompilationlevels in Lesson 0.3.
Chapters: Ch 0 -
[IBURG-Src] iburg, the code-generator generator —
iburg.cindrh/iburgatef9d6452000e3b371b446c198d2028dfa38b11c4.
Why and when: About 750 lines of C that emit the labeler of Algorithm 21.2.11; run it on sample.brg as in Lesson 21.2's box.
Chapters: Ch 21 -
[IDRIS2-Parser] Idris 2's parser-combinator core (a compiler parsed by combinators) —
src/Libraries/Text/Parser/Core.idrinidris-lang/Idris2atv0.7.0. Symbols:Grammar,commit.
Why and when: A self-hosting compiler whose parser is a combinator library with explicit commit (Lesson 4.5 §7).
Chapters: Ch 4 -
[Infer-Biabduction] Infer's separation-logic heap predicates (points-to, list segments) —
infer/src/biabduction/Predicates.mliinfacebook/inferatv1.2.0. Symbols:hpred0,lseg_kind.
Why and when: Lesson 19.9's shape-analysis box: the symbolic heaps of bi-abduction [CDOY09].
Chapters: Ch 19 -
[JAVAC-Attr] javac's attribution (name and type analysis) including illegal forward references —
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.javainopenjdk/jdkatjdk-21+35. Symbols:Attr.checkInit,Attr.visitIdent.
Why and when: JLS §8.3.3 in code: a field initializer may not read a later field by simple name (Lesson 5.3 §2). ReadcheckInitafter Lesson 5.3.
Chapters: Ch 5, Ch 6 -
[JAVAC-Flow] javac's flow analysis (reachability and definite assignment) —
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.javainopenjdk/jdkatjdk-21+35. Symbols:Flow.AliveAnalyzer,Flow.AssignAnalyzer.
Why and when: JLS chapters 14.22 and 16 in code:AliveAnalyzeris Definition 5.7.1 andAssignAnalyzerAlgorithm 5.7.5 with when-true/when-false sets. Read after Lesson 5.7.
Chapters: Ch 5 -
[JAVAC-Gen] javac's bytecode generation for assignments —
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.javainopenjdk/jdkatjdk-21+35. Symbols:visitAssign.
Why and when: Java's left-to-right evaluation of the target's place before the value, as in Pebble (Lesson 11.4 §7).
Chapters: Ch 11 -
[JAVAC-Lambda] javac's lifting of lambda bodies into synthetic methods —
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.javainopenjdk/jdkatjdk-21+35. Symbols:LambdaToMethod.
Why and when: Lambda lifting with the captures as leading parameters (Algorithm 11.8.4); thejavapbox of Lesson 11.8.
Chapters: Ch 11 -
[JAVAC-TransTypes] javac's erasure pass (casts and bridges) —
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.javainopenjdk/jdkatjdk-21+35. Symbols:TransTypes.retype,TransTypes.coerce.
Why and when: Where thecheckcastinstructions of Lesson 6.9's javap box are inserted:retypeerases andcoerceadds the cast back where the erased type is too general.
Chapters: Ch 6 -
[JAVAC-Types] javac's subtyping, wildcard containment and erasure —
src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.javainopenjdk/jdkatjdk-21+35. Symbols:Types.isSubtype,Types.containsType,Types.erasure.
Why and when: Nominal subtyping with generics:containsTypedecides? extends/? supercontainment (use-site variance, Lesson 6.5) anderasurecomputes the erased types of Lesson 6.9.
Chapters: Ch 6 -
[Jikes-ArraySSA] Heap Array SSA in the Jikes RVM optimizing compiler —
rvm/src/org/jikesrvm/compilers/opt/ssa/SSADictionary.javainJikesRVM/JikesRVMat3.1.4. Symbols:SSADictionary,HeapVariable,HeapOperand.
Why and when: The production implementation of [FKS00]: heap variables per type, with phi and definition operands kept in a lookaside dictionary. Lesson 16.8.
Chapters: Ch 16 -
[JLM-RVSDG] jlm's RVSDG implementation (γ nodes; θ nodes in jlm/rvsdg/theta.hpp) —
jlm/rvsdg/gamma.hppinphate/jlmat4da82da042a7e4bb6f2c1c12a119547bfc659c5b. Symbols:GammaNode.
Why and when: A working RVSDG compiler by the RVSDG paper's authors; readGammaNodeandThetaNodeafter Definition 8.5.5.
Chapters: Ch 8 -
[KOTLIN-PCLA] Kotlin K2's inference session for partially constrained lambdas —
compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirPCLAInferenceSession.ktinJetBrains/kotlinatv2.2.20. Symbols:FirPCLAInferenceSession.
Why and when: Builder inference in the K2 compiler (Lesson 7.6 §7).
Chapters: Ch 7 -
[LARK-CYK] Lark's CYK parser —
lark/parsers/cyk.pyinlark-parser/larkat1.3.1. Symbols:to_cnf,revert_cnf,Parser._parse.
Why and when: CNF conversion and back-conversion of trees around a textbook CYK loop (Lesson 4.4 §7).
Chapters: Ch 4 -
[LARK-Earley] Lark's Earley parser —
lark/parsers/earley.pyinlark-parser/larkat1.3.1. Symbols:Parser.predict_and_complete,Parser.parse.
Why and when: A production Earley parser with SPPF output (Lesson 4.3 §7); note that Leo items were removed in this version, which the lesson measures.
Chapters: Ch 4 -
[LCC-Src] lcc's lburg and its machine descriptions (src/x86linux.md) —
lburg/lburg.cindrh/lccat2b5cf358d9aa6759923dd7461f2df7f7f2a28471.
Why and when: lburg plus the .md grammars of Lessons 21.2 and 21.8; undag in src/dag.c cuts DAGs into trees (Lesson 21.4).
Chapters: Ch 21 -
[LEAN-Expr] Lean 4 expressions (locally nameless terms) —
src/Lean/Expr.leaninleanprover/lean4atv4.19.0. Symbols:Expr.bvar,Expr.fvar,Expr.instantiate1,Expr.abstract.
Why and when:bvarholds a de Bruijn index andfvara free variable: the locally nameless design of [Cha12] in a production prover. Read after Lesson 5.2 §6.
Chapters: Ch 5 -
[LLD-ELF] lld's symbol resolution (strong, weak, lazy archive members, shared symbols) —
lld/ELF/Symbols.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Symbol::resolve,elf::reportDuplicate.
Why and when: The production version of Algorithm 0.6.6'sAdd; continue withlld/ELF/InputSection.cpp(InputSectionBase::getRelocTargetVA: S + A − P) andlld/ELF/Arch/X86_64.cpp(X86_64::relocate).
Chapters: Ch 0 -
[LLD-GC] lld's --gc-sections, a mark-sweep collector over input sections —
lld/ELF/MarkLive.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:elf::markLive.
Why and when: The file comment explains section garbage collection in a dozen lines: sections reachable from GC roots (the entry symbol, exported symbols) through relocations are kept, the rest dropped. Identical code folding islld/ELF/ICF.cpp(elf::doIcf). Read after Lesson 0.6 §6.
Chapters: Ch 0 -
[LLVM-AA] The AAResults aggregation (ask each AA in turn, stop at a definite answer) —
llvm/lib/Analysis/AliasAnalysis.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:AAResults::alias,AAResults::getModRefInfo,AAResults::callCapturesBefore.
Why and when: Lesson 19.1 §7: how the chain of AAs is queried and how call mod/ref combines memory effects with alias queries.
Chapters: Ch 19 -
[LLVM-ADCE] Aggressive dead code elimination via post-dominance frontiers —
llvm/lib/Transforms/Scalar/ADCE.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:AggressiveDeadCodeElimination::markLiveBranchesFromControlDependences.
Why and when: Control dependence as a ReverseIDFCalculator query over the live blocks (Theorem 15.4.6 in action); the "find it in LLVM" task of Lesson 15.4.
Chapters: Ch 15, Ch 17 -
[LLVM-Allocator] LLVM's bump-pointer allocator —
llvm/include/llvm/Support/Allocator.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:BumpPtrAllocatorImpl,BumpPtrAllocatorImpl::Allocate.
Why and when: Algorithm 4.7.6: 4096-byte slabs, doubling every 128 slabs, custom-sized slabs for large objects. ReadAllocateafter Lesson 4.7 §2.
Chapters: Ch 4, Ch 24 -
[LLVM-AMDGPU-CF] AMDGPU's divergent control flow as execution masks —
llvm/lib/Target/AMDGPU/SIAnnotateControlFlow.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SIAnnotateControlFlow.
Why and when: How a GPU back end turns divergent branches into mask manipulation (withSILowerControlFlow.cppin the same directory): if-conversion withexecas the predicate (Lesson 23.5 §7).
Chapters: Ch 23 -
[LLVM-APInt] Arbitrary-precision integers (and APFloat.h next to it) —
llvm/include/llvm/ADT/APInt.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:APInt::uadd_ov,APInt::sdiv,APInt::udiv,APInt::ashr,APInt::getLowBitsSet.
Why and when: Definition 10.6.12 in code; Lab 10.2 uses getLowBitsSet for the urem mask.
Chapters: Ch 10 -
[LLVM-ArgPromotion] LLVM's argument promotion —
llvm/lib/Transforms/IPO/ArgumentPromotion.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:promoteArguments,findArgParts,doPromotion.
Why and when: The legality checks and the signature rewrite of Algorithm 20.6.9 (by-pointer to by-value). Read findArgParts after Lesson 20.6.
Chapters: Ch 20 -
[LLVM-AsmParser] LLVM's assembler expression parser (precedence climbing with two tables) —
llvm/lib/MC/MCParser/AsmParser.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:AsmParser::parseBinOpRHS,getGNUBinOpPrecedence,getDarwinBinOpPrecedence.
Why and when: Two precedence tables for one parser (Lesson 3.5's box and find-it task).
Chapters: Ch 3 -
[LLVM-Attributes] The list of all IR attributes and where they may appear —
llvm/include/llvm/IR/Attributes.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:NoUndef,Memory,Captures,Range,ZExt,NoAlias.
Why and when: The authoritative list behind Definition 9.5.3's table (parameter, return and function attributes, with their intersection rules). Skim after Lesson 9.5.
Chapters: Ch 9 -
[LLVM-AutoUpgrade] Rewriting old IR constructs on load (bitcode and text) —
llvm/lib/IR/AutoUpgrade.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:UpgradeIntrinsicFunction,UpgradeIntrinsicCall,UpgradeCallsToIntrinsic,UpgradeDebugInfo.
Why and when: How LLVM keeps its compatibility promise: old intrinsic signatures (the two-operand lifetime.start of Lesson 9.6's box), debug intrinsics, and more. Read after Lesson 9.6.
Chapters: Ch 9 -
[LLVM-Basic] LLVM's basic allocator (priority queue, spill interference) —
llvm/lib/CodeGen/RegAllocBasic.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:RABasic::selectOrSplit.
Why and when: The simplest client of RegAllocBase: Algorithm 22.8.2 in under 350 lines; read it before RegAllocGreedy.cpp.
Chapters: Ch 22 -
[LLVM-BasicAA] BasicAA's stateless invalidation —
llvm/lib/Analysis/BasicAliasAnalysis.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:BasicAAResult::invalidate.
Why and when: Ignores its own preservation and checks only its dependencies (Definition 12.1.4).
Chapters: Ch 12, Ch 19 -
[LLVM-BBSections] LLVM's basic-block sections (Propeller's compiler side) —
llvm/lib/CodeGen/BasicBlockSections.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:BasicBlockSections::runOnMachineFunction,assignSections,BasicBlockSections::handleBBSections.
Why and when: Places blocks into sections from a cluster profile and emits the block address map. Read the file header after Lesson 20.10's basic-block-sections box.
Chapters: Ch 20, Ch 23 -
[LLVM-BCE] LLVM's critical-edge splitting —
llvm/lib/Transforms/Utils/BreakCriticalEdges.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SplitCriticalEdge,SplitAllCriticalEdges,BreakCriticalEdgesPass::run.
Why and when: Thebreak-crit-edgespass of Lesson 8.2's box and the on-demandSplitCriticalEdge;isCriticalEdgeis inllvm/lib/Analysis/CFG.cpp.
Chapters: Ch 8 -
[LLVM-BDCE] Bit-tracking dead code elimination —
llvm/lib/Transforms/Scalar/BDCE.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:bitTrackingDCE.
Why and when: Deletes instructions none of whose bits are demanded, and clears assumptions (flags) that no longer hold (Lesson 17.2 §7, Lesson 17.3 §6).
Chapters: Ch 17 -
[LLVM-BranchFolding] LLVM's branch folding and tail merging —
llvm/lib/CodeGen/BranchFolding.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:BranchFolder::TailMergeBlocks,BranchFolder::OptimizeBlock.
Why and when: Jump threading of empty blocks, branch simplification and common-tail merging (Algorithm 23.9.9, Proposition 23.9.10).
Chapters: Ch 23 -
[LLVM-CallingConv] The numbered calling conventions —
llvm/include/llvm/IR/CallingConv.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CallingConv::C,CallingConv::Fast,CallingConv::Cold,CallingConv::Tail,CallingConv::SwiftTail.
Why and when: The IDs behind ccc, fastcc, coldcc, tailcc and the target conventions; read with Lesson 9.5's calling-convention box.
Chapters: Ch 9 -
[LLVM-CaptureTracking] Capture tracking (does a pointer escape?) —
llvm/lib/Analysis/CaptureTracking.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:llvm::PointerMayBeCaptured,llvm::PointerMayBeCapturedBefore,llvm::DetermineUseCaptureKind.
Why and when: The use-walk of Algorithm 19.2.7, with the use-count cap; read after Lesson 19.2 §4.
Chapters: Ch 19 -
[LLVM-Casting] LLVM-style RTTI templates —
llvm/include/llvm/Support/Casting.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:isa,cast,dyn_cast,CastInfo.
Why and when:isa,castanddyn_castoverclassof(Algorithm 4.7.2); Chapter 10 studies them in depth.
Chapters: Ch 4, Ch 10 -
[LLVM-CC] x86 calling conventions in TableGen —
llvm/lib/Target/X86/X86CallingConv.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CC_X86_64_C,RetCC_X86_64_C.
Why and when: Algorithm 21.9.2 as CCIfType/CCAssignToReg rules; the driver is CCState in llvm/lib/CodeGen/CallingConvLower.cpp.
Chapters: Ch 21 -
[LLVM-CE] Constraint elimination over dominating conditions —
llvm/lib/Transforms/Scalar/ConstraintElimination.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ConstraintInfo,checkCondition.
Why and when: Fourier–Motzkin over facts from dominating branches (ConstraintSystem.cpp); the ABCD-like component of LLVM's bounds-check removal in Lesson 18.9.
Chapters: Ch 18 -
[LLVM-CFG] LLVM's reducibility test over an RPO traversal and LoopInfo —
llvm/include/llvm/Analysis/CFG.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:containsIrreducibleCFG.
Why and when: The DFS back-edge test of Algorithm 15.6.8 in twenty lines (the isProperBackedge lambda); the "find it in LLVM" task of Lesson 15.6.
Chapters: Ch 15 -
[LLVM-CFGcpp] LLVM's retreating-edge finder —
llvm/lib/Analysis/CFG.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:FindFunctionBackedges.
Why and when: A DFS with an explicit stack that reports retreating ("back") edges, Definition 15.5.1's kind Back; compare with the course's computeDFS.
Chapters: Ch 15 -
[LLVM-CFGMST] The spanning-tree builder used by PGO instrumentation —
llvm/include/llvm/Transforms/Instrumentation/CFGMST.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CFGMST::buildEdges,CFGMST::computeMinimumSpanningTree.
Why and when: Kruskal with union-find over weighted CFG edges: Algorithm 12.3.7's Place.
Chapters: Ch 12 -
[LLVM-CFGUpdate] Cancelling and deduplicating a batch of CFG updates —
llvm/include/llvm/Support/CFGUpdate.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:cfg::LegalizeUpdates.
Why and when: The Legalize step of Algorithm 15.2.8 (insert/delete pairs cancel); a short read after the batched-updates worked example.
Chapters: Ch 15 -
[LLVM-CG] LLVM's legacy call graph (external calling and calls-external nodes) —
llvm/lib/Analysis/CallGraph.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CallGraph::addToCallGraph,CallGraph::populateCallGraphNode.
Why and when: How LLVM builds the direct call graph whose SCC order E1 must reproduce (Definition 20.2.4): read addToCallGraph for the roots and populateCallGraphNode for the edges.
Chapters: Ch 20 -
[LLVM-CGSCC] The CGSCC pass manager and its adaptors —
llvm/include/llvm/Analysis/CGSCCPassManager.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ModuleToPostOrderCGSCCPassAdaptor,CGSCCToFunctionPassAdaptor,DevirtSCCRepeatedPass,CGSCCUpdateResult.
Why and when: Definition 12.1.11: the post-order SCC walk, graph updates, devirt. Read after Lesson 12.1's CGSCC box.
Chapters: Ch 12, Ch 20, Ch 24 -
[LLVM-CodeGen] The machine-code pipeline shared by LLVM back ends —
llvm/lib/CodeGen/TargetPassConfig.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TargetPassConfig::addMachinePasses.
Why and when: The back-end phase of the three-phase design: instruction selection, register allocation, scheduling and emission, customized per target (Chapters 21–23).
Chapters: Ch 0 -
[LLVM-CodeGenTM] Adding the code-generation passes and the object writer —
llvm/lib/CodeGen/CodeGenTargetMachineImpl.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CodeGenTargetMachineImpl::addPassesToEmitFile,CodeGenTargetMachineImpl::addAsmPrinter.
Why and when: Whatpebblec'semitObjectFilecalls (Algorithm 11.9.5): codegen passes, then an AsmPrinter on an object streamer. Read after Lesson 11.9 §2.
Chapters: Ch 11 -
[LLVM-CodeLayout] LLVM's ext-TSP block layout and cache-directed function sort —
llvm/lib/Transforms/Utils/CodeLayout.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:codelayout::computeExtTspLayout,codelayout::computeCacheDirectedLayout,ExtTSPImpl.
Why and when: The chain-merging layout algorithms used by block placement and by BOLT; the header contrasts them with Pettis–Hansen. Read after Algorithm 20.10.6.
Chapters: Ch 20, Ch 23 -
[LLVM-ConstantFolding] LLVM's target-aware constant folder (with llvm/lib/IR/ConstantFold.cpp for the target-independent part) —
llvm/lib/Analysis/ConstantFolding.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ConstantFoldInstruction,ConstantFoldBinaryOpOperands,ConstantFoldCall,ConstantFoldFP.
Why and when: Read after Lesson 13.1: how folding uses the DataLayout, APFloat, and the host libm for intrinsics such as sin (ConstantFoldFP), and compare with your pebble-constfold (E1).
Chapters: Ch 13 -
[LLVM-ConstantRange] ConstantRange, the wrapped-interval domain —
llvm/lib/IR/ConstantRange.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ConstantRange::add,ConstantRange::multiply,ConstantRange::unionWith.
Why and when: The abstract transformers of Lesson 17.2 §2 (add, multiply, union of wrapped intervals); compareaddwith the proof of Lemma 17.2.5.
Chapters: Ch 17 -
[LLVM-ConvertUTF] LLVM's UTF-8 validation and conversion routines —
llvm/lib/Support/ConvertUTF.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:isLegalUTF8Sequence,getNumBytesForUTF8,ConvertUTF8toUTF32.
Why and when: Table-driven UTF-8 validation (compare with Algorithm 1.9.8): the trailing-bytes table and the range checks of isLegalUTF8. Read after Lesson 1.9.
Chapters: Ch 1 -
[LLVM-CR] Wrapped intervals of APInts —
llvm/include/llvm/IR/ConstantRange.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ConstantRange::unionWith,ConstantRange::addWithNoWrap.
Why and when: The interval domain LLVM uses, including no-wrap-aware arithmetic (Lesson 14.7 §7 and the nsw rule of exercise E6).
Chapters: Ch 14 -
[LLVM-CtxImpl] The context's uniquing tables —
llvm/lib/IR/LLVMContextImpl.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LLVMContextImpl,IntegerTypes,IntConstants,StructConstants,AnonStructTypes.
Why and when: Where every uniqued type and constant lives (Lesson 10.1, Algorithm 10.1.4); pair with ConstantInt::get in llvm/lib/IR/Constants.cpp.
Chapters: Ch 10 -
[LLVM-CVP] Correlated value propagation (LVI-driven rewrites) —
llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:narrowSDivOrSRem,processUDivOrURem.
Why and when: What LVI's facts buy: signed-to-unsigned division, narrowing, nuw/nsw inference, folded compares (Lesson 17.2 §7).
Chapters: Ch 17 -
[LLVM-Cycle] LLVM's CycleInfo (Havlak's loop nesting forest) —
llvm/include/llvm/ADT/GenericCycleImpl.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GenericCycleInfoCompute::run,GenericCycleInfoCompute::dfs,GenericCycle::appendEntry.
Why and when: Core reading. Header candidates in reverse preorder, non-descendant predecessors as extra entries: the production version of Algorithm 15.5.9; read after Lesson 15.5 §4.
Chapters: Ch 15 -
[LLVM-DA] LLVM's dependence analysis (GKT tests) —
llvm/lib/Analysis/DependenceAnalysis.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DependenceInfo::depends,DependenceInfo::gcdMIVtest,DependenceInfo::banerjeeMIVtest,DependenceInfo::strongSIVtest.
Why and when: Core reading. The GCD, Banerjee and SIV tests of Lesson 18.6 as LLVM runs them; the header comment names [GKT91] as its source.
Chapters: Ch 18 -
[LLVM-DAE] LLVM's dead-argument and dead-return-value elimination —
llvm/lib/Transforms/IPO/DeadArgumentElimination.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DeadArgumentEliminationPass::surveyFunction,DeadArgumentEliminationPass::markLive,DeadArgumentEliminationPass::removeDeadStuffFromFunction.
Why and when: The liveness propagation of Algorithm 20.6.8 over arguments and return values. Read after Lesson 20.6's dead-argument elimination.
Chapters: Ch 20 -
[LLVM-DAGCombiner] Lowering sdiv by a power of two in the code generator —
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DAGCombiner::visitSDIV,DAGCombiner::BuildSDIVPow2.
Why and when: The biased sequence of Theorem 12.3.9 in the back end (with target hooks such as select-based forms).
Chapters: Ch 12 -
[LLVM-DAGISelEmitter] TableGen's generator of the SelectionDAG matcher table —
llvm/utils/TableGen/DAGISelEmitter.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DAGISelEmitter::run.
Why and when: Sorts patterns by complexity (PatternToMatch::getPatternComplexity in Common/CodeGenDAGPatterns.cpp) and emits the table that Algorithm 21.5.10 interprets. Read after Lesson 21.5 §7.
Chapters: Ch 21 -
[LLVM-DataLayout] Data layout parsing, alignment rules and struct layout —
llvm/lib/IR/DataLayout.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DataLayout::parseLayoutString,DataLayout::getAlignment,StructLayout::StructLayout.
Why and when: Algorithm 9.2.6 (the integer "next larger width" rule, natural alignment for vectors and unknown floats) and Algorithm 9.4.2 (struct layout). Read after Lesson 9.2 and compare withgep_offsetin tools/course/lib/llvmir.py.
Chapters: Ch 9 -
[LLVM-DB] Demanded bits, a backward analysis along use-def chains —
llvm/lib/Analysis/DemandedBits.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DemandedBits::performAnalysis.
Why and when: Liveness at bit granularity, computed sparsely over instructions (Lesson 14.6's first box).
Chapters: Ch 14 -
[LLVM-DCE] LLVM's worklist dead-code elimination (and ADCE.cpp for the aggressive variant) —
llvm/lib/Transforms/Scalar/DCE.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:eliminateDeadCode,DCEInstruction.
Why and when: Algorithm 13.5.10 in about 100 lines, using isInstructionTriviallyDead; compare with your pebble-dce (E4) and with ADCE.cpp.
Chapters: Ch 13, Ch 17 -
[LLVM-DDG] LLVM's loop data dependence graph —
llvm/include/llvm/Analysis/DDG.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DataDependenceGraph,PiBlockDDGNode.
Why and when: The dependence graph printed byprint<ddg>in Lesson 8.5;llvm/lib/Analysis/DDG.cppbuilds it.
Chapters: Ch 8 -
[LLVM-DeltaSrc] llvm-reduce's chunked delta loop —
llvm/tools/llvm-reduce/deltas/Delta.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:runDeltaPass,increaseGranularity.
Why and when: Algorithm 12.7.5's inner loop; the individual reductions are the Reduce*.cpp files next to it.
Chapters: Ch 12 -
[LLVM-DemandedBits] Backward demanded-bits analysis —
llvm/lib/Analysis/DemandedBits.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DemandedBits::determineLiveOperandBits.
Why and when: Which bits of each value can reach an observable use;print<demanded-bits>in Lesson 17.2 prints it. BDCE.cpp (bitTrackingDCE) is its client.
Chapters: Ch 17 -
[LLVM-DenseMap] DenseMap in LLVM 23 (linear probing, used bits, Algorithm R) —
llvm/include/llvm/ADT/DenseMap.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DenseMapBase::LookupBucketFor,DenseMapBase::eraseFromFilledBucket,DenseMapBase::remove_if,DenseMapBase::findBucketForInsertion.
Why and when: Core reading. Algorithm 10.6.5 as shipped; the file comment names Knuth's Algorithm R. The hash functions are in DenseMapInfo.h (densemap::detail::mix). Read after Lesson 10.6 §2.
Chapters: Ch 10 -
[LLVM-DenseMap22] DenseMap before LLVM 23 (quadratic probing, tombstones) —
llvm/include/llvm/ADT/DenseMap.hinllvm/llvm-projectatllvmorg-22.1.0. Symbols:DenseMapBase::LookupBucketFor,DenseMapBase::findBucketForInsertion,getTombstoneKey.
Why and when: The design most existing documentation and books describe; compare ProbeAmt and the tombstone rehash rule with LLVM 23 (Lesson 10.6 §3's second trace).
Chapters: Ch 10 -
[LLVM-DFAEmitter] A subset construction inside TableGen (VLIW packetizer automata) —
llvm/utils/TableGen/DFAEmitter.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DfaEmitter::constructDfa,DfaEmitter::visitDfaState.
Why and when: Determinization with states interned in a UniqueVector, the pattern of Algorithm 1.2.5, used by LLVM's DFA packetizer backends. Read after Lesson 1.2 §7.
Chapters: Ch 1 -
[LLVM-DFImpl] LLVM's Cytron-style dominance frontier computation —
llvm/include/llvm/Analysis/DominanceFrontierImpl.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DominanceFrontierBase::analyze,DFCalculateWorkObject.
Why and when: DF_local then DF_up over the dominator tree with an explicit work stack: Algorithm 15.3.6 without recursion. Read after Lesson 15.3 §2.
Chapters: Ch 15 -
[LLVM-DIBuilder] The DIBuilder API that E3 uses —
llvm/lib/IR/DIBuilder.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DIBuilder::createCompileUnit,DIBuilder::createFunction,DIBuilder::createAutoVariable,DIBuilder::insertDeclare,DIBuilder::insertDbgValueIntrinsic,DIBuilder::finalize.
Why and when: Every callpebble-debugifymakes, andfinalize's handling ofretainedNodes. ReadcreateFunctionandfinalizeSubprogrambefore writing the pass.
Chapters: Ch 24 -
[LLVM-Distribute] Loop distribution driven by LoopAccessAnalysis —
llvm/lib/Transforms/Scalar/LoopDistribute.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InstPartitionContainer.
Why and when: Lesson 18.7's fission in LLVM: the file header explains why it preserves the textual order of memory operations.
Chapters: Ch 18 -
[LLVM-DivConst] LLVM's magic-number computation for division by constants (used by TargetLowering::BuildUDIV/BuildSDIV) —
llvm/lib/Support/DivisionByConstantInfo.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SignedDivisionByConstantInfo::get,UnsignedDivisionByConstantInfo::get.
Why and when: Warren's algorithms in APInt, with LLVM's pre-shift and widen options (Lesson 13.7 §7); read after Theorem 13.7.6 and the unit test llvm/unittests/Support/DivisionByConstantTest.cpp.
Chapters: Ch 13 -
[LLVM-Dominators] DominatorTree's invalidation predicate —
llvm/lib/IR/Dominators.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DominatorTree::invalidate.
Why and when: Preserved by name, by all, or by the CFGAnalyses set — the rule the pm-invalidation drill uses.
Chapters: Ch 12 -
[LLVM-DSE] Dead store elimination on MemorySSA —
llvm/lib/Transforms/Scalar/DeadStoreElimination.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:eliminateDeadStores.
Why and when: Where "dead" means an overwritten or never-read store: the memory side of Lesson 17.3 §6, taught in full in Ch 19.
Chapters: Ch 17, Ch 19 -
[LLVM-DTU] LLVM's batched, eager or lazy dominator-tree updater —
llvm/include/llvm/Analysis/GenericDomTreeUpdater.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GenericDomTreeUpdater::applyUpdates,GenericDomTreeUpdater::flush,GenericDomTreeUpdater::UpdateStrategy.
Why and when: The API every CFG-changing transform uses (Algorithm 15.2.8); read with Lesson 15.2 §7 and the jump-threading box there.
Chapters: Ch 15 -
[LLVM-DwarfDebug] Emitting DWARF from machine code and debug records —
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DwarfDebug::buildLocationList,DwarfDebug::collectEntityInfo,DwarfDebug::beginInstruction.
Why and when: Where location lists and the line table are produced fromDBG_VALUEs and!dbglocations; readbuildLocationListafter Algorithm 24.4.7 and Theorem 24.4.10.
Chapters: Ch 24 -
[LLVM-DwarfEH] Lowering
resumeto_Unwind_Resumebefore instruction selection —llvm/lib/CodeGen/DwarfEHPrepare.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DwarfEHPrepare.
Why and when: The small IR pass betweeninvoke/landingpadand the tables; read with Lesson 11.7 §7.
Chapters: Ch 11 -
[LLVM-EarlyCSE] LLVM's EarlyCSE (dominator-scoped value numbering) —
llvm/lib/Transforms/Scalar/EarlyCSE.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SimpleValue,DenseMapInfo<SimpleValue>::getHashValue,EarlyCSEPass::run.
Why and when: Hash-based value numbering with commutative operands swapped before hashing: the key of Definition 8.3.4 in production (Lesson 8.3's box).
Chapters: Ch 8, Ch 13, Ch 17 -
[LLVM-EARLYCSE] Dominator-tree CSE with scoped tables of available expressions —
llvm/lib/Transforms/Scalar/EarlyCSE.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:EarlyCSE.
Why and when: Available expressions without iteration, thanks to SSA (Lesson 14.3's EarlyCSE box).
Chapters: Ch 14 -
[LLVM-EarlyIfCvt] LLVM's early if-conversion to selects —
llvm/lib/CodeGen/EarlyIfConversion.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SSAIfConv::canConvertIf,EarlyIfConverter::shouldConvertIf.
Why and when: Diamonds and triangles to selects with a trace-metrics cost model (Algorithm 23.5.7). ReadshouldConvertIffor the "half the mispredict penalty" rule.
Chapters: Ch 23 -
[LLVM-EditDistance] LLVM's Levenshtein distance with an upper bound —
llvm/include/llvm/ADT/edit_distance.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ComputeEditDistance,ComputeMappedEditDistance.
Why and when: Algorithm 5.8.6 with one row of memory and an early exit when every cell exceeds the bound. Read after Lesson 5.8 §2;StringRef::edit_distancecalls it.
Chapters: Ch 5 -
[LLVM-EHStreamer] Emission of the call-site and action tables (LSDA) —
llvm/lib/CodeGen/AsmPrinter/EHStreamer.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:EHStreamer::computeCallSiteTable,EHStreamer::emitExceptionTable.
Why and when: Builds the call-site table the unwinder searches in Algorithm 11.7.2, merging adjacent ranges and adding "no landing pad" gaps; read after Lesson 11.7 §3.
Chapters: Ch 11 -
[LLVM-ELFWriter] The ELF object writer —
llvm/lib/MC/ELFObjectWriter.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ELFObjectWriter::recordRelocation,ELFObjectWriter::useSectionSymbol,ELFWriter::writeObject.
Why and when: How fixups become RELA records and when a local symbol is replaced by its section (Algorithm 21.10.10).
Chapters: Ch 21 -
[LLVM-EqClasses] LLVM's union-find (equivalence classes with leader pointers) —
llvm/include/llvm/ADT/EquivalenceClasses.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:EquivalenceClasses::unionSets,EquivalenceClasses::ECValue::getLeader.
Why and when: The data structure of Algorithm 7.1.10 in LLVM's ADT library;getLeaderdoes path compression. Read the class comment after Lesson 7.1 §7.
Chapters: Ch 7 -
[LLVM-Error] Error and Expected —
llvm/include/llvm/Support/Error.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Error,Expected,ErrorInfo,handleErrors,handleAllErrors,cantFail,ExitOnError,Error::assertIsChecked.
Why and when: Definition 10.7.2's state table is read directly from the constructors, operator bool and assertIsChecked; do the must-check drill with this file open.
Chapters: Ch 10 -
[LLVM-FastISel] FastISel —
llvm/lib/CodeGen/SelectionDAG/FastISel.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:FastISel::selectInstruction,FastISel::tryToFoldLoad.
Why and when: Algorithm 21.6.3: bottom-up per-instruction selection with target hooks and fallback.
Chapters: Ch 21 -
[LLVM-FileCheckSrc] FileCheck's matcher —
llvm/lib/FileCheck/FileCheck.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:FileCheck::checkInput,FileCheckString::Check,FileCheckString::CheckDag,FileCheckString::CheckNot,FileCheckString::CheckNext,Pattern::match.
Why and when: The operational semantics of Algorithm 12.4.4, line for line; tools/course/lib/filecheck.py follows it.
Chapters: Ch 12 -
[LLVM-FixIrr] LLVM's fix-irreducible (guard blocks instead of node splitting) —
llvm/lib/Transforms/Utils/FixIrreducible.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:fixIrreducible.
Why and when: Turns each irreducible cycle into a natural loop through a ControlFlowHub dispatch block; the alternative to node splitting in Lesson 15.6 §6-7.
Chapters: Ch 15 -
[LLVM-Folders] The IRBuilder folders —
llvm/include/llvm/IR/ConstantFolder.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ConstantFolder::FoldBinOp,NoFolder,InstSimplifyFolder,TargetFolder.
Why and when: ConstantFolder here; NoFolder in llvm/include/llvm/IR/NoFolder.h; InstSimplifyFolder and TargetFolder in llvm/include/llvm/Analysis/. Definition 10.3.2's domains read off directly.
Chapters: Ch 10 -
[LLVM-FuncSpec] LLVM's function specialization (inside IPSCCP) —
llvm/lib/Transforms/IPO/FunctionSpecialization.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:FunctionSpecializer::run,FunctionSpecializer::findSpecializations,InstCostVisitor.
Why and when: Cloning for constant and function-pointer arguments with a bonus-based cost model. Read findSpecializations after Lesson 20.4 §2.
Chapters: Ch 20 -
[LLVM-Function] Function destruction and dropAllReferences —
llvm/lib/IR/Function.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Function::~Function,Function::deleteBodyImpl.
Why and when: "After this it is safe to delete instructions": why use edges are cut before the ownership tree is deleted (Theorem 10.1.12).
Chapters: Ch 10 -
[LLVM-FunctionAttrs] Inference of memory(...) and other attributes over call-graph SCCs —
llvm/lib/Transforms/IPO/FunctionAttrs.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:addMemoryAttrs,checkFunctionMemoryAccess.
Why and when: Algorithm 9.5.5 in production: calls to SCC members are skipped and the SCC gets one effect (Proposition 9.5.9). Read after Lesson 9.5 §4.
Chapters: Ch 9, Ch 19, Ch 20, Ch 24 -
[LLVM-FunctionImport] LLVM's ThinLTO import decisions and importer —
llvm/lib/Transforms/IPO/FunctionImport.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ModuleImportsManager::computeImportForModule,computeImportForFunction,selectCallee,FunctionImporter::importFunctions.
Why and when: Algorithm 20.9.5 in production: thresholds, the evolution factor, hot and cold multipliers. The "find where LLVM does it" question of Lesson 20.9 is in this file.
Chapters: Ch 20 -
[LLVM-Fuse] Loop fusion —
llvm/lib/Transforms/Scalar/LoopFuse.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:dependencesAllowFusion.
Why and when: Fusion legality (Theorem 18.7.15) with dependence analysis; read after the fusion box.
Chapters: Ch 18 -
[LLVM-FuzzerLoop] libFuzzer's main loop —
compiler-rt/lib/fuzzer/FuzzerLoop.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Fuzzer::Loop,Fuzzer::MutateAndTestOne,Fuzzer::RunOne.
Why and when: Algorithm 12.6.4 in production: corpus selection, mutation, and the NEW/REDUCE logic.
Chapters: Ch 12 -
[LLVM-GDT] LLVM's dominator-tree data structure, queries and printer —
llvm/include/llvm/Support/GenericDomTree.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DominatorTreeBase::dominates,DominatorTreeBase::updateDFSNumbers,DominatorTreeBase::findNearestCommonDominator,DominatorTreeBase::print.
Why and when: The {in,out} DFS numbers of printand the O(1) dominance query of Corollary 15.1.7; compare with the course's provided DomTree after Lesson 15.1 §7.
Chapters: Ch 15 -
[LLVM-GDTC] LLVM's Semi-NCA dominator and post-dominator construction and incremental updates —
llvm/include/llvm/Support/GenericDomTreeConstruction.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SemiNCAInfo::runDFS,SemiNCAInfo::eval,SemiNCAInfo::runSemiNCA,SemiNCAInfo::FindRoots,SemiNCAInfo::RemoveRedundantRoots,SemiNCAInfo::InsertReachable,SemiNCAInfo::DeleteReachable,SemiNCAInfo::DeleteUnreachable,SemiNCAInfo::HasProperSupport,SemiNCAInfo::ApplyUpdates.
Why and when: Core reading. The production implementation behind DominatorTree and PostDominatorTree. Read runSemiNCA after Lesson 15.1 (phase 2 is the three-line climb of Algorithm 15.1.19), FindRoots after Lesson 15.4, and InsertReachable/DeleteReachable after Lesson 15.2.
Chapters: Ch 15 -
[LLVM-GISel-Combine] GlobalISel's generic combine rules —
llvm/include/llvm/Target/GlobalISel/Combine.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:mul_to_shl,trivial_combines.
Why and when: GICombineRule definitions (match, apply) with C++ halves in CombinerHelper.cpp; the mul_to_shl rule of Lesson 21.6's box.
Chapters: Ch 21 -
[LLVM-GISelCombine] The GlobalISel combiner's TableGen rules —
llvm/include/llvm/Target/GlobalISel/Combine.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GICombineRule,GICombinePatFrag,add_sub_reg.
Why and when: Peephole rules as TableGen data, compiled into a matcher table (Lesson 13.2 §7). Read a dozen rules after the lesson.
Chapters: Ch 13 -
[LLVM-GlobalISelSrc] The GlobalISel passes —
llvm/lib/CodeGen/GlobalISelinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IRTranslator::translate,Legalizer::legalizeMachineFunction,RegBankSelect::assignInstr,InstructionSelect::selectInstr.
Why and when: One file per stage of Lesson 21.6's pipeline; AArch64's target parts are in llvm/lib/Target/AArch64/GISel/.
Chapters: Ch 21 -
[LLVM-GlobalOpt] LLVM's global optimizer —
llvm/lib/Transforms/IPO/GlobalOpt.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:optimizeGlobalsInModule,processGlobal,processInternalGlobal,SRAGlobal.
Why and when: Constant globals, stored-once globals, scalar replacement of aggregate globals and dead globals (Algorithm 20.6.10). Read processInternalGlobal after Lesson 20.6.
Chapters: Ch 20 -
[LLVM-GlobalsAA] GlobalsAA (mod/ref of non-address-taken internal globals per function) —
llvm/lib/Analysis/GlobalsModRef.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GlobalsAAResult::AnalyzeGlobals,GlobalsAAResult::AnalyzeCallGraph,GlobalsAAResult::getModRefInfo.
Why and when: Lesson 19.2's GlobalsAA: which globals escape, and bottom-up mod/ref over call-graph SCCs; note the nosync/nocallback conditions for declarations.
Chapters: Ch 19 -
[LLVM-Greedy] LLVM's greedy register allocator —
llvm/lib/CodeGen/RegAllocGreedy.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:RAGreedy::selectOrSplitImpl,RAGreedy::tryEvict,RAGreedy::tryRegionSplit,RAGreedy::evictInterference.
Why and when: Algorithm 22.8.3: stages, eviction with cascades, and the splitting strategies. Follow selectOrSplitImpl top-down after Lesson 22.8 §2.
Chapters: Ch 22 -
[LLVM-GVN] LLVM's GVN (hash-based value numbers, load elimination and PRE) —
llvm/lib/Transforms/Scalar/GVN.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GVNPass::ValueTable::lookupOrAdd,GVNPass::propagateEquality,GVNPass::PerformLoadPRE,GVNPass::performScalarPRE.
Why and when: Hash-based value numbering in RPO with a leader table, equality propagation from branches, load PRE and a simple scalar PRE (Lessons 17.4 and 17.6).
Chapters: Ch 17, Ch 19 -
[LLVM-GVNHOIST] Code hoisting based on ANTIC (very busy) points —
llvm/lib/Transforms/Scalar/GVNHoist.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GVNHoist.
Why and when: Very busy expressions put to work (Lesson 14.3's GVNHoist box); read the file comment.
Chapters: Ch 14 -
[LLVM-GVNHoist] GVN-based hoisting of very busy expressions —
llvm/lib/Transforms/Scalar/GVNHoist.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GVNHoist::hoistExpressions.
Why and when: Hoists equal-valued computations from all successors to a common dominator (Lesson 17.5 §6).
Chapters: Ch 17 -
[LLVM-GVNSink] GVN-based sinking into a common successor —
llvm/lib/Transforms/Scalar/GVNSink.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GVNSink::sinkBB.
Why and when: The mirror image of GVN-hoist, merging "almost equal" instructions with phis of their differing operands (Lesson 17.5 §6).
Chapters: Ch 17 -
[LLVM-HexEIF] Hexagon's multi-block early if-converter —
llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:HexagonEarlyIfConversion::isProfitable,HexagonEarlyIfConversion::convert.
Why and when: The closest thing to hyperblock formation in LLVM: nested regions predicated with a cost limit. Read after Lesson 23.5's Hexagon box.
Chapters: Ch 23 -
[LLVM-HotCold] LLVM's hot/cold splitting —
llvm/lib/Transforms/IPO/HotColdSplitting.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:HotColdSplitting::run,HotColdSplitting::outlineColdRegions.
Why and when: Finds cold single-entry regions (profile or unreachable/noreturn heuristics) and outlines them into .cold functions. Read after Lesson 20.4's hot/cold splitting.
Chapters: Ch 20 -
[LLVM-IC] Folding operations through phis, per incoming edge —
llvm/lib/Transforms/InstCombine/InstructionCombining.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InstCombinerImpl::foldBinopWithPhiOperands,InstCombinerImpl::foldOpIntoPhi.
Why and when: How -O2 recovers the MOP answer of Lesson 14.2's example by evaluating per path after the fact.
Chapters: Ch 14 -
[LLVM-ICP] LLVM's profile-guided indirect-call promotion —
llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IndirectCallPromoter::processFunction,IndirectCallPromoter::getPromotionCandidatesForCallSite,promoteIndirectCalls.
Why and when: Reads value profiles and promotes hot targets behind a guard (Lessons 20.7 and 20.10); the thresholds are the cl::opts in IndirectCallPromotionAnalysis.cpp.
Chapters: Ch 20 -
[LLVM-IDF] LLVM's Sreedhar-Gao iterated dominance frontier (IDFCalculator) —
llvm/include/llvm/Support/GenericIteratedDominanceFrontier.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IDFCalculatorBase::calculate,IDFCalculatorBase::setLiveInBlocks.
Why and when: Core reading. The priority queue keyed by (level, DFS-in number) and the SuccLevel > RootLevel filter of Algorithm 15.3.14; the "find it in LLVM" task of Lesson 15.3 starts here.
Chapters: Ch 15, Ch 16 -
[LLVM-IfCvt] LLVM's post-RA if-converter (full predication) —
llvm/lib/CodeGen/IfConversion.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IfConverter::AnalyzeBlock,IfConverter::IfConvertDiamond,IfConverter::IfConvertTriangle.
Why and when: Predicates whole blocks on ARM/Thumb-2 and other predicated targets. Read after the ARM box of Lesson 23.5 §7.
Chapters: Ch 23 -
[LLVM-ilist] Intrusive lists (and simple_ilist.h, ilist_node.h) —
llvm/include/llvm/ADT/ilist.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:iplist_impl::erase,iplist_impl::remove,simple_ilist::size.
Why and when: The container of instructions, blocks and functions; note the file comment on the linear size() and read simple_ilist.h and ilist_node.h next to it (Lesson 10.1).
Chapters: Ch 10 -
[LLVM-ImmutableMap] LLVM's persistent AVL-tree map (ImmutableMap / ImmutableSet.h) —
llvm/include/llvm/ADT/ImmutableMap.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ImmutableMap,ImmutableMap::Factory::add,ImutAVLTree.
Why and when: A production persistent map with path copying and hash-consed nodes (Algorithm 5.2.7), used by the Clang Static Analyzer's program states. ReadImmutableSet.h'sImutAVLFactory::add_internalafter the L2 milestone.
Chapters: Ch 5 -
[LLVM-IndVars] Induction-variable simplification, LFTR and IV-comparison folding —
llvm/lib/Transforms/Scalar/IndVarSimplify.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IndVarSimplify::linearFunctionTestReplace.
Why and when: LFTR (Lesson 18.4) and the removal of IV comparisons that makes loop bounds checks vanish (Lesson 18.9; see alsoSimplifyIndVar.cpp).
Chapters: Ch 18 -
[LLVM-InlineAdvisor] LLVM's inline advisor interface and default advisor —
llvm/lib/Analysis/InlineAdvisor.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DefaultInlineAdvisor::getAdviceImpl,llvm::shouldInline.
Why and when: Where the inliner asks "should I inline this call?" and where a learned advisor plugs in (Definition 20.3.10).
Chapters: Ch 20 -
[LLVM-InlineCost] LLVM's inline cost analysis —
llvm/lib/Analysis/InlineCost.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:CallAnalyzer::analyze,InlineCostCallAnalyzer,LastCallToStaticBonus,llvm::getInlineCost.
Why and when: Core reading. The production version of the course cost model: simplification during analysis, bonuses, thresholds. Read CallAnalyzer::analyze and InlineCostCallAnalyzer after Lesson 20.3 §2.
Chapters: Ch 20 -
[LLVM-InlineFunction] Inlining through an invoke —
llvm/lib/Transforms/Utils/InlineFunction.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:HandleInlinedLandingPad,HandleInlinedEHPad,HandleCallsInBlockInlinedThroughInvoke.
Why and when: Algorithm 24.6.8: calls of the copied body become invokes to the caller's pad, resumes become branches, clauses are merged; the funclet variant rewrites parent tokens.
Chapters: Ch 24 -
[LLVM-Inliner] LLVM's CGSCC inliner pass —
llvm/lib/Transforms/IPO/Inliner.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InlinerPass::run,ModuleInlinerWrapperPass.
Why and when: The bottom-up inliner loop: call sites per SCC, inline history against recursion through inlining, deletion of dead callees. Compare with pebble-inline (Algorithm 20.3.9).
Chapters: Ch 20 -
[LLVM-Inliner-noalias] How the inliner turns noalias parameters into scoped metadata —
llvm/lib/Transforms/Utils/InlineFunction.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:AddAliasScopeMetadata.
Why and when: Lesson 19.3 §7: the translation that keepsrestrictalive after inlining.
Chapters: Ch 19 -
[LLVM-InlineSpiller] LLVM's inline spiller (rematerialization, folding, spill hoisting) —
llvm/lib/CodeGen/InlineSpiller.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InlineSpiller::reMaterializeFor,InlineSpiller::spillAroundUses,HoistSpillHelper::runHoistSpills.
Why and when: Algorithms 22.9.7 and 22.9.9: rematerialize before uses, fold stack accesses, and hoist spills of the same value bottom-up on the dominator tree.
Chapters: Ch 22 -
[LLVM-InstCombine] GEP canonicalization to the byte-offset form, and freeze folding —
llvm/lib/Transforms/InstCombine/InstructionCombining.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InstCombinerImpl::visitGetElementPtrInst,shouldCanonicalizeGEPToPtrAdd,InstCombinerImpl::visitFreeze.
Why and when: Algorithm 9.4.9 as LLVM implements it ("Canonicalize constant GEPs to i8 type", "gep %T to gep [sizeof(%T) x i8]"). Read after Lesson 9.4 §6 with the instcombine box open.
Chapters: Ch 9, Ch 13, Ch 24 -
[LLVM-InstCombineMulDiv] InstCombine's multiplication and division rewrites —
llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InstCombinerImpl::visitMul,InstCombinerImpl::visitUDiv,InstCombinerImpl::visitSDiv.
Why and when: The IR-level strength reductions LLVM performs, and why sdiv by 2^k stays sdiv (Lesson 12.3 §7).
Chapters: Ch 12 -
[LLVM-Instr] Instruction insertion and the debug-record head bit —
llvm/lib/IR/Instruction.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Instruction::insertBefore,Instruction::insertInto,InsertPosition.
Why and when: The head-bit logic and the "Inserting PHI after debug-records!" assertion of Lesson 10.3; InsertPosition is declared (and its Instruction* constructor deprecated) in Instruction.h.
Chapters: Ch 10 -
[LLVM-InstSimplify] InstSimplify's phi folding (all incoming values equal, undef, self references) —
llvm/lib/Analysis/InstructionSimplify.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:simplifyPHINode.
Why and when: The rules mem2reg applies to its new phis at the end, and Aycock-Horspool's two reduction rules in production form (Lesson 16.3 §7).
Chapters: Ch 16 -
[LLVM-InstVisitor] The CRTP instruction visitor —
llvm/include/llvm/IR/InstVisitor.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InstVisitor::visit,DELEGATE,InstVisitor::delegateCallInst.
Why and when: Definition 10.4.8's delegation chains, generated from Instruction.def; the answer to the visitMemCpyInst quiz question is in delegateCallInst.
Chapters: Ch 10 -
[LLVM-Interchange] Loop interchange —
llvm/lib/Transforms/Scalar/LoopInterchange.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:populateDependencyMatrix,isLegalToInterChangeLoops,LoopInterchangeProfitability::isProfitable.
Why and when: Theorem 18.7.4 on a direction matrix, with a cache-cost profitability model; in the default -O2 pipeline of LLVM 23.
Chapters: Ch 18 -
[LLVM-Interp] LLVM's IR interpreter (lli -force-interpreter) —
llvm/lib/ExecutionEngine/Interpreter/Execution.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Interpreter::run,Interpreter::visitBinaryOperator.
Why and when: A walker over LLVM IR with one visit method per instruction kind — a real tree/graph-walking interpreter, 110× slower than LLVM's JIT in Lesson 0.2's box.
Chapters: Ch 0, Ch 10 -
[LLVM-Intrinsics] Target-independent intrinsic definitions (TableGen) —
llvm/include/llvm/IR/Intrinsics.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:int_sadd_with_overflow,int_smul_with_overflow,int_umul_with_overflow.
Why and when: Signatures, overloading and attributes of every target-independent intrinsic (Definition 9.5.6). Read the overflow intrinsics before lab E6.
Chapters: Ch 9 -
[LLVM-IPSCCP] Interprocedural SCCP (arguments, returns and globals) —
llvm/lib/Transforms/IPO/SCCP.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:runIPSCCP.
Why and when: The same solver across calls of internal functions: the preview of Lesson 17.1 §6, continued in Ch 20.
Chapters: Ch 17, Ch 20 -
[LLVM-IRB] IRBuilder (folders, inserters, state) —
llvm/include/llvm/IR/IRBuilder.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IRBuilderBase::Insert,IRBuilderBase::SetInsertPoint,IRBuilderDefaultInserter,IRBuilderCallbackInserter,IRBuilderBase::FastMathFlagGuard,IRBuilderBase::InsertPointGuard.
Why and when: Core reading. Algorithm 10.3.3 is CreateAdd → Folder.FoldNoWrapBinOp → Insert; read the class after Lesson 10.3 §2 and keep it open during Lab 10.1.
Chapters: Ch 10 -
[LLVM-IRCE] Inductive range-check elimination —
llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InductiveRangeCheck::extractRangeChecksFromBranch,InductiveRangeCheckElimination::run.
Why and when: Algorithm 18.9.8; the file header's example is exactlysum_nof Lesson 18.9.
Chapters: Ch 18, Ch 24 -
[LLVM-IROutliner] LLVM's IR-level outliner —
llvm/lib/Transforms/IPO/IROutliner.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:IROutliner::run,IROutliner::doOutline.
Why and when: Outlining of similar IR regions (with different constants as parameters); compare with the machine outliner in Lesson 20.4 §6.
Chapters: Ch 20 -
[LLVM-IVDesc] Induction and reduction descriptors used by the vectorizer —
llvm/lib/Analysis/IVDescriptors.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InductionDescriptor::isInductionPHI,RecurrenceDescriptor::isReductionPHI.
Why and when: How LLVM classifies header phis as inductions or reductions (Lessons 18.2 and 18.8).
Chapters: Ch 18 -
[LLVM-JIT] ORC's LLJIT — the method JIT the lab uses —
llvm/lib/ExecutionEngine/Orc/LLJIT.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LLJITBuilderState::prepareForConstruction,LLJIT::addIRModule,LLJIT::lookupLinkerMangled.
Why and when: What happens betweenaddIRModuleand a callable function pointer in the lab's JIT engine;prepareForConstructionpicks defaults for the host.
Chapters: Ch 0 -
[LLVM-JumpThreading] Jump threading with a lazy DomTreeUpdater —
llvm/lib/Transforms/Scalar/JumpThreading.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:JumpThreadingPass::runImpl,JumpThreadingPass::threadEdge.
Why and when: Makes many insertions and deletions per function and flushes them lazily; the batched-updates example of Lesson 15.2. Search for UpdateStrategy::Lazy.
Chapters: Ch 15, Ch 17 -
[LLVM-Kaleidoscope] The Kaleidoscope tutorial's expression parser —
llvm/examples/Kaleidoscope/Chapter2/toy.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ParseBinOpRHS,BinopPrecedence.
Why and when: The smallest production-quality precedence climber:ParseBinOpRHSwith a precedence map. Read it first among the sources of Lesson 4.1 §7.
Chapters: Ch 4 -
[LLVM-KB] Known-zero/known-one bit abstraction —
llvm/include/llvm/Support/KnownBits.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:KnownBits.
Why and when: A bit-level domain; its low bits are the power-of-two congruences of Definition 14.7.5.
Chapters: Ch 14 -
[LLVM-KnownBits] The known-bits domain and its transfer functions —
llvm/lib/Support/KnownBits.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:KnownBits::computeForAddSub.
Why and when: Zero/one masks per bit and the carry-aware addition of Lemma 17.2.9; read after Lesson 17.2 §2.
Chapters: Ch 17 -
[LLVM-LAA] LoopAccessAnalysis —
llvm/lib/Analysis/LoopAccessAnalysis.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MemoryDepChecker::isDependent,MemoryDepChecker::Dependence::isSafeForVectorization,RuntimePointerChecking::generateChecks.
Why and when: Core reading. Byte distances, the safe VF and runtime checks (Lesson 18.6); used by the vectorizer, loop distribution and versioning.
Chapters: Ch 18 -
[LLVM-LazyReexports] Lazy reexports: stubs, trampolines and the call-through manager —
llvm/lib/ExecutionEngine/Orc/LazyReexports.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LazyCallThroughManager::resolveTrampolineLandingAddress,LazyCallThroughManager::notifyResolved,LazyReexportsMaterializationUnit.
Why and when: Definition 24.3.4 and Algorithm 24.3.5 in code: what happens on the first call through a stub, and where a failed lookup lands (ErrorHandlerAddr).
Chapters: Ch 24 -
[LLVM-LCG] LLVM's LazyCallGraph (call and ref edges, RefSCCs, incremental updates) —
llvm/lib/Analysis/LazyCallGraph.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LazyCallGraph::buildRefSCCs,LazyCallGraph::RefSCC::switchInternalEdgeToRef,LazyCallGraph::RefSCC::switchInternalEdgeToCall.
Why and when: The graph the new pass manager's CGSCC walk runs on. Read the file header and buildRefSCCs after Lesson 20.2's Definition 20.2.6.
Chapters: Ch 20 -
[LLVM-LCSSA] The LCSSA pass —
llvm/lib/Transforms/Utils/LCSSA.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:formLCSSAForInstructions,formLCSSA,formLCSSARecursively.
Why and when: Core reading. Algorithm 15.7.8: exit phis for every instruction used outside its loop, then SSAUpdater; the "find it in LLVM" task of Lesson 15.7.
Chapters: Ch 15 -
[LLVM-LegacyPM] The legacy pass manager's scheduler —
llvm/lib/IR/LegacyPassManager.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PMTopLevelManager::schedulePass,FPPassManager::runOnFunction,PMDataManager::removeNotPreservedAnalysis.
Why and when: Algorithm 12.1.6 in production; still used by the code generator.
Chapters: Ch 12 -
[LLVM-LegalizeInt] Type legalization that turns a too-wide division into a libcall —
llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DAGTypeLegalizer::ExpandIntRes_SDIV.
Why and when: Algorithm 11.9.2's "LibCall" outcome in the code generator:RTLIB::getSDIVthenmakeLibCall. The quiz's find-in-LLVM question for Lesson 11.9.
Chapters: Ch 11 -
[LLVM-LegalizeTypes] SelectionDAG type legalization —
llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DAGTypeLegalizer::run.
Why and when: Algorithm 21.5.7: the worklist that promotes, expands, softens and splits illegal types (the operation legalizer is LegalizeDAG.cpp next to it).
Chapters: Ch 21 -
[LLVM-LI] Natural loops (and llvm/include/llvm/Analysis/CycleAnalysis.h for cycles) —
llvm/include/llvm/Analysis/LoopInfo.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LoopInfo.
Why and when: The loop nesting forest that intervals approximate (Lesson 14.5); Ch 15 builds it.
Chapters: Ch 14 -
[LLVM-LICM] LLVM's loop-invariant code motion, sinking and scalar promotion —
llvm/lib/Transforms/Scalar/LICM.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:llvm::hoistRegion,llvm::sinkRegion,llvm::canSinkOrHoistInst,llvm::promoteLoopAccessesToScalars.
Why and when: The production LICM with MemorySSA; comparehoistRegionwith E1's pass after Lesson 18.1.
Chapters: Ch 18, Ch 19 -
[LLVM-litSrc] lit's shell-test runner —
llvm/utils/lit/lit/TestRunner.pyinllvm/llvm-projectatllvmorg-23.1.2. Symbols:executeShTest,parseIntegratedTestScript.
Why and when: RUN-line parsing, substitutions and the internal shell behind Algorithm 12.4.7.
Chapters: Ch 12 -
[LLVM-LiveDebugValues] LiveDebugValues (the VarLoc-based implementation) —
llvm/lib/CodeGen/LiveDebugValues/VarLocBasedImpl.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:VarLocBasedLDV::transferRegisterDef,VarLocBasedLDV::transferSpillOrRestoreInst,VarLocBasedLDV::join.
Why and when: Algorithm 24.4.7 in production: the dataflow that propagates variable locations across blocks, with the clobber-at-call and spill/restore transfers of the drill's model.
Chapters: Ch 24 -
[LLVM-LiveIntervals] LLVM's live interval analysis (segments over slot indexes) —
llvm/lib/CodeGen/LiveIntervals.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LiveIntervals::computeVirtRegInterval,LiveIntervals::getSpillWeight.
Why and when: How LLVM builds the live intervals of Definition 22.1.8, with holes and value numbers, and the per-instruction spill weight used by Definition 22.9.1.
Chapters: Ch 22 -
[LLVM-LLJIT] LLJIT and LLLazyJIT —
llvm/include/llvm/ExecutionEngine/Orc/LLJIT.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LLJIT,LLJIT::lookup,LLJIT::getIRTransformLayer,LLLazyJIT::addLazyIRModule,LLJITBuilder.
Why and when: The API Lab 10.1's tests and Lab 10.3 use; LLJIT.cpp (prepareForConstruction) shows the default layer stack of Algorithm 10.8.5.
Chapters: Ch 10, Ch 24 -
[LLVM-LLParser] LLVM's textual IR parser (hand-written recursive descent) —
llvm/lib/AsmParser/LLParser.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LLParser::parseTopLevelEntities.
Why and when: A switch on the token kind per construct: the technique LLVM uses instead of a generated LR parser (Lesson 3.1's find-it task).
Chapters: Ch 3, Ch 9 -
[LLVM-LoopInfo] LLVM's natural-loop discovery (LoopInfo) —
llvm/include/llvm/Support/GenericLoopInfoImpl.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LoopInfoBase::analyze,discoverAndMapSubloop,PopulateLoopsDFS.
Why and when: Core reading. Natural loops discovered by a backward walk per header that skips inner subloops (Algorithm 15.5.7 made linear); read after Lesson 15.5 §2.
Chapters: Ch 15 -
[LLVM-LoopInfoCpp] LoopInfo for IR, and the canonical-form predicates —
llvm/lib/Analysis/LoopInfo.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Loop::isLoopSimplifyForm,Loop::isLCSSAForm,Loop::isRecursivelyLCSSAForm.
Why and when: The checks behind Definitions 15.7.3 and 15.7.4; short, read them before Lesson 15.7 §2.
Chapters: Ch 15 -
[LLVM-LoopPredication] Loop predication of guards —
llvm/lib/Transforms/Scalar/LoopPredication.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LoopPredication::widenICmpRangeCheck.
Why and when: Algorithm 18.9.9; the header comment explains why SCEV facts must not be used circularly to widen a guard.
Chapters: Ch 18 -
[LLVM-LoopRotate] Loop rotation (top-tested to guarded do-while) —
llvm/lib/Transforms/Utils/LoopRotationUtils.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LoopRotate::rotateLoop.
Why and when: Algorithm 11.4.7 in production: duplicate the header into the preheader as a guard and move the test to the latch. The header-size limit lives inLoopRotation.cpp(LoopRotatePass::run).
Chapters: Ch 11, Ch 15, Ch 18 -
[LLVM-LoopSimplify] The loop-simplify pass —
llvm/lib/Transforms/Utils/LoopSimplify.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:simplifyOneLoop,InsertPreheaderForLoop,separateNestedLoop,insertUniqueBackedgeBlock.
Why and when: Core reading. Algorithm 15.7.6 in production; read simplifyOneLoop top to bottom after Lesson 15.7 §2, then separateNestedLoop with the skip.c box.
Chapters: Ch 15, Ch 24 -
[LLVM-LoopVersioning] LLVM's loop versioning utility —
llvm/lib/Transforms/Utils/LoopVersioning.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LoopVersioning::versionLoop,LoopVersioning::addPHINodes,LoopVersioning::annotateLoopWithNoAlias.
Why and when: Algorithm 24.2.5 in production: cloning withcloneLoopWithPreheader, the exit phis, and thenoaliasscopes that tell later passes the runtime checks passed.
Chapters: Ch 24 -
[LLVM-LPM] The loop pass manager —
llvm/include/llvm/Transforms/Scalar/LoopPassManager.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:FunctionToLoopPassAdaptor,LPMUpdater.
Why and when: Loop pipelines that may add and delete loops while running (Lesson 12.1 §6).
Chapters: Ch 12 -
[LLVM-LSR] LLVM's Loop Strength Reduce —
llvm/lib/Transforms/Scalar/LoopStrengthReduce.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LSRInstance::SolveRecurse,LSRInstance::NarrowSearchSpaceUsingHeuristics.
Why and when: The cost-driven formula search of Lesson 18.4; read the file header's overview first.
Chapters: Ch 18 -
[LLVM-LTOSrc] LLVM's LTO driver (regular and thin) —
llvm/lib/LTO/LTO.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LTO::run,LTO::runRegularLTO,LTO::runThinLTO.
Why and when: The implementation behind llvm-lto2 and the linker plugins: symbol resolutions, internalization, the regular and thin paths. Read after Lesson 20.9 §2.
Chapters: Ch 20 -
[LLVM-LV] SSA liveness of virtual registers on Machine IR —
llvm/lib/CodeGen/LiveVariables.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LiveVariables::analyze,LiveVariables::MarkVirtRegAliveInBlock,LiveVariables::HandleVirtRegUse.
Why and when: The path-exploration liveness of Algorithm 14.6.4, producing the kill flags register allocation needs (Lessons 14.3 and 14.6).
Chapters: Ch 14, Ch 18 -
[LLVM-LVI] On-demand interval analysis per (value, block) —
llvm/lib/Analysis/LazyValueInfo.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LazyValueInfoImpl::solve,LazyValueInfoImpl::solveBlockValue.
Why and when: A demand-driven interval analysis with branch refinement on edges, the closest LLVM relative of exercise E6 (Lessons 14.1 and 14.7).
Chapters: Ch 14, Ch 17 -
[LLVM-LVLegality] Vectorization legality —
llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LoopVectorizationLegality::canVectorize,LoopVectorizationLegality::canVectorizeWithIfConvert,LoopVectorizationLegality::canFoldTailByMasking.
Why and when: What the vectorizer accepts: inductions, reductions, if-convertible control flow, masked tails.
Chapters: Ch 18 -
[LLVM-LVLICM] Loop versioning to enable LICM of possibly aliased memory —
llvm/lib/Transforms/Scalar/LoopVersioningLICM.cppinllvm/llvm-projectatllvmorg-23.1.2.
Why and when: Versioning (Lesson 18.5) used for LICM (Lesson 18.1): a runtime no-alias check buys hoisting.
Chapters: Ch 18 -
[LLVM-MachineCombiner] Latency-driven reassociation and combining of machine instructions —
llvm/lib/CodeGen/MachineCombiner.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MachineCombiner::combineInstructions,TargetInstrInfo::getMachineCombinerPatterns.
Why and when: Tree-height reduction with real latencies (Lesson 13.6 §7). Read combineInstructions after the lesson.
Chapters: Ch 13, Ch 21 -
[LLVM-MachineCSE] LLVM's machine CSE —
llvm/lib/CodeGen/MachineCSE.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MachineCSE::PerformCSE,MachineCSE::isProfitableToCSE.
Why and when: Scoped value numbering over the dominator tree on SSA MachineInstrs (Proposition 23.10.4).
Chapters: Ch 23 -
[LLVM-MachineLICM] LLVM's machine LICM (early and post-RA) —
llvm/lib/CodeGen/MachineLICM.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MachineLICMImpl::HoistOutOfLoop,MachineLICMImpl::IsProfitableToHoist.
Why and when: Hoisting with register-pressure checks before allocation and only with free registers after it (Proposition 23.10.8).
Chapters: Ch 23 -
[LLVM-MachineOutliner] LLVM's machine outliner (suffix-tree based) —
llvm/lib/CodeGen/MachineOutliner.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:InstructionMapper,MachineOutliner::findCandidates,MachineOutliner::outline.
Why and when: Maps machine instructions to integers, finds repeats with a suffix tree and asks the target for the cost of each outlining strategy. Read after Lesson 20.4's outlining.
Chapters: Ch 20 -
[LLVM-MachineSink] LLVM's machine sinking —
llvm/lib/CodeGen/MachineSink.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MachineSinking::SinkInstruction,MachineSinking::FindSuccToSinkTo.
Why and when: Moves instructions into the successor that uses them (Lesson 23.10 §2); readFindSuccToSinkTofor the legality and profitability rules.
Chapters: Ch 23 -
[LLVM-MachO] AArch64 Mach-O relocation writer —
llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:AArch64MachObjectWriter::recordRelocation.
Why and when: The mapping from AArch64 fixup kinds to ARM64_RELOC_* types seen in Lesson 21.10's object box.
Chapters: Ch 21 -
[LLVM-MBP] LLVM's block placement (chains, loop rotation, tail duplication, ext-TSP) —
llvm/lib/CodeGen/MachineBlockPlacement.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MachineBlockPlacement::buildChain,MachineBlockPlacement::selectBestSuccessor,MachineBlockPlacement::applyExtTsp.
Why and when: A loop-aware descendant of Pettis–Hansen, with an optional ext-TSP stage. ReadbuildChainafter Algorithm 23.9.2.
Chapters: Ch 23 -
[LLVM-MC] LLVM's integrated assembler — ELF object writer —
llvm/lib/MC/ELFObjectWriter.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ELFWriter,ELFWriter::computeSymbolTable,ELFWriter::writeSectionHeaders.
Why and when: Where sections, symbols and relocations of Lesson 0.6'smain.oare written;llvm/lib/MC/MCParser/AsmParser.cppparses assembly text and inline asm.
Chapters: Ch 0 -
[LLVM-MCASrc] llvm-mca's block reciprocal-throughput bound —
llvm/lib/MCA/Support.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:computeBlockRThroughput.
Why and when: Ten lines that compute the "Block RThroughput" of everyllvm-mcareport: exactly the maximum of Definition 23.1.10. Read it after Theorem 23.1.12.
Chapters: Ch 23 -
[LLVM-MCAssembler] The MC assembler (layout, relaxation, fixups) —
llvm/lib/MC/MCAssembler.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MCAssembler::layout,MCAssembler::relaxOnce,MCAssembler::evaluateFixup.
Why and when: Algorithm 21.10.6 as a fused forward sweep and Algorithm 21.10.10's fixup evaluation. Read relaxOnce after Theorem 21.10.7.
Chapters: Ch 21 -
[LLVM-MCP] LLVM's post-RA machine copy propagation —
llvm/lib/CodeGen/MachineCopyPropagation.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MachineCopyPropagation::forwardUses,MachineCopyPropagation::forwardCopyPropagateBlock.
Why and when: Forwards and removes the copies that allocation leaves behind; the file header states the legality conditions quoted in Lesson 22.8 §4.
Chapters: Ch 22 -
[LLVM-Mem2Reg] LLVM's mem2reg (phi placement by iterated dominance frontiers) —
llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PromoteMemToReg.
Why and when: Where the phis of Lesson 8.4's LLVM box and Lesson 8.7's PIR box are placed.
Chapters: Ch 8, Ch 9, Ch 11, Ch 15, Ch 16 -
[LLVM-Mem2RegPass] The mem2reg pass wrapper (which allocas are collected, the repeat loop) —
llvm/lib/Transforms/Utils/Mem2Reg.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:promoteMemoryToRegister,PromotePass::run.
Why and when: Collects the promotable allocas of the entry block, which is why E5 puts every alloca there; read with Lesson 11.1 §7.
Chapters: Ch 11, Ch 16 -
[LLVM-MemCpyOpt] MemCpyOpt (store merging, memcpy forwarding, memset formation, call-slot optimization) —
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MemCpyOptPass::tryMergingIntoMemset,MemCpyOptPass::processMemCpyMemCpyDependence,MemCpyOptPass::performMemCpyToMemSetOptzn,MemCpyOptPass::performCallSlotOptzn.
Why and when: Lesson 19.11's memcpyopt; read the four named transforms after its box.
Chapters: Ch 19 -
[LLVM-Metadata] Metadata as value and value as metadata —
llvm/lib/IR/Metadata.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MetadataAsValue::get,ValueAsMetadata::handleRAUW,ValueAsMetadata::handleDeletion.
Why and when: How metadata follows RAUW without use lists (Lesson 10.2 §4); the declarations are in llvm/include/llvm/IR/Metadata.h.
Chapters: Ch 10 -
[LLVM-MISched] LLVM's MachineScheduler and GenericScheduler —
llvm/lib/CodeGen/MachineScheduler.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:GenericScheduler::tryCandidate,SchedBoundary::getNextResourceCycle,SchedBoundary::bumpCycle,ScheduleDAGMILive::schedule.
Why and when: Core reading. The default pre-RA scheduler: bidirectional list scheduling with pressure, latency and resource heuristics. ReadtryCandidateafter Lesson 23.3 and again after Lesson 23.7, with-misched-print-dagsoutput in hand.
Chapters: Ch 23 -
[LLVM-MLAdvisor] LLVM's ML inline advisor (MLGO) —
llvm/lib/Analysis/MLInlineAdvisor.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MLInlineAdvisor::getAdviceImpl,MLInlineAdvisor::onPassEntry.
Why and when: The features MLGO feeds its model and how the model's decision becomes advice; read with Lesson 20.3's MLGO section.
Chapters: Ch 20 -
[LLVM-Module] Module destruction (drop references, then clear the lists) —
llvm/lib/IR/Module.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Module::~Module,Module::dropAllReferences.
Why and when: Algorithm 10.1.5 in five lines; read with Function::~Function.
Chapters: Ch 10 -
[LLVM-ModuloSchedule] LLVM's modulo-schedule code generators (prologue, kernel, epilogue; MVE; peeling) —
llvm/lib/CodeGen/ModuloSchedule.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ModuloScheduleExpander::expand,ModuloScheduleExpanderMVE,PeelingModuloScheduleExpander.
Why and when: Three code generators for one schedule (Definition 23.6.11): phi renaming, modulo variable expansion and stage peeling. Read after Theorem 23.6.15.
Chapters: Ch 23 -
[LLVM-MSSA] MemorySSA's invalidation predicate —
llvm/lib/Analysis/MemorySSA.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:MemorySSAAnalysis::Result::invalidate.
Why and when: Invalidated when not preserved, or when AA or the dominator tree is (Lesson 12.1's cascade box).
Chapters: Ch 12, Ch 14, Ch 16, Ch 19 -
[LLVM-MustExec] Guaranteed-execution queries used by LICM —
llvm/lib/Analysis/MustExecute.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SimpleLoopSafetyInfo::isGuaranteedToExecute,ICFLoopSafetyInfo::isGuaranteedToExecute.
Why and when: Definition 18.1.3 in code; read after the "guaranteed execution" part of Lesson 18.1.
Chapters: Ch 18 -
[LLVM-NewGVN] NewGVN, LLVM's optimistic sparse GVN after Gargi —
llvm/lib/Transforms/Scalar/NewGVN.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:NewGVN::iterateTouchedInstructions,NewGVN::performCongruenceFinding,CongruenceClass.
Why and when: Its header cites [Gar02] and Simpson's SCC-based VN; congruence classes that start optimistic, touched-instruction iteration, PredicateInfo (Lesson 17.5 §7).
Chapters: Ch 17 -
[LLVM-NewPMDriver] opt's pipeline driver —
llvm/tools/opt/NewPMDriver.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:registerEPCallbacks,runPassPipeline.
Why and when: Why -passes-ep-* cannot name plugin passes: the flags are parsed before plugins register (Lesson 12.2 §7).
Chapters: Ch 12 -
[LLVM-NV2Sched] LLVM's Arm Neoverse V2 scheduling model —
llvm/lib/Target/AArch64/AArch64SchedNeoverseV2.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:NeoverseV2Model.
Why and when: A modern Arm server-core model to compare with Skylake's (Lesson 23.1 §7): wider buffers, different port structure, the same TableGen vocabulary.
Chapters: Ch 23 -
[LLVM-PartialInliner] LLVM's partial inliner —
llvm/lib/Transforms/IPO/PartialInlining.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PartialInlinerImpl::tryPartialInline,PartialInlinerImpl::computeOutliningInfo.
Why and when: Recognizes an early-return guard, outlines the rest and inlines the guard. Read after Lesson 20.4's partial inlining.
Chapters: Ch 20 -
[LLVM-PassPlugin] The pass-plugin ABI (LLVM 22+ header location) —
llvm/include/llvm/Plugins/PassPlugin.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PassPluginLibraryInfo,LLVM_PLUGIN_API_VERSION,llvmGetPassPluginInfo.
Why and when: What PebblePasses.so exports; the course's pebble/lib/Passes/Plugin.cpp implements it.
Chapters: Ch 12 -
[LLVM-PassRegistry] The table of built-in pass names —
llvm/lib/Passes/PassRegistry.definllvm/llvm-projectatllvmorg-23.1.2. Symbols:FUNCTION_PASS,FUNCTION_ANALYSIS.
Why and when: Every name opt accepts, including the print<...> printers of Lesson 12.3.
Chapters: Ch 12 -
[LLVM-PatternMatch] The PatternMatch combinator library —
llvm/include/llvm/IR/PatternMatch.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:match,BinaryOp_match,bind_ty,deferredval_ty,specificval_ty,m_Not,m_Neg,m_SMax.
Why and when: Core reading. Algorithm 10.5.3 is BinaryOp_match::match; note that m_SMax matches only the intrinsic in LLVM 23 (Lesson 10.5 real-world box).
Chapters: Ch 10, Ch 13 -
[LLVM-PB] PassBuilder's parsing and extension-point callbacks —
llvm/include/llvm/Passes/PassBuilder.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PassBuilder::registerPipelineParsingCallback,PassBuilder::registerPeepholeEPCallback,PassBuilder::registerOptimizerLastEPCallback.
Why and when: Every extension point a plugin can use (Definition 12.2.2).
Chapters: Ch 12, Ch 24 -
[LLVM-PBP] How -O1/-O2/-O3 pipelines are built —
llvm/lib/Passes/PassBuilderPipelines.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PassBuilder::buildPerModuleDefaultPipeline,PassBuilder::buildModuleSimplificationPipeline,PassBuilder::buildFunctionSimplificationPipeline,PassBuilder::buildO1FunctionSimplificationPipeline,PassBuilder::invokePeepholeEPCallbacks.
Why and when: Algorithm 12.2.5 in code: read buildPerModuleDefaultPipeline, then follow the simplification pipeline.
Chapters: Ch 12, Ch 24 -
[LLVM-PBQP] LLVM's PBQP reduction rules (used by the PBQP register allocator) —
llvm/include/llvm/CodeGen/PBQP/ReductionRules.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:applyR1,applyR2,backpropagate.
Why and when: The R1/R2 reductions of Algorithm 21.4.12 in about 220 lines. Read with Lesson 21.4's PBQP box.
Chapters: Ch 21 -
[LLVM-PBQPRA] LLVM's PBQP register allocation graph and solver —
llvm/include/llvm/CodeGen/RegAllocPBQP.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PBQP::RegAlloc::RegAllocSolverImpl::reduce,PBQP::RegAlloc::solve.
Why and when: The reduction order of Lesson 22.7 §7 (optimal R0–R2 first, then conservatively allocatable nodes, then lowest spill cost per degree); the graph is built in RegAllocPBQP.cpp.
Chapters: Ch 22 -
[LLVM-Peel] Loop peeling —
llvm/lib/Transforms/Utils/LoopPeel.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:llvm::peelLoop,llvm::canPeel.
Why and when: Peeling first and last iterations (Lesson 18.5); the count heuristics are incomputePeelCount.
Chapters: Ch 18 -
[LLVM-Peephole] LLVM's machine peephole optimizer —
llvm/lib/CodeGen/PeepholeOptimizer.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PeepholeOptimizer::optimizeCmpInstr,PeepholeOptimizer::isLoadFoldable,PeepholeOptimizer::optimizeExtInstr.
Why and when: Target-hook-driven rewrites before allocation: compare elimination, load folding, copy rewriting (Lesson 23.10 §2).
Chapters: Ch 23 -
[LLVM-PEI] Prologue/epilogue insertion and frame layout —
llvm/lib/CodeGen/PrologEpilogInserter.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PEIImpl::calculateFrameObjectOffsets,PEIImpl::insertPrologEpilogCode,PEIImpl::replaceFrameIndices.
Why and when: Algorithms 21.9.6 and 21.9.8; shrink-wrapping (Algorithm 21.9.10) is ShrinkWrap.cpp in the same directory.
Chapters: Ch 21 -
[LLVM-PGOInstr] IR-level PGO instrumentation (pgo-instr-gen) —
llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:FuncPGOInstrumentation,SplitCriticalEdge.
Why and when: Spanning-tree counter placement in production (Theorem 12.3.12), with critical-edge splitting.
Chapters: Ch 12 -
[LLVM-PGOSrc] LLVM's IR PGO instrumentation and profile use —
llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PGOInstrumentationGen::run,instrumentOneFunc,PGOUseFunc::populateCounters,PGOUseFunc::setBranchWeights.
Why and when: Spanning-tree counter placement (via CFGMST.h), value-profiling sites, count reconstruction and branch weights. Read the file header first (Lesson 20.10's quiz asks about it).
Chapters: Ch 20 -
[LLVM-PHIElim] LLVM's machine-level phi elimination (copies in predecessors, critical-edge splitting) —
llvm/lib/CodeGen/PHIElimination.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PHIEliminationImpl::LowerPHINode,PHIEliminationImpl::SplitPHIEdges.
Why and when: Destruction in LLVM's back end: a fresh virtual register per phi, a COPY at the end of each predecessor and one at the block start (Sreedhar's Method I), and edge splitting when the incoming value is live past the phi. Lessons 16.6-16.7.
Chapters: Ch 16 -
[LLVM-PI] Pass instrumentation callbacks —
llvm/include/llvm/IR/PassInstrumentation.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PassInstrumentationCallbacks.
Why and when: shouldRunOptionalPass, beforeSkippedPass, beforeNonSkippedPass, afterPass: the hooks of Algorithm 12.1.8.
Chapters: Ch 12 -
[LLVM-Pipeliner] LLVM's MachinePipeliner (swing modulo scheduling) —
llvm/lib/CodeGen/MachinePipeliner.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SwingSchedulerDAG::schedulePipeline,SwingSchedulerDAG::calculateRecMII,SwingSchedulerDAG::computeNodeOrder,ResourceManager::calculateResMII.
Why and when: Core reading. SMS in production: MII, node sets, ordering and scheduling, with-pipeliner-*debug options. Read it after Lesson 23.6 §7 with the Hexagon box's-debug-only=pipelineroutput.
Chapters: Ch 23 -
[LLVM-Pipelines] The -O0/-O1/-O2/-O3 pass pipelines of LLVM's new pass manager —
llvm/lib/Passes/PassBuilderPipelines.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PassBuilder::buildPerModuleDefaultPipeline,PassBuilder::buildO0DefaultPipeline.
Why and when: The composition of passes thatdefault<O2>means (Lesson 0.1's box prints it); come back in Ch 12 and Ch 24 when you build Pebble's own pipeline.
Chapters: Ch 0, Ch 17, Ch 20 -
[LLVM-PMH] The new pass manager's core templates —
llvm/include/llvm/IR/PassManager.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:AnalysisManager,InnerAnalysisManagerProxy,OuterAnalysisManagerProxy,ModuleToFunctionPassAdaptor,RequiredPassInfoMixin,OptionalPassInfoMixin.
Why and when: The data structures of Algorithms 12.1.7–12.1.10. Read after Lesson 12.1 §2; PreservedAnalyses itself is in llvm/include/llvm/IR/Analysis.h.
Chapters: Ch 12 -
[LLVM-PostDom] LLVM's post-dominator tree analysis and printer —
llvm/lib/Analysis/PostDominators.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PostDominatorTree,PostDominatorTreeAnalysis,PostDominatorTreePrinterPass.
Why and when: The analysis wrapper of Lesson 15.4 (the tree itself is built by LLVM-GDTC with a virtual root); open it with the printbox.
Chapters: Ch 15 -
[LLVM-PostRA] LLVM's legacy post-RA list scheduler with anti-dependence breaking —
llvm/lib/CodeGen/PostRASchedulerList.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SchedulePostRATDList,PostRAScheduler::runOnMachineFunction.
Why and when: Top-down scheduling after allocation with a hazard recognizer and optionalCriticalAntiDepBreaker/AggressiveAntiDepBreaker(Proposition 23.7.10).
Chapters: Ch 23 -
[LLVM-PredicateInfo] LLVM's PredicateInfo (e-SSA copies after branches and assumes) —
llvm/lib/Transforms/Utils/PredicateInfo.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:PredicateInfoBuilder::buildPredicateInfo,PredicateInfoBuilder::renameUses.
Why and when: e-SSA in LLVM: bitcast copies (formerly ssa.copy intrinsics) on the edges of conditional branches, consumed by SCCP and NewGVN. Lesson 16.8's SSI/e-SSA box.
Chapters: Ch 16 -
[LLVM-RAFast] LLVM's fast (local) register allocator used at -O0 —
llvm/lib/CodeGen/RegAllocFast.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:RegAllocFastImpl::allocateBasicBlock,RegAllocFastImpl::allocateInstruction.
Why and when: Algorithm 22.2.5: allocate one block bottom-up, spill everything live across block boundaries. Read allocateBasicBlock after Lesson 22.2 §7.
Chapters: Ch 22 -
[LLVM-RDA] Reaching definitions of physical registers after register allocation —
llvm/lib/CodeGen/ReachingDefAnalysis.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ReachingDefInfo::run,ReachingDefInfo::processBasicBlock,ReachingDefInfo::reprocessBasicBlock.
Why and when: Reaching definitions with LoopTraversal's two-pass order (Lessons 14.3 and 14.4 §6).
Chapters: Ch 14 -
[LLVM-Reassociate] A pass built on hand-written matching —
llvm/lib/Transforms/Scalar/Reassociate.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:isReassociableOp,LinearizeExprTree.
Why and when: Tree manipulation with dyn_cast and opcode tests (Lesson 10.5 §7); contrast with InstCombineAddSub.cpp's PatternMatch style.
Chapters: Ch 10, Ch 13 -
[LLVM-RegCoalescer] LLVM's register coalescer (value-numbered live intervals) —
llvm/lib/CodeGen/RegisterCoalescer.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:JoinVals::analyzeValue,JoinVals::valuesIdentical,RegisterCoalescer::joinCopy.
Why and when: The coalescing phase after PHIElimination; JoinVals compares value numbers, not just live ranges, so copies of one value do not interfere (Lesson 16.7).
Chapters: Ch 16, Ch 22 -
[LLVM-Regex] LLVM's POSIX regex matcher (Henry Spencer's engine), used by FileCheck —
llvm/lib/Support/regexec.cinllvm/llvm-projectatllvmorg-23.1.2. Symbols:llvm_regexec,smatcher,lmatcher.
Why and when: NFA simulation with state sets as bit masks (Lesson 1.2), backtracking only for backreferences (backrefin regengine.inc). The "find where LLVM does it" task of Lessons 1.1–1.2.
Chapters: Ch 1 -
[LLVM-RegionInfo] Single-entry single-exit regions (print
) —llvm/lib/Analysis/RegionInfo.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:RegionInfo,RegionInfoPrinterPass.
Why and when: The modern descendant of intervals (Lesson 15.6): nested SESE regions computed from dominance and post-dominance frontiers, used by Polly.
Chapters: Ch 15 -
[LLVM-RemoveDIs] The debug-record classes —
llvm/lib/IR/DebugProgramInstruction.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DbgVariableRecord,DbgMarker,DbgRecord::insertBefore.
Why and when: What a#dbg_valueis in memory (aDbgVariableRecordhanging off aDbgMarker), which is why instruction counts do not see it. Read alongside [LLVM-DbgRecords].
Chapters: Ch 24 -
[LLVM-ReOpt] ORC's re-optimization layer (tiering by symbol redirection) —
llvm/include/llvm/ExecutionEngine/Orc/ReOptimizeLayer.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ReOptimizeLayer,ReOptimizeLayer::reoptimizeIfCallFrequent,ReOptimizeLayer::CallCountThreshold.
Why and when: Algorithm 24.3.6: call-count instrumentation, the threshold of 10, and redirection through aRedirectableSymbolManager. The.cppnext to it has the instrumentation IR.
Chapters: Ch 24 -
[LLVM-RI] Single-entry single-exit regions —
llvm/lib/Analysis/RegionInfo.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:RegionInfo.
Why and when: The region tree that structural analysis would summarize (Lesson 14.5's RegionInfo box).
Chapters: Ch 14 -
[LLVM-RPOT] LLVM's generic postorder and RPO iterators —
llvm/include/llvm/ADT/PostOrderIterator.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:post_order,ReversePostOrderTraversal.
Why and when: An explicit-stack DFS over anyGraphTraitsgraph: Algorithm 8.2.8 in production, used by the RPO box of Lesson 8.2.
Chapters: Ch 8 -
[LLVM-RRList] SelectionDAG's bottom-up list schedulers (source, list-burr, list-hybrid, list-ilp) —
llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ScheduleDAGRRList::ListScheduleBottomUp,bu_ls_rr_sort,hybrid_ls_rr_sort,ilp_ls_rr_sort,src_ls_rr_sort.
Why and when: Four priority functions on one bottom-up engine (Lesson 23.7 §2). Compare the sort functions with the priorities of Lesson 23.3.
Chapters: Ch 23 -
[LLVM-RS4GC] Rewriting calls into statepoints with base/derived pairs —
llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:findBasePointers,findLiveSetAtInst,RewriteStatepointsForGC::runOnFunction.
Why and when: Algorithm 24.5.6 in production: liveness at each call, the base pointer of every live value (phis get base phis), and the relocation of derived pointers after the call.
Chapters: Ch 24 -
[LLVM-RuntimeLibcalls] The table of every runtime library call LLVM may emit —
llvm/include/llvm/IR/RuntimeLibcalls.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SDIV_I128,__divti3.
Why and when: Maps libcalls (Definition 11.9.1) to symbols per target, such as__divti3for a 128-bit signed division; read with Lesson 11.9 §7.
Chapters: Ch 11 -
[LLVM-SampleSrc] LLVM's sample-profile loader (AutoFDO) —
llvm/lib/Transforms/IPO/SampleProfile.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SampleProfileLoader::getInstWeight,SampleProfileLoader::inlineHotFunctions,SampleProfileLoader::emitAnnotations.
Why and when: How line-offset samples become block weights, how the profiled binary's inlining is replayed, and where the annotations are written. Read after Lesson 20.10's sampling box.
Chapters: Ch 20 -
[LLVM-SCCIt] LLVM's generic iterative Tarjan SCC iterator —
llvm/include/llvm/ADT/SCCIterator.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:scc_iterator::DFSVisitOne,scc_iterator::DFSVisitChildren,scc_iterator::GetNextSCC.
Why and when: The exact algorithm and visiting order of Algorithm 20.2.3; read it before E1 and compare its lowlink updates with yours.
Chapters: Ch 20 -
[LLVM-SCCIterator] LLVM's Tarjan SCC iterator —
llvm/include/llvm/ADT/SCCIterator.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:scc_iterator::DFSVisitChildren,StackElement::MinVisited.
Why and when: The same SCC bookkeeping as Digraph (Theorem 3.3.10): MinVisited plays the role of N[x] (Lesson 3.3's find-it task).
Chapters: Ch 3 -
[LLVM-SCCP] LLVM's sparse conditional constant (and range) propagation solver —
llvm/lib/Transforms/Utils/SCCPSolver.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SCCPInstVisitor::solve,SCCPInstVisitor::markEdgeExecutable,MaxNumRangeExtensions.
Why and when: Wegman–Zadeck SCCP over ValueLatticeElement, with executable edges and range widening (Lessons 14.1, 14.6 and 14.7).
Chapters: Ch 14, Ch 15, Ch 17, Ch 20 -
[LLVM-SCCPPass] The intraprocedural sccp pass (solver driver and rewriting) —
llvm/lib/Transforms/Scalar/SCCP.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:runSCCP,SCCPPass::run.
Why and when: Where the solver's results become IR: constants replaced, dead blocks removed, flags and range attributes added (Lesson 17.1 §7 and Lesson 17.2's range box).
Chapters: Ch 17 -
[LLVM-SCEV] ScalarEvolution's invalidation predicate with dependencies —
llvm/lib/Analysis/ScalarEvolution.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ScalarEvolution::invalidate.
Why and when: The textbook example of an analysis that must consult its dependencies (AC, DT, LI) when invalidated.
Chapters: Ch 12, Ch 14, Ch 18 -
[LLVM-SCEVExpr] The SCEV expression classes —
llvm/include/llvm/Analysis/ScalarEvolutionExpressions.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SCEVAddRecExpr,SCEVUnknown.
Why and when: The data structure behind the CR notation of Lesson 18.3;SCEVAddRecExpr::evaluateAtIterationis Definition 18.3.1's evaluation.
Chapters: Ch 18 -
[LLVM-ScheduleDAG] LLVM's scheduling-DAG node and edge types —
llvm/include/llvm/CodeGen/ScheduleDAG.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SDep,SUnit.
Why and when:SUnitandSDep(kindsData,Anti,Output,Order, with latencies), shared by the SelectionDAG and MachineInstr schedulers. Read it to decode DAG dumps.
Chapters: Ch 23 -
[LLVM-ScopedNoAlias] Scoped noalias AA (alias.scope / noalias metadata) —
llvm/lib/Analysis/ScopedNoAliasAA.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ScopedNoAliasAAResult::alias,ScopedNoAliasAAResult::mayAliasInScopes.
Why and when: Algorithm 19.3.6's subset test in about 30 lines; read after Lesson 19.3 §2.
Chapters: Ch 19 -
[LLVM-SDAG] LLVM's SelectionDAG (a hash-consed DAG per basic block) —
llvm/include/llvm/CodeGen/SelectionDAG.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SelectionDAG,CSEMap.
Why and when: The expression-DAG IR of LLVM's instruction selector (Ch 21); nodes are CSE'd throughFoldingSet<SDNode> CSEMapas they are created.
Chapters: Ch 8 -
[LLVM-SDB] Where an LLVM
switchbecomes clusters and a comparison tree —llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SelectionDAGBuilder::visitSwitch,SelectionDAGBuilder::lowerWorkItem,SelectionDAGBuilder::splitWorkItem.
Why and when: Sorts the cases, forms clusters and emits the balanced tree of Algorithm 11.3.7; readvisitSwitchthensplitWorkItemafter Lesson 11.3 §2.
Chapters: Ch 11 -
[LLVM-SDCombiner] The SelectionDAG combiner —
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DAGCombiner::combine,DAGCombiner::visitADD,DAGCombiner::visitMUL.
Why and when: Algorithm 21.5.4 in production: a worklist of visit* rewrites run at four legality levels. Read visitMUL after Lesson 21.5 §3.
Chapters: Ch 21 -
[LLVM-SDInstrs] LLVM's dependence-DAG construction for MachineInstrs —
llvm/lib/CodeGen/ScheduleDAGInstrs.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ScheduleDAGInstrs::buildSchedGraph,ScheduleDAGInstrs::addPhysRegDeps,ScheduleDAGInstrs::addVRegDefDeps,ScheduleDAGInstrs::addChainDependencies.
Why and when: The production version of Algorithm 23.2.6: a bottom-up walk with def/use maps, memory chains with a barrier, and the-dag-maps-huge-regioncap. ReadbuildSchedGraphafter Lesson 23.2 §7 with a-debug-only=machine-schedulerdump next to it.
Chapters: Ch 23 -
[LLVM-SDISel] The SelectionDAG driver and the matcher-table interpreter —
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SelectionDAGISel::CodeGenAndEmitDAG,SelectionDAGISel::SelectCodeCommon,SelectionDAGISel::SelectAllBasicBlocks.
Why and when: The phase order of Lesson 21.5 (CodeGenAndEmitDAG), Algorithm 21.5.10 (SelectCodeCommon) and FastISel's fallback loop (SelectAllBasicBlocks, Lesson 21.6).
Chapters: Ch 21 -
[LLVM-SelectionDAG] SelectionDAG construction with CSE through the CSEMap folding set —
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SelectionDAG::getNode,CSEMap.
Why and when: The per-block DAG of instruction selection (Lesson 13.5 §7): every getNode looks the node up first, which is DAG construction with value numbering.
Chapters: Ch 13 -
[LLVM-SI] The standard instrumentations (optnone, opt-bisect, print-changed, ...) —
llvm/lib/Passes/StandardInstrumentations.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:OptNoneInstrumentation::shouldRun,OptPassGateInstrumentation::shouldRun,IRChangedPrinter.
Why and when: How optnone and -opt-bisect-limit skip optional passes and how -print-changed diffs IR. Read with Lessons 12.1 and 12.7.
Chapters: Ch 12 -
[LLVM-SimplifyCFG] SimplifyCFG, LLVM's CFG canonicalizer —
llvm/lib/Transforms/Utils/SimplifyCFG.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:foldBranchToCommonDest,simplifySwitchLookup.
Why and when:foldBranchToCommonDestturns jumping code into boolean values when speculation is safe (Lesson 11.2 §7; the lab's--O2runs);simplifySwitchLookupturns switches into lookup tables (Lesson 11.3 §6).
Chapters: Ch 11, Ch 17, Ch 24 -
[LLVM-SjLj] setjmp/longjmp exception handling preparation —
llvm/lib/CodeGen/SjLjEHPrepare.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SjLjEHPrepareImpl.
Why and when: Inserts the function context registration, the call-site index stores and the dispatch of Algorithm 11.7.4; compare its per-call cost with zero-cost tables (Lesson 11.7 §5).
Chapters: Ch 11 -
[LLVM-SKLSched] LLVM's Skylake client scheduling model —
llvm/lib/Target/X86/X86SchedSkylakeClient.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SkylakeClientModel,SKLWriteResPair,SKLFPDivider.
Why and when: A full out-of-order model: ports, port groups, the non-pipelined FP divider and per-class latencies. Lesson 23.1'svdivpdexample comes from here; grep a class name from anllvm-mcareport to find its definition.
Chapters: Ch 23 -
[LLVM-SL] Stack-slot liveness by round-robin iteration over bit vectors —
llvm/lib/Analysis/StackLifetime.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:StackLifetime::calculateLocalLiveness.
Why and when: Algorithm 14.4.1 in production, with a TODO to switch to a worklist (Lesson 14.4).
Chapters: Ch 14 -
[LLVM-SLP] The SLP vectorizer —
llvm/lib/Transforms/Vectorize/SLPVectorizer.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:BoUpSLP::buildTree,BoUpSLP::getTreeCost,SLPVectorizerPass::vectorizeStores.
Why and when: Algorithm 18.8.7 in production; the tree building and cost model behind the SLP box.
Chapters: Ch 18 -
[LLVM-SmallVector] SmallVector growth policy —
llvm/lib/Support/SmallVector.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:getNewCapacity,SmallVectorBase::grow_pod,SmallVectorBase::mallocForGrow.
Why and when: The 2 * OldCapacity + 1 rule of Definition 10.6.1; the template itself is in llvm/include/llvm/ADT/SmallVector.h.
Chapters: Ch 10 -
[LLVM-SPARSE] LLVM's generic sparse propagation solver (Kildall-style framework as a template) —
llvm/include/llvm/Analysis/SparsePropagation.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:AbstractLatticeFunction,SparseSolver,SparseSolver::Solve.
Why and when: The framework interface (lattice values, MergeValues, ComputeInstructionState) and the solver (Lessons 14.2 and 14.6); its client is CalledValuePropagation.cpp.
Chapters: Ch 14 -
[LLVM-SpillPlacement] LLVM's spill placement analysis (Hopfield network over edge bundles) —
llvm/lib/CodeGen/SpillPlacement.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SpillPlacement::iterate,SpillPlacement::update.
Why and when: The energy function in the file header is the objective quoted in Lesson 22.8 §4; used by region splitting to decide where a value lives in a register.
Chapters: Ch 22 -
[LLVM-SpillWeights] LLVM's spill weight computation —
llvm/lib/CodeGen/CalcSpillWeights.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:VirtRegAuxInfo::weightCalcHelper,VirtRegAuxInfo::isRematerializable,VirtRegAuxInfo::allUsesAvailableAt.
Why and when: Definition 22.9.1 and Algorithm 22.9.3 in code, including the remat halving, the hint boost and the loop-exit factor; normalizeSpillWeight is in CalcSpillWeights.h.
Chapters: Ch 22 -
[LLVM-SplitKit] LLVM's live-range splitting machinery —
llvm/lib/CodeGen/SplitKit.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SplitAnalysis,SplitEditor::finish.
Why and when: How greedy's split decisions become new intervals and lr-split copies (Proposition 22.8.7).
Chapters: Ch 22 -
[LLVM-SROA] Scalar replacement of aggregates (SROA), which ends by calling PromoteMemToReg —
llvm/lib/Transforms/Scalar/SROA.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SROA::runOnAlloca,SROA::promoteAllocas.
Why and when: Splits aggregate allocas (Pebble's structs and caller copies) into scalars before promotion; the reason-O1removes most of E5's memory traffic (Lesson 11.1 §6).
Chapters: Ch 11, Ch 16, Ch 19 -
[LLVM-SSAUpdater] LLVM's SSAUpdater (repair SSA after a value is duplicated) —
llvm/lib/Transforms/Utils/SSAUpdater.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SSAUpdater::AddAvailableValue,SSAUpdater::GetValueInMiddleOfBlock,SSAUpdater::RewriteUse.
Why and when: The on-demand, Braun-like SSA repair used by loop rotation, jump threading and LCSSA; the search itself is in llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h (SSAUpdaterImpl::GetValue, FindDominators, FindExistingPHI). Lesson 16.4 §2.
Chapters: Ch 16 -
[LLVM-SSAUpdaterBulk] SSAUpdaterBulk (many variables at once, via IDFCalculator) —
llvm/lib/Transforms/Utils/SSAUpdaterBulk.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SSAUpdaterBulk::RewriteAllUses,ComputeLiveInBlocks.
Why and when: The frontier-based alternative to SSAUpdater for many rewritten values: live-in blocks plus IDFCalculator, exactly Cytron-style pruned placement. Lesson 16.4 §6.
Chapters: Ch 16 -
[LLVM-StackMaps] The stack-map records the back end emits —
llvm/lib/CodeGen/StackMaps.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:StackMaps::recordStatepoint,StackMaps::parseOperand,StackMaps::emitCallsiteEntries.
Why and when: The location kinds (Register, Direct, Indirect, Constant, ConstantIndex) and record layout thatllvm-readobj --stackmapprints in Lesson 24.2's box. ReadparseOperandto see how a spilled value becomesIndirect.
Chapters: Ch 24 -
[LLVM-StatepointLowering] Lowering a statepoint to a call plus a stack-map record —
llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SelectionDAGBuilder::LowerStatepoint,lowerStatepointMetaArgs.
Why and when: How the deopt and GC operands of a statepoint become locations: after Lesson 24.2 §7, for the question "where does the Constant 0/0/2 header come from".
Chapters: Ch 24 -
[LLVM-STLExtras] make_early_inc_range and friends —
llvm/include/llvm/ADT/STLExtras.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:early_inc_iterator_impl,make_early_inc_range,enumerate,zip_equal.
Why and when: Theorem 10.1.14's early increment is operator* doing (I)++; the comment states the exact contract ("the current iterator can be invalidated", the next one must not be).
Chapters:* Ch 10 -
[LLVM-StressSrc] llvm-stress's random IR generator —
llvm/tools/llvm-stress/llvm-stress.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Modifier,FillFunction,IntroduceControlFlow.
Why and when: Algorithm 12.5.8 in about 800 lines; a good model for a random Pebble generator in Chapter 24.
Chapters: Ch 12 -
[LLVM-StringMatcher] TableGen's generated string matchers (switch on length, then on characters) —
llvm/lib/TableGen/StringMatcher.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:StringMatcher::Emit,StringMatcher::EmitStringMatcherForChar.
Why and when: The switch-on-length technique of Lesson 1.8 as a code generator; used for assembler mnemonics and register names in every LLVM backend.
Chapters: Ch 1 -
[LLVM-Summary] LLVM's ThinLTO module summary builder —
llvm/lib/Analysis/ModuleSummaryAnalysis.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:computeFunctionSummary,buildModuleSummaryIndex.
Why and when: What a function summary records (Definition 20.9.4): instruction count, calls with hotness, references, flags. Read after the Lesson 20.9 summary box.
Chapters: Ch 20 -
[LLVM-SwiftError] Keeping a
swifterrorvalue in a register across a function —llvm/lib/CodeGen/SwiftErrorValueTracking.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SwiftErrorValueTracking.
Why and when: How LLVM supports explicit error returns in a dedicated register (Lesson 11.7, Definition 11.7.5); read after the Swift box.
Chapters: Ch 11 -
[LLVM-SwitchLowering] LLVM's jump-table and bit-test clustering —
llvm/lib/CodeGen/SwitchLoweringUtils.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SwitchCG::SwitchLowering::findJumpTables,SwitchCG::SwitchLowering::findBitTestClusters,SwitchCG::SwitchLowering::buildJumpTable,SwitchCG::sortAndRangeify.
Why and when: The Kannan–Proebsting dynamic program with LLVM's score, and the bit-test clusters; the oracle of theswitch-loweringdrill reproduces it. Read with Lesson 11.3 §2 and §7.
Chapters: Ch 11 -
[LLVM-TailDup] LLVM's machine-level tail duplication —
llvm/lib/CodeGen/TailDuplicator.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TailDuplicator::tailDuplicateAndUpdate,TailDuplicator::shouldTailDuplicate.
Why and when: The tail duplication LLVM runs early and during block placement.shouldTailDuplicateis the size heuristic; read it after Algorithm 23.4.6.
Chapters: Ch 23 -
[LLVM-TargetLowering] The legalization actions a target declares —
llvm/include/llvm/CodeGen/TargetLowering.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TargetLoweringBase::LegalizeAction,TargetLoweringBase::LegalizeTypeAction,TargetLoweringBase::setOperationAction.
Why and when: The action enums of Definition 21.5.6 and the setters targets call in their constructors.
Chapters: Ch 21 -
[LLVM-TargetRegistry] The registry of back ends that makes LLVM retargetable —
llvm/include/llvm/MC/TargetRegistry.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TargetRegistry::lookupTarget,Target::createTargetMachine.
Why and when: Algorithm 0.4.4's registry: each back end registers itself; a triple selects it. Read withllvm/tools/llc/llc.cpp.
Chapters: Ch 0 -
[LLVM-TargetSched] How schedulers query the machine model (operand latency with ReadAdvance) —
llvm/lib/CodeGen/TargetSchedule.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TargetSchedModel::computeOperandLatency,TargetSchedModel::computeInstrLatency.
Why and when: The code behind Proposition 23.1.9: operand latency is the write's latency minus the read's advance. ReadcomputeOperandLatencywhen a-debug-only=machine-schedulerdump shows an unexpected edge latency.
Chapters: Ch 23 -
[LLVM-TargetSchedTD] The TableGen classes of LLVM's per-operand machine model —
llvm/include/llvm/Target/TargetSchedule.tdinllvm/llvm-projectatllvmorg-23.1.2. Symbols:SchedMachineModel,ProcResource,SchedWriteRes,WriteRes,ReadAdvance.
Why and when: The documentation-in-comments of the machine model of Definition 23.1.8: issue width, micro-op buffer, resources withReleaseAtCycles, per-operand latency and forwarding. Read the header comment first, then look up each class a.tdmodel uses.
Chapters: Ch 23 -
[LLVM-TBAA] Type-based alias analysis over TBAA metadata —
llvm/lib/Analysis/TypeBasedAliasAnalysis.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TypeBasedAAResult::alias,matchAccessTags.
Why and when: The file's header comment explains the scalar and struct-path formats; matchAccessTags is Algorithm 9.6.3 generalized to struct paths. Read after Lesson 9.6.
Chapters: Ch 9, Ch 19 -
[LLVM-TLB] The target's jump-table density and size thresholds —
llvm/lib/CodeGen/TargetLoweringBase.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TargetLoweringBase::isSuitableForJumpTable.
Why and when: The density test (at least 10%, 40% when optimizing for size) and minimum table size that decide Lesson 11.3's jump-table clusters;TargetLowering.hholdsisSuitableForBitTests.
Chapters: Ch 11 -
[LLVM-TPC] Where the scheduling and machine-optimization passes sit in LLVM's code generator pipeline —
llvm/lib/CodeGen/TargetPassConfig.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TargetPassConfig::addMachinePasses,TargetPassConfig::addOptimizedRegAlloc.
Why and when: The pass order of Lessons 23.7–23.10 in one function: MachineScheduler before allocation, post-RA scheduling after it, block placement and branch folding at the end.
Chapters: Ch 23 -
[LLVM-TRE] LLVM's tail-call marking and tail-recursion elimination —
llvm/lib/Transforms/Scalar/TailRecursionElimination.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:markTails,canTransformAccumulatorRecursion,TailRecursionEliminator::eliminateCall,TailRecursionEliminator::processBlock.
Why and when: markTails (Definition 20.8.2) and TRE with accumulators (Algorithm 20.8.4). Compare eliminateCall with your E4 after you pass the tests.
Chapters: Ch 20 -
[llvm-tutor] llvm-tutor — out-of-tree LLVM passes and tools with the new pass manager —
README.mdinbanach-space/llvm-tutoratmain.
Why and when: A collection of small, well-commented out-of-tree passes (OpcodeCounter, MBASub, RIV …) that use exactly this chapter's APIs (InstVisitor-style iteration, IRBuilder, PatternMatch-free rewrites) with a CMake setup like Lesson 10.8's. Browse after Lab 10.2; its README on the main branch states LLVM 23 as the supported version.
Chapters: Ch 10 -
[LLVM-Twine] Twine (lazy concatenation) —
llvm/include/llvm/ADT/Twine.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Twine,Twine::concat,Twine::str,Twine::toStringRef.
Why and when: Read the class comment ("A Twine is not intended for use directly and should not be stored") and concat, which decides between storing a leaf and a pointer (Theorem 10.6.18).
Chapters: Ch 10 -
[LLVM-UAJ] Unroll-and-jam —
llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cppinllvm/llvm-projectatllvmorg-23.1.2.
Why and when: Unrolling an outer loop and fusing the inner copies: a combination of Lessons 18.5 and 18.7.
Chapters: Ch 18 -
[LLVM-Unroll] The loop unrolling transformation —
llvm/lib/Transforms/Utils/LoopUnroll.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:llvm::UnrollLoop.
Why and when: The IR surgery of unrolling that E4 reimplements for full unrolling (Lesson 18.5).
Chapters: Ch 18 -
[LLVM-UnrollPass] Unrolling heuristics and thresholds —
llvm/lib/Transforms/Scalar/LoopUnrollPass.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:llvm::computeUnrollCount.
Why and when: Where full, partial and runtime unrolling are decided; the quiz asks for its default threshold.
Chapters: Ch 18 -
[LLVM-Unswitch] Trivial and non-trivial loop unswitching —
llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:unswitchTrivialBranch,unswitchNontrivialInvariants.
Why and when: Algorithm 18.5.10 with the cost budget of Lesson 18.5 §5.
Chapters: Ch 18 -
[LLVM-Use] The Use class and its intrusive use list —
llvm/include/llvm/IR/Use.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Use::addToList,Use::removeFromList,Use::Prev.
Why and when: Algorithm 10.2.3 verbatim; the Use ** Prev trick is worth reading slowly.
Chapters: Ch 10 -
[LLVM-User] Co-allocated and hung-off operand storage —
llvm/include/llvm/IR/User.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:User::operator new,IntrusiveOperandsAllocMarker,HungOffOperandsAllocMarker,User::getOperandList.
Why and when: Definition 10.2.5 in code; read with llvm/lib/IR/User.cpp (growHungoffUses).
Chapters: Ch 10 -
[LLVM-UTC] The IR check generator —
llvm/utils/update_test_checks.pyinllvm/llvm-projectatllvmorg-23.1.2. Symbols:main,UpdateTestChecks.common.generalize_check_lines,UpdateTestChecks.common.FunctionTestBuilder.
Why and when: Algorithm 12.4.8; the naming and generalization logic is in llvm/utils/UpdateTestChecks/common.py.
Chapters: Ch 12 -
[LLVM-Value] RAUW and value-handle notification —
llvm/lib/IR/Value.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Value::doRAUW,Value::replaceUsesWithIf,ValueHandleBase::ValueIsDeleted,ValueHandleBase::ValueIsRAUWd.
Why and when: Algorithm 10.2.6 (the loop taking the head of the use list) and Algorithm 10.2.8.
Chapters: Ch 10 -
[LLVM-ValueH] Value, its use list head, and Use::set —
llvm/include/llvm/IR/Value.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Value::addUse,Value::hasUseList,Value::uses,Value::users,Use::set.
Why and when: Where ConstantData is excluded from use lists (hasUseList) and where Use::set is defined; the answer to Lesson 10.2's "Find where LLVM does it" task.
Chapters: Ch 10 -
[LLVM-ValueTracking] Poison and UB reasoning used by all of LLVM's optimizers —
llvm/lib/Analysis/ValueTracking.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:canCreatePoison,propagatesPoison,isGuaranteedNotToBePoison,programUndefinedIfPoison,handleGuaranteedNonPoisonOps.
Why and when: Definition 9.7.3 (canCreatePoison), the rules of Definition 9.7.4 (propagatesPoison) and the operands that turn poison into UB (handleGuaranteedNonPoisonOps). Read after Lesson 9.7.
Chapters: Ch 9, Ch 11, Ch 17, Ch 18 -
[LLVM-Verifier] The IR verifier (rules W2–W7 of Definition 9.3.4) —
llvm/lib/IR/Verifier.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:Verifier::visitFunction,Verifier::visitBasicBlock,Verifier::visitPHINode,Verifier::visitInstruction,Verifier::verifyDominatesUse.
Why and when: Every message quoted in Lesson 9.3 and in the lab's F-tasks comes from here. After Lesson 9.3, find each W-rule's check; the file is long but each visit function is short.
Chapters: Ch 9 -
[LLVM-Versioning] Loop versioning with runtime memory checks —
llvm/lib/Transforms/Utils/LoopVersioning.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:LoopVersioning::versionLoop,LoopVersioning::annotateLoopWithNoAlias.
Why and when: Algorithm 18.5.12; the checks come from LoopAccessAnalysis (Lesson 18.6).
Chapters: Ch 18 -
[LLVM-VH] Value handle kinds —
llvm/include/llvm/IR/ValueHandle.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:WeakVH,WeakTrackingVH,AssertingVH,TrackingVH,CallbackVH,PoisoningVH.
Why and when: The table of Definition 10.2.7; note how AssertingVH compiles to a plain pointer without ABI-breaking checks.
Chapters: Ch 10 -
[LLVM-VirtRegMap] LLVM's virtual register map and rewriter —
llvm/lib/CodeGen/VirtRegMap.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:VirtRegRewriter::rewrite,VirtRegRewriter::handleIdentityCopy.
Why and when: Algorithm 22.8.8: replace virtual registers by physical ones and delete identity copies.
Chapters: Ch 22 -
[LLVM-VL] The value lattice shared by SCCP and LazyValueInfo —
llvm/include/llvm/Analysis/ValueLattice.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ValueLatticeElement,ValueLatticeElement::mergeIn,ValueLatticeElement::MergeOptions.
Why and when: unknown/undef/constant/notconstant/constantrange/overdefined, the join (mergeIn) and the simple widening by extension count (Lessons 14.1 and 14.7).
Chapters: Ch 14 -
[LLVM-WasmEHPrepare] Preparing funclet IR for WebAssembly's engine-driven unwinding —
llvm/lib/CodeGen/WasmEHPrepare.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:WasmEHPrepareImpl::prepareThrows,WasmEHPrepareImpl::prepareEHPads,WasmEHPrepareImpl::prepareEHPad.
Why and when: The header comment is the best short description of Wasm EH from the compiler's side (Definition 24.6.4's__wasm_lpad_context);prepareEHPadis Algorithm 24.6.5.
Chapters: Ch 24 -
[LLVM-WinEHPrepare] Funclet coloring, cloning and state numbering —
llvm/lib/CodeGen/WinEHPrepare.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:WinEHPrepareImpl::colorFunclets,WinEHPrepareImpl::cloneCommonBlocks,WinEHPrepareImpl::removeImplausibleInstructions,calculateStateNumbersForInvokes,WinEHPrepareImpl::demotePHIsOnFunclets.
Why and when: Algorithms 24.6.2 and 24.6.3 in production. ReadcolorFuncletsfirst (a worklist over blocks with the pad-exit rules), thencloneCommonBlocks.
Chapters: Ch 24 -
[LLVM-WPD] LLVM's whole-program devirtualization —
llvm/lib/Transforms/IPO/WholeProgramDevirt.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DevirtModule::run,DevirtModule::trySingleImplDevirt,DevirtModule::tryVirtualConstProp,DevirtModule::tryUniformRetValOpt.
Why and when: Single-implementation devirtualization, virtual constant propagation and branch funnels over type metadata. Read the file header and DevirtModule::run after Lesson 20.7 §2.
Chapters: Ch 20 -
[LLVM-X86AsmBackend] x86 relaxation and fixup application —
llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:X86AsmBackend::fixupNeedsRelaxationAdvanced,X86AsmBackend::relaxInstruction,X86AsmBackend::applyFixup.
Why and when: The rel8 test (isInt<8>) and JMP_1 to JMP_4 rewrite of Lesson 21.10's relaxation box.
Chapters: Ch 21 -
[LLVM-X86ELF] Choosing x86-64 ELF relocation types —
llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:X86ELFObjectWriter::getRelocType.
Why and when: Where a call becomesR_X86_64_PLT32and a string addressR_X86_64_PC32, as in Lesson 11.9'sllvm-objdumpbox.
Chapters: Ch 11 -
[LLVM-X86ISelDAG] x86 SelectionDAG selection hooks (address-mode matching) —
llvm/lib/Target/X86/X86ISelDAGToDAG.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:X86DAGToDAGISel::matchAddress,X86DAGToDAGISel::selectAddr.
Why and when: Handwritten address-mode folding that duplicates shared address arithmetic (Lesson 21.4 §7).
Chapters: Ch 21 -
[LLVM-X86ISelLowering] x86 legality declarations and custom lowering —
llvm/lib/Target/X86/X86ISelLowering.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:X86TargetLowering::X86TargetLowering.
Why and when: The setOperationAction calls behind Lesson 21.5's legalization tables and the legalization drill's oracle.
Chapters: Ch 21 -
[LLVM-X86MCEmitter] The x86 instruction encoder —
llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:X86MCCodeEmitter::encodeInstruction,X86MCCodeEmitter::emitMemModRMByte,X86MCCodeEmitter::emitREXPrefix.
Why and when: Algorithm 21.10.2 with all the special cases; read emitMemModRMByte with Proposition 21.10.3.
Chapters: Ch 21 -
[LLVM29-LinScan] LLVM 2.9's linear scan allocator (removed in LLVM 3.0) —
llvm/lib/CodeGen/RegAllocLinearScan.cppinllvm/llvm-projectatllvmorg-2.9.0. Symbols:RALinScan::linearScan.
Why and when: The historical LLVM default before greedy; read it after Lesson 22.5 to see linear scan with live intervals in production code.
Chapters: Ch 22 -
[LUA-Opcodes] Lua 5.4 opcode definitions —
lopcodes.hinlua/luaatv5.4.6. Symbols:OP_ADD,OP_MODK.
Why and when: The register instruction formats (R[A] := R[B] % K[C]) of Lesson 8.1'sluacbox;lcode.callocates the registers.
Chapters: Ch 8 -
[LUA-Src] Lua 5.4's register-based VM —
lvm.cinlua/luaatv5.4.6. Symbols:luaV_execute,vmdispatch.
Why and when:luaV_executeis a switch-dispatched register VM (lopcodes.hdocuments the iABC format);ljumptab.hprovides a computed-goto variant.
Chapters: Ch 0 -
[LUAJIT-Src] LuaJIT's trace recorder entry points and side exits —
src/lj_trace.cinLuaJIT/LuaJITatv2.1. Symbols:lj_trace_hot,lj_trace_ins,lj_trace_exit.
Why and when: Hot-loop detection, recording and side exits (Algorithm 0.3.5);src/lj_record.c(lj_record_ins) records each bytecode.
Chapters: Ch 0 -
[MENHIR-src] Menhir's Pager construction (GitHub mirror of the Inria repository); see also src/lr0.ml, src/LALR.ml, src/LR1Canonical.ml, src/LRijkstra.ml —
src/LR1Pager.mlinLexiFi/menhirat20231231. Symbols:Run.
Why and when: Menhir's LR constructions and error-site search, each with an explanatory header comment (Lessons 3.1, 3.3, 3.4, 3.7). Read the header of LR1Pager.ml and of LRijkstra.ml.
Chapters: Ch 3 -
[ML-ULEX] ml-ulex, the derivative-based lexer generator of SML/NJ —
tools/ml-lpt/ml-ulex/lex-gen.smlinsmlnj/smlnjatv2026.2-rc3. Symbols:LexGen.mkDFA.
Why and when: Algorithm 1.3.10 (regular vectors, derivative classes) by two of the authors of [ORT09].
Chapters: Ch 1 -
[MLIR-ArithToLLVM] A complete dialect conversion (arith to llvm) —
mlir/lib/Conversion/ArithToLLVM/ArithToLLVM.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ArithToLLVMConversionPass,populateArithToLLVMConversionPatterns,ConstantOpLowering.
Why and when: The smallest real conversion pass: a target, a type converter, patterns,applyPartialConversion.mlir/test/Conversion/ArithToLLVM/arith-to-llvm.mliris the worked example of Lesson 24.7 §3.
Chapters: Ch 24 -
[MLIR-DF] MLIR's dataflow solver (with DataFlow/SparseAnalysis.h, IntegerRangeAnalysis.h, LivenessAnalysis.h) —
mlir/include/mlir/Analysis/DataFlowFramework.hinllvm/llvm-projectatllvmorg-23.1.2. Symbols:DataFlowSolver,DataFlowAnalysis.
Why and when: One solver running dense and sparse analyses together; its sparse analyses are Algorithm 14.6.2 over MLIR values (Lessons 14.1, 14.2 and 14.6).
Chapters: Ch 14 -
[MLIR-DialectConv] MLIR's dialect conversion framework —
mlir/lib/Transforms/Utils/DialectConversion.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:applyPartialConversion,applyFullConversion,OperationLegalizer.
Why and when: The legalization driver behind Algorithm 8.7.3; its headermlir/include/mlir/Transforms/DialectConversion.hdocuments targets and patterns.
Chapters: Ch 8 -
[MLIR-DialectConversion] MLIR's dialect-conversion driver —
mlir/lib/Transforms/Utils/DialectConversion.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:mlir::applyPartialConversion,OperationLegalizer.
Why and when: The implementation of Algorithm 0.1.14;mlir/lib/Conversion/SCFToControlFlow/SCFToControlFlow.cpp(ForLowering) is the pattern that loweredscf.forin Lesson 0.1's box.
Chapters: Ch 0, Ch 24 -
[MLIR-Pass] MLIR's nested pass adaptor —
mlir/lib/Pass/Pass.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:OpToOpPassAdaptor::runOnOperation,OpToOpPassAdaptor::runPipeline.
Why and when: Algorithm 12.1.15: how nested pipelines are scheduled, in parallel when threading is enabled.
Chapters: Ch 12 -
[MLIR-Rewrite] MLIR's greedy worklist pattern-rewrite driver —
mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:applyPatternsGreedily,GreedyPatternRewriteDriver.
Why and when: The same worklist engine as Algorithm 13.2.4 for MLIR patterns (C++, PDL or PDLL). Optional, after Lesson 13.2 §6.
Chapters: Ch 13 -
[MLIR-SCF] Lowering structured control flow (scf) to blocks with arguments (cf) —
mlir/lib/Conversion/SCFToControlFlow/SCFToControlFlow.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:ForLowering,IfLowering.
Why and when: Howscf.for'siter_argsbecome block arguments of a loop header (Lessons 8.4 and 8.7).
Chapters: Ch 8 -
[MLIR-Translate] MLIR to LLVM IR translation (block arguments to phis) —
mlir/lib/Target/LLVMIR/ModuleTranslation.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:connectPHINodes.
Why and when:connectPHINodesturns block arguments into phi entries: Algorithm 8.4.6 (ArgsToPhi) in production, seen in Lesson 8.4's MLIR box.
Chapters: Ch 8 -
[MLRISC-RA] SML/NJ MLRISC's iterated register coalescing core —
MLRISC/ra/ra-core.smlinsmlnj/legacyatv110.99.9.
Why and when: IRC as written by George and Appel's colleagues, with Briggs and George counters (Lesson 22.4 §7).
Chapters: Ch 22 -
[MLTON-SSA] MLton's SSA IR (blocks with arguments) —
mlton/ssa/ssa-tree.siginMLton/mltonaton-20210117-release. Symbols:Block,Goto.
Why and when: A functional-language compiler whose SSA uses block arguments andGoto {dst, args}: the SSA side of Theorem 8.6.12 in a production ML compiler.
Chapters: Ch 8 -
[MLYACC-parser] ML-Yacc's parser driver with Burke–Fisher error correction —
ml-yacc/lib/parser2.smlinsmlnj/legacyatv110.99.9. Symbols:CHANGE,parse.
Why and when: The implementation behind Lesson 3.7's ML-Yacc box; the header describes the partial, deferred method of [BF87].
Chapters: Ch 3 -
[MYPY-Checker] mypy's narrowing by isinstance and is None —
mypy/checker.pyinpython/mypyatv1.19.1. Symbols:find_isinstance_check,conditional_types.
Why and when: Occurrence typing for Python:find_isinstance_checkmaps a condition to the (if, else) type maps of Definition 6.6.2. Read after the mypy box of Lesson 6.6.
Chapters: Ch 6 -
[MYPY-Subtypes] mypy's subtype check and the Any type —
mypy/subtypes.pyinpython/mypyatv1.19.1. Symbols:_is_subtype,SubtypeVisitor.visit_any.
Why and when: Gradual typing in mypy:_is_subtypereturns true when the right side isAny, andvisit_anywhen the left side is (unless a proper subtype is asked for) — consistency folded into subtyping, with no cast inserted. Read after Lesson 6.7's mypy box.
Chapters: Ch 6 -
[NOM] nom's ordered choice (
alt;many0is in src/multi/mod.rs) —src/branch/mod.rsinrust-bakery/nomat8.0.0. Symbols:alt,many0.
Why and when: Single-result backtracking combinators for Rust (Lesson 4.5 §2 and §7);altis Algorithm 4.5.3's choice.
Chapters: Ch 4 -
[OCAML-Closure] OCaml's closure conversion (non-flambda middle end) —
middle_end/closure/closure.mlinocaml/ocamlat4.14.1. Symbols:close_functions.
Why and when: Builds flat closures and their environments; the source of Lesson 11.8's Clambda box.
Chapters: Ch 11 -
[OCAML-Ctype] OCaml's unifier, levels and generalization —
typing/ctype.mlinocaml/ocamlat4.14.1. Symbols:generalize,begin_def,end_def,update_level,unify,occur.
Why and when: Algorithm J with levels in production (Lessons 7.1–7.3): in-place unification, the occurs check andgeneralize. Readgeneralizeandupdate_level.
Chapters: Ch 7 -
[OCAML-parser] OCaml's grammar for Menhir —
parsing/parser.mlyinocaml/ocamlat5.2.0. Symbols:implementation,expr.
Why and when: A production compiler whose parser is generated by Menhir (Lesson 3.8).
Chapters: Ch 3 -
[OCAML-Typecore] OCaml's expression type checker (expected types, expansiveness) —
typing/typecore.mlinocaml/ocamlat4.14.1. Symbols:type_expect,is_nonexpansive.
Why and when: Where OCaml propagates expected types (Algorithm M-style, Lesson 7.2 §7) and decides the value restriction (is_nonexpansive, Lesson 7.3 §7).
Chapters: Ch 7 -
[Open64-SSAPRE] Open64's SSAPRE (down-safety step; see also opt_eavail.cxx and opt_efinalize.cxx) —
osprey/be/opt/opt_eant.cxxinopen64-compiler/open64at590bdf3d58944cb93aafd89480a5590a863ded60. Symbols:EXP_WORKLST::Compute_du_info.
Why and when: The production SSAPRE of [CCK+97], by the same group: one file per step (opt_eant.cxx: anticipation / down-safety, opt_eavail.cxx: WillBeAvail, opt_efinalize.cxx: Finalize). The repository has no release tags; the pointer is pinned to a commit.
Chapters: Ch 17 -
[PARSEC-Prim] Parsec's core (consumed/empty replies,
try) —src/Text/Parsec/Prim.hsinhaskell/parsecatv3.1.16.1. Symbols:ParsecT,try,parserPlus.
Why and when: Definition 4.5.4 and Algorithm 4.5.5 in Haskell. ReadparserPlusandtryafter Lesson 4.5 §2.
Chapters: Ch 4 -
[PEGEN-Parser] pegen's runtime (memoization and left-recursion decorators) —
src/pegen/parser.pyinwe-like-parsers/pegenatv0.3.0. Symbols:memoize,memoize_left_rec.
Why and when: Algorithm 4.2.7 and Algorithm 4.2.8 as two Python decorators; the lesson's traces came from them. Read after Lesson 4.2 §3.
Chapters: Ch 4 -
[PG-gram] PostgreSQL's SQL grammar for Bison —
src/backend/parser/gram.yinpostgres/postgresatREL_17_0. Symbols:%expect 0,precedence declarations.
Why and when: A 19 513-line conflict-free LALR grammar with 23 precedence lines (Lessons 3.5 and 3.8's boxes). Read the precedence block and its comments.
Chapters: Ch 3 -
[PHP-parser] PHP's language grammar for Bison —
Zend/zend_language_parser.yinphp/php-srcatphp-8.3.0. Symbols:%expect 0,%define api.pure full.
Why and when: A general-purpose language parsed by a Bison LALR parser (Lesson 3.8). Look at the precedence declarations at the top.
Chapters: Ch 3 -
[PYPY-Src] PyPy's meta-interpreter (the meta-tracing JIT) —
rpython/jit/metainterp/pyjitpl.pyinpypy/pypyatrelease-pypy3.10-v7.3.17. Symbols:MetaInterp.
Why and when: Traces the RPython interpreter;rpython/rlib/jit.pydefinesJitDriverandjit_merge_point, the hints that mark the user program's loops (Lesson 0.3).
Chapters: Ch 0 -
[RA-Expr] rust-analyzer's expression parser (Pratt with binding-power pairs) —
src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rsinrust-lang/rustat1.94.1. Symbols:expr_bp,current_op.
Why and when:expr_bpis Algorithm 4.1.8 almost line for line, in a resilient parser. Read after Lesson 4.1 §2, then again after Lesson 4.6 for its recovery.
Chapters: Ch 4 -
[RA-LexedStr] rust-analyzer's conversion of rustc_lexer tokens (trivia included) —
crates/parser/src/lexed_str.rsinrust-lang/rust-analyzerat2026-09-21. Symbols:LexedStr::new.
Why and when: How rust-analyzer keeps whitespace and comments as WHITESPACE/COMMENT tokens for its lossless green trees (Lesson 1.10).
Chapters: Ch 1 -
[RA-ParserCore] rust-analyzer's parser core (recovery primitives) —
src/tools/rust-analyzer/crates/parser/src/parser.rsinrust-lang/rustat1.94.1. Symbols:Parser::err_recover,Parser::err_and_bump.
Why and when: The two recovery primitives of Algorithm 4.6.3; the recovery sets live next to the grammar functions (ITEM_RECOVERY_SET). Read after Lesson 4.6 §2.
Chapters: Ch 4 -
[RA-Reparse] rust-analyzer's incremental reparsing —
src/tools/rust-analyzer/crates/syntax/src/parsing/reparsing.rsinrust-lang/rustat1.94.1. Symbols:incremental_reparse,reparse_token,reparse_block,is_balanced.
Why and when: Algorithm 4.6.7 in 200 lines. Read it before the lab's ★ milestone L6.
Chapters: Ch 4 -
[RA2-Design] regalloc2's design notes (Cranelift's register allocator) —
doc/GENERAL.mdinbytecodealliance/regalloc2atv0.15.2.
Why and when: SSA input with block parameters, bundles, eviction and splitting; the README at the same tag describes regalloc2 as a port of IonMonkey's backtracking allocator (Lessons 22.6 and 22.8).
Chapters: Ch 22 -
[RE2-DFA] RE2's lazy DFA —
re2/dfa.ccingoogle/re2at2024-07-02. Symbols:DFA::RunStateOnByte,DFA::RunWorkqOnByte,DFA::ResetCache.
Why and when: Core reading. The production lazy DFA of Lesson 1.2 (Algorithm 1.2.6): state cache, memory budget, cache reset and fallback. Read the comments at the top of the file first.
Chapters: Ch 1 -
[RE2C-Min] re2c's DFA minimization (Moore, table filling) —
src/dfa/minimization.ccinskvadrik/re2cat3.1. Symbols:minimization_moore,minimization_table.
Why and when: Moore's algorithm in a lexer generator, with rule- and tag-aware initial partitions (Lesson 1.4).
Chapters: Ch 1 -
[REGEX-AUTOMATA-Min] Hopcroft's algorithm in Rust's regex-automata —
regex-automata/src/dfa/minimize.rsinrust-lang/regexatregex-automata-0.4.9. Symbols:Minimizer::run.
Why and when: A readable production Hopcroft implementation with the worklist and state-set partitions of Algorithm 1.4.5.
Chapters: Ch 1 -
[ROSLYN-DA] Roslyn's definite-assignment pass for C# —
src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.csindotnet/roslynatVisual-Studio-2022-Version-17.8. Symbols:DefiniteAssignmentPass.
Why and when: C#'s definite assignment on bound trees, with the state as a bit vector per variable slot. Read after Lesson 5.7 §7 next to [JAVAC-Flow].
Chapters: Ch 5 -
[ROSLYN-Green] Roslyn's green nodes (red nodes in SyntaxNode.cs) —
src/Compilers/Core/Portable/Syntax/GreenNode.csindotnet/roslynatVisual-Studio-2022-Version-17.14.34. Symbols:GreenNode,GreenNode.FullWidth,SyntaxNode.Position.
Why and when: The origin of red–green trees: green nodes know only widths;SyntaxNode(red) adds position and parent (Definition 4.7.7). Read after Lesson 4.7 §2.
Chapters: Ch 4 -
[ROSLYN-Lexer] The C# compiler's lexer with leading and trailing trivia —
src/Compilers/CSharp/Portable/Parser/Lexer.csindotnet/roslynatVisual-Studio-2022-Version-17.12. Symbols:Lexer.LexSyntaxLeadingTrivia,Lexer.LexSyntaxTrailingTrivia,Lexer.LexSyntaxTrivia.
Why and when: Definition 1.10.2 in production: how Roslyn decides which trivia is trailing (same line) and which is leading.
Chapters: Ch 1 -
[ROWAN] rowan's green-node cache (hash-consing of small nodes); nodes in src/green/node.rs, red cursors in src/cursor.rs —
src/green/node_cache.rsinrust-analyzer/rowanatv0.15.18. Symbols:NodeCache::node,NodeCache::token.
Why and when: Where the "at most three children" rule of Algorithm 4.7.8 lives, observed in Lesson 4.7's rowan box. Read withsrc/green/node.rsafter Lesson 4.7 §2.
Chapters: Ch 4 -
[RUBY-news33] Ruby 3.3 release notes (Bison replaced by Lrama) —
NEWS.mdinruby/rubyatv3_3_0. Symbols:Replace Bison with Lrama LALR parser generator.
Why and when: Why a language project wrote its own LALR generator (Lesson 3.8 §6).
Chapters: Ch 3 -
[RUBY-news34] Ruby 3.4 release notes (Prism becomes the default parser) —
NEWS.mdinruby/rubyatv3_4_0. Symbols:The default parser is now Prism.
Why and when: A language moving from a generated LALR parser to a hand-written one in 2024 (Lesson 3.8); prism/prism.c is the parser.
Chapters: Ch 3 -
[Rust-Borrowck] rustc's borrow checker entry point —
compiler/rustc_borrowck/src/lib.rsinrust-lang/rustat1.94.1. Symbols:do_mir_borrowck,MirBorrowckCtxt.
Why and when: Where the borrow checker runs on MIR: the dataflow analyses it sets up (borrows, moves, initialization) and the error reporting. Readdo_mir_borrowckafter Algorithm 24.5.8;elaborate_drops.rsnext door is Algorithm 24.5.8'sElaborateDrops.
Chapters: Ch 24 -
[Rust-Debuginfo] rustc's MIR locals to debug variables —
compiler/rustc_codegen_ssa/src/mir/debuginfo.rsinrust-lang/rustat1.94.1. Symbols:debug_introduce_local,compute_per_local_var_debug_info.
Why and when: How a front end with its own IR decides which MIR locals becomeDILocalVariables and where their#dbg_declare/#dbg_valuego; compare with E3's naming rule.
Chapters: Ch 24 -
[RUST-Rt] Rust's runtime entry point —
library/std/src/rt.rsinrust-lang/rustat1.94.1. Symbols:lang_start,lang_start_internal.
Why and when: The runtime side of a generatedmain: initialize, runmain, catch a panic and return 101. Compare with Pebble'spebble_main.c(Lesson 11.9).
Chapters: Ch 11 -
[RUSTC-AsPlace] rustc's place lowering (with
as_operand.rsnext to it) —compiler/rustc_mir_build/src/builder/expr/as_place.rsinrust-lang/rustat1.94.1. Symbols:as_place.
Why and when: The place/operand split of Definition 11.4.1 in a production MIR builder; read with Lesson 11.4 §7.
Chapters: Ch 11 -
[RUSTC-Assert] rustc's lowering of MIR
Assertto a panic call —compiler/rustc_codegen_ssa/src/mir/block.rsinrust-lang/rustat1.94.1. Symbols:codegen_assert_terminator.
Why and when: The unwind policy of Lesson 11.6: a failed check calls a panic function whose call has an unwind edge.
Chapters: Ch 11 -
[RUSTC-AST] rustc's AST (struct plus kind enum) —
compiler/rustc_ast/src/ast.rsinrust-lang/rustat1.94.1. Symbols:Expr,ExprKind,BinOpKind.
Why and when: A sum-type AST at production scale (Lesson 4.7 §2): compareExprKindwith Clang'sStmtNodes.td.
Chapters: Ch 4 -
[RUSTC-Borrowck] rustc's report of uses of possibly-uninitialized variables (E0381) —
compiler/rustc_borrowck/src/diagnostics/conflict_errors.rsinrust-lang/rustat1.94.1. Symbols:MirBorrowckCtxt::report_use_of_moved_or_uninitialized.
Why and when: Definite assignment done on MIR by the borrow checker's maybe-uninitialized dataflow, reported as E0381. Read after Lesson 5.7 §7.
Chapters: Ch 5, Ch 6 -
[RUSTC-BRG] rustc's collection pass (the module tree before resolution) —
compiler/rustc_resolve/src/build_reduced_graph.rsinrust-lang/rustat1.94.1. Symbols:build_reduced_graph,BuildReducedGraphVisitor.
Why and when: The collect pass of Algorithm 5.3.2: every item enters its module before any body is resolved, which makes items order-independent. Read after Lesson 5.3 §2.
Chapters: Ch 5 -
[RUSTC-Closure] rustc's closure checking with an expected signature —
compiler/rustc_hir_typeck/src/closure.rsinrust-lang/rustat1.94.1. Symbols:check_expr_closure,deduce_closure_signature.
Why and when: Whyapply(|x| x + 1)needs no annotation:deduce_closure_signaturereads the parameter types from the expected type. Read after the rustc box of Lesson 6.4.
Chapters: Ch 6 -
[RUSTC-Coercion] rustc's coercions (the only implicit conversions in Rust) —
compiler/rustc_hir_typeck/src/coercion.rsinrust-lang/rustat1.94.1. Symbols:Coerce,Coerce::coerce_unsized.
Why and when: Rust has no numeric promotion but does coerce references (auto-deref, unsizing,&mutto&) at "coercion sites", which are exactly the checking positions of Lesson 6.4. Read after Lesson 6.3 §7.
Chapters: Ch 6 -
[RUSTC-Coherence] rustc's overlap and orphan checks —
compiler/rustc_trait_selection/src/traits/coherence.rsinrust-lang/rustat1.94.1. Symbols:overlapping_trait_impls.
Why and when: Algorithm 7.7.5 in rustc; the impl-side orphan check is incompiler/rustc_hir_analysis/src/coherence/orphan.rs(orphan_check_impl).
Chapters: Ch 7 -
[RUSTC-DepGraph] rustc's dependency graph and red-green marking —
compiler/rustc_query_system/src/dep_graph/graph.rsinrust-lang/rustat1.94.1. Symbols:DepGraph,DepGraph::try_mark_green.
Why and when:try_mark_greenis Algorithm 0.1.12'sTryMarkGreen; read it after the query worked example in Lesson 0.1.
Chapters: Ch 0, Ch 5 -
[RUSTC-DF] rustc's MIR dataflow framework (lattices in framework/lattice.rs, analyses in impls/) —
compiler/rustc_mir_dataflow/src/framework/mod.rsinrust-lang/rustat1.90.0. Symbols:Analysis,Analysis::iterate_to_fixpoint.
Why and when: A trait-based monotone framework with an RPO-seeded work queue; MaybeLiveLocals and MaybeUninitializedPlaces feed the borrow checker (Lessons 14.1–14.4).
Chapters: Ch 14 -
[Rustc-Dom] rustc's Semi-NCA dominators —
compiler/rustc_data_structures/src/graph/dominators/mod.rsinrust-lang/rustat1.90.0. Symbols:dominators.
Why and when: A compact Semi-NCA following Georgiadis's thesis, with comments that restate Lemma 15.1.18; read after Lesson 15.1 §7.
Chapters: Ch 15 -
[RUSTC-EditDistance] rustc's edit distance and "a similar name exists" suggestions —
compiler/rustc_span/src/edit_distance.rsinrust-lang/rustat1.94.1. Symbols:edit_distance,find_best_match_for_name.
Why and when: OSA distance with a length-based cutoff and case-insensitive tie-breaking: compare with Clang's rule after Lesson 5.8 §2.
Chapters: Ch 5 -
[RUSTC-Fallback] rustc's fallback of unresolved literal variables —
compiler/rustc_hir_typeck/src/fallback.rsinrust-lang/rustat1.94.1. Symbols:type_inference_fallback,fallback_if_possible.
Why and when: "Unconstrained ints are replaced withi32": Algorithm 7.6.3's defaulting step.
Chapters: Ch 7 -
[RUSTC-HIR] rustc's AST-to-HIR lowering of while loops —
compiler/rustc_ast_lowering/src/expr.rsinrust-lang/rustat1.94.1. Symbols:lower_expr_while_in_loop_scope.
Why and when: Algorithm 8.3.3 in production:whilebecomesloop { if c {…} else { break } }withLoopSource::While(Lesson 8.3).
Chapters: Ch 8 -
[RUSTC-HirId] rustc's HIR node ids (owner + local index) —
compiler/rustc_hir_id/src/lib.rsinrust-lang/rustat1.94.1. Symbols:HirId,OwnerId,ItemLocalId.
Why and when: The doc comment onHirIdexplains why ids are two-level: stability under edits for incremental compilation (Lesson 4.7's arena box).
Chapters: Ch 4 -
[RUSTC-Hygiene] rustc's hygiene (syntax contexts and expansion marks) —
compiler/rustc_span/src/hygiene.rsinrust-lang/rustat1.94.1. Symbols:SyntaxContext,ExpnData,Transparency.
Why and when: Marks and contexts of Definition 4.8.5, with the three transparencies. Read after the rustc hygiene box of Lesson 4.8.
Chapters: Ch 4, Ch 5 -
[RUSTC-Imports] rustc's import resolution fixed point —
compiler/rustc_resolve/src/imports.rsinrust-lang/rustat1.94.1. Symbols:ImportResolver::resolve_imports,ImportResolver::finalize_imports.
Why and when: Algorithm 5.3.4: rounds of import resolution while the number of undetermined imports decreases, then error reporting for the rest. Read after Lesson 5.3 §3.
Chapters: Ch 5 -
[RUSTC-Infer] rustc's inference context and its union-find tables —
compiler/rustc_infer/src/infer/mod.rsinrust-lang/rustat1.94.1. Symbols:InferCtxt,next_ty_var,next_int_var,next_float_var.
Why and when: Type, integer and float inference variables in separate unification tables (Lessons 7.1 and 7.6).
Chapters: Ch 7 -
[RUSTC-Late] rustc's late resolution of local names (ribs) —
compiler/rustc_resolve/src/late.rsinrust-lang/rustat1.94.1. Symbols:Rib,RibKind,LateResolutionVisitor,LateResolutionVisitor::resolve_ident_in_lexical_scope.
Why and when: A stack of ribs, each a map from identifiers to resolutions, searched from the innermost: Algorithm 5.2.2 in production. Read after Lesson 5.2 §7.
Chapters: Ch 5 -
[RUSTC-Lexer] rustc's standalone lexer crate —
compiler/rustc_lexer/src/lib.rsinrust-lang/rustat1.94.1. Symbols:tokenize,Cursor::advance_token,is_id_start,is_id_continue,Cursor::raw_double_quoted_string.
Why and when: Core reading. A hand-written lexer that returns trivia as tokens (Lesson 1.10), handles raw strings with hashes (Lesson 1.7) and nested block comments, and uses Unicode XID tables (Lesson 1.9). Short enough to read in one sitting after Lesson 1.5.
Chapters: Ch 1 -
[RUSTC-LogicalOp] rustc's MIR building for
&&and||—compiler/rustc_mir_build/src/builder/expr/into.rsinrust-lang/rustat1.94.1. Symbols:LogicalOp.
Why and when: Short-circuit operators become control flow in MIR, as in Algorithm 11.2.2; read with the rustc box of Lesson 11.2.
Chapters: Ch 11 -
[RUSTC-Lower] rustc's AST → HIR lowering of expressions —
compiler/rustc_ast_lowering/src/expr.rsinrust-lang/rustat1.94.1. Symbols:LoweringContext::lower_expr_for.
Why and when:lower_expr_foris Algorithm 4.7.10's Rust template, documented in its comment. Read after Lesson 4.7's HIR box.
Chapters: Ch 4 -
[RUSTC-Lowering] rustc's AST-to-HIR lowering of for loops and ? —
compiler/rustc_ast_lowering/src/expr.rsinrust-lang/rustat1.94.1. Symbols:LoweringContext::lower_expr_for,LoweringContext::lower_expr_try.
Why and when: Desugaring (Definition 5.6.5, Algorithm 5.6.6):forbecomesloop+matchonIterator::nextbefore type checking. Read after Lesson 5.6 §5.
Chapters: Ch 5 -
[RUSTC-MBE] rustc's macros by example (matching in macro_parser.rs/macro_rules.rs, transcription here) —
compiler/rustc_expand/src/mbe/transcribe.rsinrust-lang/rustat1.94.1. Symbols:transcribe_pnr,macro_rules.rs expand_macro,macro_rules.rs try_match_macro,macro_parser.rs.
Why and when: Algorithm 4.8.4 in production: the NFA matcher and the invisible-delimiter transcription of Theorem 4.8.9. Read after Lesson 4.8 §2.
Chapters: Ch 4, Ch 5 -
[RUSTC-MIR] rustc's MIR construction —
compiler/rustc_mir_build/src/builder/mod.rsinrust-lang/rustat1.94.1. Symbols:build_mir_inner_impl,construct_fn.
Why and when: Where MIR bodies are built; the data structures (Body,BasicBlockData,TerminatorKind) are incompiler/rustc_middle/src/mir/. Read with Lesson 8.7's MIR box.
Chapters: Ch 8 -
[RUSTC-Mono] rustc's monomorphization collector —
compiler/rustc_monomorphize/src/collector.rsinrust-lang/rustat1.94.1. Symbols:collect_crate_mono_items,MonoItem.
Why and when: The worklist of Algorithm 6.9.2: starting from roots, every instantiated generic function reachable from them becomes aMonoItem. Read after Lesson 6.9 §3.
Chapters: Ch 6, Ch 7 -
[RUSTC-NonSSA] rustc's choice of which MIR locals get allocas —
compiler/rustc_codegen_ssa/src/mir/analyze.rsinrust-lang/rustat1.94.1. Symbols:non_ssa_locals.
Why and when: The hybrid of Lesson 11.1 §6: SSA values for locals assigned once and never borrowed, allocas for the rest.
Chapters: Ch 11 -
[RUSTC-ParseExpr] rustc's expression parser —
compiler/rustc_parse/src/parser/expr.rsinrust-lang/rustat1.94.1. Symbols:Parser::parse_expr_assoc_with.
Why and when: Precedence climbing withAssocOpfixity, non-associative comparisons (the error Pebble's E0206 mirrors) and ranges. Read after Lesson 4.1 §7.
Chapters: Ch 4 -
[RUSTC-Parser] rustc's parser diagnostics and recovery (with stmt.rs and mod.rs next to it) —
compiler/rustc_parse/src/parser/diagnostics.rsinrust-lang/rustat1.90.0. Symbols:Parser::recover_stmt,Parser::create_snapshot_for_diagnostic,Parser::restore_snapshot,Parser::expected_one_of_not_found.
Why and when: Snapshots for speculative recovery, panic mode to the end of a statement, and "expected one of …" messages;mod.rshasParser::look_ahead(k-token peeks, Lesson 2.6) andstmt.rshasparse_stmt_without_recovery(Lesson 2.5).
Chapters: Ch 2 -
[RUSTC-Select] rustc's trait selection —
compiler/rustc_trait_selection/src/traits/select/mod.rsinrust-lang/rustat1.94.1. Symbols:SelectionContext::select.
Why and when: Instance resolution for traits (Lesson 7.7 §7): candidate assembly, confirmation and evaluation of obligations.
Chapters: Ch 7 -
[RUSTC-Symbol] rustc's pre-interned keywords and symbols —
compiler/rustc_span/src/symbol.rsinrust-lang/rustat1.94.1. Symbols:symbols!,Symbol::intern.
Why and when: Keywords as the first interned symbols (kw::As, kw::Break, …): Lesson 1.8's interning technique in Rust's compiler.
Chapters: Ch 1 -
[RUSTC-THIR] rustc's THIR (typed high-level tree IR) —
compiler/rustc_middle/src/thir.rsinrust-lang/rustat1.94.1. Symbols:Thir,ExprKind.
Why and when: The typed tree from which MIR is built (Lessons 8.3 and 8.7).
Chapters: Ch 8 -
[RUSTC-Try] rustc's desugaring of the
?operator —compiler/rustc_ast_lowering/src/expr.rsinrust-lang/rustat1.94.1. Symbols:lower_expr_try.
Why and when: Error returns as ordinary control flow (Lesson 11.6, Definition 11.7.5):?becomes a match on theTrytrait's result and an early return.
Chapters: Ch 11 -
[RUSTC-Typeck] rustc's expected types (the checking mode of its bidirectional checker) —
compiler/rustc_hir_typeck/src/expectation.rsinrust-lang/rustat1.94.1. Symbols:Expectation,Expectation::only_has_type.
Why and when: Core reading.Expectation::ExpectHasTypeis the ⇐ of Lesson 6.4;check_expr_with_expectationinexpr.rsnext to it is the single entry point that switches modes. Read after Lesson 6.4 §7 and connect the "expected due to this" notes of the box to it.
Chapters: Ch 6, Ch 7 -
[RUSTC-TypeckErrors] rustc's type-checking diagnostics (break/continue outside a loop, E0268) —
compiler/rustc_hir_typeck/src/errors.rsinrust-lang/rustat1.94.1. Symbols:BreakNonLoop,OutsideLoop.
Why and when: The diagnostic structs behind E0268, the rustc analogue of Pebble's E0304. Read after Lesson 5.7 §7.
Chapters: Ch 5 -
[RUSTC-TypeckResults] rustc's per-body side tables of type-checking results —
compiler/rustc_middle/src/ty/typeck_results.rsinrust-lang/rustat1.94.1. Symbols:TypeckResults,TypeckResults::node_type,TypeckResults::type_dependent_defs.
Why and when: Side tables keyed byHirIdinstead of AST fields (Lesson 5.6 §3). Read after Lesson 5.6 and compare with [GO-Info].
Chapters: Ch 5 -
[RUSTC-TypeIR] rustc's de Bruijn indices for bound regions and types —
compiler/rustc_type_ir/src/lib.rsinrust-lang/rustat1.94.1. Symbols:DebruijnIndex,DebruijnIndex::shifted_in.
Why and when: De Bruijn indices outside the lambda calculus: late-bound regions underfor<'a>binders useDebruijnIndexwithshifted_in/shifted_out(Lemma 5.2.13). Read after Lesson 5.2 §7.
Chapters: Ch 5 -
[RUSTC-Variance] rustc's variance inference for type and lifetime parameters —
compiler/rustc_hir_analysis/src/variance/mod.rsinrust-lang/rustat1.94.1. Symbols:variances_of,crate_variances.
Why and when: Rust infers declaration-site variance from how a parameter is used in the type's fields (a fixed point over the crate), instead of asking for annotations as Kotlin and Scala do. Read after Lesson 6.5's variance section.
Chapters: Ch 6 -
[RUSTC-X86ABI] rustc's System V x86-64 classification —
compiler/rustc_target/src/callconv/x86_64.rsinrust-lang/rustat1.94.1. Symbols:classify,classify_arg.
Why and when: The same psABI classes with a different but equivalent coercion (i64for a loneint); read with Lesson 11.5's rustc box.
Chapters: Ch 11 -
[SG-Crate] The scopegraphs Rust crate (scope graphs as a library) —
scopegraphs/src/lib.rsinmetaborg/rust-scopegraphsatv0.3.3. Symbols:ScopeGraph,query.
Why and when: Scope graphs with regular path queries and label orders as a Rust library, from the Statix group. Read its documentation after the ★ part of the lab.
Chapters: Ch 5 -
[SIL-Docs] Swift Intermediate Language (SIL) reference —
docs/SIL.rstinswiftlang/swiftatswift-6.1-RELEASE. Symbols:Basic Blocks,Mandatory optimization passes (critical edge splitting).
Why and when: Core reading. SIL's definition: block arguments as the alternative to phi nodes (quoted in Lesson 8.7) and mandatory critical-edge splitting for non-cond_branch terminators (Lesson 8.2).
Chapters: Ch 8, Ch 16 -
[SIMDJSON-Src] simdjson's stage-1 scanner (bulk character classification) —
src/generic/stage1/json_scanner.hinsimdjson/simdjsonatv3.10.1. Symbols:json_scanner::next,json_character_block::classify.
Why and when: The block-at-a-time classification of Lesson 1.5 in the library that made it famous; read with [LL19].
Chapters: Ch 1 -
[SMLNJ-CPS] SML/NJ's CPS intermediate language —
compiler/CPS/cps/cps.siginsmlnj/smlnjatv2025.1. Symbols:cexp,APP,FIX.
Why and when: The CPS datatype of [App92] as it exists today:APPcalls,FIXbinds mutually recursive local functions (Lesson 8.6).
Chapters: Ch 8 -
[Soot] Soot's call-graph builders (CHATransformer; Spark with rta/vta/on-fly-cg) —
src/main/java/soot/jimple/spark/SparkTransformer.javainsoot-oss/sootat4.6.0. Symbols:SparkTransformer.internalTransform.
Why and when: The Java framework whose CHA, RTA and VTA the Lesson 20.1 boxes run; CHATransformer is in soot/jimple/toolkits/callgraph/. Read the option handling in SparkTransformer to see how rta and vta change Spark.
Chapters: Ch 20 -
[SOUPER-src] A Souper synthesis test (division by 515 as multiply and shift) —
test/Infer/div_const.optingoogle/souperat963d4df436f3dc0b039cc0e47ada0577a26f5c4e. Symbols:infer,result.
Why and when: The concrete result derived by CEGIS in Lesson 13.3 §3 and verified by Alive2 in §7; browse test/Infer for more synthesized optimizations.
Chapters: Ch 13 -
[SQLITE-parse] SQLite's grammar for the Lemon LALR(1) generator (tool/lemon.c) —
src/parse.yinsqlite/sqliteatversion-3.46.0. Symbols:cmd,expr.
Why and when: An LR grammar in a very widely deployed system, with Lemon's own syntax for precedence and destructors (Lesson 3.8).
Chapters: Ch 3 -
[STOKE-src] STOKE's documentation of its search and cost function —
README.mdinStanfordPL/stokeat98d8a0f028f2daf2052bfe607dbc32ec8d55ba9e. Symbols:src/search,src/cost.
Why and when: The cost-function and proposal-mass options quoted in Lesson 13.3 §7; read the "Cost Function" section after Algorithm 13.3.5.
Chapters: Ch 13 -
[SVF-DDA] SVF's demand-driven, context-sensitive points-to queries with budgets —
svf/lib/DDA/ContextDDA.cppinSVF-tools/SVFatSVF-3.3. Symbols:ContextDDA::computeDDAPts,ContextDDA::handleOutOfBudgetDpm.
Why and when: Lesson 19.8's demand-driven analysis with refinement budgets.
Chapters: Ch 19 -
[SVF-FS] SVF's staged, sparse flow-sensitive points-to analysis —
svf/lib/WPA/FlowSensitive.cppinSVF-tools/SVFatSVF-3.3. Symbols:FlowSensitive::initialize,FlowSensitive::processSVFGNode.
Why and when: Lesson 19.6's SFS: an auxiliary Andersen builds the SVFG (sparse value-flow graph), and the flow-sensitive solver runs on it.
Chapters: Ch 19 -
[SVF-Wave] SVF's wave-propagation Andersen with difference propagation —
svf/lib/WPA/AndersenWaveDiff.cppinSVF-tools/SVFatSVF-3.3. Symbols:AndersenWaveDiff::solveWorklist,AndersenWaveDiff::postProcessNode.
Why and when: Lesson 19.4's wave propagation in a maintained research framework.
Chapters: Ch 19 -
[Swift-ARCSeqOpts] Swift's ARC pair elimination —
lib/SILOptimizer/ARC/ARCSequenceOpts.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:ARCSequenceOpts,processFunctionWithoutLoopSupport,processFunctionWithLoopSupport.
Why and when: The dataflow that pairs a retain with a matching release and deletes both, run twice; the variant of Lesson 24.5 §6. Noswiftcin the course container: read the source.
Chapters: Ch 24 -
[SWIFT-CFGOpt] SIL critical-edge splitting —
lib/SILOptimizer/Utils/CFGOptUtils.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:swift::splitCriticalEdge,swift::splitCriticalEdgesFrom.
Why and when: Swift's implementation of Definition 8.2.5 for SIL (Lesson 8.2).
Chapters: Ch 8 -
[SWIFT-CondFail] Swift's
cond_faillowered to a trap —lib/IRGen/IRGenSIL.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:IRGenSILFunction::visitCondFailInst.
Why and when: The trap policy of Lesson 11.6 in a production language: a failed check branches to a cold block that traps.
Chapters: Ch 11 -
[SWIFT-CSOptimizer] Swift's disjunction favoring —
lib/Sema/CSOptimizer.cppinswiftlang/swiftatswift-6.3.3-RELEASE. Symbols:determineBestChoicesInContext.
Why and when: The heuristics that order overload alternatives before the search (Lesson 7.5 §6).
Chapters: Ch 7 -
[SWIFT-CSRanking] Swift's ranking of constraint-system solutions —
lib/Sema/CSRanking.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:ConstraintSystem::compareSolutions,isDeclAsSpecializedAs.
Why and when: Overloading resolved by comparing whole solutions by score, then declarations by "more specialized": a different architecture from Algorithm 5.4.3 (Lesson 5.4 §6).
Chapters: Ch 5 -
[SWIFT-CSSolver] Swift's solver entry points and complexity limits —
lib/Sema/CSSolver.cppinswiftlang/swiftatswift-6.3.3-RELEASE. Symbols:ConstraintSystem::solve,ConstraintSystem::solveImpl.
Why and when: Where solving starts and where "too complex" is decided (isTooComplex). Read after Lesson 7.5 §5.
Chapters: Ch 7 -
[SWIFT-CSStep] Swift's solver steps (component splitting, disjunction search) —
lib/Sema/CSStep.cppinswiftlang/swiftatswift-6.3.3-RELEASE. Symbols:SplitterStep::take,ComponentStep::take,DisjunctionStep::attempt.
Why and when: The search of Algorithm 7.5.4 as a stack of steps. ReadSplitterStep::takefor the components andDisjunctionStepfor the backtracking over overloads.
Chapters: Ch 7 -
[SWIFT-DIsrc] Swift's definite-initialization pass on SIL —
lib/SILOptimizer/Mandatory/DefiniteInitialization.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:LifetimeChecker,LifetimeChecker::doIt.
Why and when: Definite initialization done on an IR instead of the AST, including the stored properties ofselfin initializers. Read after Lesson 5.7 §7.
Chapters: Ch 5 -
[SWIFT-Evaluator] Swift's request evaluator (memoization and cycle detection) —
lib/AST/Evaluator.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:Evaluator,Evaluator::checkDependency,Evaluator::diagnoseCycle.
Why and when: Queries (Lesson 5.6 §4) with cycle diagnostics: a request that depends on itself is reported rather than overflowing the stack. Read with [SWIFT-RequestEvaluator].
Chapters: Ch 5 -
[SWIFT-Exclusivity] Swift's static enforcement of exclusive access (on SIL) —
lib/SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:checkStaticExclusivity,diagnoseExclusivityViolation.
Why and when: A dataflow overbegin_access/end_accessmarkers that reports overlapping accesses at compile time;AccessEnforcementSelection.cppnext to it decides which accesses need dynamic checks. Read after Lesson 6.8's exclusivity section.
Chapters: Ch 6 -
[SWIFT-Fold] Swift's operator folding after parsing —
lib/Sema/TypeCheckExpr.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:foldSequence.
Why and when: Swift parses a flat sequence of operands and operators and folds it by declared precedence groups later, because operators are user-defined (Lesson 4.1 §6).
Chapters: Ch 4 -
[SWIFT-FrontendOptions] Swift's solver limit options —
include/swift/Option/FrontendOptions.tdinswiftlang/swiftatswift-6.3.3-RELEASE. Symbols:solver_expression_time_threshold_EQ,solver_scope_threshold_EQ.
Why and when: The-solver-expression-time-thresholdand-solver-scope-thresholdflags used by the slow tests of Lesson 7.5 §7.
Chapters: Ch 7 -
[SWIFT-GenProto] Swift's witness-table emission —
lib/IRGen/GenProto.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:FragileWitnessTableBuilder,emitSILWitnessTable.
Why and when: How a protocol conformance becomes a table of function pointers passed to generic code (Lesson 6.9 §2);lib/SILOptimizer/Transforms/GenericSpecializer.cppis the optimizer's monomorphizing counterpart.
Chapters: Ch 6 -
[SWIFT-Lexer] The Swift compiler's lexer —
lib/Parse/Lexer.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:Lexer::lexImpl,Lexer::lexStringLiteral,skipToEndOfInterpolatedExpression.
Why and when: A hand-written lexer with string interpolation\(…)like Pebble's; compare its bracket skipping with Pebble's mode stack after Lesson 1.7.
Chapters: Ch 1 -
[SWIFT-ParseStmt] The Swift compiler's C++ statement parser —
lib/Parse/ParseStmt.cppinswiftlang/swiftatswift-6.1-RELEASE. Symbols:Parser::parseStmt,Parser::BacktrackingScope.
Why and when: Recursive descent with scoped backtracking (Lesson 2.5 §7). Compare itsBacktrackingScopewith Clang'sTentativeParsingAction.
Chapters: Ch 2 -
[SWIFT-SILArg] SIL block arguments ("phi arguments") —
include/swift/SIL/SILArgument.hinswiftlang/swiftatswift-6.1-RELEASE. Symbols:SILArgument,SILPhiArgument.
Why and when: SIL's name for a block parameter that merges values isSILPhiArgument: Theorem 8.4.10 in a class name.
Chapters: Ch 8 -
[SWIFT-SILGen] SIL generation from the type-checked Swift AST —
lib/SILGen/SILGen.cppinswiftlang/swiftatswift-6.1-RELEASE.
Why and when: The AST → SIL step of swiftc's pipeline (Lesson 8.7);lib/IRGen/IRGenSIL.cpplowers SIL to LLVM IR.
Chapters: Ch 8 -
[SWIFTSYNTAX-Arena] SwiftSyntax's arena for raw (green) nodes —
Sources/SwiftSyntax/SyntaxArena.swiftinswiftlang/swift-syntaxat601.0.1. Symbols:SyntaxArena,RawSyntax.
Why and when: Green nodes allocated in an arena instead of reference-counted (Lesson 4.7 §6);RawSyntax.swiftholds the layout.
Chapters: Ch 4 -
[SWIFTSYNTAX-Recovery] swift-syntax's precedence-based recovery for a lossless CST —
Sources/SwiftParser/Recovery.swiftinswiftlang/swift-syntaxat601.0.1. Symbols:canRecoverTo,RecoveryConsumptionHandle.
Why and when: Phrase-level recovery that keeps skipped tokens as "unexpected" nodes in the tree (Lesson 2.7 §7) and a lossless CST (Lesson 2.1 §7).
Chapters: Ch 2, Ch 4 -
[SWIFTSYNTAX-Trivia] SwiftSyntax's trivia representation —
Sources/SwiftSyntax/Trivia.swiftinswiftlang/swift-syntaxat600.0.1. Symbols:Trivia,TriviaPiece.
Why and when: Structured trivia pieces (spaces, newlines, comments) attached to tokens (Lesson 1.10 §6).
Chapters: Ch 1 -
[TBLGEN-Patterns] TableGen's type inference for instruction-selection patterns —
llvm/utils/TableGen/Common/CodeGenDAGPatterns.cppinllvm/llvm-projectatllvmorg-23.1.2. Symbols:TreePattern::InferAllTypes,TreePatternNode::ApplyTypeConstraints.
Why and when: Constraint propagation to a fixed point over sets of machine value types (Lesson 7.4 §7). ReadInferAllTypes's loop.
Chapters: Ch 7 -
[TCC-Src] TCC's parser-and-code-generator in one —
tccgen.cinTinyCC/tinyccatrelease_0_9_27. Symbols:gen_op,vpushi,block.
Why and when: The single pass of Lesson 0.1:blockparses a statement and emits its code,gen_opemits an operator as soon as its operands are known.
Chapters: Ch 0 -
[TS-build] tree-sitter's parse-table construction (item sets with lookaheads, conflict reports) —
crates/generate/src/build_tables/build_parse_table.rsintree-sitter/tree-sitteratv0.27.0. Symbols:ParseTableBuilder::add_parse_state,ParseTableBuilder::add_actions,ParseTableBuilder::handle_conflict.
Why and when: How tree-sitter builds LR(1)-style item sets, reports conflicts with interpretations and suggested resolutions (Lesson 3.6's box), and merges states afterwards (minimize_parse_table.rs).
Chapters: Ch 3 -
[TS-Checker] tsc's checker (declared types, widening, evolving arrays, inference, flow types) —
src/compiler/checker.tsinmicrosoft/TypeScriptatv6.0.2. Symbols:getWidenedTypeForVariableLikeDeclaration,getWidenedLiteralType,getEvolvingArrayType,inferTypes,getFlowTypeOfReference.
Why and when: Algorithm 7.6.6 in tsc. Search for the listed functions; each is a few dozen lines.
Chapters: Ch 7 -
[TS-Parser] tree-sitter's incremental parser and lexer driver —
lib/src/parser.cintree-sitter/tree-sitteratv0.25.3. Symbols:ts_parser__lex,ts_parser__can_reuse_first_leaf,ts_parser__reuse_node.
Why and when: Core reading. Incremental relexing in production (Lesson 1.10): which leaves are reused after an edit and when the lexer must run again. Read ts_parser__can_reuse_first_leaf after the tree-sitter box.
Chapters: Ch 1 -
[TS-parser] tree-sitter's runtime GLR-style parser and error recovery —
lib/src/parser.cintree-sitter/tree-sitteratv0.27.0. Symbols:ts_parser__advance,ts_parser__condense_stack,ts_parser__select_tree,ts_parser__recover.
Why and when: Stack versions, merging and tree selection by dynamic precedence and error cost (Lesson 3.6 §7); stack.c holds the graph-structured stack.
Chapters: Ch 3 -
[TS-Reuse] tree-sitter's incremental GLR parser (subtree reuse and recovery) —
lib/src/parser.cintree-sitter/tree-sitteratv0.25.10. Symbols:ts_parser__reuse_node,ts_parser__breakdown_top_of_stack,ts_parser__can_reuse_first_leaf,ts_parser__recover.
Why and when: Algorithm 4.6.6 in production, including the reuse checks and error recovery;ts_subtree_editis inlib/src/subtree.c. Read after Lesson 4.6 §2.
Chapters: Ch 4 -
[TSC-Checker] The TypeScript checker (narrowing, structural assignability, contextual typing) —
src/compiler/checker.tsinmicrosoft/TypeScriptatv5.9.3. Symbols:getFlowTypeOfReference,narrowTypeByTypeof,isTypeRelatedTo,getContextualType.
Why and when: Core reading. One 50 000-line file holds Lesson 6.6's control-flow narrowing (getFlowTypeOfReferencewalks flow nodes backwards;narrowTypeByTypeofis the typeof guard of Algorithm 6.6.3), Lesson 6.5's structural assignability and Lesson 6.4's contextual typing. Search for the symbols; do not read linearly.
Chapters: Ch 6 -
[V8-Baseline] V8's Sparkplug baseline compiler (and Liftoff in src/wasm/baseline/) —
src/baseline/baseline-compiler.ccinv8/v8at13.6.99.
Why and when: Template-style code generation straight from bytecode, the macro-expansion design point of Lesson 21.1 §7.
Chapters: Ch 21 -
[V8-Deopt] V8's deoptimizer rebuilding interpreter frames —
src/deoptimizer/deoptimizer.ccinv8/v8at13.6.233. Symbols:Deoptimizer::DoComputeOutputFrames,Deoptimizer::DoComputeUnoptimizedFrame.
Why and when: The production form of Algorithm 24.2.7's transfer: translation records to interpreter frames. ReadDoComputeOutputFramesafter Lesson 24.2 §7 to see how many registers of state a real deopt restores.
Chapters: Ch 24 -
[V8-ParserBase] V8's JavaScript parser (recursive descent, templated over the full and pre-parser) —
src/parsing/parser-base.hinv8/v8at12.9.1. Symbols:ParserBase<Impl>::ParseStatement.
Why and when: A fourth production recursive-descent parser (Lesson 2.5 §7); the same statement dispatch as Clang, for JavaScript.
Chapters: Ch 2, Ch 4 -
[V8-RegAlloc] V8 TurboFan's linear scan register allocator —
src/compiler/backend/register-allocator.ccinv8/v8at12.4.254.21. Symbols:LinearScanAllocator::AllocateRegisters,TopLevelLiveRange.
Why and when: Linear scan with splitting, deferred-block spilling and gap moves (Lessons 22.5 and 22.9).
Chapters: Ch 22 -
[V8-Scanner] V8's scanner (parser-directed regex rescanning) —
src/parsing/scanner.ccinv8/v8at12.9.1. Symbols:Scanner::ScanRegExpPattern.
Why and when: How V8 lexes/as division by default and rescans as a regex when the parser expects an expression (Algorithm 1.7.8).
Chapters: Ch 1 -
[V8-Scheduler] TurboFan's scheduler (sea of nodes to blocks) —
src/compiler/scheduler.ccinv8/v8at12.4.254.21. Symbols:Scheduler::ScheduleEarly,Scheduler::ScheduleLate.
Why and when: Theschedulephase of Lesson 8.5's V8 box; Turboshaft's CFG IR is insrc/compiler/turboshaft/graph.h.
Chapters: Ch 8, Ch 15 -
[V8-Src] V8's tiering decisions (Ignition → Sparkplug → Maglev → TurboFan) —
src/execution/tiering-manager.ccinv8/v8at12.4.254.21. Symbols:TieringManager::MaybeOptimizeFrame.
Why and when: Where V8 decides a function is "hot and stable";src/baseline/baseline-compiler.cc(Sparkplug),src/maglev/maglev-compiler.ccandsrc/compiler/pipeline.cc(TurboFan) are the tiers.
Chapters: Ch 0 -
[V8-TDZ] V8's bytecode generator (temporal-dead-zone hole checks) —
src/interpreter/bytecode-generator.ccinv8/v8at13.4.1. Symbols:BytecodeGenerator::BuildThrowIfHole,HoleCheckElisionScope.
Why and when: Howlet/consthoisting is implemented: the slot holds a "hole" and accesses check it, eliding redundant checks per basic block (Lesson 5.1 §2).
Chapters: Ch 5 -
[WebKit-B3] B3's Phi and Upsilon opcodes (JavaScriptCore's back-end IR) —
Source/JavaScriptCore/b3/B3Opcode.hinWebKit/WebKitatWebKit-7622.2.11.14.6. Symbols:Upsilon,Phi,UpsilonValue (b3/B3UpsilonValue.h),validatePhisAreDominatedByUpsilons (b3/B3Validate.cpp).
Why and when: Upsilon/phi SSA in a production JIT: Upsilons store to a phi's shadow variable in the predecessors; the validator checks that every path to a Phi passes an Upsilon. Lesson 16.5.
Chapters: Ch 16 -
[WebKit-Dom] WebKit's dominators (Semi-NCA below 20 000 nodes, Lengauer-Tarjan above, naive self-check) —
Source/WTF/wtf/Dominators.hinWebKit/WebKitatwpewebkit-2.48.0. Symbols:Dominators,NaiveDominators,maxNodesForSemiNCADominance.
Why and when: The hybrid of Lesson 15.1 §6 and the only production use of iterative dominator sets (as a self-check); read after the comparison lab.
Chapters: Ch 15 -
[WT-Winch] Winch, Wasmtime's baseline compiler (one visit method per Wasm operator) —
winch/codegen/src/visitor.rsinbytecodealliance/wasmtimeatv37.0.2.
Why and when: Macro expansion in production (Lesson 21.1 §7): compare its output with Cranelift's in the lesson's box.
Chapters: Ch 21 -
[YARPGen] YARPGen's expression evaluation and UB-removing rebuild (policies in src/gen_policy.cpp) —
src/expr.cppinintel/yarpgenate2a051221b835869d3efad3f4a2554050f65845c. Symbols:evaluate,rebuild.
Why and when: Algorithm 12.5.7: each expression node's evaluate() detects UB and rebuild() rewrites it away.
Chapters: Ch 12 -
[Z3-Ast] Z3's term representation (quantified variables as de Bruijn indices) —
src/ast/ast.hinZ3Prover/z3atz3-4.15.3. Symbols:var,quantifier.
Why and when: De Bruijn indices in an SMT solver: bound variables of quantifiers arevarnodes with an index. Read after Lesson 5.2 §7.
Chapters: Ch 5
Official documentation and specifications¶
-
[AAPCS64] Procedure Call Standard for the Arm 64-bit Architecture (AArch64). abi-aa 2025Q4. link
Why and when: AArch64's rules for composite types (HFAs, the 16-byte limit, indirect passing), the macOS side of Lesson 11.5.
Chapters: Ch 11, Ch 21 -
[ANTLR4-LeftRecDoc] ANTLR 4 documentation: Left-recursive rules. ANTLR 4.13.2. link
Why and when: The user-level statement of what ANTLR 4 accepts (direct left recursion only) and how precedence and associativity follow from alternative order (Lesson 2.4 §7).
Chapters: Ch 2 -
[BAJIT] Building a JIT: Starting out with KaleidoscopeJIT (tutorial chapters 1–3). LLVM 23.1.2. link
Why and when: Builds an ORC JIT layer by layer (compile layer, optimize layer, lazy compile-on-demand); the hands-on companion to Algorithm 10.8.5 and 10.8.6. Chapters 2–3 are the neighbouring files BuildingAJIT2.rst and BuildingAJIT3.rst.
Chapters: Ch 10 -
[BASH-Manual] GNU Bash Reference Manual: Shell Functions. Bash 5.2. link
Why and when: Dynamic scoping still in daily use: a function sees its caller'slocalvariables. Read the section, then run the Bash box of Lesson 5.1.
Chapters: Ch 5 -
[BISON-Manual] GNU Bison manual: shift/reduce conflicts, %expect, counterexamples, GLR. Bison 3.8.2. link
Why and when: The reference for the Bison outputs pasted in Lessons 2.1–2.3 (conflict reports,-Wcounterexamples,%expect) and for GLR ambiguity reports. Read "Shift/Reduce" and "Counterexamples".
Chapters: Ch 2, Ch 3, Ch 4, Ch 5 -
[C-Std] ISO/IEC 9899 (C) working draft N3220. C2y working draft, 2024. link
Why and when: §6.10 specifies preprocessing directives and macro replacement, including rescanning and the rule that a macro is not replaced inside its own expansion (the hide sets of Lesson 0.6).
Chapters: Ch 0 -
[C11] ISO/IEC 9899:201x (C11) committee draft N1570: §6.3 Conversions. link
Why and when: §6.3.1.1 (integer promotions), §6.3.1.3 (signed and unsigned integers) and §6.3.1.8 (usual arithmetic conversions): the rules Algorithm 6.3.6 transcribes. Read with Lesson 6.3 §2.
Chapters: Ch 6, Ch 19 -
[CL-Docs] Cranelift IR reference (cranelift/docs/ir.md) and project documentation. Wasmtime v37.0.2. link
Why and when: CLIF: SSA with block parameters, types, instructions. Read it with the CLIF box of Lesson 0.4 open.
Chapters: Ch 0, Ch 9 -
[CL-EgraphRFC] Cranelift: Using E-Graphs for Verified, Cooperating Middle-End Optimizations (RFC). link
Why and when: The design document of Cranelift's aegraphs by its author, Chris Fallin: phase ordering, acyclic e-graphs, elaboration and rule priority. Read with Lesson 17.8 §6–7.
Chapters: Ch 17 -
[CLANG-DFDOC] Data flow analysis: an informal introduction (Clang documentation). LLVM 23.1.2. link
Why and when: Clang's own tutorial for its dataflow framework: lattices, joins, fixpoint iteration and the termination argument, with CFG pictures. Read after Lesson 14.1 as a friendly second view.
Chapters: Ch 14 -
[CLANG-Internals] Clang Internals Manual: the Lexer and Parser libraries, annotation tokens. LLVM 23.1.2. link
Why and when: The official description of Clang's token and annotation-token design used by tentative parsing (Lesson 2.5 §7); read the "Annotation Tokens" section.
Chapters: Ch 2, Ch 5 -
[CLANG-Modules] Standard C++ Modules (Clang documentation). LLVM 23.1.2. link
Why and when: How clang compiles C++20 module interfaces once into BMI files that importers load instead of re-preprocessing headers — the "modules" variant of Lesson 0.6 §6. Read the introduction and the "Background and terminology" section.
Chapters: Ch 0 -
[CLANG-PCH] Precompiled Header and Modules Internals (Clang documentation). LLVM 23.1.2. link
Why and when: What a precompiled header stores (the serialized AST after a common include prefix) and how clang loads it lazily; the end-user view is the "Precompiled Headers" section ofclang/docs/UsersManual.md. Read after Lesson 0.6 §6.
Chapters: Ch 0 -
[CPP-basiclval] C++ working draft, [basic.lval] ¶11 (the type-access rule) and [cstddef.syn] (std::byte). C++ working draft (eel.is/c++draft). link
Why and when: C++'s version of the aliasing rule: an object may be accessed through its dynamic type, a signed/unsigned variant, or char, unsigned char or std::byte. Read with Lesson 19.3 §2.
Chapters: Ch 19 -
[CPP-Draft] Working Draft, Programming Languages — C++ (eel.is HTML rendering). link
Why and when: [basic.scope.pdecl] (point of declaration), [basic.lookup.argdep] (ADL) and [over.match] (overload resolution). Look up the stable names cited in Lessons 5.1 and 5.4.
Chapters: Ch 5 -
[CPP-Over] Working Draft, Programming Languages — C++: [over.match] (overload resolution) and [over.ics.rank]. link
Why and when: The normative ranking of implicit conversion sequences (exact match, promotion, conversion; user-defined; ellipsis) and the "better viable function" relation. Read [over.ics.rank] with Lesson 6.3 §2.
Chapters: Ch 6 -
[Cranelift-ISLE-ref] ISLE language reference (Cranelift). wasmtime 37.0.2. link
Why and when: Terms, extractors, constructors and rule priorities of ISLE. Read the "Rules" and "Priorities" sections after Lesson 13.2.
Chapters: Ch 13 -
[CSHARP-DA] C# language specification: Variables, §9.4 Definite assignment. link
Why and when: C#'s version of the JLS rules, with the definite-assignment state per statement and expression kind. Read after Lesson 5.7 §4 and compare with [JLS21-16].
Chapters: Ch 5 -
[Dalvik] Android Open Source Project — Dalvik bytecode and instruction formats. link
Why and when: Dalvik's register-based bytecode: 16-bit code units and 4-, 8- or 16-bit register fields. The register-VM example of Lesson 8.1 that has no tool in the course container.
Chapters: Ch 8 -
[DOOP-DOC] Doop: Datalog 101 and Doop 101. link
Why and when: Doop's introduction to Datalog and its evaluation to a fixed point, and (docs/doop-101.md) how its points-to results are queried. Read after Lesson 14.8 §2.
Chapters: Ch 14 -
[Dre11] How To Write Shared Libraries (Ulrich Drepper). 4.1.2, 2011. link
Why and when: The glibc maintainer's explanation of dynamic linking: symbol lookup order, relocations processed at startup, PLT/GOT, lazy binding and its cost. The source for Algorithm 0.6.8.
Chapters: Ch 0 -
[DWARF5] DWARF Debugging Information Format, Version 5. 5 (February 2017). link
Why and when: Core reading. The standard: §2.5 (location expressions, Definition 24.4.3), §2.6 (location lists), §6.2 (the line-number program). Read §2.5 with the drilldwarf-locationopen; skip the type-unit and split-DWARF chapters.
Chapters: Ch 24 -
[ECMA24] ECMA-262, 15th edition: ECMAScript 2024 Language Specification. ES2024. link
Why and when: §14.3.1 (let and const: the temporal dead zone), §14.3.2 (var hoisting) and §14.7.4 (per- iteration bindings offor (let …)). Read after Lesson 5.1 §2.
Chapters: Ch 5 -
[ECMA262] ECMAScript 2024 Language Specification (ECMA-262, 15th edition). ECMA-262 2024. link
Why and when: §12 (ECMAScript Language: Lexical Grammar) defines the goal symbols InputElementDiv and InputElementRegExp (Definition 1.7.3). Read the introduction of §12 after Lesson 1.7.
Chapters: Ch 1 -
[ELF] Tool Interface Standard (TIS) Executable and Linking Format (ELF) Specification, Version 1.2. link
Why and when: The ELF container: sections, symbol tables, relocations, program headers. Keep open while reading thellvm-readelfoutput in Lesson 0.6.
Chapters: Ch 0, Ch 21 -
[FLEX-Manual] Lexical Analysis With Flex (the flex manual). flex 2.6.4. link
Why and when: Core reading. Rules, priority and longest match, start conditions and their stack (Lesson 1.7),-bbacking-up reports (Lesson 1.6), and table compression options-Cf/-Cem(Lesson 1.5). Keep it open while doing the flex boxes.
Chapters: Ch 1 -
[GCC-GIMPLE] GCC Internals: GIMPLE. GCC 15. link
Why and when: GIMPLE's statement codes, operands, SSA names and PHI nodes, maintained with GCC (gcc/doc/gimple.texi). Read with Lesson 9.8's GIMPLE box.
Chapters: Ch 9 -
[GCC-Install] Installing GCC: Building (gcc/doc/install.texi) — 3-stage bootstrap and stage comparison. gcc-15.1.0. link
Why and when: States the default native build: a 3-stage bootstrap followed by "a comparison test of the stage2 and stage3 compilers" — Algorithm 0.5.8 in GCC's words.
Chapters: Ch 0 -
[GCC-Int] GNU Compiler Collection (GCC) Internals — Passes and Files of the Compiler; GENERIC; GIMPLE; RTL. GCC 15. link
Why and when: GCC's three IRs and its pass structure, from the maintainers. Read the "Passes and Files of the Compiler" chapter after Lesson 0.4's GCC section. The manual is generated fromgcc/doc/passes.texi,generic.texi,gimple.texiandrtl.texiin the GCC source tree (e.g. the gcc-mirror/gcc tagreleases/gcc-15.1.0), a mirror if the web page is unreachable.
Chapters: Ch 0, Ch 8, Ch 12 -
[GCC-LoopDoc] GCC Internals, "Loop Analysis and Representation" (node LCSSA). GCC 15. link
Why and when: GCC's loop tree, its canonical-loop properties and loop-closed SSA, in the texinfo source of the internals manual; read after Lesson 15.7 to compare with LLVM.
Chapters: Ch 15 -
[GCC-MaS] GCC Internals, "Match and Simplify". GCC 15. link
Why and when: The match.pd language reference (simplify, match, for, :c, @@, if, with). Read with Lesson 13.2 §2 (external pattern DSLs).
Chapters: Ch 13 -
[GCC-matchpd] GCC Internals: Match and Simplify (the match.pd language), with gcc/match.pd. GCC 15.2.0. link
Why and when: GCC's pattern DSL compiled by genmatch into GENERIC and GIMPLE folders; compare its (simplify …) forms with PatternMatch and GlobalISel rules after Lesson 10.5. The rules themselves are in gcc/match.pd at the same tag.
Chapters: Ch 10, Ch 13 -
[GCC-MD] GCC Internals: Machine Descriptions (md.texi). GCC 15. link
Why and when: define_insn, define_expand, define_split, constraints and predicates: the GCC side of Lesson 21.8. Read "Patterns" and "Constraints" with the lesson's i386.md box.
Chapters: Ch 21 -
[GCC-Plugins] GNU Compiler Collection Internals: Plugins. GCC 15. link
Why and when: PLUGIN_PASS_MANAGER_SETUP and struct register_pass_info: inserting a pass relative to a named reference pass — GCC's extension points (Lesson 12.2 §1).
Chapters: Ch 12 -
[GCC-StrictAliasing] GCC manual: -fstrict-aliasing (Optimize Options). GCC 14. link
Why and when: GCC's statement of when type-based aliasing is assumed, with the union-punning exception GCC documents. Read with Lesson 19.3 §4.
Chapters: Ch 19 -
[GCC-TreeSSAPasses] GCC Internals, "Tree SSA passes". GCC 15. link
Why and when: The list of GIMPLE passes with the names used by -fdump-tree-* (ccp, cddce, fre, pre, dom/threading); keep it open when reading the GCC boxes of this chapter.
Chapters: Ch 17 -
[GCC34] GCC 3.4 Release Series, Changes, New Features, and Fixes (C++ section). GCC 3.4. link
Why and when: Records that a hand-written recursive-descent C++ parser replaced the yacc-derived one (Lesson 2.5 §1): a production compiler choosing recursive descent over a generator.
Chapters: Ch 2, Ch 3 -
[GCC41] GCC 4.1 Release Series, Changes, New Features, and Fixes (C family). GCC 4.1. link
Why and when: Records that the Bison-based C and Objective-C parser was replaced by a hand-written recursive-descent parser (Lesson 2.5 §1).
Chapters: Ch 2, Ch 3 -
[GHC-Impred] GHC User's Guide: Impredicative polymorphism. GHC 9.4.7. link
Why and when: What Quick Look accepts in practice (Lesson 7.8 §7).
Chapters: Ch 7 -
[GHC-RankN] GHC User's Guide: Arbitrary-rank polymorphism. GHC 9.4.7. link
Why and when: The rules GHC applies toRankNTypesprograms, including simplified subsumption (Lesson 7.8 §6).
Chapters: Ch 7 -
[GitBisect] git-bisect — Use binary search to find the commit that introduced a bug. Git 2.43. link
Why and when: bisect start/good/bad,bisect runand its exit-code convention (125 = skip). Read with Lesson 12.7's bisection section.
Chapters: Ch 12 -
[GPERF-Manual] GNU gperf: a perfect hash function generator. gperf 3.1. link
Why and when: Input format, key-position selection and the generatedin_word_setfunction used in Lesson 1.8's real-world box.
Chapters: Ch 1 -
[IEEE754] IEEE Standard for Floating-Point Arithmetic (IEEE Std 754-2019). 754-2019. link
Why and when: The formats and correctly rounded operations APFloat implements in software (Lesson 10.6); §4 (rounding) and §7 (exceptions/status flags) map onto APFloat's roundingMode and opStatus.
Chapters: Ch 10, Ch 13 -
[Insta] insta: snapshot testing for Rust. link
Why and when: Snapshot testing with review (cargo insta review), inline snapshots and redactions. Read for the variants in Lesson 12.5 §6.
Chapters: Ch 12 -
[Intel-SDM] Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (Instruction Set Reference). link
Why and when: Ch. 2 (Instruction Format): prefixes, REX, ModRM and SIB with Table 2-2, the basis of Algorithm 21.10.2 and Proposition 21.10.3.
Chapters: Ch 21 -
[ISLE] ISLE language reference (Cranelift's instruction-selection and rewrite DSL). Wasmtime v37.0.2. link
Why and when: A term-rewriting DSL with overlapping rules and explicit priorities; the third point in Lesson 10.5's comparison of rule DSLs.
Chapters: Ch 10, Ch 21 -
[ItaniumABI] Itanium C++ ABI (§2.9 Run-Time Type Information). link
Why and when: The type_info layout and the __dynamic_cast interface and algorithm (§2.9.5–2.9.7) behind Lesson 10.4's C++ RTTI; the rationale paragraph explains why only direct bases are stored.
Chapters: Ch 10 -
[ItaniumEH] Itanium C++ ABI: Exception Handling. link
Why and when: The two-phase unwinding model (search, then cleanup) and __cxa_throw that Lesson 10.7's Algorithm 10.7.5 outlines.
Chapters: Ch 10, Ch 11 -
[JASTADD] JastAdd reference manual (reference attribute grammars in Java). JastAdd2 2.3.6. link
Why and when: Syntax ofsyn,inh,eqandcircularattributes as used in the JastAdd box of Lesson 5.5. Read before running the box.
Chapters: Ch 5 -
[JLS] The Java Language Specification, Java SE 21 Edition, Chapter 16: Definite Assignment. Java SE 21. link
Why and when: Definite initialization as a language rule, specified construct by construct (Lesson 14.3, Definition 14.3.19 and §6).
Chapters: Ch 14 -
[JLS21-10] The Java Language Specification, Java SE 21: §10.5, Array Store Exception. link
Why and when: The run-time check that makes covariant arrays safe (Lesson 6.2's box): Java's type system is sound only because this store check exists. Read with Lesson 6.2 §4.
Chapters: Ch 6 -
[JLS21-14] The Java Language Specification, SE 21: Chapter 14, Blocks, Statements, and Patterns. link
Why and when: §14.22 (unreachable statements): the syntax-directed "can complete normally" rules that Definition 5.7.1 adapts, including theif (false)exception. Read after Lesson 5.7 §2.
Chapters: Ch 5 -
[JLS21-16] The Java Language Specification, SE 21: Chapter 16, Definite Assignment. link
Why and when: Core reading. The most precise specification of definite assignment in any mainstream language, with when-true/when-false rules for conditions. Read §16.2.10–16.2.12 (loops) after Lesson 5.7 §4.
Chapters: Ch 5 -
[JLS21-5] The Java Language Specification, Java SE 21: Chapter 5, Conversions and Contexts. link
Why and when: Java's conversions listed by context (assignment, invocation, casting, numeric promotion): a specification in which each checking position of Lesson 6.4 names the conversions it allows. Read §5.1.2 (widening primitive) and §5.6 (numeric contexts) with Lesson 6.3.
Chapters: Ch 6 -
[JLS21-6] The Java Language Specification, SE 21: Chapter 6, Names. link
Why and when: §6.3 (scope of a declaration) and §6.4 (shadowing and obscuring, and the rule that a local may not redeclare a local). Read after Lesson 5.1 §6.
Chapters: Ch 5 -
[JLS21-8] The Java Language Specification, SE 21: Chapter 8, Classes. link
Why and when: §8.3.3 (restrictions on field references in initializers): order-independent members with one declare-before-use exception. Read after Lesson 5.3 §2.
Chapters: Ch 5 -
[JVMS] The Java Virtual Machine Specification, Java SE 21 Edition — Chapter 4 (class files), §4.10 (verification). Java SE 21. link
Why and when: §4.10.1 (verification by type checking with StackMapTable frames) and §4.10.2 (by type inference) are the production versions of Algorithm 8.1.6; read them after Lesson 8.1.
Chapters: Ch 8 -
[KAL] My First Language Frontend with LLVM (Kaleidoscope), chapters 3–4: code generation to LLVM IR, JIT and optimizer support. LLVM 23.1.2. link
Why and when: The canonical first use of IRBuilder, a module and a context; chapter 4 (LangImpl04.rst) adds a JIT. Work through them before Lab 10.1 if IRBuilder is new to you.
Chapters: Ch 10 -
[KAL7] My First Language Frontend with LLVM (Kaleidoscope), chapter 7: mutable variables. LLVM 23.1.2. link
Why and when: The tutorial statement of the allocas +mem2regstrategy E5 uses; read before E5 if you have not seen it.
Chapters: Ch 11 -
[KOTLIN-Builders] Kotlin documentation: Using builders with builder type inference. link
Why and when: What builder inference accepts, with examples likebuildList(Algorithm 7.6.4).
Chapters: Ch 7 -
[KOTLIN-Casts] Kotlin documentation: Type checks and casts (smart casts). link
Why and when: The conditions under which Kotlin smart-casts a variable after anischeck (the variable must be stable: aval, or a localvarnot captured by a lambda that modifies it). Read with Lesson 6.6 §6; not runnable in this course's container.
Chapters: Ch 6 -
[KOTLIN-Generics] Kotlin documentation: Generics (declaration-site variance, type projections). link
Why and when: Kotlin'sout/indeclaration-site variance and its use-site "type projections", with the rule that anoutparameter may appear only in out-positions. Read with Lesson 6.5's variance section and compare with Java's wildcards in the javac box.
Chapters: Ch 6 -
[KOTLIN-Spec] Kotlin language specification: Type inference. link
Why and when: Kotlin's local inference, constraint systems per call and builder inference (Lesson 7.6). Read the overview and the section on builder-style inference.
Chapters: Ch 7 -
[LARK-Docs] Lark documentation: parsers (Earley, LALR(1), CYK). Lark 1.3.1. link
Why and when: Lark's own comparison of its three parsers, quoted in Lessons 4.3 and 4.4.
Chapters: Ch 4 -
[LLVM-AADoc] LLVM Alias Analysis Infrastructure. LLVM 23.1.2. link
Why and when: Core reading. The AliasAnalysis interface (MemoryLocation, AliasResult, ModRefInfo), how AA implementations are chained, and aa-eval. Read with Lesson 19.1.
Chapters: Ch 19 -
[LLVM-AdvBuilds] Advanced Build Configurations: Bootstrap Builds. LLVM 23.1.2. link
Why and when:CLANG_ENABLE_BOOTSTRAP,ninja stage2, and the stage3 build that "should be bit-for-bit identical" to stage2 (Theorem 0.5.14). Read when you build LLVM yourself.
Chapters: Ch 0 -
[LLVM-Atomics] LLVM Atomic Instructions and Concurrency Guide. LLVM 23.1.2. link
Why and when: What each ordering means for optimizations and code generation, and why non-atomic races yield undef (Proposition 9.4.13). Read after Lesson 9.4's atomics section.
Chapters: Ch 9 -
[LLVM-Bitcode] LLVM Bitcode File Format. LLVM 23.1.2. link
Why and when: The bitstream container, VBR encoding (the vbr4 example of Lesson 9.6), abbreviations and relative operand IDs. Read withllvm-bcanalyzer -dumpoutput next to it.
Chapters: Ch 9 -
[LLVM-BOLT] BOLT README (input requirements, perf profiling, perf2bolt, llvm-bolt options). LLVM 23.1.2. link
Why and when: The documented BOLT workflow quoted in Lesson 20.10 (the course image has no llvm-bolt or perf). Read Steps 1–3 if you want to run BOLT on your own machine.
Chapters: Ch 20, Ch 23 -
[LLVM-BugpointRedesign] Bugpoint Redesign. LLVM 23.1.2. link
Why and when: Why bugpoint was replaced: confusing, slow, low-quality reductions; the plan that became llvm-reduce. Read with Lesson 12.7 §1.
Chapters: Ch 12 -
[LLVM-CMake] Building LLVM with CMake — Embedding LLVM in your project. LLVM 23.1.2. link
Why and when: find_package(LLVM CONFIG), llvm_map_components_to_libnames and the variables LLVMConfig.cmake exports (Lesson 10.8 §2); the section this chapter's examples/CMakeLists.txt follows.
Chapters: Ch 10 -
[LLVM-CodeGenDoc] The LLVM Target-Independent Code Generator. LLVM 23.1.2. link
Why and when: Core reading. The official overview of the back end: SelectionDAG phases, legalization, scheduling, the MC layer. Read "Instruction Selection" with Lesson 21.5 and "The MC Layer" with Lesson 21.10.
Chapters: Ch 21, Ch 22 -
[LLVM-CS] LLVM Coding Standards. LLVM 23.1.2. link
Why and when: "Do not use RTTI or Exceptions", "Use of auto", naming and early exits; the rules LLVM-facing code in this course follows. Read the RTTI/exceptions section with Lessons 10.4 and 10.7.
Chapters: Ch 10 -
[LLVM-CycleTerm] LLVM Cycle Terminology. LLVM 23.1.2. link
Why and when: The definition of cycles, entries and the cycle nesting forest that CycleInfo computes, citing Havlak; read after Lesson 15.5 §2 and compare with Definition 15.5.6.
Chapters: Ch 15 -
[LLVM-DbgRecords] Debug info migration: From intrinsics to records (RemoveDIsDebugInfo). LLVM 23.1.2. link
Why and when: The move from llvm.dbg.value calls to #dbg_value records, the textual format change and the API (getDbgRecordRange). Read with Lesson 9.6's debug-records section.
Chapters: Ch 9, Ch 10, Ch 24 -
[LLVM-DevPolicy] LLVM Developer Policy: IR Backwards Compatibility. LLVM 23.1.2. link
Why and when: The compatibility promise quoted in Lesson 9.6: bitcode back to 3.0 is readable, the text format has no promise, non-debug metadata may be dropped. Read the "IR Backwards Compatibility" section after Lesson 9.6.
Chapters: Ch 9 -
[LLVM-EH] Exception Handling in LLVM. LLVM 23.1.2. link
Why and when: invoke, landingpad, resume and personality functions for the Itanium ABI, and the funclet instructions for Windows. Read before lab E8.
Chapters: Ch 9, Ch 10, Ch 11, Ch 24 -
[LLVM-FileCheck] FileCheck — Flexible pattern matching file verifier. LLVM 23.1.2. link
Why and when: Core reading. The reference for every directive, variables and numeric expressions. Read alongside Lesson 12.4 §2; Algorithm 12.4.4 makes its prose precise.
Chapters: Ch 12 -
[LLVM-GC] Garbage Collection with LLVM. LLVM 23.1.2. link
Why and when: The two strategies LLVM offers a collector:llvm.gcrootshadow stacks and statepoint stack maps, with thegc "name"attribute andGCStrategy. Read "Built In GC Strategies" after Lesson 24.5 §6.
Chapters: Ch 24 -
[LLVM-GEP] The Often Misunderstood GEP Instruction (GetElementPtr FAQ). LLVM 23.1.2. link
Why and when: Core reading. Answers the questions Lesson 9.4 raises (the leading zero index, why GEP never dereferences, out-of-bounds GEPs, what inbounds means). Read it right after Lesson 9.4 §3 and before lab E9.
Chapters: Ch 9 -
[LLVM-GISel] Global Instruction Selection (GlobalISel). LLVM 23.1.2. link
Why and when: Core reading. GlobalISel's goals (performance, granularity, modularity) and a page per pass. Read the index and the pipeline pages with Lesson 21.6.
Chapters: Ch 21 -
[LLVM-ICGuide] InstCombine contributor guide. LLVM 23.1.2. link
Why and when: How PatternMatch-based peepholes are written and tested in LLVM, canonical forms, and why one canonical form per pattern avoids infinite combine loops (Lesson 10.5 §4).
Chapters: Ch 10, Ch 13 -
[LLVM-LangRef] LLVM Language Reference Manual. LLVM 23.1.2. link
Why and when: Read "Well-Formedness", thephiinstruction and terminator instructions with Lessons 8.2 and 8.4: LLVM's rules for basic blocks and phi-SSA.
Chapters: Ch 8, Ch 9, Ch 11, Ch 13, Ch 19 -
[LLVM-LangRef-Call] LLVM Language Reference, the call instruction (tail, musttail, notail). LLVM 23.1.2. link
Why and when: The exact guarantees of the tail markers that Lesson 20.8's TCE relies on; search for "musttail" in the call instruction's section.
Chapters: Ch 20 -
[LLVM-LangRefPhi] LLVM Language Reference Manual — 'phi' instruction. LLVM 23.1.2. link
Why and when: The normative phi rules: at the top of the block, one incoming value per predecessor, and at run time the phi "logically takes on the value specified by the pair corresponding to the predecessor basic block that executed just prior to the current block". Lesson 16.1 §2.
Chapters: Ch 16 -
[LLVM-LibFuzzer] libFuzzer — a library for coverage-guided fuzz testing. LLVM 23.1.2. link
Why and when: The fuzz-target contract, flags (-seed, -runs, -minimize_crash, -dict), the output format of Lesson 12.6's log, and advice on harnesses. Read before Lesson 12.6 §7.
Chapters: Ch 12 -
[LLVM-lit] lit — LLVM Integrated Tester. LLVM 23.1.2. link
Why and when: Test discovery, configuration files, substitutions, features and result codes (Definition 12.4.6).
Chapters: Ch 12 -
[LLVM-LoopTerm] LLVM Loop Terminology (and Canonical Forms). LLVM 23.1.2. link
Why and when: Defines rotated loops, preheaders and latches as LLVM uses them; read with Lesson 11.4's Definition 11.4.6.
Chapters: Ch 11, Ch 15 -
[LLVM-LTO] LLVM Link Time Optimization — Design and Implementation. LLVM 23.1.2. link
Why and when: The linker–LTO interface (symbol resolution, visibility) that Lesson 20.9's internalization depends on.
Chapters: Ch 20 -
[LLVM-MCA] llvm-mca — LLVM Machine Code Analyzer (command guide). LLVM 23.1.2. link
Why and when: Options, views (-timeline,-resource-pressure,-bottleneck-analysis) and the meaning of every column in the summary. Keep it open while reproducing Lesson 23.1's boxes.
Chapters: Ch 23 -
[LLVM-MCJIT] MCJIT Design and Implementation. LLVM 23.1.2. link
Why and when: How MCJIT compiles whole modules to in-memory objects and links them with RuntimeDyld (Algorithm 10.8.3); read to understand what ORC replaced.
Chapters: Ch 10 -
[LLVM-MemorySSADoc] LLVM MemorySSA documentation. LLVM 23.1.2. link
Why and when: MemoryDef, MemoryUse, MemoryPhi, liveOnEntry, the walker API and the "use optimization" invariant; read with Lesson 16.8 before using MemorySSA in Ch 19.
Chapters: Ch 16, Ch 19 -
[LLVM-MIRPatterns] MIR Patterns in TableGen (GlobalISel combiner rules). LLVM 23.1.2. link
Why and when: The declarative rule language of the GlobalISel combiner (GICombineRule, PatFrags, GIReplaceReg) shown in Lesson 10.5's real-world box.
Chapters: Ch 10 -
[LLVM-MLGO] Machine Learning - Guided Optimization (MLGO). LLVM 23.1.2. link
Why and when: How LLVM builds with a model (AOT or development mode), the training corpus tools and the interfaces. Read after Lesson 20.3's MLGO section.
Chapters: Ch 20 -
[LLVM-NPM] Using the New Pass Manager. LLVM 23.1.2. link
Why and when: How LLVM's pass manager caches analyses and how passes reportPreservedAnalyses— Algorithm 0.1.8 in LLVM's vocabulary; essential again in Ch 12.
Chapters: Ch 0, Ch 12, Ch 20 -
[LLVM-OpaquePtr] Opaque Pointers. LLVM 23.1.2. link
Why and when: Why typed pointers (i32*) were removed, the migration timeline (LLVM 14–17), and what replaced pointee types (types on loads, stores, GEPs and calls). Read after Lesson 9.2.
Chapters: Ch 9 -
[LLVM-OptBisect] Using -opt-bisect-limit to debug optimization errors. LLVM 23.1.2. link
Why and when: Which passes are counted, how to bisect, and how to combine it with -print-after. Read with Lesson 12.7 §2.
Chapters: Ch 12 -
[LLVM-ORC] ORC Design and Implementation (ORCv2). LLVM 23.1.2. link
Why and when: The JIT APIs the lab uses:LLJIT,ThreadSafeModule, symbol lookup, lazy compilation. Read before milestone L5 of the lab.
Chapters: Ch 0, Ch 10, Ch 24 -
[LLVM-Passes] LLVM's Analysis and Transform Passes. LLVM 23.1.2. link
Why and when: One-paragraph descriptions of domtree, postdomtree, domfrontier, loops, loop-simplify, lcssa, adce and the printers used in this chapter's real-world boxes.
Chapters: Ch 15, Ch 17 -
[LLVM-PGO] Clang Users Manual, Profile Guided Optimization (instrumentation, CSPGO, sampling profilers, sample profile formats). LLVM 23.1.2. link
Why and when: The flags of Lesson 20.10's boxes (-fprofile-generate, -fcs-profile-generate, -fprofile-sample-use), the text sample format and create_llvm_prof. Read the "Profile Guided Optimization" section before running the boxes yourself.
Chapters: Ch 20 -
[LLVM-PM] LLVM Programmer's Manual. LLVM 23.1.2. link
Why and when: Core reading. The chapter's primary reference. Sections by lesson: "The isa<>, cast<> and dyn_cast<> templates" (10.4); "Passing strings (StringRef and Twine)", "Picking the Right Data Structure" (10.6); "Error handling" (10.7); "Iterating over def-use & use-def chains", "Replacing an Instruction with another Value", "The User and owned Use classes' memory layout" (10.1–10.2).
Chapters: Ch 10 -
[LLVM-Reduce] llvm-reduce — LLVM automatic testcase reducer. LLVM 23.1.2. link
Why and when: Interestingness tests, delta passes and options. Read before running Lesson 12.7's box.
Chapters: Ch 12 -
[LLVM-RN23] LLVM 23 Release Notes. LLVM 23.1.2. link
Why and when: Records the removal of bugpoint in favor of llvm-reduce and reduce_pipeline.py (Lesson 12.7 §1).
Chapters: Ch 12 -
[LLVM-RTTI] How to set up LLVM-style RTTI for your class hierarchy. LLVM 23.1.2. link
Why and when: The recipe for a kind enum plusclassof, including deeper hierarchies with first/last ranges (Theorem 4.7.11). Read with Lesson 4.7 §2.
Chapters: Ch 4, Ch 10 -
[LLVM-SourceLevelDebugging] Source Level Debugging with LLVM. LLVM 23.1.2. link
Why and when: Core reading. The metadata (DICompileUnit,DISubprogram,DILocalVariable,DILocation), the debug records and the rules a pass must obey to keep them truthful. Read "Debug information format" before E3 and "Debug info in optimized code" after Algorithm 24.4.7.
Chapters: Ch 24 -
[LLVM-Statepoints] Garbage Collection Safepoints in LLVM (statepoints). LLVM 23.1.2. link
Why and when: Core reading.gc.statepoint,gc.relocate, the deopt operand bundle andRewriteStatepointsForGC: the substrate for both deoptimization (Lesson 24.2) and precise GC (Lesson 24.5). Read the "Overview" and "Deoptimization" sections first.
Chapters: Ch 24 -
[LLVM-Stress] llvm-stress — generate random .ll files. LLVM 23.1.2. link
Why and when: The two options (-seed, -size) and the intended use: crash testing of passes and code generators.
Chapters: Ch 12 -
[LLVM-TableGenRef] TableGen Programmer's Reference. LLVM 23.1.2. link
Why and when: The exact semantics of classes, defs, let and multiclasses behind Algorithm 21.8.3. Read the "let" and "multiclass" sections with Lesson 21.8 §2.
Chapters: Ch 21 -
[LLVM-TestingGuide] LLVM Testing Infrastructure Guide. LLVM 23.1.2. link
Why and when: Core reading. How LLVM's regression tests are organized and written with lit and FileCheck, and when to use update_test_checks.py. Read before Lesson 12.4.
Chapters: Ch 12 -
[LLVM-ThinLTO] Clang ThinLTO documentation. LLVM 23.1.2. link
Why and when: Using ThinLTO with Clang and the linkers: caches, parallelism, distributed builds. Read after Lesson 20.9 §6.
Chapters: Ch 20 -
[LLVM-TypeMetadata] Type Metadata (!type, llvm.type.test, vtable layout for CFI and devirtualization). LLVM 23.1.2. link
Why and when: How Clang describes class hierarchies to LLVM; the input of whole-program devirtualization. Read before Lesson 20.7 §2.
Chapters: Ch 20 -
[LLVM-UB] Undefined Behavior (UB) in LLVM. LLVM 23.1.2. link
Why and when: LLVM's own guide to immediate UB, undef, poison and freeze, with the rationale for deferred UB and many small examples. Read it alongside Lesson 9.7 §1–2.
Chapters: Ch 9 -
[LLVM-Vectorizers] Auto-Vectorization in LLVM. LLVM 23.1.2. link
Why and when: The user-level overview of the loop and SLP vectorizers, with pragmas and remarks; read it before Lesson 18.8.
Chapters: Ch 18 -
[LLVM-VPlan] Vectorization Plan. LLVM 23.1.2. link
Why and when: The design of VPlan (recipes, regions, planning); read after Lesson 18.8's VPlan box.
Chapters: Ch 18 -
[LLVM-WLP] Writing an LLVM Pass (legacy PM version). LLVM 23.1.2. link
Why and when: The legacy pass classes (ModulePass, CallGraphSCCPass, FunctionPass, LoopPass) and getAnalysisUsage; read its sections on pass classes and analysis usage for Lesson 12.1's comparison, not to write passes.
Chapters: Ch 12 -
[LLVM-WNPM] Writing an LLVM Pass (new pass manager). LLVM 23.1.2. link
Why and when: Core reading. The mechanics of a pass: run(), PreservedAnalyses, required passes, and registering a plugin. Read before exercise E1.
Chapters: Ch 12 -
[MENHIR-Manual] Menhir reference manual. Menhir 20231231. link
Why and when: Construction modes (--lalr, default Pager, --canonical), conflict explanations, and the .messages workflow (--list-errors, --compile-errors, --compare-errors) of Lesson 3.7.
Chapters: Ch 3 -
[MIR-LangRef] Machine IR (MIR) Format Reference Manual. LLVM 23.1.2. link
Why and when: The textual MIR that every -stop-after box and the labs/ch21-mir tasks print. Keep it open during exercise E5.
Chapters: Ch 21 -
[MLIR-Conv] MLIR Dialect Conversion. LLVM 23.1.2. link
Why and when: Conversion targets, legality and rewrite patterns — the documentation of Algorithm 0.1.14.
Chapters: Ch 0 -
[MLIR-DFDOC] Writing DataFlow Analyses in MLIR. LLVM 23.1.2. link
Why and when: How MLIR's DataFlowSolver runs several sparse and dense analyses together; read after Lesson 14.6 to see Algorithm 14.6.2 as a reusable framework.
Chapters: Ch 14 -
[MLIR-LangRef] MLIR Language Reference (operations, regions, blocks and block arguments, dominance). LLVM 23.1.2. link
Why and when: The authoritative definition of MLIR blocks with arguments and of region dominance; read "High Level Structure", "Blocks" and "Regions" with Lessons 8.4 and 8.7.
Chapters: Ch 8 -
[MLIR-PM] MLIR Pass Infrastructure. LLVM 23.1.2. link
Why and when: Core reading. Operation passes, OpPassManager nesting, analysis management, dynamic pipelines, instrumentation and crash reproducers. Read after Lesson 12.1 §2 (Definition 12.1.14).
Chapters: Ch 12 -
[MLIR-Rationale] MLIR Rationale — "Block Arguments vs PHI nodes". LLVM 23.1.2. link
Why and when: Why MLIR chose block arguments ("representationally identical" to phis): no phis to skip at block tops, entry-block arguments replace function arguments, no atomically executing phi groups (it names the lost-copy problem), no long unordered predecessor lists. Lesson 16.5.
Chapters: Ch 16 -
[N1757] N1757: Right Angle Brackets (Revision 2). WG21 N1757 (2005). link
Why and when: Daveed Vandevoorde's C++11 proposal that makes the first non-nested>>in a template argument list two>tokens (Algorithm 1.7.9); the wording is now [temp.names]. Read after Lesson 1.7.
Chapters: Ch 1 -
[P1949] P1949R7: C++ Identifier Syntax using Unicode Standard Annex 31. WG21 P1949R7 (2021). link
Why and when: Why C++23 adopted XID_Start/XID_Continue and requires identifiers in NFC (Lesson 1.9 §1 and §6). Read the motivation section.
Chapters: Ch 1 -
[PE-COFF] PE Format (Microsoft Portable Executable and Common Object File Format). link
Why and when: COFF sections, symbols and the x64 relocation types (IMAGE_REL_AMD64_REL32, ADDR32NB) seen in Lesson 21.10's object box. Read "COFF Relocations" after §3.
Chapters: Ch 21 -
[PEP227] PEP 227 – Statically Nested Scopes. link
Why and when: The design document of Python's LEGB rule and of why a name assigned anywhere in a function is local throughout it (UnboundLocalError). Read after Lesson 5.1 §2.
Chapters: Ch 5 -
[PEP617] PEP 617: New PEG parser for CPython. Python 3.9. link
Why and when: Why CPython left its LL(1) pgen parser for PEG: the LL(1) restriction forced grammar hacks. Read "Background on LL(1) parsers" after Lesson 2.3; it is the best real-world account of LL(1)'s limits.
Chapters: Ch 2, Ch 4 -
[Polly-Docs] Polly — The Architecture. LLVM 23.1.2. link
Why and when: Where Polly sits in the pipeline and how SCoPs are detected, optimized and code-generated; Lesson 18.7 §7 relies on it because Polly is not in this course's LLVM build.
Chapters: Ch 18 -
[POLONIUS] The Polonius book (rules/loans.md, rules/relations.md). link
Why and when: The borrow check restated in Datalog over origins and loans; the naive rules R1–R8 are quoted in Lesson 6.8 §6. Readrules/loans.mdafter Algorithm 6.8.8 and compare "origins contain loans" with NLL's "regions contain points".
Chapters: Ch 6 -
[PY-Lexical] The Python Language Reference: 2. Lexical analysis. Python 3.13. link
Why and when: §2.1.8 defines INDENT/DEDENT with an indentation stack (Algorithm 1.7.10) and §2.3 NFKC identifiers (Lesson 1.9). Read those two sections after Lesson 1.7.
Chapters: Ch 1 -
[RA-SyntaxDoc] rust-analyzer: syntax trees (green nodes, red nodes, trivia, interning). rust-analyzer 2026-09-21. link
Why and when: The design notes of rust-analyzer's red–green trees, with the alternatives (trivia on tokens, Roslyn, Swift). Read after Lesson 4.7 §2; the lesson checks one of its claims.
Chapters: Ch 4 -
[RE2C-Manual] re2c user manual (C back end). re2c 3.1. link
Why and when: re2c's syntax, conditions, direct-code generation options (--case-ranges), and the--dfa-minimizationoption shown in Lesson 1.4. Read with Lessons 1.4–1.5.
Chapters: Ch 1 -
[RFC1023] Rust RFC 1023: Rebalancing coherence. link
Why and when: Rust's orphan rules and the reasoning for global coherence across crates (Lesson 7.7 §1, Theorem 7.7.8). Read the motivation and the "orphan rules" section.
Chapters: Ch 7 -
[RFC1560] Rust RFC 1560: Name resolution changes (globs, shadowing, item-like imports). link
Why and when: The rules Lesson 5.3 §2 summarizes: explicit imports shadow globs and two globs conflict only when the name is used. Read after Lesson 5.3.
Chapters: Ch 5 -
[RFC2094] Rust RFC 2094: Non-lexical lifetimes. link
Why and when: Core reading. Lifetimes as sets of CFG points computed by liveness and outlives constraints (a fixed point), then loans in scope as forward dataflow: Lesson 6.8's Algorithm 6.8.8. Read "Problem case #1–#4" first, then "Layer 1" and "Layer 5".
Chapters: Ch 6 -
[RFC2451] Rust RFC 2451: Re-rebalancing coherence. link
Why and when: The current orphan rule with "uncovered type parameters" quoted in rustc's E0117 note (Lesson 7.7 §7). Read after RFC 1023.
Chapters: Ch 7 -
[RFC3629] RFC 3629: UTF-8, a transformation format of ISO 10646. November 2003. link
Why and when: The IETF definition of UTF-8 restricted to U+10FFFF, with the security considerations (overlong forms) behind Lesson 1.9's strict decoder. Short; read §3–4 and §10.
Chapters: Ch 1 -
[ROSLYN-Overview] .NET Compiler Platform (Roslyn) Overview — immutable syntax trees and compilations. dotnet/roslyn commit e0882714833e0943485161b1a01d52e835baf3eb. link
Why and when: Roslyn's compiler-as-API design: immutable, snapshot-based syntax trees and compilations that share unchanged parts between versions (red-green trees; Lesson 0.1 §6).
Chapters: Ch 0, Ch 5 -
[RUST-MIR] Rust Compiler Development Guide: The MIR (Mid-level IR). rustc 1.94 era. link
Why and when: MIR's locals, places, statements, terminators and how to dump it; read with Lesson 9.8's MIR box and compare theassertterminators with PIR's.
Chapters: Ch 9 -
[RUST-RefMBE] The Rust Reference: macros by example (fragment specifiers, forwarding, hygiene). reference@52ffdc0 (September 2026). link
Why and when: The specification of fragment specifiers, opaque forwarding and mixed-site hygiene used in Lesson 4.8. Read "Hygiene" and "Follow-set ambiguity restrictions".
Chapters: Ch 4 -
[RUSTC-DevDiag] rustc dev guide: Errors and lints (diagnostic structure, suggestions, applicability). link
Why and when: Multi-span labels, notes and machine-applicable suggestions as rustc defines them. Read after Lesson 5.8 §2 and compare with Definition 5.8.1.
Chapters: Ch 5 -
[RUSTC-DevGuide] Rust Compiler Development Guide: Type inference. link
Why and when: How rustc's inference context, snapshots and variable kinds fit together (Lesson 7.6).
Chapters: Ch 7 -
[RUSTC-DevGuide-Typeck] rustc dev guide: Type checking (hir-typeck) and MIR borrow check. link
Why and when: How rustc's checker is organized (expectations, coercions, inference variables resolved at the end of each body) and, in the "MIR borrow check" chapter, how NLL runs on MIR. Read after Lessons 6.4 and 6.8.
Chapters: Ch 6 -
[RUSTC-DevIncr] rustc dev guide: Incremental compilation in detail. link
Why and when: The red–green algorithm,try_mark_greenand fingerprint-based early cutoff described by the rustc team. Read after Lesson 5.6 §4.
Chapters: Ch 5 -
[RUSTC-DevQueries] rustc dev guide: Queries — demand-driven compilation. link
Why and when: How rustc is organized as queries with memoized results and providers. Read before Algorithm 5.6.4 in Lesson 5.6.
Chapters: Ch 5 -
[Rustc-Guide] Rust Compiler Development Guide — the MIR, THIR and HIR chapters. link
Why and when: rustc's IR pipeline explained by its developers: HIR (desugaring), THIR (typed tree) and MIR (CFG of locals and places). Read the MIR overview after Lesson 8.7's MIR box.
Chapters: Ch 8 -
[RUSTC-Query] rustc dev guide: Queries — demand-driven compilation; Incremental compilation (red-green algorithm). link
Why and when: How rustc is organized as queries and how the red-green algorithm decides what to reuse (Algorithm 0.1.12). Read both pages after Lesson 0.1's query section.
Chapters: Ch 0 -
[Salsa] Salsa — a generic framework for on-demand, incrementalized computation. link
Why and when: The query engine of rust-analyzer: tracked functions, revisions, durability, early cutoff. The overview chapter of its book is a compact second explanation of Algorithm 0.1.12.
Chapters: Ch 0 -
[SALSA] The salsa book (incremental recomputation for rust-analyzer). salsa 0.23. link
Why and when: Inputs, tracked functions, revisions and durability: the red–green algorithm as a library. Read "Overview" and "The red-green algorithm" after Lesson 5.6 §4.
Chapters: Ch 5 -
[SE0176] Swift Evolution SE-0176: Enforce Exclusive Access to Memory. link
Why and when: The Law of Exclusivity (no overlapping accesses unless both are reads), enforced statically for locals and inout arguments and dynamically for class properties, globals and escaping captures. Read "Proposed solution" with Lesson 6.8's exclusivity section; it is the model for Pebble's rule E0414.
Chapters: Ch 6 -
[SE0326] Swift Evolution SE-0326: Enable multi-statement closure parameter/result type inference. link
Why and when: How Swift widened its inference scope to closure bodies without letting constraint systems grow (Lesson 7.5 §6).
Chapters: Ch 7 -
[SE0382] Swift Evolution SE-0382: Expression macros. swift-evolution@cf74276. link
Why and when: Swift's macros: syntax-tree in, syntax-tree out, type-checked arguments, and the explicit statement that they are not hygienic (makeUniqueNameinstead). Read after Lesson 4.8 §6.
Chapters: Ch 4 -
[SOUFFLE-DOC] Soufflé: project README and language documentation. Soufflé 2.5. link
Why and when: Installation (release packages) and the language; the Datalog dialect of Lesson 14.8's boxes. Read before running the Soufflé boxes.
Chapters: Ch 14, Ch 19 -
[Swift-ARCOpt] ARC Optimization in Swift (docs/ARCOptimization.md). Swift 6.1. link
Why and when: Core reading. Swift's own account of retain/release semantics, owned vs guaranteed conventions, and the optimizer's pairing and code-motion rules. Read "Reference Counting" and "ARC Sequence Optimization" after Algorithm 24.5.3.
Chapters: Ch 24 -
[SWIFT-DI] The Swift Programming Language: Initialization (two-phase initialization and safety checks). link
Why and when: The user-facing rules that Swift's definite-initialization pass enforces: every stored property set beforeselfis used. Read after Lesson 5.7 §1; the implementation is [SWIFT-DIsrc].
Chapters: Ch 5 -
[SWIFT-Error] Swift error handling rationale. swift-6.1-RELEASE. link
Why and when: Why Swift chose explicit error returns in a register over table-driven unwinding; the design argument behind Lesson 11.7's third technique.
Chapters: Ch 11 -
[Swift-Ownership] Swift Ownership Manifesto (docs/OwnershipManifesto.md). Swift 6.1. link
Why and when: Why a reference-counted language adds ownership (moves, borrows, non-copyable types) on top of ARC: the design space between Lesson 24.5's first and third technique.
Chapters: Ch 24 -
[SWIFT-Req] Swift Request-Evaluator (docs/RequestEvaluator.md). swift-6.1-RELEASE. link
Why and when: Swift's incremental adoption of demand-driven requests with cycle detection inside a traditional compiler (Lesson 0.1 §6); implemented byclass Evaluatorin include/swift/AST/Evaluator.h.
Chapters: Ch 0 -
[SWIFT-RequestEvaluator] Swift's request evaluator design. swift-6.1-RELEASE. link
Why and when: Requests as memoized, cycle-checked queries: the architecture of Lesson 5.6 §4 in Swift. Read before [SWIFT-Evaluator].
Chapters: Ch 5 -
[SWIFT-SIL] Swift Intermediate Language (SIL) specification, docs/SIL/SIL.md. Swift 6.2. link
Why and when: SIL's values, types, ownership and basic block arguments ("This corresponds to LLVM's phi nodes"), quoted in Lesson 9.8. Read the "Basic Blocks" and "Values and Operands" sections after Lesson 9.8.
Chapters: Ch 9 -
[SWIFT-TypeChecker] Swift's type checker design (constraints, overload sets, solution ranking). swift-6.1-RELEASE. link
Why and when: How Swift resolves overloads inside a constraint solver and ranks complete solutions. Read the overview and "Comparing Solutions" after Lesson 5.4 §6.
Chapters: Ch 5 -
[SWIFT-TypeCheckerDoc] Swift Type Checker Design and Implementation (docs/TypeChecker.md). Swift 6.3.3 (swift-6.3.3-RELEASE). link
Why and when: The design document of Swift's constraint-based checker: constraint kinds, disjunctions, solution ranking and default literal types (Lesson 7.5). Read "Approach", "Constraints" and "Constraint Solving".
Chapters: Ch 7 -
[SysV-ABI] System V Application Binary Interface, AMD64 Architecture Processor Supplement. link
Why and when: Defines the x86-64 relocation types, the calling convention and the PLT/GOT layout used in Lesson 0.6 §3. The "Relocation Types" table of the Object Files chapter (x86-64-ABI/object-files.tex) gives R_X86_64_PC32 = S + A − P and R_X86_64_PLT32 = L + A − P, where L is the PLT entry — S itself when the symbol is defined in the output.
Chapters: Ch 0, Ch 11, Ch 21 -
[TCC-Doc] Tiny C Compiler Reference Documentation (tcc-doc.texi), "Parser" section. tcc 0.9.27. link
Why and when: "The parser is hardcoded … It does only one pass, except" for two cases — the primary source for TCC's single-pass design (Lesson 0.1).
Chapters: Ch 0 -
[TR-Guide] The Typed Racket Guide: Occurrence Typing. link
Why and when: Occurrence typing as programmers meet it: predicates such asnumber?refine the type of a variable in the branches of anif. Read with Lesson 6.6 §2 before [THF08].
Chapters: Ch 6 -
[TS-Compat] TypeScript Handbook: Type Compatibility (A Note on Soundness). TypeScript 5.9. link
Why and when: TypeScript's own list of places where the type system is intentionally unsound (method parameter bivariance, array covariance, optional parameters). Read with Lesson 6.2 §4.
Chapters: Ch 6 -
[TS-docs] tree-sitter documentation: creating parsers (precedence, conflicts, dynamic precedence). tree-sitter 0.27. link
Why and when: The grammar DSL used in Lesson 3.6's box: prec.left/right, prec.dynamic and the conflicts field that turns on GLR forking.
Chapters: Ch 3 -
[TS-Handbook] TypeScript Handbook and compiler options (target, downlevel emit). link
Why and when: What--targetdoes: which constructs are erased and which are downleveled — the transpiler box of Lesson 0.3.
Chapters: Ch 0, Ch 7 -
[TS-Narrowing] TypeScript Handbook: Narrowing. TypeScript 5.9. link
Why and when: Every narrowing form TypeScript supports (typeof, truthiness, equality,in,instanceof, assignments, discriminated unions,never), with the control-flow analysis explained informally. Read alongside Lesson 6.6 §7; the drillnarrowingcovers the typeof/equality/assignment subset.
Chapters: Ch 6 -
[Turnt] Turnt: a simple expect-style testing tool. Turnt 1.12.0. link
Why and when: Cornell's snapshot tester (turnt.toml, --save, --diff), used by the Bril course infrastructure; the tool of Lesson 12.5's first box.
Chapters: Ch 12 -
[UAX15] Unicode Standard Annex #15: Unicode Normalization Forms. Unicode 16.0. link
Why and when: NFC, NFD, NFKC, NFKD and the stream-safe text format (Definition 1.9.6, Lesson 1.9 §5). Read §1–3; the rest covers implementation details.
Chapters: Ch 1 -
[UAX31] Unicode Standard Annex #31: Unicode Identifiers and Syntax. Unicode 16.0. link
Why and when: Core reading. Default identifier syntax (XID_Start / XID_Continue), profiles, stability and NFKC closure (Definition 1.9.5, Proposition 1.9.13). Read §2 and §5 after Lesson 1.9.
Chapters: Ch 1 -
[Unicode16] The Unicode Standard, Version 16.0: Core Specification. Unicode 16.0. link
Why and when: §3.9 defines well-formed UTF-8 (Table 3-7, Definition 1.9.3) and the U+FFFD substitution of maximal subparts (Definition 1.9.4) that Pebble's lexer follows. Read §3.9 only.
Chapters: Ch 1 -
[Wasm-EH] WebAssembly Exception Handling proposal — Exceptions.md. proposal repository, main branch (2023 legacy and 2024 exnref forms). link
Why and when: Core reading. The instructions (try,catch,catch_all,delegate,rethrow,throw) and their semantics; the "Changes to the text format" section shows the nesting the assembly in Lesson 24.6 §7 uses.
Chapters: Ch 24 -
[WASM-SPEC] WebAssembly Core Specification. WebAssembly 2.0. link
Why and when: The formal definition of Wasm's structured control, validation (the appendix "Validation Algorithm" is Proposition 9.8.13's algorithm) and execution. Read the control-instruction and validation sections after Lesson 9.8.
Chapters: Ch 9 -
[WasmSpec] WebAssembly Core Specification — Validation (instructions) and the validation algorithm appendix. Release 2.0. link
Why and when: The typing rules of every instruction and the appendix's one-pass validation algorithm with an operand stack and a control stack: typed height consistency (Lesson 8.1).
Chapters: Ch 8
Talks and videos¶
-
[Bru18] Max Brunsfeld. Tree-sitter: a new parsing system for programming tools. Strange Loop 2018, 2018. link
Why and when: tree-sitter's author on incremental GLR parsing, error recovery and its use in editors (Lesson 4.6 §1). Watch after Lesson 4.6.
Chapters: Ch 4 -
[Car14] Chandler Carruth. Efficiency with Algorithms, Performance with Data Structures. CppCon 2014, 2014. link
Why and when: The argument, from an LLVM developer, that cache misses from node-based containers dominate, and why LLVM uses flat vectors, open addressing and small-size optimization. Watch before Lesson 10.6 (slides in the linked CppCon repository; the video is on YouTube).
Chapters: Ch 10 -
[DD18] Andrea Di Biagio and Matt Davis. Understanding the Performance of Code Using LLVM's Machine Code Analyzer (llvm-mca). 2018 LLVM Developers' Meeting, 2018. link
Why and when: The authors ofllvm-mcawalk through its pipeline (dispatch, scheduler, retire) and its views. Watch it before reading thellvm-mcaboxes of Lesson 23.1 §7.
Chapters: Ch 23 -
[Fal23b] Chris Fallin. ægraphs: Acyclic E-graphs for Efficient Optimization in a Production Compiler. EGRAPHS 2023 (PLDI 2023 workshop), invited talk, 2023. link
Why and when: How Cranelift's mid-end became an acyclic e-graph with elaboration back to a CFG, the design behind Lesson 21.7's aegraph box. Slides; a recorded video is linked from the PLDI 2023 program and on Vimeo.
Chapters: Ch 21 -
[Ham16] Lang Hames. ORC -- LLVM's Next Generation of JIT API. 2016 LLVM Developers' Meeting, 2016. link
Why and when: The introduction of ORC by its author: layers, lazy compilation and why MCJIT was replaced. Watch after Lesson 10.8 §2; some API names predate ORCv2.
Chapters: Ch 10 -
[Ham18] Lang Hames and Breckin Loggins. Updating ORC JIT for Concurrency. 2018 LLVM Developers' Meeting (tutorial), 2018. link
Why and when: The ORCv2 redesign behind LLJIT: ExecutionSession, JITDylibs, symbol states and ThreadSafeModule (Lesson 10.8, Proposition 10.8.9). Watch before reading ORCv2.rst.
Chapters: Ch 10 -
[Kud17] Jakub Kuderski. Dominator Trees and incremental updates that transcend time. 2017 LLVM Developers' Meeting, San Jose, 2017. link
Why and when: The author of LLVM's incremental updater explains why hand-written updates kept breaking, how DBS and the Semi-NCA subtree rebuild replaced them, and how batched updates (applyUpdates) work; theDomTreeUpdaterwrapper came a year later (2018). Slides at the URL; the video is on the LLVM YouTube channel. Watch after Lesson 15.2 §7 (extra reading, not an origin).
Chapters: Ch 15 -
[LoopTut19] Kit Barton, Ettore Tiotto, Hal Finkel, Michael Kruse, and Johannes Doerfert. Writing Loop Optimizations in LLVM (tutorial). 2019 LLVM Developers' Meeting, San Jose, 2019. link
Why and when: Walks through LoopInfo, loop-simplify form, LCSSA and rotation as a pass writer sees them; watch before Ch 18, after Lesson 15.7 (extra reading).
Chapters: Ch 15
Blog posts and articles¶
-
[Cox07] Russ Cox. Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby, ...). 2007. link
Why and when: The article that popularized the difference between backtracking and Thompson's simulation, with graphs of (a?)^n a^n. Read after Lesson 1.2 §5; not an origin (that is [Tho68]).
Chapters: Ch 1 -
[Cox09] Russ Cox. Regular Expression Matching: the Virtual Machine Approach. 2009. link
Why and when: The Pike VM with submatch threads, the instruction-list form of Thompson's construction used by the lab (Program.cpp). Read before implementing Lab L2.
Chapters: Ch 1 -
[Cox10] Russ Cox. Regular Expression Matching in the Wild. 2010. link
Why and when: How RE2 combines the lazy DFA, the Pike VM, one-pass NFAs and bit-state backtracking. Read after Lesson 1.2 §7 for the engineering behind the lazy DFA.
Chapters: Ch 1 -
[Fal23] Chris Fallin. Cranelift's Instruction Selector DSL, ISLE: Term-Rewriting Made Practical. 2023. link
Why and when: Why Cranelift replaced handwritten lowering with ISLE, and how rules, priorities and the trie compiler work. Read before Lesson 21.7 §2.
Chapters: Ch 21 -
[Hoe10] Björn Höhrmann. Flexible and Economical UTF-8 Decoder. 2010. link
Why and when: A table-driven DFA for UTF-8 validation and decoding (Lesson 1.9 §6): Table 3-7 compiled into a 9-state automaton over byte classes. A good exercise in applying Lesson 1.2 to bytes.
Chapters: Ch 1 -
[Kis13] Oleg Kiselyov. How OCaml type checker works — or what polymorphism and garbage collection have in common. 2013. link
Why and when: A readable walk-through of level-based generalization in OCaml'sctype.ml, from the naive algorithm to levels and lazy level adjustment. Read after Lesson 7.3 §3 (not an origin: cite [Rem92] for that).
Chapters: Ch 7 -
[Kla20] Aleksey Kladov. Simple but powerful Pratt parsing. 2020. link
Why and when: Pratt parsing with pairs of binding powers, the convention of Definition 4.1.7 and of rust-analyzer'sexpr_bp. Read after Lesson 4.1 §2; the code is 100 lines of Rust.
Chapters: Ch 4 -
[Kla23] Aleksey Kladov. Resilient LL parsing tutorial. 2023. link
Why and when: Core reading. The design of rust-analyzer's resilient parser explained from scratch, with runnable code: the source of Algorithm 4.6.3. Read it after Lesson 4.6 §2, before exercise E6.
Chapters: Ch 4 -
[Mer25] Darius Mercadier. Land ahoy: leaving the Sea of Nodes. V8 blog, 2025. link
Why and when: Why V8 replaced TurboFan's sea of nodes with the CFG-based Turboshaft: effect chains that mirror control, hard scheduling, poor cache behavior; compile time divided by 2 and up to 190× faster load elimination. The source of Lesson 8.5's "why V8 left" discussion (not the origin of any technique).
Chapters: Ch 8 -
[MR25] Fangrui Song. LLVM integrated assembler: Engineering better fragments. 2025. link
Why and when: A tour of the recent rework of MC fragments (fixed contents plus a variable tail) and relaxation by the engineer who did much of it. Read after Lesson 21.10 §7.
Chapters: Ch 21 -
[Nor99] Theodore S. Norvell. Parsing expressions by recursive descent. 1999. link
Why and when: The survey that named "precedence climbing" and compares it with the classic and shunting-yard solutions; a good second explanation after Lesson 4.1 §1.
Chapters: Ch 4 -
[Ole11] Jakob Stoklund Olesen. Greedy Register Allocation in LLVM 3.0. 2011. link
Why and when: Core reading. The design rationale of greedy by its author: why not linear scan, the priority queue, eviction, live-range splitting and its measurements. Read before Lesson 22.8; the slides of his 2011 LLVM Developers' Meeting talk (llvm.org/devmtg/2011-11) add pictures of splitting.
Chapters: Ch 22 -
[Piz25] Filip Pizlo. Pizlo SSA Form (short version). 2025. link
Why and when: The author of B3 explains Phi/Upsilon form: every phi has a shadow variable that Upsilons assign, so blocks know nothing about SSA. Extra reading for Lesson 16.5 (the design itself dates from B3, 2015; see [WebKit-B3]).
Chapters: Ch 16 -
[Pop24] Nikita Popov. This year in LLVM (2023). 2024. link
Why and when: Extra reading by the LLVM maintainer who drove the opaque-pointer migration and the move toward getelementptr i8 / ptradd: why typed GEPs obstruct canonicalization and what the byte-offset form buys. Read after Lesson 9.4 §6.
Note: Unverified: the URL could not be opened from the authoring or the review environment (the site is blocked there), so neither the link nor the summary of its content below has been checked against the post; the blog's index is www.npopov.com. The LLVM 19 release notes (nusw/nuw GEP flags) and the InstCombine source [LLVM-InstCombine] are the verified references for the same facts.
Chapters: Ch 9 -
[V8-Ignition] Ross McIlroy. Firing up the Ignition interpreter. 2016. link
Why and when: Why V8 introduced a register-based bytecode interpreter with an accumulator, and how its handlers are generated — the design behind Lesson 0.2's--print-bytecodebox.
Chapters: Ch 0, Ch 8 -
[V8-Maglev] Toon Verwaest, Leszek Swirski, Victor Gomes, Olivier Flückiger, Darius Mercadier, and Camillo Bruni. Maglev — V8's Fastest Optimizing JIT. 2023. link
Why and when: The mid tier introduced in Chrome M117, between Sparkplug and TurboFan; explains why a fast optimizing tier pays off (Lesson 0.3 §6).
Chapters: Ch 0 -
[V8-Sparkplug] Leszek Swirski. Sparkplug — a non-optimizing JavaScript compiler. 2021. link
Why and when: V8's baseline tier: compiles Ignition bytecode to machine code in one linear pass, reusing the interpreter's frame layout. Read with Lesson 0.3's tiering box.
Chapters: Ch 0