Crate melior

source ·
Expand description

Melior is the rustic MLIR bindings for Rust. It aims to provide a simple, safe, and complete API for MLIR with a reasonably sane ownership model represented by the type system in Rust.

This crate is a wrapper of the MLIR C API.

Dependencies

LLVM/MLIR 15 needs to be installed on your system. On Linux and macOS, you can install it via Homebrew.

brew install llvm@15

Safety

Although Melior aims to be completely safe, some part of the current API is not.

  • Access to operations, types, or attributes that belong to dialects not loaded in contexts can lead to runtime errors or segmentation faults in the worst case.
    • Fix plan: Load all dialects by default on creation of contexts, and provide unsafe constructors of contexts for advanced users.
  • IR object references returned from functions that move ownership of arguments might get invalidated later.
    • This is because we need to borrow &self rather than &mut self to return such references.
    • e.g. Region::append_block()
    • Fix plan: Use dynamic check, such as RefCell, for the objects.

Examples

Building a function to add integers

use melior::{
    Context,
    dialect,
    ir::*,
    utility::register_all_dialects,
};

let registry = dialect::Registry::new();
register_all_dialects(&registry);

let context = Context::new();
context.append_dialect_registry(&registry);
context.get_or_load_dialect("func");

let location = Location::unknown(&context);
let module = Module::new(location);

let integer_type = Type::integer(&context, 64);

let function = {
    let region = Region::new();
    let block = Block::new(&[(integer_type, location), (integer_type, location)]);

    let sum = block.append_operation(
        operation::Builder::new("arith.addi", location)
            .add_operands(&[
                block.argument(0).unwrap().into(),
                block.argument(1).unwrap().into(),
            ])
            .add_results(&[integer_type])
            .build(),
    );

    block.append_operation(
        operation::Builder::new("func.return", Location::unknown(&context))
            .add_operands(&[sum.result(0).unwrap().into()])
            .build(),
    );

    region.append_block(block);

    operation::Builder::new("func.func", Location::unknown(&context))
        .add_attributes(&[
            (
                Identifier::new(&context, "function_type"),
                Attribute::parse(&context, "(i64, i64) -> i64").unwrap(),
            ),
            (
                Identifier::new(&context, "sym_name"),
                Attribute::parse(&context, "\"add\"").unwrap(),
            ),
        ])
        .add_regions(vec![region])
        .build()
};

module.body().append_operation(function);

assert!(module.as_operation().verify());

Modules

Dialect handles, instances, and registry.
IR objects and builders.
Passes and pass managers.
Utility functions.

Structs

A context of IR, dialects, and passes.
A reference to a context.
An execution engine.
A string reference.

Enums

A Melior error.