Skip to content

Commit 90b2f51

Browse files
authored
Replace llvmlite with Rust/Inkwell (#199)
1 parent 8f892f9 commit 90b2f51

32 files changed

+3662
-549
lines changed

Cargo.lock

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ pecos-qis-ffi-types = { version = "0.1.1", path = "crates/pecos-qis-ffi-types" }
121121
pecos-qis-selene = { version = "0.1.1", path = "crates/pecos-qis-selene" }
122122
pecos-qis-core = { version = "0.1.1", path = "crates/pecos-qis-core" }
123123
pecos-hugr-qis = { version = "0.1.1", path = "crates/pecos-hugr-qis" }
124+
pecos-llvm = { version = "0.1.1", path = "crates/pecos-llvm" }
124125
pecos-rslib = { version = "0.1.1", path = "python/pecos-rslib/rust" }
125126
pecos-wasm = { version = "0.1.1", path = "crates/pecos-wasm" }
126127
pecos-build-utils = { version = "0.1.1", path = "crates/pecos-build-utils" }

crates/pecos-llvm/Cargo.toml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[package]
2+
name = "pecos-llvm"
3+
version.workspace = true
4+
edition.workspace = true
5+
description = "Rust wrapper for LLVM IR generation using inkwell"
6+
readme.workspace = true
7+
authors.workspace = true
8+
homepage.workspace = true
9+
repository.workspace = true
10+
license.workspace = true
11+
keywords.workspace = true
12+
categories.workspace = true
13+
14+
[dependencies]
15+
pecos-core.workspace = true
16+
thiserror.workspace = true
17+
log.workspace = true
18+
regex.workspace = true
19+
20+
# Inkwell for LLVM IR generation
21+
[dependencies.inkwell]
22+
workspace = true
23+
features = ["llvm14-0"]
24+
25+
[features]
26+
default = []
27+
28+
[build-dependencies]
29+
pecos-llvm-utils.workspace = true
30+
31+
[lints]
32+
workspace = true

crates/pecos-llvm/build.rs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
fn main() {
2+
// Always validate LLVM since this crate requires LLVM
3+
validate_llvm();
4+
}
5+
6+
fn validate_llvm() {
7+
use pecos_llvm_utils::is_valid_llvm_14;
8+
use std::env;
9+
use std::path::PathBuf;
10+
11+
// Check if LLVM_SYS_140_PREFIX is already set and valid
12+
if let Ok(sys_prefix) = env::var("LLVM_SYS_140_PREFIX") {
13+
let path = PathBuf::from(&sys_prefix);
14+
if is_valid_llvm_14(&path) {
15+
// LLVM is configured and valid, we're good!
16+
return;
17+
}
18+
eprintln!("\n═══════════════════════════════════════════════════════════════");
19+
eprintln!("ERROR: Invalid LLVM_SYS_140_PREFIX");
20+
eprintln!("═══════════════════════════════════════════════════════════════");
21+
eprintln!();
22+
eprintln!("LLVM_SYS_140_PREFIX is set to: {sys_prefix}");
23+
eprintln!("But this is not a valid LLVM 14 installation.");
24+
eprintln!();
25+
eprintln!("Please either:");
26+
eprintln!(" 1. Fix the path to point to a valid LLVM 14 installation");
27+
eprintln!(" 2. Unset it and configure LLVM:");
28+
eprintln!(" unset LLVM_SYS_140_PREFIX");
29+
eprintln!(" cargo run -p pecos-llvm-utils --bin pecos-llvm -- configure");
30+
eprintln!("═══════════════════════════════════════════════════════════════\n");
31+
panic!("Invalid LLVM_SYS_140_PREFIX. See error message above.");
32+
}
33+
34+
// LLVM_SYS_140_PREFIX not set - print setup instructions
35+
print_llvm_not_found_error_extended();
36+
panic!("LLVM 14 not configured. See error message above for setup instructions.");
37+
}
38+
39+
fn print_llvm_not_found_error_extended() {
40+
eprintln!("\n═══════════════════════════════════════════════════════════════");
41+
eprintln!("LLVM 14 Setup Required for pecos-qir");
42+
eprintln!("═══════════════════════════════════════════════════════════════");
43+
eprintln!();
44+
eprintln!("The pecos-qir crate requires LLVM 14 for QIR generation.");
45+
eprintln!("Choose one of these installation methods:");
46+
eprintln!();
47+
eprintln!("Option 1: Use pecos-llvm installer (recommended)");
48+
eprintln!(" cargo run -p pecos-llvm-utils --bin pecos-llvm -- install");
49+
eprintln!(" cargo build");
50+
eprintln!();
51+
eprintln!(" The installer automatically configures PECOS.");
52+
eprintln!(" (Downloads LLVM 14.0.6 to ~/.pecos/llvm/ - ~400MB, ~5 minutes)");
53+
eprintln!();
54+
55+
#[cfg(target_os = "macos")]
56+
{
57+
eprintln!("Option 2: Install via Homebrew");
58+
eprintln!(" # Install LLVM 14");
59+
eprintln!(" brew install llvm@14");
60+
eprintln!();
61+
eprintln!(" # Configure PECOS to use it");
62+
eprintln!(" cargo run -p pecos-llvm-utils --bin pecos-llvm -- configure");
63+
eprintln!();
64+
eprintln!(" # Build PECOS");
65+
eprintln!(" cargo build");
66+
eprintln!();
67+
eprintln!(" Note: Works on both Intel and Apple Silicon Macs");
68+
eprintln!();
69+
}
70+
71+
#[cfg(target_os = "linux")]
72+
{
73+
eprintln!("Option 2: Install via system package manager");
74+
eprintln!();
75+
eprintln!(" Debian/Ubuntu:");
76+
eprintln!(" sudo apt update");
77+
eprintln!(" sudo apt install llvm-14 llvm-14-dev");
78+
eprintln!();
79+
eprintln!(" Fedora/RHEL:");
80+
eprintln!(" sudo dnf install llvm14 llvm14-devel");
81+
eprintln!();
82+
eprintln!(" Arch Linux:");
83+
eprintln!(" # LLVM 14 may need to be built from AUR");
84+
eprintln!(" yay -S llvm14");
85+
eprintln!();
86+
eprintln!(" Then configure and build:");
87+
eprintln!(" cargo run -p pecos-llvm-utils --bin pecos-llvm -- configure");
88+
eprintln!(" cargo build");
89+
eprintln!();
90+
}
91+
92+
#[cfg(target_os = "windows")]
93+
{
94+
eprintln!("Option 2: Manual installation (advanced)");
95+
eprintln!();
96+
eprintln!(" WARNING: The official LLVM installer lacks development files.");
97+
eprintln!(" You need a FULL development package from community sources:");
98+
eprintln!();
99+
eprintln!(" Recommended sources:");
100+
eprintln!(" https://github.com/bitgate/llvm-windows-full-builds");
101+
eprintln!(" https://github.com/vovkos/llvm-package-windows");
102+
eprintln!();
103+
eprintln!(" After extracting to C:\\LLVM (or similar):");
104+
eprintln!(" set LLVM_SYS_140_PREFIX=C:\\LLVM");
105+
eprintln!(" cargo run -p pecos-llvm-utils --bin pecos-llvm -- configure");
106+
eprintln!(" cargo build");
107+
eprintln!();
108+
}
109+
110+
eprintln!("Alternative: Set LLVM path manually");
111+
eprintln!(" Instead of 'configure', you can set environment variables:");
112+
eprintln!();
113+
#[cfg(target_os = "windows")]
114+
eprintln!(" set LLVM_SYS_140_PREFIX=C:\\path\\to\\llvm");
115+
#[cfg(not(target_os = "windows"))]
116+
eprintln!(" export LLVM_SYS_140_PREFIX=/path/to/llvm");
117+
#[cfg(not(target_os = "windows"))]
118+
eprintln!(" Or add llvm-config to PATH:");
119+
#[cfg(not(target_os = "windows"))]
120+
eprintln!(" export PATH=\"/path/to/llvm/bin:$PATH\"");
121+
eprintln!();
122+
eprintln!("For detailed instructions, see:");
123+
eprintln!(" https://github.com/CQCL/PECOS/blob/master/docs/user-guide/getting-started.md");
124+
eprintln!();
125+
eprintln!("═══════════════════════════════════════════════════════════════\n");
126+
}

crates/pecos-llvm/src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2024 The PECOS Developers
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//! LLVM IR generation using inkwell
16+
//!
17+
//! This crate provides Rust types and functions for generating LLVM IR,
18+
//! designed to be compatible with Python's llvmlite usage patterns.
19+
//!
20+
//! The main module is `llvm_compat`, which provides types for LLVM IR generation
21+
//! that are compatible with Python's llvmlite API.
22+
23+
pub mod llvm_compat;
24+
pub mod prelude;
25+
26+
// Re-export main types at crate root for convenience
27+
pub use llvm_compat::{
28+
LLConstant, LLContext, LLFunction, LLFunctionType, LLIRBuilder, LLModule, LLResult, LLType,
29+
LLValue,
30+
};

0 commit comments

Comments
 (0)