#ir #ast

souper-ir

A library for manipulating Souper IR

4 releases (stable)

2.1.0 Oct 16, 2020
2.0.0 Oct 15, 2020
1.0.0 Jul 25, 2020
0.1.0 Jul 17, 2020
Download history 943/week @ 2022-04-22 928/week @ 2022-04-29 842/week @ 2022-05-06 750/week @ 2022-05-13 869/week @ 2022-05-20 779/week @ 2022-05-27 1240/week @ 2022-06-03 519/week @ 2022-06-10 734/week @ 2022-06-17 1576/week @ 2022-06-24 1648/week @ 2022-07-01 1193/week @ 2022-07-08 1877/week @ 2022-07-15 2297/week @ 2022-07-22 2455/week @ 2022-07-29 2100/week @ 2022-08-05

8,977 downloads per month
Used in 2 crates

MIT/Apache

86KB
1.5K SLoC

souper-ir

A library for manipulating Souper IR.

CI

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.

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))?;

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.

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)?;

Dependencies

~29KB