Expand description

This module exposes the machine-specific backend definition pieces.

The MachInst infrastructure is the compiler backend, from CLIF (ir::Function) to machine code. The purpose of this infrastructure is, at a high level, to do instruction selection/lowering (to machine instructions), register allocation, and then perform all the fixups to branches, constant data references, etc., needed to actually generate machine code.

The container for machine instructions, at various stages of construction, is the VCode struct. We refer to a sequence of machine instructions organized into basic blocks as “vcode”. This is short for “virtual-register code”, though it’s a bit of a misnomer because near the end of the pipeline, vcode has all real registers. Nevertheless, the name is catchy and we like it.

The compilation pipeline, from an ir::Function (already optimized as much as you like by machine-independent optimization passes) onward, is as follows. (N.B.: though we show the VCode separately at each stage, the passes mutate the VCode in place; these are not separate copies of the code.)


    ir::Function                (SSA IR, machine-independent opcodes)
        |
        |  [lower]
        |
    VCode<arch_backend::Inst>   (machine instructions:
        |                        - mostly virtual registers.
        |                        - cond branches in two-target form.
        |                        - branch targets are block indices.
        |                        - in-memory constants held by insns,
        |                          with unknown offsets.
        |                        - critical edges (actually all edges)
        |                          are split.)
        | [regalloc]
        |
    VCode<arch_backend::Inst>   (machine instructions:
        |                        - all real registers.
        |                        - new instruction sequence returned
        |                          out-of-band in RegAllocResult.
        |                        - instruction sequence has spills,
        |                          reloads, and moves inserted.
        |                        - other invariants same as above.)
        |
        | [preamble/postamble]
        |
    VCode<arch_backend::Inst>   (machine instructions:
        |                        - stack-frame size known.
        |                        - out-of-band instruction sequence
        |                          has preamble prepended to entry
        |                          block, and postamble injected before
        |                          every return instruction.
        |                        - all symbolic stack references to
        |                          stackslots and spillslots are resolved
        |                          to concrete FP-offset mem addresses.)
        | [block/insn ordering]
        |
    VCode<arch_backend::Inst>   (machine instructions:
        |                        - vcode.final_block_order is filled in.
        |                        - new insn sequence from regalloc is
        |                          placed back into vcode and block
        |                          boundaries are updated.)
        | [redundant branch/block
        |  removal]
        |
    VCode<arch_backend::Inst>   (machine instructions:
        |                        - all blocks that were just an
        |                          unconditional branch are removed.)
        |
        | [branch finalization
        |  (fallthroughs)]
        |
    VCode<arch_backend::Inst>   (machine instructions:
        |                        - all branches are in lowered one-
        |                          target form, but targets are still
        |                          block indices.)
        |
        | [branch finalization
        |  (offsets)]
        |
    VCode<arch_backend::Inst>   (machine instructions:
        |                        - all branch offsets from start of
        |                          function are known, and all branches
        |                          have resolved-offset targets.)
        |
        | [MemArg finalization]
        |
    VCode<arch_backend::Inst>   (machine instructions:
        |                        - all MemArg references to the constant
        |                          pool are replaced with offsets.
        |                        - all constant-pool data is collected
        |                          in the VCode.)
        |
        | [binary emission]
        |
    Vec<u8>                     (machine code!)

Re-exports

pub use lower::*;
pub use vcode::*;
pub use compile::*;
pub use blockorder::*;
pub use abi::*;
pub use abi_impl::*;
pub use buffer::*;
pub use adapter::*;
pub use helpers::*;
pub use inst_common::*;
pub use valueregs::*;

Modules

ABI definitions.

Implementation of a vanilla ABI, shared between several machines. The implementation here assumes that arguments will be passed in registers first, then additional args on the stack; that the stack grows downward, contains a standard frame (return address and frame pointer), and the compiler is otherwise free to allocate space below that with its choice of layout; and that the machine has some notion of caller- and callee-save registers. Most modern machines, e.g. x86-64 and AArch64, should fit this mold and thus both of these backends use this shared implementation.

Adapter for a MachBackend to implement the TargetIsa trait.

Computation of basic block order in emitted code.

In-memory representation of compiled machine code, with labels and fixups to refer to those labels. Handles constant-pool island insertion and also veneer insertion for out-of-range jumps.

Compilation backend pipeline: optimized IR to VCode / binemit.

Miscellaneous helpers for machine backends.

A place to park MachInst::Inst fragments which are common across multiple architectures.

This module implements lowering (instruction selection) from Cranelift IR to machine instructions with virtual registers. This is almost the final machine code, except for register allocation.

Data structure for tracking the (possibly multiple) registers that hold one SSA Value.

This implements the VCode container: a CFG of Insts that have been lowered.

Structs

The result of a MachBackend::compile_function() call. Contains machine code (as bytes) and a disassembly, if requested.

Input data for UnwindInfoGenerator.

Enums

Describes a block terminator (not call) in the vcode, when its branches have not yet been finalized (so a branch may have two targets).

Expected unwind info type.

Traits

Top-level machine backend trait, which wraps all monomorphized code and allows a virtual call from the machine-independent Function::compile().

A machine instruction.

A trait describing the ability to encode a MachInst into binary machine code.

Constant information used to emit an instruction.

A trait describing the emission state carried between MachInsts when emitting a function body.

A descriptor of a label reference (use) in an instruction set.

UnwindInfo generator/helper.