melior 0.4.2

The rustic MLIR bindings in Rust
docs.rs failed to build melior-0.4.2
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

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 16 needs to be installed on your system. On Linux and macOS, you can install it via Homebrew.

brew install llvm@16

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