souper_ir/
lib.rs

1//! A library for manipulating [Souper] IR.
2//!
3//! [![](https://docs.rs/souper-ir/badge.svg)](https://docs.rs/souper-ir/)
4//! [![](https://img.shields.io/crates/v/souper-ir.svg)](https://crates.io/crates/souper-ir)
5//! [![](https://img.shields.io/crates/d/souper-ir.svg)](https://crates.io/crates/souper-ir)
6//! ![CI](https://github.com/fitzgen/souper-ir/workflows/CI/badge.svg)
7//!
8//! This crate provides AST types for parsing or generating Souper IR. It is a
9//! suitable building block either for writing a custom LHS extractor, or for
10//! translating learned optimizations into your own peephole optimizations pass.
11//!
12//! ## AST
13//!
14//! The AST type definitions and builders live in the `souper_ir::ast` module.
15//!
16//! ## Parsing Souper IR
17//!
18//! When the `parse` Cargo feature is enabled, the `souper_ir::parse` module
19//! contains functions for parsing Souper IR from a file or an in-memory string.
20//!
21//! ```
22//! # #[cfg(feature = "parse")]
23//! # fn foo() -> souper_ir::parse::Result<()> {
24//! use std::path::Path;
25//!
26//! // We provide a filename to get better error messages.
27//! let filename = Path::new("example.souper");
28//!
29//! let replacements = souper_ir::parse::parse_replacements_str("
30//!     ;; x + x --> 2 * x
31//!     %0 = var
32//!     %1 = add %0, %0
33//!     %2 = mul %0, 2
34//!     cand %1, %2
35//!
36//!     ;; x & x --> x
37//!     %0 = var
38//!     %1 = and %0, %0
39//!     cand %1, %0
40//! ", Some(filename))?;
41//! # let _ = replacements;
42//! # Ok(())
43//! # }
44//! ```
45//!
46//! ## Emitting Souper IR's Text Format
47//!
48//! When the `stringify` Cargo feature is enabled, then the
49//! `souper_ir::ast::Replacement`, `souper_ir::ast::LeftHandSide`, and
50//! `souper_ir::ast::RightHandSide` types all implement `std::fmt::Display`. The
51//! `Display` implementation writes the AST type out as Souper's text format.
52//!
53//! ```
54//! # #[cfg(feature = "stringify")]
55//! # fn foo() -> std::io::Result<()> {
56//! use souper_ir::ast;
57//!
58//! // Build this Souper left-hand side:
59//! //
60//! //     %x:i32 = var
61//! //     %y = mul %x, 2
62//! //     infer %y
63//! //
64//! // We expect that Souper would be able to synthesize a right-hand side that
65//! // does a left shift by one instead of a multiplication.
66//!
67//! let mut lhs = ast::LeftHandSideBuilder::default();
68//!
69//! let x = lhs.assignment(
70//!     Some("x".into()),
71//!     Some(ast::Type { width: 32 }),
72//!     ast::AssignmentRhs::Var,
73//!     vec![],
74//! );
75//!
76//! let y = lhs.assignment(
77//!     Some("y".into()),
78//!     None,
79//!     ast::Instruction::Mul {
80//!         a: x.into(),
81//!         b: ast::Constant { value: 2, r#type: None }.into(),
82//!     },
83//!     vec![],
84//! );
85//!
86//! let lhs = lhs.finish(y, vec![]);
87//!
88//! // Now we can stringify the LHS (and then, presumably, give it to Souper)
89//! // with `std::fmt::Display`:
90//!
91//! use std::io::Write;
92//!
93//! let mut file = std::fs::File::create("my-lhs.souper")?;
94//! write!(&mut file, "{}", lhs)?;
95//! # Ok(())
96//! # }
97//! ```
98//! [Souper]: https://github.com/google/souper
99
100#![deny(missing_debug_implementations)]
101#![deny(missing_docs)]
102
103pub mod ast;
104
105#[cfg(feature = "parse")]
106pub mod parse;
107
108#[cfg(feature = "stringify")]
109mod stringify;