Skip to main content

rucc_ir/
lib.rs

1//! The SSA IR with block parameters, and its printer, parser and verifier.
2//!
3//! Design: `spec/08-ir.md`. Layer rank 8, see `spec/18-package-layout.md`.
4//!
5//! One IR, target-independent, in SSA form, produced by lowering the typed AST and consumed by
6//! the optimizer and the code generator. The MIR is a second, target-dependent representation
7//! and lives in its own crate.
8//!
9//! **Block parameters, not phi nodes.** A phi is a pseudo-instruction whose operands are
10//! positionally tied to a predecessor list stored somewhere else, and every IR built that way
11//! collects bugs where the two get out of step during a CFG edit. Block parameters put the
12//! correspondence in the branch, where it belongs: `br_if %c, block2(%a, %b), block3(%d)`.
13//! Removing a predecessor is then a local edit, and there is no such thing as a malformed phi.
14//!
15//! # What is here so far
16//!
17//! The vocabulary: [`Type`] and [`Float`] for the type system, [`Opcode`] with [`IntPred`] and
18//! [`FloatPred`] for the instruction set, [`Flags`] with [`MemOrder`] and [`RmwOp`] for what
19//! rides on an instruction, and [`Attrs`] for what is true of a whole function rather than of
20//! one instruction in it. [`Signature`] for what a function takes and returns, with [`Abi`] on
21//! each [`Param`] for what a call asks of it beyond its type, which is the one thing about a C
22//! function that reading the C cannot answer. The containers: [`Func`], holding [`BlockData`] and
23//! [`InstData`] and [`ValueData`] in flat tables, with [`Builder`] to append to it, and
24//! [`Module`], holding the functions with the [`Global`]s and the [`Alias`]es and the target
25//! they are all for. The textual form: [`print()`], which writes a module out, and [`parse()`],
26//! which reads it back byte for byte. And [`verify()`], which says whether a module is one the
27//! rest of the compiler may believe.
28//!
29//! Every crate in the workspace is published, and publishing implies a promise. This one is
30//! tier 3: its Rust API is explicitly unstable and will change without a major version bump.
31//! Depend on the `rucc` binary's behaviour, not on this.
32
33#![doc(html_root_url = "https://docs.rs/rucc-ir/0.2.21")]
34
35mod attrs;
36#[cfg(test)]
37mod fixtures;
38mod flags;
39mod func;
40mod inst;
41mod module;
42mod opcode;
43mod parse;
44mod print;
45mod ty;
46mod verify;
47
48pub use attrs::{AttrSet, Attrs, FpContract};
49pub use flags::{Flags, MemOrder, RmwOp};
50pub use func::{Builder, Counts, Func};
51pub use inst::{
52    Abi, AsmInfo, Block, BlockCall, BlockCallList, BlockData, CallInfo, Def, Extra, Imm, ImmList,
53    Inst, InstData, InstLayout, MemInfo, Meta, MetaNode, Param, Sig, Signature, SwitchInfo, Value,
54    ValueData, ValueList, ValueRef,
55};
56pub use module::{
57    Alias, AliasId, AliasKind, Byte, ByteRange, DataLayout, DataList, Datum, FuncId, Global,
58    GlobalId, Linkage, Module, ModuleCounts, Reloc, SymbolRef, TlsModel, Visibility,
59};
60pub use opcode::{ExtraKind, FloatPred, IntPred, Opcode};
61pub use parse::{ParseError, parse};
62pub use print::{Printer, print, print_func};
63pub use ty::{Float, Kind, Type};
64pub use verify::{VerifyError, verify, verify_func};
65
66/// The milestone in `spec/17-milestones.md` that fills this crate in.
67pub const MILESTONE: &str = "M2";
68
69/// The version of the textual form, written in the module header.
70///
71/// The IR is not a stable interface before 1.0 and this number does not promise that it is.
72/// It exists so that a dump from one build read by another build fails with something a person
73/// can act on rather than with a parse error twenty lines in.
74pub const FORMAT_VERSION: u32 = 0;
75
76#[cfg(test)]
77mod tests {
78    #[test]
79    fn milestone_is_recorded() {
80        assert!(super::MILESTONE.starts_with('M'));
81    }
82}