an intermediate representation
/ IR = 'eye-arr' /
When you translate a book from French to Japanese, you do not work letter by letter on the original; you first grasp the meaning, then express it in the new language. A compiler does something similar. Rather than going straight from source text to machine code, it first converts your program into its own internal form — neither the source language nor the target machine. That internal form is the intermediate representation, or IR.
An IR is a data structure, not text you usually write by hand, designed so the compiler can analyze and rewrite the program easily. It typically looks like a simplified, regular language: operations are broken into small uniform steps, control flow is made explicit as blocks and jumps, and many source conveniences (loops, complex expressions, overloading) are lowered into a handful of basic operations. Crucially the IR is language- and target-neutral. A C program and a Rust program can both be lowered into the same IR shape, and that one IR can later be turned into x86 or ARM code. Most real compilers use several IRs in sequence, starting high-level (close to the source) and gradually lowering to low-level (close to the machine).
It matters because the IR is the secret to compiler reuse: write N language front ends and M machine back ends and you get N times M compilers by sharing one IR and one optimizer in the middle, instead of writing a separate translator for every pair. It is also the thing the optimizer actually operates on — every optimization in this field is a rewrite of IR. A caveat: the IR is a moving target inside one compiler; 'the IR' usually means several forms, and what you can express or prove changes as the program is lowered from high-level to low-level.
// C source: // a high-level-ish IR (three-address form): int y = (a + b) * 2; t1 = a + b t2 = t1 * 2 y = t2
One nested expression becomes a flat sequence of tiny operations — easy for the optimizer to reason about.
There is rarely just one IR: compilers lower through several, high-level to low-level, so what an analysis can see (types, loops, raw addresses) depends on which IR level you are looking at.