Other meanings of Code generation
Computer science
Code generation is the phase of a compiler that transforms an intermediate representation (IR) of source code into a target language, typically machine code or assembly language. It is the final stage of the compiler's back end, following analysis and optimization phases. The generated code's efficiency is critical for runtime performance. Modern compilers employ techniques such as instruction selection, register allocation, and instruction scheduling to produce optimized code. Code generation can also refer to the automatic creation of source code from high-level models, but in the context of compilers it specifically denotes the translation of IR to target code.
Code generation is the last phase of a compiler's back end, taking the optimized intermediate representation (IR) and converting it into executable target code. This phase must ensure that the generated code is semantically equivalent to the original source and that it meets target-specific constraints such as register usage, instruction formats, and calling conventions. The output is typically assembly code or machine code that can be assembled or linked into a final executable. The correctness of this phase is paramount, as any error propagates to the runtime. In modern compilers, code generation is often divided into sub-phases: instruction selection, register allocation, and instruction scheduling, each addressing a different aspect of code quality.
Instruction selection maps IR operations to target machine instructions using pattern matching, often via tree grammars (e.g., BURS, burg) or dynamic programming. Register allocation assigns variables to a limited set of registers; graph coloring and linear scan are the dominant algorithms. Instruction scheduling reorders instructions to exploit instruction-level parallelism, using list scheduling for basic blocks and modulo scheduling for loops. Some compilers also employ peephole optimization, which replaces small sequences of generated instructions with more efficient ones. These techniques are combined to produce code that runs quickly and uses resources efficiently.
One major challenge is handling complex instruction set architectures (CISC) with variable-length instructions and addressing modes, which complicates instruction selection. Pipelined processors require careful scheduling to avoid stalls, while memory hierarchy considerations demand that the code generator manage data locality. Trade-offs exist between code size and execution speed, especially in embedded systems. Additionally, modern compilers must support multiple target architectures, often using retargetable code generators such as GCC's RTL or LLVM's target description files. These tools abstract target-specific details, allowing the same optimization passes to work across platforms.
The first compilers, such as the Fortran I compiler (1957), already included a code generation phase that produced efficient machine code for the IBM 704. The theory of code generation was formalized in the 1970s and 1980s, with contributions from Alfred Aho, Ravi Sethi, and Jeffrey Ullman. Aside from static compilation, just-in-time (JIT) compilation also performs code generation at runtime, as seen in Java Virtual Machines and modern JavaScript engines. Code generation for virtual machines (e.g., bytecode generation) and for graphics processing units (GPUs) involves unique constraints. Peephole optimization, a simple yet effective technique, was first described in the 1960s and remains widely used.
Help improve the encyclopedia. Reports go straight to the site manager.