Skip to main content

Crate codegen_lang

Crate codegen_lang 

Source
Expand description

§codegen_lang

A backend abstraction that turns the ir-lang intermediate representation into code for a concrete target.

A compiler’s middle end hands the backend a function in SSA form; the backend lays that control-flow graph out as a linear stream of instructions a machine can run. This crate draws the line between the two. Backend is the trait a target implements, and Bytecode is the target shipped here: a small, register-based bytecode that is enough to inspect, serialize, and run generated code without pulling in a native code generator. A backend built on LLVM or Cranelift slots in behind the same trait, producing its own Output.

§Lowering model

Each IR value is given its own virtual Register, so an Op names its operands and result by register rather than by a position on a stack. Each basic block becomes a Label in a flat op stream. A block’s parameters are filled by Move ops emitted on the edges that target it — the bytecode’s stand-in for an SSA phi node, which is how a value crosses a control-flow join. The input is checked with Function::validate before lowering, so a backend only ever sees well-formed SSA and the op stream it returns is faithful to the function it came from.

§Example

Lower fn double(x: int) -> int { x + x } and read the result back:

use codegen_lang::{compile, BinOp, Op};
use ir_lang::{Builder, Type};

let mut b = Builder::new("double", &[Type::Int], Type::Int);
let x = b.block_params(b.entry())[0];
let sum = b.bin(BinOp::Add, x, x);
b.ret(Some(sum));

let program = compile(&b.finish()).expect("double is well-formed");
assert_eq!(program.name(), "double");

// One add, then a return of its result.
assert!(matches!(program.ops()[0], Op::Bin { op: BinOp::Add, .. }));
assert!(matches!(program.ops()[1], Op::Return { value: Some(_) }));

§Features

  • std (default) — links the standard library. Without it the crate is #![no_std] and needs only alloc.
  • serde — derives Serialize and Deserialize for Program and its parts, so a compiled program can be cached or moved between tools.

§Stability

The public surface is frozen and stable as of 1.0.0: it follows Semantic Versioning, with no breaking changes before 2.0. CodegenError is #[non_exhaustive], so a backend reporting a new kind of failure is an additive, non-breaking change. The full surface and the SemVer promise are catalogued in docs/API.md.

Structs§

Bytecode
The reference backend: lowers a function to a flat, register-based Program.
Label
A jump target: a position in a program’s op stream that a control-flow op transfers to.
Program
A lowered function: a flat bytecode program ready to be inspected, serialized, or run.
Reg
A virtual register: a numbered slot that holds one value while a program runs.

Enums§

BinOp
A binary operation.
CodegenError
The reason a Backend could not lower a function.
Const
A constant operand loaded by Op::Const.
Op
One bytecode instruction.
UnOp
A unary operation.

Traits§

Backend
A code generator: lowers a function in SSA form to a concrete target representation.

Functions§

compile
Lowers a function to bytecode with the default Bytecode backend.