hugr_llvm/lib.rs
1//! # A crate for lowering `HUGR`s into LLVM.
2//!
3//! ## Five minute Introduction to LLVM and [inkwell]
4//!
5//! References:
6//! * The full specification for LLVM IR as on the main branch: <https://llvm.org/docs/LangRef.html>.
7//! * The full specification for LLVM IR version for version 14.0: <https://releases.llvm.org/14.0.0/docs/LangRef.html>
8//! * The documentation for the [inkwell] crate <https://thedan64.github.io/inkwell/inkwell/index.html>
9//!
10//! LLVM offers a stable C interface to most of it's functionality. These
11//! bindings are exposed to rust through the `llvm-sys` crate; there is quite a
12//! lot of feature-ing and build-time logic done there to support various
13//! linking configurations and llvm versions.
14//!
15//! The [inkwell] crate offers safe wrappers around these bindings and is what
16//! we use throughout.
17//!
18//! ### Definition of LLVM terms:
19//!
20//! * [Context](inkwell::context::Context): A context owns all of the many LLVM
21//! objects. Most all `inkwell` types take a lifetime parameter which ensures
22//! they do not outlive their owning `Context`. A `Context` is not thread safe.
23//! A Context is used to construct modules, types, builders, and basic blocks.
24//!
25//! * [Module](inkwell::module::Module): A module is owned by a `Context`. It is
26//! a container for globals and functions. A `foo.ll` file containing LLVM IR
27//! would be loaded into a `Module`.
28//!
29//! * [Function](inkwell::values::FunctionValue): A function has a name(symbol),
30//! parameters, a return type, linkage(symbol visibility) and various other
31//! attributes. It may contain basic blocks, in which case compiling the owning
32//! module will produce object code for the function. If it does not contain
33//! basic blocks then it represents an external symbol that can be called, and
34//! object code for that symbol must be linked with the object code from this
35//! module.
36//!
37//! * [Instruction](inkwell::values::InstructionOpcode): A basic block is an
38//! ordered list of instructions. Examples: `load`, `store`, `iadd`, `ret`. They
39//! are all defined in the `LangRef`.
40//!
41//! * [Intrinsic](inkwell::intrinsics::Intrinsic): A "special function" provided
42//! by LLVM. These are called like functions but are treated like an
43//! instruction(i.e. special cased) by various passes. The differences between
44//! `Instruction` and `Intrinsic` are not well motivated and are largely an
45//! accident of history. They are all defined in the `LangRef`.
46//!
47//! * [Values](inkwell::values): The things `Instruction`s take and return. They
48//! can be the parameters of functions, the results of instructions,
49//! constants, symbol references to globals, and other more esoteric things.
50//! Mostly we use [`BasicValueEnum`] or [`BasicValue`].
51//!
52//! * [Types](inkwell::types): Every `Value` has a type. For example `i32`,
53//! `f64`, `ptr`. In particular types are used to construct constant values.
54//!
55//! * [Builder](inkwell::builder::Builder): This is the mechanism by which one
56//! inserts instructions into a basic block into a basic block. A builder has
57//! a "current position" where the next instruction will be inserted. It has
58//! many functions such as [`inkwell::builder::Builder::build_call`] which are
59//! used to create and insert instructions.
60//!
61//! [`BasicValueEnum`]: [inkwell::values::BasicValueEnum]
62//! [`BasicValue`]: [inkwell::values::BasicValue]
63//!
64#![expect(missing_docs)] // TODO: Fix...
65
66pub mod custom;
67pub mod emit;
68pub mod extension;
69pub mod sum;
70pub mod types;
71pub mod utils;
72
73#[allow(unreachable_code)]
74#[must_use]
75pub fn llvm_version() -> &'static str {
76 #[cfg(feature = "llvm14-0")]
77 return "llvm14";
78 panic!("No recognised llvm feature.")
79}
80
81#[cfg(any(test, feature = "test-utils"))]
82pub mod test;
83
84pub use custom::{CodegenExtension, CodegenExtsBuilder};
85
86pub use inkwell;
87pub use inkwell::llvm_sys;