Why is an intermediate representation (IR) phase valuable even when a compiler targets only a single machine architecture?
Think about your answer, then reveal below.
Model answer: IR decouples the front end (language-specific parsing and semantic analysis) from the back end (machine-specific code generation). Even for a single target, IR enables optimization passes expressed at a level above machine code but below source code — constant folding, dead code elimination, inlining, and loop transformations are all easier to implement on a clean IR than on raw assembly. The IR is also the right level for analyses that require seeing the whole program at once.
The IR is the architectural boundary that makes the classic front end / middle end / back end split work. Optimizations written against the IR remain correct regardless of the source language or target machine. Without IR, every optimization would need to be reimplemented for each source-target combination. Even for single-target compilers, the IR pays for itself by making the optimization infrastructure reusable and testable independently of code generation.