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