In 30 seconds
By 2019, iPhone apps, Google production servers, PlayStation games, and even Sony's movie-effects pipeline were compiling through infrastructure that began as a small University of Illinois project. Chris Lattner tells Lex Fridman that LLVM's real achievement was not new algorithms but a modular design rivals could share, because rebuilding a compiler is too expensive and compiler engineers are too scarce. The same layering instinct then shows up in Clang, Swift, Swift for TensorFlow, bfloat16 on Google's TPUs, and MLIR.
- 1Harsh commercial rivals collaborate on LLVM because rebuilding it in-house is too expensive, and compiler talent is even harder to hire than the money.
- 2Lattner keeps returning to the same claim: the hard part of compilers is software engineering, not inventing algorithms. Most of what LLVM implements was already in the textbooks.
- 3Objective-C cannot be patched into memory safety, because its object system sits on C pointers. Drop the pointers and it is no longer Objective-C.
- 4Swift's `import numpy` looks like one line. Underneath it is about 1,200 lines of Swift plus two new language features—dynamic member lookup and dynamic calls—that took a year to land.
- 5When automatic differentiation lives in the language, you can reuse decades of Fortran source-to-source AD techniques that need to see a whole function, not one operator at a time.
- 6bfloat16 keeps float32's exponent range and spends fewer bits on the mantissa, which matches training's tiny gradients and large magnitudes—and silicon multipliers get cheaper, because area scales with the square of mantissa bits.
Read the full transcript by chapter
He learned computers by typing the book wrong
Fridman starts where these interviews often start: the first program. Lattner says he began as a kid after his parents bought a BASIC book. He typed programs out of the book, watched them work, typed them in wrong, and then stared at the screen until he understood why they failed. There is no conversion story in the memory. There is only the loop of input, breakage, and debugging.
The languages stacked in a Microsoft line: BASIC, then GW-BASIC, QBasic, and QuickBasic, each a slightly fancier dialect of the same family. From there he jumped to Pascal, wrote a lot of assembly, and only later arrived at C++. Smalltalk showed up somewhere along the way, but it was not the starting point. Fridman jokes that he took the dark path into the machine instead of the Lisp route—higher-level, more philosophical, more hippie.
The move to C happened in high school, because Pascal could not do enough and he wanted a different world. Pointers and C syntax confused him at first. Pascal already forced you to allocate and own memory, but it also gave you a string type, so you could think about a string instead of an array of characters laid out consecutively. C made layout impossible to ignore. Almost everything he later built lives on that layer.
A compiler is a bridge between two exploding messes
Lattner's definition of a compiler is deliberately plain. On one side are humans who will not write binary and do not want to rethink every chip. On the other side are machines, and there are more kinds of them every year: x86, ARM, GPUs, and now accelerators built for machine learning. The art, he says, is letting people think at the abstraction they actually want, then getting the thing they wrote to run on a specific piece of hardware.
Languages multiply at the same time. C, JavaScript, Python, and Swift are all trying to capture programmer intent so other humans can maintain it, not just so a machine can execute it. Compilers therefore run in phases: a language-specific front end, a shared optimizer, and a hardware-specific back end. The reason is software engineering. These systems are huge, and nobody wants to rewrite the middle for every language and every chip.
LLVM's bet is to standardize that middle and that back end. Swift, Rust, Julia, and Clang's C, C++, and Objective-C look wildly different at the surface—JavaScript's idea of false is not C's—but they can share one optimizer and one code generator. LLVM is not a paper specification. It is a pile of reusable code, a platform you build a concrete compiler on, and a community of hundreds.
The strange part is commercial. Google and Apple commit to the same infrastructure. So do AMD and Intel, and NVIDIA and AMD on the graphics side. They do not do it from kindness. A production compiler is expensive, and the skill set is scarce. Even a large company, Lattner argues, does not really want to implement the whole thing alone.
He only meant to stay a year and accidentally built the stack
LLVM began as a university project at the University of Illinois: Lattner, his advisor, and two or three research students. After graduating he joined Apple, which put it into products—first the OpenGL stack, later the C compiler, then Clang, then Swift. Google later invested so heavily in C++ tooling that, in his telling, it effectively owns Clang. NVIDIA uses Clang and LLVM for CUDA.
He was not aiming at a twenty-year empire. He went to Illinois for a one-year non-thesis master's and a return to industry. He got nerd-sniped into staying five years because the work was fun: hard software engineering, plus learning to collaborate with version control on a real team. At the time of the interview LLVM was about nineteen years old, already older than GCC had been when LLVM started.
The pull toward compilers came from an undergraduate professor at a tiny school—seven or nine computer-science students, on the side of the math department—who taught the compilers course as the class that stitches algorithms and data structures into one semester-long codebase. You have to live with your own decisions instead of abandoning a half-finished project for a B. That professor pushed him toward graduate school even though he did not want to be an academic.
He is not primarily a math person, so the formal theory of parsing was not the hook. Early LLVM was implementing standard algorithms that already lived in advanced compiler curricula. Building them, reading about them, and setting the next goal was the fun. The research contribution, as he describes it, was construction rather than a new theorem.
A for-loop has to stop looking like a for-loop
Asked why turning C++ into machine code is hard, Lattner starts with the language itself: something like a 400-page spec, plus syntax, semantics, and decades of history piled on C. Subsystems interact in ways nobody fully holds in their head. Clang's bet against GCC was not only correctness. GCC had become the industry standard, but it was full of global variables and hard to reuse for research or for tools it had never been designed to support.
Clang wanted better error messages, faster compile times, and classes of tools GCC never supported—refactoring and static analysis. That means keeping extra information without destroying compile speed. The front end still has to build syntax trees, check every rule in the spec, and turn failures into messages a human can actually use.
Then comes lowering. After parsing, the program is an abstract syntax tree: a plus node with two children, a call node with a callee and arguments. LLVM's intermediate representation is a control-flow graph. Operations become simple instructions—add these, multiply those, maybe a call—lined up in basic blocks, with branches between blocks instead of nested trees. LLVM can run on the order of 150 passes over that form.
A C `for` is the example that makes the shape change obvious. In the AST it is one node with pointers to the initializer, the condition, the increment, and the body. In the CFG you get a block for code before the loop, a block for the body and increment, a branch back to the top, and a compare-and-branch out. It looks more like assembly, which is the point: language-specific mess can stay in the front end so the middle is shareable.
A compiler rewrites one graph many times; a network keeps changing the graph
Fridman hears neural-network graphs in the description. Lattner says the ideas rhyme and the details do not. Networks learn representations at different depths and transform from one layer's representation to the next. Compilers keep relatively few representations and apply many transformations to the same one, often iteratively, until the code is closer to what the machine wants.
The passes are familiar if you have ever optimized a loop: hoist invariant expressions so they run fewer times, delete redundant work, fold constants, turn `2 * x` into a left shift. Compilers also run analyses that recover higher-level properties for later passes. If a representation is used once, it is probably an intermediate. If it is rewritten for dozens of rounds, it is the foundation.
Register allocation is the optimization that makes the rest matter
Asked for the biggest bang, Lattner goes to register allocation, a problem that was already central in the 1980s. Memory is slow, registers are fast, and there are not many of them—x86 in some modes has sixteen. Source code invents dozens of temporaries, often inside a loop that may run millions of times. Getting that mapping right is still one of the compiler's hardest jobs.
If that inner loop loads and stores, it is slow. If every live value fits in registers, it can be an order of magnitude faster. The compiler does not see the programmer's `x`. It sees several values, each with a lifetime across the function, each of which might live in a register, spill to memory, or be recomputed instead of reloaded. The program becomes a graph with a time dimension, and physical resources have to be assigned along it.
RISC pipelines made the next classic problem: instruction scheduling. The processor can do more than one thing at once only if the compiler orders instructions so the pipeline stays full instead of stalling. The constraints—latencies, dependencies, execution ports—are messy. The algorithms are decades old and full of handwritten heuristics and magic numbers, which Lattner flags as a research opening for machine learning, usually on small spaces such as generating a matrix multiply for a GPU.
The algorithms were in the textbook; the win was getting rivals to share them
Lattner does not claim LLVM's fame is a pile of novel compiler results. It has strong implementations of important algorithms, and smart people worked on it. The profound part, he says, is standardization: it made work possible that would not have happened otherwise. Java had already changed the industry in the mid-1990s by making JIT compilation, garbage collection, and memory-safe portable code mainstream; LLVM's contribution was a shared substrate underneath many languages and chips.
Sony picked up LLVM for graphics compilation in its movie-production pipeline, which he says lets them ship better special effects. That was not the design target. He treats unexpected reuse as the test of infrastructure: good layering and composability. GCC, he argues, is excellent as a C or Fortran compiler and weaker as a platform you can retarget, partly because replacing a subsystem was never the original design.
Clang and LLVM compile iPhone apps and the OS, Google's production servers, GameCube titles, and PlayStation 4 games. Versus GCC on Linux, he says they are close enough that it barely matters. The hard problem, in his experience, is engineering: hundreds of people doing detailed low-level work without the codebase collapsing. Linux distributions stayed on GCC for a mix of technical and social reasons, not because LLVM had failed to catch up.
Modularity was the original goal. He wrote a register allocator; someone smarter pulled it out and replaced it, which he counts as success. Community scale uses code owners—often hardware vendors for their backends—who need not review every patch but must make sure reviews and architecture happen. He is still nominally at the top of that stack, mostly mediating technical fights. The LLVM Foundation, then six or seven years old, handles money and events and stays out of technical direction.
Clang began as a secret C compiler written after hours
Lattner joined Apple in 2005 to make LLVM production-ready, landing in the Intel transition, the 64-bit transition, and the iPhone's move to ARM, where a modular back end paid off. The programmer-facing side was still weak. If you were pounding out Objective-C, the error messages, compile times, and IDE tooling were not as good as they could be.
So he started a C compiler on nights and weekends, promising nobody. The preprocessor—trigraphs and other historical residue—was both hated and central to compile-time pain. The realization was a gap many people never cross: this is not impossible, it is merely hard. He told his manager; the manager's response was that they did need to solve the problem, and that he could have one more person.
The goals were pragmatic: better diagnostics, faster compiles, and refactoring and analysis GCC never had. C++ was the brutal piece. People assume it is impossible to implement; Lattner says it is very nearly impossible. The only path is incremental construction plus hiring engineers who actually know the subsystems—templates, exception tables, ABI compatibility—because no one person knows all of it.
Swift's real fight was a room that loved Objective-C
After the first version of C++ support in Clang, he started another night project: Swift. Implementing C++ makes you think there has to be something better. He prototyped in spare time, then talked with Bertrand Serlet, then Apple's senior vice president of software and a language person, who encouraged the early design. Only later did he tell his manager and a wider circle.
The remaining obstacle was social. The internal story of the iPhone's success was that it succeeded because of Objective-C. Apple had hired people who loved the language; leadership often traced to NeXT, where Objective-C became real. They had grown up writing it. Proposing a new language was heretical. Lattner's read was different: the loudest voices loved Objective-C, and a quieter majority kept hitting sharp corners.
Why not just file off Objective-C's edges? The answer that unlocked the project was memory safety. Objective-C's object system sits on C pointers; it is an extension of C. Pointers are unsafe. Remove them and it is not Objective-C anymore. You cannot patch that. Once the room accepted the foundation was unfixable, the work became a design problem: if we do something new, what should it be?
Some choices were forced by context. It would be a typed language, for performance and refactoring tools. It would be compiled: around 2010 the iPhone was still memory-constrained, and shipping standalone compiled code is part of Apple's value system. In the late 1990s Apple had seriously considered moving its development experience to Java. That was a different era, and a different set of constraints.
The first line of Swift has to run, and import numpy is a language feature
After enough years with LLVM, Lattner stopped treating compilation as static versus dynamic versus interpreted. It is a spectrum. Swift is statically compiled and also dynamically compiled; interpretation is possible even if nobody had done it yet. In Colab and Jupyter, each line goes through the Swift front end, optimizer, and code generator, then gets injected as machine code into a live Unix process, patching the process in place. That is not an accident of the implementation. The stack was layered for it.
The design principle he keeps citing is progressive disclosure of complexity, borrowed from UI. Lesson one is `print("hello world")`—one line, no `main`, no headers, no Java `public static void main`. Then variables, control flow, functions, classes, generics, modules. Each layer runs on its own. That is normal in Python and unusual in compiled languages, which usually demand declarations up front because the compiler needs types.
The language still has to serve two audiences: library authors who want to reach the metal, and users who only want to compose libraries. Interoperability with Python looks like magic from the outside. A dynamically typed language, Lattner says, can be described as having no types or as having one type: the Python object. Swift already has many types. Add `PythonObject`. `import numpy` returns a Python object—the module—and attribute access and calls become dynamic lookups into the Python interpreter.
The glue is about 1,200 lines of pure Swift on top of C interop, because talking to CPython is a C calling convention. Making those 1,200 lines writable required two Swift features—dynamic member lookup and dynamic calls—proposed, implemented, standardized, and landed over a year. Users see one import. What they are standing on is a language change. Python's machine-learning-driven language change, as far as he can recall, is the `@` matrix-multiply operator.
TensorFlow is a compiler, and bfloat16 is a bet on range over precision
Fridman asks how eager Python becomes a graph for GPUs and TPUs. Lattner, who says he is only tangentially involved in Autograph, describes it as a decorator that intercepts a function, parses it, and lowers ifs and multiplies into graph nodes—compiler technique applied to Python. Swift for TensorFlow is another front end onto the same graphs and runtime as Python, Go, Rust, and Julia. Python is the special case: almost all community effort, its own autodiff and APIs, and a ceiling set by what you can do as a library. Other languages are mostly wrappers around TensorFlow's C API, usually without automatic differentiation.
Swift is the third camp. TensorFlow, he argues, is fundamentally a compiler: it takes models and makes them fast on hardware, with a front end, an optimizer, and many back ends. Swift's premise is that you may change any layer of that stack, so you should re-ask the division of labor between programmer and compiler. A type system lets the compiler build graphs, cluster, fuse, and optimize without the user doing it by hand. Language-integrated automatic differentiation is a key contribution, because 1970s Fortran source-to-source tools need to see a whole function—something operator-at-a-time frameworks cannot give them.
Google was on its third-generation TPU: more than 100 petaflops in a large liquid-cooled box, and not out of ideas yet. Hardware takes years; algorithms move faster, so you bet transistors on the future. bfloat16 is the exhibit. It is 16-bit float with a smaller mantissa and a larger exponent, matching float32's range. Training needs tiny gradients that would underflow in IEEE half precision, and also large-magnitude values. Precision in the middle can slacken. Multiplier area and delay scale with the square of mantissa bits and only linearly with the exponent, so the format is cheaper in silicon. It began as a research trick for compressing weights on the network, then was burned into the chip.
Three weeks before the interview, Google announced MLIR, Multi-Level Intermediate Representation, at a compilers-for-machine-learning conference. TensorFlow embeds several vendor compilers: Google's XLA, NVIDIA's TensorRT, Intel's nGraph. They solve overlapping problems and all want to plug into TensorFlow. MLIR is common infrastructure so they can share code instead of reinventing the same machinery. People joke it is LLVM with the lessons of LLVM applied. Lattner agrees in spirit: LLVM is strong at what it was designed for, and twenty years later people are solving higher-level problems that need new technology.
He prefers Google's open source, respects Tesla's vision, and put a dragon on the slides
MLIR was not yet open source but would be; Lattner says he believes in that path. Asked to compare Apple and Google, he prefers Google's approach, with a fair caveat that Apple's habits are thirty-five years old and the company is adapting. A business should make money. What makes money is the differentiated product, not the string library. Keeping that library secret is no longer the layer that matters, even if it did fifteen years earlier. Open-sourcing TensorFlow, in his view, was a profound bet: he can imagine a company treating machine learning as a secret weapon and refusing to share. That decision changed the field and, he thinks, paid Google back.
Around that period he spent about five months at Tesla as vice president of Autopilot software, during the Hardware 1 to Hardware 2 cutover. Hardware 1 had been designed for simple automation—traffic-aware cruise and that class of feature—and the fact that Tesla feature-crept it into useful lane-keeping still impresses him. The hard job was moving from a third-party vision stack to an in-house one, under time pressure, while still using the Hardware 1 team's knowledge. The cultural fit was not there. He saw the highest turnover he had seen at any company. What he came to respect is Elon Musk's ability to attract talent with a concrete future people want to buy into. Plenty of people on a street corner can say they are going to Mars; few can make others believe it and build the path. He respects the vision. He does not respect all of the methods.
Working hard, he agrees, includes a lot of hours. The part that is actually hard is holding short-term delivery and long-term judgment at once. If you only finish the next task, you miss the hurdle you should have jumped. If you only architect three years out, you ship nothing. At Apple he could oscillate because he built teams and leadership that could take responsibility, which freed him to be "a little bit crazy" about the next thing. For himself—not a rule he projects onto the team—he wants to love the work, put in the hours, and treat changing the world as the point.
LLVM's logo is a dragon. The kind explanation is power, speed, intelligence, elegance, modularity. The real one is the Dragon Book, the classic compilers textbook. At Apple they needed a slide icon and had none; someone asked what logo a compiler should have, and he said a dragon was the best they had. Apple's designers made it, the community adopted it, later designers improved it. His wife, also a compiler engineer, runs the LLVM Foundation and hands out stickers at the Grace Hopper conference; *Game of Thrones* made the dragon cool, which occasionally helps recruit the next generation.
More from this channel
3:36:56EN
5:15:51EN
3:12:58EN
3:46:18EN
3:51:47EN
2:53:42EN