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.8.0")]
34
35mod asm;
36mod attrs;
37mod facts;
38#[cfg(test)]
39mod fixtures;
40mod flags;
41mod func;
42mod inst;
43mod module;
44mod opcode;
45mod parse;
46mod print;
47pub mod term;
48mod ty;
49mod verify;
50
51pub use asm::{AsmOperand, AsmOperands, AsmRole};
52pub use attrs::{AttrSet, Attrs, FpContract};
53pub use facts::{Bounds, Facts};
54pub use flags::{Flags, MemOrder, Owner, RmwOp, StorageClass};
55pub use func::{Builder, Counts, Func};
56pub use inst::{
57 Abi, AbiList, AsmInfo, Block, BlockCall, BlockCallList, BlockData, CallInfo, Def, Extra, Imm,
58 ImmList, Inst, InstData, InstLayout, MemInfo, Meta, MetaNode, Param, PlaneNode, Restrict, Sig,
59 Signature, SlotList, SwitchInfo, TbaaNode, VaInfo, Value, ValueData, ValueList, ValueRef,
60};
61pub use module::{
62 Alias, AliasId, AliasKind, Byte, ByteRange, DataLayout, DataList, Datum, FuncId, Global,
63 GlobalId, Linkage, Module, ModuleCounts, Reloc, SymbolRef, TlsModel, Visibility,
64};
65pub use opcode::{ExtraKind, FloatPred, IntPred, Opcode};
66pub use parse::{ParseError, parse};
67pub use print::{Printer, print, print_func};
68pub use ty::{Float, Kind, Type};
69pub use verify::{VerifyError, verify, verify_func};
70
71/// The milestone in `spec/17-milestones.md` that fills this crate in.
72pub const MILESTONE: &str = "M2";
73
74/// The version of the textual form, written in the module header.
75///
76/// The IR is not a stable interface before 1.0 and this number does not promise that it is.
77/// It exists so that a dump from one build read by another build fails with something a person
78/// can act on rather than with a parse error twenty lines in.
79pub const FORMAT_VERSION: u32 = 0;
80
81#[cfg(test)]
82mod tests {
83 #[test]
84 fn milestone_is_recorded() {
85 assert!(super::MILESTONE.starts_with('M'));
86 }
87}