core: Update cargo dependencies

pull/382/head
David Mak 2024-02-19 19:30:25 +08:00
parent e1dbe2526a
commit 8492503af2
17 changed files with 1123 additions and 966 deletions

100
Cargo.lock generated
View File

@ -2,17 +2,6 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
dependencies = [
"getrandom",
"once_cell",
"version_check",
]
[[package]]
name = "ahash"
version = "0.8.9"
@ -133,12 +122,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.0.83"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730"
[[package]]
name = "cfg-if"
@ -371,15 +357,6 @@ dependencies = [
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash 0.7.8",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -391,6 +368,9 @@ name = "hashbrown"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
dependencies = [
"ahash",
]
[[package]]
name = "heck"
@ -432,23 +412,23 @@ checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
[[package]]
name = "inkwell"
version = "0.2.0"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f4fcb4a4fa0b8f7b4178e24e6317d6f8b95ab500d8e6e1bd4283b6860e369c1"
checksum = "b597a7b2cdf279aeef6d7149071e35e4bc87c2cf05a5b7f2d731300bffe587ea"
dependencies = [
"either",
"inkwell_internals",
"libc",
"llvm-sys",
"once_cell",
"parking_lot",
"thiserror",
]
[[package]]
name = "inkwell_internals"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b185e7d068d6820411502efa14d8fbf010750485399402156b72dd2a548ef8e9"
checksum = "4fa4d8d74483041a882adaa9a29f633253a66dde85055f0495c121620ac484b2"
dependencies = [
"proc-macro2",
"quote",
@ -676,7 +656,7 @@ dependencies = [
name = "nac3parser"
version = "0.1.2"
dependencies = [
"ahash 0.8.9",
"ahash",
"insta",
"lalrpop",
"lalrpop-util",
@ -1114,12 +1094,12 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "string-interner"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e2531d8525b29b514d25e275a43581320d587b86db302b9a7e464bac579648"
checksum = "07f9fdfdd31a0ff38b59deb401be81b73913d76c9cc5b1aed4e1330a223420b9"
dependencies = [
"cfg-if",
"hashbrown 0.11.2",
"hashbrown 0.14.3",
"serde",
]
@ -1166,9 +1146,9 @@ dependencies = [
[[package]]
name = "target-lexicon"
version = "0.12.13"
version = "0.12.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae"
checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
[[package]]
name = "tempfile"
@ -1405,7 +1385,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.0",
"windows-targets 0.52.3",
]
[[package]]
@ -1425,17 +1405,17 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.52.0"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f"
dependencies = [
"windows_aarch64_gnullvm 0.52.0",
"windows_aarch64_msvc 0.52.0",
"windows_i686_gnu 0.52.0",
"windows_i686_msvc 0.52.0",
"windows_x86_64_gnu 0.52.0",
"windows_x86_64_gnullvm 0.52.0",
"windows_x86_64_msvc 0.52.0",
"windows_aarch64_gnullvm 0.52.3",
"windows_aarch64_msvc 0.52.3",
"windows_i686_gnu 0.52.3",
"windows_i686_msvc 0.52.3",
"windows_x86_64_gnu 0.52.3",
"windows_x86_64_gnullvm 0.52.3",
"windows_x86_64_msvc 0.52.3",
]
[[package]]
@ -1446,9 +1426,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6"
[[package]]
name = "windows_aarch64_msvc"
@ -1458,9 +1438,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f"
[[package]]
name = "windows_i686_gnu"
@ -1470,9 +1450,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb"
[[package]]
name = "windows_i686_msvc"
@ -1482,9 +1462,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58"
[[package]]
name = "windows_x86_64_gnu"
@ -1494,9 +1474,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614"
[[package]]
name = "windows_x86_64_gnullvm"
@ -1506,9 +1486,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c"
[[package]]
name = "windows_x86_64_msvc"
@ -1518,9 +1498,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6"
[[package]]
name = "yaml-rust"

View File

@ -12,13 +12,13 @@ crate-type = ["cdylib"]
itertools = "0.12"
pyo3 = { version = "0.20", features = ["extension-module"] }
parking_lot = "0.12"
tempfile = "3.8"
tempfile = "3.10"
nac3parser = { path = "../nac3parser" }
nac3core = { path = "../nac3core" }
nac3ld = { path = "../nac3ld" }
[dependencies.inkwell]
version = "0.2"
version = "0.4"
default-features = false
features = ["llvm14-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"]

View File

@ -12,7 +12,11 @@ use nac3core::{
use nac3parser::ast::{Expr, ExprKind, Located, Stmt, StmtKind, StrRef};
use inkwell::{
context::Context, module::Linkage, types::IntType, values::BasicValueEnum, AddressSpace,
context::Context,
module::Linkage,
types::IntType,
values::{BasicValueEnum, CallSiteValue},
AddressSpace,
};
use pyo3::{PyObject, PyResult, Python, types::{PyDict, PyList}};
@ -25,6 +29,7 @@ use std::{
hash::{Hash, Hasher},
sync::Arc,
};
use itertools::Either;
/// The parallelism mode within a block.
#[derive(Copy, Clone, Eq, PartialEq)]
@ -139,15 +144,15 @@ impl<'a> ArtiqCodeGenerator<'a> {
let max = ctx
.builder
.build_call(smax, &[old_end.into(), now.into()], "smax")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
let end_store = self.gen_store_target(
ctx,
&end,
store_name.map(|name| format!("{name}.addr")).as_deref())?
.unwrap();
ctx.builder.build_store(end_store, max);
ctx.builder.build_store(end_store, max).unwrap();
}
Ok(())
@ -268,7 +273,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
let start = self
.gen_store_target(ctx, &start_expr, Some("start.addr"))?
.unwrap();
ctx.builder.build_store(start, now);
ctx.builder.build_store(start, now).unwrap();
Ok(Some(start_expr)) as Result<_, String>
},
|v| Ok(Some(v)),
@ -283,7 +288,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
let end = self
.gen_store_target(ctx, &end_expr, Some("end.addr"))?
.unwrap();
ctx.builder.build_store(end, now);
ctx.builder.build_store(end, now).unwrap();
self.end = Some(end_expr);
self.name_counter += 1;
self.parallel_mode = match id.to_string().as_str() {
@ -477,12 +482,14 @@ fn rpc_codegen_callback_fn<'ctx>(
)
});
let stackptr = ctx.builder.build_call(stacksave, &[], "rpc.stack");
let args_ptr = ctx.builder.build_array_alloca(
ptr_type,
ctx.ctx.i32_type().const_int(arg_length as u64, false),
"argptr",
);
let stackptr = ctx.builder.build_call(stacksave, &[], "rpc.stack").unwrap();
let args_ptr = ctx.builder
.build_array_alloca(
ptr_type,
ctx.ctx.i32_type().const_int(arg_length as u64, false),
"argptr",
)
.unwrap();
// -- rpc args handling
let mut keys = fun.0.args.clone();
@ -515,16 +522,16 @@ fn rpc_codegen_callback_fn<'ctx>(
for (i, arg) in real_params.iter().enumerate() {
let arg_slot = generator.gen_var_alloc(ctx, arg.get_type(), Some(&format!("rpc.arg{i}"))).unwrap();
ctx.builder.build_store(arg_slot, *arg);
let arg_slot = ctx.builder.build_bitcast(arg_slot, ptr_type, "rpc.arg");
ctx.builder.build_store(arg_slot, *arg).unwrap();
let arg_slot = ctx.builder.build_bitcast(arg_slot, ptr_type, "rpc.arg").unwrap();
let arg_ptr = unsafe {
ctx.builder.build_gep(
args_ptr,
&[int32.const_int(i as u64, false)],
&format!("rpc.arg{i}"),
)
};
ctx.builder.build_store(arg_ptr, arg_slot);
}.unwrap();
ctx.builder.build_store(arg_ptr, arg_slot).unwrap();
}
// call
@ -542,18 +549,22 @@ fn rpc_codegen_callback_fn<'ctx>(
None,
)
});
ctx.builder.build_call(
rpc_send,
&[service_id.into(), tag_ptr.into(), args_ptr.into()],
"rpc.send",
);
ctx.builder
.build_call(
rpc_send,
&[service_id.into(), tag_ptr.into(), args_ptr.into()],
"rpc.send",
)
.unwrap();
// reclaim stack space used by arguments
ctx.builder.build_call(
stackrestore,
&[stackptr.try_as_basic_value().unwrap_left().into()],
"rpc.stackrestore",
);
ctx.builder
.build_call(
stackrestore,
&[stackptr.try_as_basic_value().unwrap_left().into()],
"rpc.stackrestore",
)
.unwrap();
// -- receive value:
// T result = {
@ -581,41 +592,45 @@ fn rpc_codegen_callback_fn<'ctx>(
let ret_ty = ctx.get_llvm_abi_type(generator, fun.0.ret);
let need_load = !ret_ty.is_pointer_type();
let slot = ctx.builder.build_alloca(ret_ty, "rpc.ret.slot");
let slotgen = ctx.builder.build_bitcast(slot, ptr_type, "rpc.ret.ptr");
ctx.builder.build_unconditional_branch(head_bb);
let slot = ctx.builder.build_alloca(ret_ty, "rpc.ret.slot").unwrap();
let slotgen = ctx.builder.build_bitcast(slot, ptr_type, "rpc.ret.ptr").unwrap();
ctx.builder.build_unconditional_branch(head_bb).unwrap();
ctx.builder.position_at_end(head_bb);
let phi = ctx.builder.build_phi(ptr_type, "rpc.ptr");
let phi = ctx.builder.build_phi(ptr_type, "rpc.ptr").unwrap();
phi.add_incoming(&[(&slotgen, prehead_bb)]);
let alloc_size = ctx
.build_call_or_invoke(rpc_recv, &[phi.as_basic_value()], "rpc.size.next")
.unwrap()
.into_int_value();
let is_done = ctx.builder.build_int_compare(
inkwell::IntPredicate::EQ,
int32.const_zero(),
alloc_size,
"rpc.done",
);
let is_done = ctx.builder
.build_int_compare(
inkwell::IntPredicate::EQ,
int32.const_zero(),
alloc_size,
"rpc.done",
)
.unwrap();
ctx.builder.build_conditional_branch(is_done, tail_bb, alloc_bb);
ctx.builder.build_conditional_branch(is_done, tail_bb, alloc_bb).unwrap();
ctx.builder.position_at_end(alloc_bb);
let alloc_ptr = ctx.builder.build_array_alloca(ptr_type, alloc_size, "rpc.alloc");
let alloc_ptr = ctx.builder.build_bitcast(alloc_ptr, ptr_type, "rpc.alloc.ptr");
let alloc_ptr = ctx.builder.build_array_alloca(ptr_type, alloc_size, "rpc.alloc").unwrap();
let alloc_ptr = ctx.builder.build_bitcast(alloc_ptr, ptr_type, "rpc.alloc.ptr").unwrap();
phi.add_incoming(&[(&alloc_ptr, alloc_bb)]);
ctx.builder.build_unconditional_branch(head_bb);
ctx.builder.build_unconditional_branch(head_bb).unwrap();
ctx.builder.position_at_end(tail_bb);
let result = ctx.builder.build_load(slot, "rpc.result");
let result = ctx.builder.build_load(slot, "rpc.result").unwrap();
if need_load {
ctx.builder.build_call(
stackrestore,
&[stackptr.try_as_basic_value().unwrap_left().into()],
"rpc.stackrestore",
);
ctx.builder
.build_call(
stackrestore,
&[stackptr.try_as_basic_value().unwrap_left().into()],
"rpc.stackrestore",
)
.unwrap();
}
Ok(Some(result))
}

View File

@ -642,7 +642,13 @@ impl Nac3 {
let builder = context.create_builder();
let modinit_return = main.get_function("__modinit__").unwrap().get_last_basic_block().unwrap().get_terminator().unwrap();
builder.position_before(&modinit_return);
builder.build_call(main.get_function("attributes_writeback").unwrap(), &[], "attributes_writeback");
builder
.build_call(
main.get_function("attributes_writeback").unwrap(),
&[],
"attributes_writeback",
)
.unwrap();
main.link_in_module(load_irrt(&context))
.map_err(|err| CompileError::new_err(err.to_string()))?;

View File

@ -1,4 +1,5 @@
use inkwell::{values::BasicValueEnum, AddressSpace, AtomicOrdering};
use inkwell::{values::{BasicValueEnum, CallSiteValue}, AddressSpace, AtomicOrdering};
use itertools::Either;
use nac3core::codegen::CodeGenContext;
/// Functions for manipulating the timeline.
@ -26,32 +27,28 @@ impl TimeFns for NowPinningTimeFns64 {
.module
.get_global("now")
.unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now"));
let now_hiptr =
ctx.builder.build_bitcast(now, i32_type.ptr_type(AddressSpace::default()), "now.hi.addr");
let BasicValueEnum::PointerValue(now_hiptr) = now_hiptr else {
unreachable!()
};
let now_hiptr = ctx.builder
.build_bitcast(now, i32_type.ptr_type(AddressSpace::default()), "now.hi.addr")
.map(BasicValueEnum::into_pointer_value)
.unwrap();
let now_loptr = unsafe {
ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(2, false)], "now.lo.addr")
};
}.unwrap();
let (BasicValueEnum::IntValue(now_hi), BasicValueEnum::IntValue(now_lo)) = (
ctx.builder.build_load(now_hiptr, "now.hi"),
ctx.builder.build_load(now_loptr, "now.lo"),
) else {
unreachable!()
};
let now_hi = ctx.builder.build_load(now_hiptr, "now.hi")
.map(BasicValueEnum::into_int_value)
.unwrap();
let now_lo = ctx.builder.build_load(now_loptr, "now.lo")
.map(BasicValueEnum::into_int_value)
.unwrap();
let zext_hi = ctx.builder.build_int_z_extend(now_hi, i64_type, "");
let shifted_hi = ctx.builder.build_left_shift(
zext_hi,
i64_type.const_int(32, false),
"",
);
let zext_lo = ctx.builder.build_int_z_extend(now_lo, i64_type, "");
ctx.builder.build_or(shifted_hi, zext_lo, "now_mu").into()
let zext_hi = ctx.builder.build_int_z_extend(now_hi, i64_type, "").unwrap();
let shifted_hi = ctx.builder
.build_left_shift(zext_hi, i64_type.const_int(32, false), "")
.unwrap();
let zext_lo = ctx.builder.build_int_z_extend(now_lo, i64_type, "").unwrap();
ctx.builder.build_or(shifted_hi, zext_lo, "now_mu").map(Into::into).unwrap()
}
fn emit_at_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>, t: BasicValueEnum<'ctx>) {
@ -59,39 +56,36 @@ impl TimeFns for NowPinningTimeFns64 {
let i64_type = ctx.ctx.i64_type();
let i64_32 = i64_type.const_int(32, false);
let BasicValueEnum::IntValue(time) = t else {
unreachable!()
};
let time = t.into_int_value();
let time_hi = ctx.builder.build_int_truncate(
ctx.builder.build_right_shift(time, i64_32, false, "time.hi"),
i32_type,
"",
);
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "time.lo");
let time_hi = ctx.builder
.build_int_truncate(
ctx.builder.build_right_shift(time, i64_32, false, "time.hi").unwrap(),
i32_type,
"",
)
.unwrap();
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "time.lo").unwrap();
let now = ctx
.module
.get_global("now")
.unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now"));
let now_hiptr = ctx.builder.build_bitcast(
now,
i32_type.ptr_type(AddressSpace::default()),
"now.hi.addr",
);
let BasicValueEnum::PointerValue(now_hiptr) = now_hiptr else {
unreachable!()
};
let now_hiptr = ctx.builder
.build_bitcast(now, i32_type.ptr_type(AddressSpace::default()), "now.hi.addr")
.map(BasicValueEnum::into_pointer_value)
.unwrap();
let now_loptr = unsafe {
ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(2, false)], "now.lo.addr")
};
}.unwrap();
ctx.builder
.build_store(now_hiptr, time_hi)
.unwrap()
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
ctx.builder
.build_store(now_loptr, time_lo)
.unwrap()
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
}
@ -107,57 +101,53 @@ impl TimeFns for NowPinningTimeFns64 {
.module
.get_global("now")
.unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now"));
let now_hiptr =
ctx.builder.build_bitcast(now, i32_type.ptr_type(AddressSpace::default()), "now.hi.addr");
let BasicValueEnum::PointerValue(now_hiptr) = now_hiptr else {
unreachable!()
};
let now_hiptr = ctx.builder
.build_bitcast(now, i32_type.ptr_type(AddressSpace::default()), "now.hi.addr")
.map(BasicValueEnum::into_pointer_value)
.unwrap();
let now_loptr = unsafe {
ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(2, false)], "now.lo.addr")
};
}.unwrap();
let (
BasicValueEnum::IntValue(now_hi),
BasicValueEnum::IntValue(now_lo),
BasicValueEnum::IntValue(dt),
) = (
ctx.builder.build_load(now_hiptr, "now.hi"),
ctx.builder.build_load(now_loptr, "now.lo"),
dt,
) else {
unreachable!()
};
let now_hi = ctx.builder.build_load(now_hiptr, "now.hi")
.map(BasicValueEnum::into_int_value)
.unwrap();
let now_lo = ctx.builder.build_load(now_loptr, "now.lo")
.map(BasicValueEnum::into_int_value)
.unwrap();
let dt = dt.into_int_value();
let zext_hi = ctx.builder.build_int_z_extend(now_hi, i64_type, "");
let shifted_hi = ctx.builder.build_left_shift(
zext_hi,
i64_type.const_int(32, false),
"",
);
let zext_lo = ctx.builder.build_int_z_extend(now_lo, i64_type, "");
let now_val = ctx.builder.build_or(shifted_hi, zext_lo, "now");
let zext_hi = ctx.builder.build_int_z_extend(now_hi, i64_type, "").unwrap();
let shifted_hi = ctx.builder
.build_left_shift(zext_hi, i64_type.const_int(32, false), "")
.unwrap();
let zext_lo = ctx.builder.build_int_z_extend(now_lo, i64_type, "").unwrap();
let now_val = ctx.builder.build_or(shifted_hi, zext_lo, "now").unwrap();
let time = ctx.builder.build_int_add(now_val, dt, "time");
let time_hi = ctx.builder.build_int_truncate(
ctx.builder.build_right_shift(
time,
i64_type.const_int(32, false),
false,
"",
),
i32_type,
"time.hi",
);
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "time.lo");
let time = ctx.builder.build_int_add(now_val, dt, "time").unwrap();
let time_hi = ctx.builder
.build_int_truncate(
ctx.builder.build_right_shift(
time,
i64_type.const_int(32, false),
false,
"",
).unwrap(),
i32_type,
"time.hi",
)
.unwrap();
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "time.lo").unwrap();
ctx.builder
.build_store(now_hiptr, time_hi)
.unwrap()
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
ctx.builder
.build_store(now_loptr, time_lo)
.unwrap()
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
}
@ -174,16 +164,16 @@ impl TimeFns for NowPinningTimeFns {
.module
.get_global("now")
.unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now"));
let now_raw = ctx.builder.build_load(now.as_pointer_value(), "now");
let BasicValueEnum::IntValue(now_raw) = now_raw else {
unreachable!()
};
let now_raw = ctx.builder.build_load(now.as_pointer_value(), "now")
.map(BasicValueEnum::into_int_value)
.unwrap();
let i64_32 = i64_type.const_int(32, false);
let now_lo = ctx.builder.build_left_shift(now_raw, i64_32, "now.lo");
let now_hi = ctx.builder.build_right_shift(now_raw, i64_32, false, "now.hi");
ctx.builder.build_or(now_lo, now_hi, "now_mu").into()
let now_lo = ctx.builder.build_left_shift(now_raw, i64_32, "now.lo").unwrap();
let now_hi = ctx.builder.build_right_shift(now_raw, i64_32, false, "now.hi").unwrap();
ctx.builder.build_or(now_lo, now_hi, "now_mu")
.map(Into::into)
.unwrap()
}
fn emit_at_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>, t: BasicValueEnum<'ctx>) {
@ -191,39 +181,36 @@ impl TimeFns for NowPinningTimeFns {
let i64_type = ctx.ctx.i64_type();
let i64_32 = i64_type.const_int(32, false);
let BasicValueEnum::IntValue(time) = t else {
unreachable!()
};
let time = t.into_int_value();
let time_hi = ctx.builder.build_int_truncate(
ctx.builder.build_right_shift(time, i64_32, false, ""),
i32_type,
"time.hi",
);
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "now_trunc");
let time_hi = ctx.builder
.build_int_truncate(
ctx.builder.build_right_shift(time, i64_32, false, "").unwrap(),
i32_type,
"time.hi",
)
.unwrap();
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "now_trunc").unwrap();
let now = ctx
.module
.get_global("now")
.unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now"));
let now_hiptr = ctx.builder.build_bitcast(
now,
i32_type.ptr_type(AddressSpace::default()),
"now.hi.addr",
);
let BasicValueEnum::PointerValue(now_hiptr) = now_hiptr else {
unreachable!()
};
let now_hiptr = ctx.builder
.build_bitcast(now, i32_type.ptr_type(AddressSpace::default()), "now.hi.addr")
.map(BasicValueEnum::into_pointer_value)
.unwrap();
let now_loptr = unsafe {
ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(1, false)], "now.lo.addr")
};
}.unwrap();
ctx.builder
.build_store(now_hiptr, time_hi)
.unwrap()
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
ctx.builder
.build_store(now_loptr, time_lo)
.unwrap()
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
}
@ -240,41 +227,41 @@ impl TimeFns for NowPinningTimeFns {
.module
.get_global("now")
.unwrap_or_else(|| ctx.module.add_global(i64_type, None, "now"));
let now_raw = ctx.builder.build_load(now.as_pointer_value(), "");
let now_raw = ctx.builder
.build_load(now.as_pointer_value(), "")
.map(BasicValueEnum::into_int_value)
.unwrap();
let (BasicValueEnum::IntValue(now_raw), BasicValueEnum::IntValue(dt)) = (now_raw, dt) else {
unreachable!()
};
let dt = dt.into_int_value();
let now_lo = ctx.builder.build_left_shift(now_raw, i64_32, "now.lo");
let now_hi = ctx.builder.build_right_shift(now_raw, i64_32, false, "now.hi");
let now_val = ctx.builder.build_or(now_lo, now_hi, "now_val");
let time = ctx.builder.build_int_add(now_val, dt, "time");
let time_hi = ctx.builder.build_int_truncate(
ctx.builder.build_right_shift(time, i64_32, false, "time.hi"),
i32_type,
"now_trunc",
);
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "time.lo");
let now_hiptr = ctx.builder.build_bitcast(
now,
i32_type.ptr_type(AddressSpace::default()),
"now.hi.addr",
);
let BasicValueEnum::PointerValue(now_hiptr) = now_hiptr else {
unreachable!()
};
let now_lo = ctx.builder.build_left_shift(now_raw, i64_32, "now.lo").unwrap();
let now_hi = ctx.builder.build_right_shift(now_raw, i64_32, false, "now.hi").unwrap();
let now_val = ctx.builder.build_or(now_lo, now_hi, "now_val").unwrap();
let time = ctx.builder.build_int_add(now_val, dt, "time").unwrap();
let time_hi = ctx.builder
.build_int_truncate(
ctx.builder.build_right_shift(time, i64_32, false, "time.hi").unwrap(),
i32_type,
"now_trunc",
)
.unwrap();
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "time.lo").unwrap();
let now_hiptr = ctx.builder
.build_bitcast(now, i32_type.ptr_type(AddressSpace::default()), "now.hi.addr")
.map(BasicValueEnum::into_pointer_value)
.unwrap();
let now_loptr = unsafe {
ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(1, false)], "now.lo.addr")
};
}.unwrap();
ctx.builder
.build_store(now_hiptr, time_hi)
.unwrap()
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
ctx.builder
.build_store(now_loptr, time_lo)
.unwrap()
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
}
@ -289,7 +276,10 @@ impl TimeFns for ExternTimeFns {
let now_mu = ctx.module.get_function("now_mu").unwrap_or_else(|| {
ctx.module.add_function("now_mu", ctx.ctx.i64_type().fn_type(&[], false), None)
});
ctx.builder.build_call(now_mu, &[], "now_mu").try_as_basic_value().left().unwrap()
ctx.builder.build_call(now_mu, &[], "now_mu")
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap()
}
fn emit_at_mu<'ctx>(&self, ctx: &mut CodeGenContext<'ctx, '_>, t: BasicValueEnum<'ctx>) {
@ -300,7 +290,7 @@ impl TimeFns for ExternTimeFns {
None,
)
});
ctx.builder.build_call(at_mu, &[t.into()], "at_mu");
ctx.builder.build_call(at_mu, &[t.into()], "at_mu").unwrap();
}
fn emit_delay_mu<'ctx>(
@ -315,7 +305,7 @@ impl TimeFns for ExternTimeFns {
None,
)
});
ctx.builder.build_call(delay_mu, &[dt.into()], "delay_mu");
ctx.builder.build_call(delay_mu, &[dt.into()], "delay_mu").unwrap();
}
}

View File

@ -12,5 +12,5 @@ fold = []
[dependencies]
lazy_static = "1.4"
parking_lot = "0.12"
string-interner = "0.14"
string-interner = "0.15"
fxhash = "0.2"

View File

@ -5,10 +5,10 @@ pub use crate::constant::*;
use std::{fmt, collections::HashMap, cell::RefCell};
use parking_lot::{Mutex, MutexGuard};
use string_interner::{DefaultBackend, DefaultSymbol, StringInterner, symbol::SymbolU32};
use string_interner::{DefaultBackend, StringInterner, symbol::SymbolU32};
use fxhash::FxBuildHasher;
pub type Interner = StringInterner<DefaultBackend<DefaultSymbol>, FxBuildHasher>;
pub type Interner = StringInterner<DefaultBackend, FxBuildHasher>;
lazy_static! {
static ref INTERNER: Mutex<Interner> = Mutex::new(StringInterner::with_hasher(FxBuildHasher::default()));
}

View File

@ -8,11 +8,11 @@ edition = "2021"
itertools = "0.12"
crossbeam = "0.8"
parking_lot = "0.12"
rayon = "1.5"
rayon = "1.8"
nac3parser = { path = "../nac3parser" }
[dependencies.inkwell]
version = "0.2"
version = "0.4"
default-features = false
features = ["llvm14-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"]

View File

@ -1,8 +1,9 @@
use inkwell::{
IntPredicate,
types::{AnyTypeEnum, BasicTypeEnum, IntType, PointerType},
values::{ArrayValue, BasicValueEnum, IntValue, PointerValue},
values::{ArrayValue, BasicValueEnum, CallSiteValue, IntValue, PointerValue},
};
use itertools::Either;
use crate::codegen::{
CodeGenContext,
CodeGenerator,
@ -79,7 +80,7 @@ impl<'ctx> ListValue<'ctx> {
self.get_ptr(),
&[llvm_i32.const_zero(), llvm_i32.const_zero()],
var_name.as_str(),
)
).unwrap()
}
}
@ -93,13 +94,13 @@ impl<'ctx> ListValue<'ctx> {
self.0,
&[llvm_i32.const_zero(), llvm_i32.const_int(1, true)],
var_name.as_str(),
)
).unwrap()
}
}
/// Stores the array of data elements `data` into this instance.
fn store_data(&self, ctx: &CodeGenContext<'ctx, '_>, data: PointerValue<'ctx>) {
ctx.builder.build_store(self.get_data_pptr(ctx), data);
ctx.builder.build_store(self.get_data_pptr(ctx), data).unwrap();
}
/// Convenience method for creating a new array storing data elements with the given element
@ -113,7 +114,7 @@ impl<'ctx> ListValue<'ctx> {
size: Option<IntValue<'ctx>>,
) {
let size = size.unwrap_or_else(|| self.load_size(ctx, None));
self.store_data(ctx, ctx.builder.build_array_alloca(elem_ty, size, ""));
self.store_data(ctx, ctx.builder.build_array_alloca(elem_ty, size, "").unwrap());
}
/// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr`
@ -132,7 +133,7 @@ impl<'ctx> ListValue<'ctx> {
debug_assert_eq!(size.get_type(), generator.get_size_type(ctx.ctx));
let psize = self.get_size_ptr(ctx);
ctx.builder.build_store(psize, size);
ctx.builder.build_store(psize, size).unwrap();
}
/// Returns the size of this `list` as a value.
@ -143,7 +144,9 @@ impl<'ctx> ListValue<'ctx> {
.or_else(|| self.1.map(|v| format!("{v}.size")))
.unwrap_or_default();
ctx.builder.build_load(psize, var_name.as_str()).into_int_value()
ctx.builder.build_load(psize, var_name.as_str())
.map(BasicValueEnum::into_int_value)
.unwrap()
}
}
@ -156,7 +159,9 @@ impl<'ctx> ListDataProxy<'ctx> {
pub fn get_ptr(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
let var_name = self.0.1.map(|v| format!("{v}.data")).unwrap_or_default();
ctx.builder.build_load(self.0.get_data_pptr(ctx), var_name.as_str()).into_pointer_value()
ctx.builder.build_load(self.0.get_data_pptr(ctx), var_name.as_str())
.map(BasicValueEnum::into_pointer_value)
.unwrap()
}
pub unsafe fn ptr_offset_unchecked(
@ -173,7 +178,7 @@ impl<'ctx> ListDataProxy<'ctx> {
self.get_ptr(ctx),
&[idx],
var_name.as_str(),
)
).unwrap()
}
/// Returns the pointer to the data at the `idx`-th index.
@ -191,7 +196,7 @@ impl<'ctx> ListDataProxy<'ctx> {
idx,
self.0.load_size(ctx, None),
""
);
).unwrap();
ctx.make_assert(
generator,
in_range,
@ -213,7 +218,7 @@ impl<'ctx> ListDataProxy<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ptr = self.ptr_offset_unchecked(ctx, idx, name);
ctx.builder.build_load(ptr, name.unwrap_or_default())
ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap()
}
/// Returns the data at the `idx`-th flattened index.
@ -225,7 +230,7 @@ impl<'ctx> ListDataProxy<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ptr = self.ptr_offset(ctx, generator, idx, name);
ctx.builder.build_load(ptr, name.unwrap_or_default())
ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap()
}
}
@ -286,7 +291,7 @@ impl<'ctx> RangeValue<'ctx> {
self.0,
&[llvm_i32.const_zero(), llvm_i32.const_int(0, false)],
var_name.as_str(),
)
).unwrap()
}
}
@ -299,7 +304,7 @@ impl<'ctx> RangeValue<'ctx> {
self.0,
&[llvm_i32.const_zero(), llvm_i32.const_int(1, false)],
var_name.as_str(),
)
).unwrap()
}
}
@ -312,7 +317,7 @@ impl<'ctx> RangeValue<'ctx> {
self.0,
&[llvm_i32.const_zero(), llvm_i32.const_int(2, false)],
var_name.as_str(),
)
).unwrap()
}
}
@ -325,7 +330,7 @@ impl<'ctx> RangeValue<'ctx> {
debug_assert_eq!(start.get_type().get_bit_width(), 32);
let pstart = self.get_start_ptr(ctx);
ctx.builder.build_store(pstart, start);
ctx.builder.build_store(pstart, start).unwrap();
}
/// Returns the `start` value of this `range`.
@ -336,7 +341,9 @@ impl<'ctx> RangeValue<'ctx> {
.or_else(|| self.1.map(|v| format!("{v}.start")))
.unwrap_or_default();
ctx.builder.build_load(pstart, var_name.as_str()).into_int_value()
ctx.builder.build_load(pstart, var_name.as_str())
.map(BasicValueEnum::into_int_value)
.unwrap()
}
/// Stores the `end` value into this instance.
@ -348,7 +355,7 @@ impl<'ctx> RangeValue<'ctx> {
debug_assert_eq!(end.get_type().get_bit_width(), 32);
let pend = self.get_start_ptr(ctx);
ctx.builder.build_store(pend, end);
ctx.builder.build_store(pend, end).unwrap();
}
/// Returns the `end` value of this `range`.
@ -359,7 +366,9 @@ impl<'ctx> RangeValue<'ctx> {
.or_else(|| self.1.map(|v| format!("{v}.end")))
.unwrap_or_default();
ctx.builder.build_load(pend, var_name.as_str()).into_int_value()
ctx.builder.build_load(pend, var_name.as_str())
.map(BasicValueEnum::into_int_value)
.unwrap()
}
/// Stores the `step` value into this instance.
@ -371,7 +380,7 @@ impl<'ctx> RangeValue<'ctx> {
debug_assert_eq!(step.get_type().get_bit_width(), 32);
let pstep = self.get_start_ptr(ctx);
ctx.builder.build_store(pstep, step);
ctx.builder.build_store(pstep, step).unwrap();
}
/// Returns the `step` value of this `range`.
@ -382,7 +391,9 @@ impl<'ctx> RangeValue<'ctx> {
.or_else(|| self.1.map(|v| format!("{v}.step")))
.unwrap_or_default();
ctx.builder.build_load(pstep, var_name.as_str()).into_int_value()
ctx.builder.build_load(pstep, var_name.as_str())
.map(BasicValueEnum::into_int_value)
.unwrap()
}
}
@ -472,7 +483,7 @@ impl<'ctx> NDArrayValue<'ctx> {
self.0,
&[llvm_i32.const_zero(), llvm_i32.const_zero()],
var_name.as_str(),
)
).unwrap()
}
}
@ -486,13 +497,15 @@ impl<'ctx> NDArrayValue<'ctx> {
debug_assert_eq!(ndims.get_type(), generator.get_size_type(ctx.ctx));
let pndims = self.get_ndims(ctx);
ctx.builder.build_store(pndims, ndims);
ctx.builder.build_store(pndims, ndims).unwrap();
}
/// Returns the number of dimensions of this `NDArray` as a value.
pub fn load_ndims(&self, ctx: &CodeGenContext<'ctx, '_>) -> IntValue<'ctx> {
let pndims = self.get_ndims(ctx);
ctx.builder.build_load(pndims, "").into_int_value()
ctx.builder.build_load(pndims, "")
.map(BasicValueEnum::into_int_value)
.unwrap()
}
/// Returns the double-indirection pointer to the `dims` array, as if by calling `getelementptr`
@ -506,13 +519,13 @@ impl<'ctx> NDArrayValue<'ctx> {
self.get_ptr(),
&[llvm_i32.const_zero(), llvm_i32.const_int(1, true)],
var_name.as_str(),
)
).unwrap()
}
}
/// Stores the array of dimension sizes `dims` into this instance.
fn store_dims(&self, ctx: &CodeGenContext<'ctx, '_>, dims: PointerValue<'ctx>) {
ctx.builder.build_store(self.get_dims_ptr(ctx), dims);
ctx.builder.build_store(self.get_dims_ptr(ctx), dims).unwrap();
}
/// Convenience method for creating a new array storing dimension sizes with the given `size`.
@ -522,7 +535,7 @@ impl<'ctx> NDArrayValue<'ctx> {
llvm_usize: IntType<'ctx>,
size: IntValue<'ctx>,
) {
self.store_dims(ctx, ctx.builder.build_array_alloca(llvm_usize, size, ""));
self.store_dims(ctx, ctx.builder.build_array_alloca(llvm_usize, size, "").unwrap());
}
/// Returns a proxy object to the field storing the size of each dimension of this `NDArray`.
@ -541,25 +554,24 @@ impl<'ctx> NDArrayValue<'ctx> {
self.get_ptr(),
&[llvm_i32.const_zero(), llvm_i32.const_int(2, true)],
var_name.as_str(),
)
).unwrap()
}
}
/// Stores the array of data elements `data` into this instance.
fn store_data(&self, ctx: &CodeGenContext<'ctx, '_>, data: PointerValue<'ctx>) {
ctx.builder.build_store(self.get_data_ptr(ctx), data);
ctx.builder.build_store(self.get_data_ptr(ctx), data).unwrap();
}
/// Convenience method for creating a new array storing data elements with the given element
/// type `elem_ty` and
/// `size`.
/// type `elem_ty` and `size`.
pub fn create_data(
&self,
ctx: &CodeGenContext<'ctx, '_>,
elem_ty: BasicTypeEnum<'ctx>,
size: IntValue<'ctx>,
) {
self.store_data(ctx, ctx.builder.build_array_alloca(elem_ty, size, ""));
self.store_data(ctx, ctx.builder.build_array_alloca(elem_ty, size, "").unwrap());
}
/// Returns a proxy object to the field storing the data of this `NDArray`.
@ -583,7 +595,9 @@ impl<'ctx> NDArrayDimsProxy<'ctx> {
pub fn get_ptr(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
let var_name = self.0.1.map(|v| format!("{v}.dims")).unwrap_or_default();
ctx.builder.build_load(self.0.get_dims_ptr(ctx), var_name.as_str()).into_pointer_value()
ctx.builder.build_load(self.0.get_dims_ptr(ctx), var_name.as_str())
.map(BasicValueEnum::into_pointer_value)
.unwrap()
}
/// Returns the pointer to the size of the `idx`-th dimension.
@ -599,7 +613,7 @@ impl<'ctx> NDArrayDimsProxy<'ctx> {
idx,
self.0.load_ndims(ctx),
""
);
).unwrap();
ctx.make_assert(
generator,
in_range,
@ -618,7 +632,7 @@ impl<'ctx> NDArrayDimsProxy<'ctx> {
self.get_ptr(ctx),
&[idx],
var_name.as_str(),
)
).unwrap()
}
}
@ -631,7 +645,9 @@ impl<'ctx> NDArrayDimsProxy<'ctx> {
name: Option<&str>,
) -> IntValue<'ctx> {
let ptr = self.ptr_offset(ctx, generator, idx, name);
ctx.builder.build_load(ptr, name.unwrap_or_default()).into_int_value()
ctx.builder.build_load(ptr, name.unwrap_or_default())
.map(BasicValueEnum::into_int_value)
.unwrap()
}
}
@ -644,7 +660,9 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
pub fn get_ptr(&self, ctx: &CodeGenContext<'ctx, '_>) -> PointerValue<'ctx> {
let var_name = self.0.1.map(|v| format!("{v}.data")).unwrap_or_default();
ctx.builder.build_load(self.0.get_data_ptr(ctx), var_name.as_str()).into_pointer_value()
ctx.builder.build_load(self.0.get_data_ptr(ctx), var_name.as_str())
.map(BasicValueEnum::into_pointer_value)
.unwrap()
}
pub unsafe fn ptr_to_data_flattened_unchecked(
@ -657,7 +675,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
self.get_ptr(ctx),
&[idx],
name.unwrap_or_default(),
)
).unwrap()
}
/// Returns the pointer to the data at the `idx`-th flattened index.
@ -677,7 +695,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
idx,
data_sz,
""
);
).unwrap();
ctx.make_assert(
generator,
in_range,
@ -699,7 +717,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ptr = self.ptr_to_data_flattened_unchecked(ctx, idx, name);
ctx.builder.build_load(ptr, name.unwrap_or_default())
ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap()
}
/// Returns the data at the `idx`-th flattened index.
@ -711,7 +729,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ptr = self.ptr_to_data_flattened(ctx, generator, idx, name);
ctx.builder.build_load(ptr, name.unwrap_or_default())
ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap()
}
pub unsafe fn ptr_offset_unchecked(
@ -725,7 +743,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
let Ok(indices_elem_ty) = IntType::try_from(indices_elem_ty) else {
panic!("Expected list[int32] but got {indices_elem_ty}")
};
debug_assert_eq!(indices_elem_ty.get_bit_width(), 32, "Expected list[int32] but got {indices_elem_ty}");
assert_eq!(indices_elem_ty.get_bit_width(), 32, "Expected list[int32] but got {indices_elem_ty}");
let index = call_ndarray_flatten_index(
generator,
@ -739,7 +757,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
self.get_ptr(ctx),
&[index],
name.unwrap_or_default(),
)
).unwrap()
}
}
@ -763,7 +781,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
&[index],
name.unwrap_or_default(),
)
}
}.unwrap()
}
/// Returns the pointer to the data at the index specified by `indices`.
@ -787,7 +805,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
llvm_usize.const_int(indices.get_type().len() as u64, false),
self.0.load_ndims(ctx),
""
);
).unwrap();
ctx.make_assert(
generator,
nidx_leq_ndims,
@ -802,8 +820,8 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
let dim_idx = ctx.builder
.build_extract_value(indices, idx, "")
.map(|v| v.into_int_value())
.map(|v| ctx.builder.build_int_z_extend_or_bit_cast(v, llvm_usize, ""))
.map(BasicValueEnum::into_int_value)
.map(|v| ctx.builder.build_int_z_extend_or_bit_cast(v, llvm_usize, "").unwrap())
.unwrap();
let dim_sz = self.0.get_dims().get(ctx, generator, i, None);
@ -812,7 +830,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
dim_idx,
dim_sz,
""
);
).unwrap();
ctx.make_assert(
generator,
@ -844,7 +862,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
indices.load_size(ctx, None),
self.0.load_ndims(ctx),
""
);
).unwrap();
ctx.make_assert(
generator,
nidx_leq_ndims,
@ -859,7 +877,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
ctx,
|generator, ctx| {
let i = generator.gen_var_alloc(ctx, llvm_usize.into(), None)?;
ctx.builder.build_store(i, llvm_usize.const_zero());
ctx.builder.build_store(i, llvm_usize.const_zero()).unwrap();
Ok(i)
},
@ -879,16 +897,20 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
let len = ctx
.builder
.build_call(min_fn, &[indices_len.into(), ndarray_len.into()], "")
.try_as_basic_value()
.map_left(|v| v.into_int_value())
.left()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap();
let i = ctx.builder.build_load(i_addr, "").into_int_value();
Ok(ctx.builder.build_int_compare(IntPredicate::SLT, i, len, ""))
let i = ctx.builder.build_load(i_addr, "")
.map(BasicValueEnum::into_int_value)
.unwrap();
Ok(ctx.builder.build_int_compare(IntPredicate::SLT, i, len, "").unwrap())
},
|generator, ctx, i_addr| {
let i = ctx.builder.build_load(i_addr, "").into_int_value();
let i = ctx.builder.build_load(i_addr, "")
.map(BasicValueEnum::into_int_value)
.unwrap();
let (dim_idx, dim_sz) = unsafe {
(
indices.get_data().get_unchecked(ctx, i, None).into_int_value(),
@ -901,7 +923,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
dim_idx,
dim_sz,
""
);
).unwrap();
ctx.make_assert(
generator,
@ -917,9 +939,10 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
|_, ctx, i_addr| {
let i = ctx.builder
.build_load(i_addr, "")
.into_int_value();
let i = ctx.builder.build_int_add(i, llvm_usize.const_int(1, true), "");
ctx.builder.build_store(i_addr, i);
.map(BasicValueEnum::into_int_value)
.unwrap();
let i = ctx.builder.build_int_add(i, llvm_usize.const_int(1, true), "").unwrap();
ctx.builder.build_store(i_addr, i).unwrap();
Ok(())
},
@ -938,7 +961,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ptr = self.ptr_offset_unchecked_const(ctx, generator, indices, name);
ctx.builder.build_load(ptr, name.unwrap_or_default())
ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap()
}
pub unsafe fn get_unsafe(
@ -949,7 +972,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ptr = self.ptr_offset_unchecked(ctx, generator, indices, name);
ctx.builder.build_load(ptr, name.unwrap_or_default())
ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap()
}
/// Returns the data at the index specified by `indices`.
@ -961,7 +984,7 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ptr = self.ptr_offset_const(ctx, generator, indices, name);
ctx.builder.build_load(ptr, name.unwrap_or_default())
ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap()
}
/// Returns the data at the index specified by `indices`.
@ -973,6 +996,6 @@ impl<'ctx> NDArrayDataProxy<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ptr = self.ptr_offset(ctx, generator, indices, name);
ctx.builder.build_load(ptr, name.unwrap_or_default())
ctx.builder.build_load(ptr, name.unwrap_or_default()).unwrap()
}
}

View File

@ -23,9 +23,9 @@ use inkwell::{
attributes::{Attribute, AttributeLoc},
IntPredicate,
types::{AnyType, BasicType, BasicTypeEnum},
values::{BasicValueEnum, FunctionValue, IntValue, PointerValue}
values::{BasicValueEnum, CallSiteValue, FunctionValue, IntValue, PointerValue}
};
use itertools::{chain, izip, Itertools};
use itertools::{chain, izip, Itertools, Either};
use nac3parser::ast::{
self, Boolop, Comprehension, Constant, Expr, ExprKind, Location, Operator, StrRef,
};
@ -69,8 +69,8 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
index: &[IntValue<'ctx>],
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let gep = unsafe { self.builder.build_gep(ptr, index, "") };
self.builder.build_load(gep, name.unwrap_or_default())
let gep = unsafe { self.builder.build_gep(ptr, index, "") }.unwrap();
self.builder.build_load(gep, name.unwrap_or_default()).unwrap()
}
fn get_subst_key(
@ -111,8 +111,10 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
SymbolValue::Bool(v) => self.ctx.i8_type().const_int(*v as u64, true).into(),
SymbolValue::Double(v) => self.ctx.f64_type().const_float(*v).into(),
SymbolValue::Str(v) => {
let str_ptr =
self.builder.build_global_string_ptr(v, "const").as_pointer_value().into();
let str_ptr = self.builder
.build_global_string_ptr(v, "const")
.map(|v| v.as_pointer_value().into())
.unwrap();
let size = generator.get_size_type(self.ctx).const_int(v.len() as u64, false);
let ty = self.get_llvm_type(generator, self.primitives.str).into_struct_type();
ty.const_named_struct(&[str_ptr, size.into()]).into()
@ -129,11 +131,11 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
ptr,
&[zero, self.ctx.i32_type().const_int(i as u64, false)],
"elemptr",
);
self.builder.build_store(p, val);
).unwrap();
self.builder.build_store(p, val).unwrap();
}
}
self.builder.build_load(ptr, "tup_val")
self.builder.build_load(ptr, "tup_val").unwrap()
}
SymbolValue::OptionSome(v) => {
let ty = match self.unifier.get_ty_immutable(ty).as_ref() {
@ -146,7 +148,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
};
let val = self.gen_symbol_val(generator, v, ty);
let ptr = generator.gen_var_alloc(self, val.get_type(), Some("default_opt_some")).unwrap();
self.builder.build_store(ptr, val);
self.builder.build_store(ptr, val).unwrap();
ptr.into()
}
SymbolValue::OptionNone => {
@ -254,8 +256,10 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
if let Some(v) = self.const_strings.get(v) {
Some(*v)
} else {
let str_ptr =
self.builder.build_global_string_ptr(v, "const").as_pointer_value().into();
let str_ptr = self.builder
.build_global_string_ptr(v, "const")
.map(|v| v.as_pointer_value().into())
.unwrap();
let size = generator.get_size_type(self.ctx).const_int(v.len() as u64, false);
let ty = self.get_llvm_type(generator, self.primitives.str);
let val =
@ -295,24 +299,24 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
};
let float = self.ctx.f64_type();
match (op, signed) {
(Operator::Add, _) => self.builder.build_int_add(lhs, rhs, "add").into(),
(Operator::Sub, _) => self.builder.build_int_sub(lhs, rhs, "sub").into(),
(Operator::Mult, _) => self.builder.build_int_mul(lhs, rhs, "mul").into(),
(Operator::Add, _) => self.builder.build_int_add(lhs, rhs, "add").map(Into::into).unwrap(),
(Operator::Sub, _) => self.builder.build_int_sub(lhs, rhs, "sub").map(Into::into).unwrap(),
(Operator::Mult, _) => self.builder.build_int_mul(lhs, rhs, "mul").map(Into::into).unwrap(),
(Operator::Div, true) => {
let left = self.builder.build_signed_int_to_float(lhs, float, "i2f");
let right = self.builder.build_signed_int_to_float(rhs, float, "i2f");
self.builder.build_float_div(left, right, "fdiv").into()
let left = self.builder.build_signed_int_to_float(lhs, float, "i2f").unwrap();
let right = self.builder.build_signed_int_to_float(rhs, float, "i2f").unwrap();
self.builder.build_float_div(left, right, "fdiv").map(Into::into).unwrap()
}
(Operator::Div, false) => {
let left = self.builder.build_unsigned_int_to_float(lhs, float, "i2f");
let right = self.builder.build_unsigned_int_to_float(rhs, float, "i2f");
self.builder.build_float_div(left, right, "fdiv").into()
let left = self.builder.build_unsigned_int_to_float(lhs, float, "i2f").unwrap();
let right = self.builder.build_unsigned_int_to_float(rhs, float, "i2f").unwrap();
self.builder.build_float_div(left, right, "fdiv").map(Into::into).unwrap()
}
(Operator::Mod, true) => self.builder.build_int_signed_rem(lhs, rhs, "mod").into(),
(Operator::Mod, false) => self.builder.build_int_unsigned_rem(lhs, rhs, "mod").into(),
(Operator::BitOr, _) => self.builder.build_or(lhs, rhs, "or").into(),
(Operator::BitXor, _) => self.builder.build_xor(lhs, rhs, "xor").into(),
(Operator::BitAnd, _) => self.builder.build_and(lhs, rhs, "and").into(),
(Operator::Mod, true) => self.builder.build_int_signed_rem(lhs, rhs, "mod").map(Into::into).unwrap(),
(Operator::Mod, false) => self.builder.build_int_unsigned_rem(lhs, rhs, "mod").map(Into::into).unwrap(),
(Operator::BitOr, _) => self.builder.build_or(lhs, rhs, "or").map(Into::into).unwrap(),
(Operator::BitXor, _) => self.builder.build_xor(lhs, rhs, "xor").map(Into::into).unwrap(),
(Operator::BitAnd, _) => self.builder.build_and(lhs, rhs, "and").map(Into::into).unwrap(),
// Sign-ness of bitshift operators are always determined by the left operand
(Operator::LShift | Operator::RShift, signed) => {
@ -322,15 +326,17 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
let common_type = lhs.get_type();
let rhs = if common_type.get_bit_width() > 32 {
if signed {
self.builder.build_int_s_extend(rhs, common_type, "")
self.builder.build_int_s_extend(rhs, common_type, "").unwrap()
} else {
self.builder.build_int_z_extend(rhs, common_type, "")
self.builder.build_int_z_extend(rhs, common_type, "").unwrap()
}
} else {
rhs
};
let rhs_gez = self.builder.build_int_compare(IntPredicate::SGE, rhs, common_type.const_zero(), "");
let rhs_gez = self.builder
.build_int_compare(IntPredicate::SGE, rhs, common_type.const_zero(), "")
.unwrap();
self.make_assert(
generator,
rhs_gez,
@ -341,14 +347,14 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
);
match *op {
Operator::LShift => self.builder.build_left_shift(lhs, rhs, "lshift").into(),
Operator::RShift => self.builder.build_right_shift(lhs, rhs, signed, "rshift").into(),
Operator::LShift => self.builder.build_left_shift(lhs, rhs, "lshift").map(Into::into).unwrap(),
Operator::RShift => self.builder.build_right_shift(lhs, rhs, signed, "rshift").map(Into::into).unwrap(),
_ => unreachable!()
}
}
(Operator::FloorDiv, true) => self.builder.build_int_signed_div(lhs, rhs, "floordiv").into(),
(Operator::FloorDiv, false) => self.builder.build_int_unsigned_div(lhs, rhs, "floordiv").into(),
(Operator::FloorDiv, true) => self.builder.build_int_signed_div(lhs, rhs, "floordiv").map(Into::into).unwrap(),
(Operator::FloorDiv, false) => self.builder.build_int_unsigned_div(lhs, rhs, "floordiv").map(Into::into).unwrap(),
(Operator::Pow, s) => integer_power(generator, self, lhs, rhs, s).into(),
// special implementation?
(Operator::MatMult, _) => unreachable!(),
@ -367,13 +373,13 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
};
let float = self.ctx.f64_type();
match op {
Operator::Add => self.builder.build_float_add(lhs, rhs, "fadd").into(),
Operator::Sub => self.builder.build_float_sub(lhs, rhs, "fsub").into(),
Operator::Mult => self.builder.build_float_mul(lhs, rhs, "fmul").into(),
Operator::Div => self.builder.build_float_div(lhs, rhs, "fdiv").into(),
Operator::Mod => self.builder.build_float_rem(lhs, rhs, "fmod").into(),
Operator::Add => self.builder.build_float_add(lhs, rhs, "fadd").map(Into::into).unwrap(),
Operator::Sub => self.builder.build_float_sub(lhs, rhs, "fsub").map(Into::into).unwrap(),
Operator::Mult => self.builder.build_float_mul(lhs, rhs, "fmul").map(Into::into).unwrap(),
Operator::Div => self.builder.build_float_div(lhs, rhs, "fdiv").map(Into::into).unwrap(),
Operator::Mod => self.builder.build_float_rem(lhs, rhs, "fmod").map(Into::into).unwrap(),
Operator::FloorDiv => {
let div = self.builder.build_float_div(lhs, rhs, "fdiv");
let div = self.builder.build_float_div(lhs, rhs, "fdiv").unwrap();
let floor_intrinsic =
self.module.get_function("llvm.floor.f64").unwrap_or_else(|| {
let fn_type = float.fn_type(&[float.into()], false);
@ -381,8 +387,8 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
});
self.builder
.build_call(floor_intrinsic, &[div.into()], "floor")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap()
}
Operator::Pow => {
@ -392,8 +398,9 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
});
self.builder
.build_call(pow_intrinsic, &[lhs.into(), rhs.into()], "f_pow")
.try_as_basic_value()
.unwrap_left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap()
}
// special implementation?
_ => unimplemented!(),
@ -424,8 +431,17 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
let byval_id = Attribute::get_named_enum_kind_id("byval");
let offset = if fun.get_enum_attribute(AttributeLoc::Param(0), sret_id).is_some() {
return_slot = Some(self.builder.build_alloca(fun.get_type().get_param_types()[0]
.into_pointer_type().get_element_type().into_struct_type(), call_name));
return_slot = Some(self.builder
.build_alloca(
fun.get_type()
.get_param_types()[0]
.into_pointer_type()
.get_element_type()
.into_struct_type(),
call_name
)
.unwrap()
);
loc_params.push((*return_slot.as_ref().unwrap()).into());
1
} else {
@ -440,7 +456,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
}
let slot = gen_var(self, param.get_type(), Some(call_name)).unwrap();
loc_params.push(slot.into());
self.builder.build_store(slot, *param);
self.builder.build_store(slot, *param).unwrap();
} else if !loc_params.is_empty() {
loc_params.push(*param);
}
@ -460,7 +476,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
&& val_ty.get_element_type().is_struct_type()
} =>
{
self.builder.build_bitcast(*val, arg_ty, "call_arg_cast")
self.builder.build_bitcast(*val, arg_ty, "call_arg_cast").unwrap()
}
_ => *val,
})
@ -471,16 +487,20 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
let result = self
.builder
.build_invoke(fun, &params, then_block, target, call_name)
.try_as_basic_value()
.left();
.map(CallSiteValue::try_as_basic_value)
.map(Either::left)
.unwrap();
self.builder.position_at_end(then_block);
result
} else {
let param: Vec<_> = params.iter().map(|v| (*v).into()).collect();
self.builder.build_call(fun, &param, call_name).try_as_basic_value().left()
self.builder.build_call(fun, &param, call_name)
.map(CallSiteValue::try_as_basic_value)
.map(Either::left)
.unwrap()
};
if let Some(slot) = return_slot {
Some(self.builder.build_load(slot, call_name))
Some(self.builder.build_load(slot, call_name).unwrap())
} else {
result
}
@ -514,26 +534,28 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
let int32 = self.ctx.i32_type();
let zero = int32.const_zero();
unsafe {
let id_ptr = self.builder.build_in_bounds_gep(zelf, &[zero, zero], "exn.id");
let id_ptr = self.builder
.build_in_bounds_gep(zelf, &[zero, zero], "exn.id")
.unwrap();
let id = self.resolver.get_string_id(name);
self.builder.build_store(id_ptr, int32.const_int(id as u64, false));
self.builder.build_store(id_ptr, int32.const_int(id as u64, false)).unwrap();
let ptr = self.builder.build_in_bounds_gep(
zelf,
&[zero, int32.const_int(5, false)],
"exn.msg",
);
self.builder.build_store(ptr, msg);
).unwrap();
self.builder.build_store(ptr, msg).unwrap();
let i64_zero = self.ctx.i64_type().const_zero();
for (i, attr_ind) in [6, 7, 8].iter().enumerate() {
let ptr = self.builder.build_in_bounds_gep(
zelf,
&[zero, int32.const_int(*attr_ind, false)],
"exn.param",
);
).unwrap();
let val = params[i].map_or(i64_zero, |v| {
self.builder.build_int_s_extend(v, self.ctx.i64_type(), "sext")
self.builder.build_int_s_extend(v, self.ctx.i64_type(), "sext").unwrap()
});
self.builder.build_store(ptr, val);
self.builder.build_store(ptr, val).unwrap();
}
}
gen_raise(generator, self, Some(&zelf.into()), loc);
@ -577,14 +599,14 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
let cond = self
.builder
.build_call(expect_fun, &[cond.into(), i1_true.into()], "expect")
.try_as_basic_value()
.left()
.unwrap()
.into_int_value();
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap();
let current_fun = self.builder.get_insert_block().unwrap().get_parent().unwrap();
let then_block = self.ctx.append_basic_block(current_fun, "succ");
let exn_block = self.ctx.append_basic_block(current_fun, "fail");
self.builder.build_conditional_branch(cond, then_block, exn_block);
self.builder.build_conditional_branch(cond, then_block, exn_block).unwrap();
self.builder.position_at_end(exn_block);
self.raise_exn(generator, err_name, err_msg, params, loc);
self.builder.position_at_end(then_block);
@ -607,7 +629,7 @@ pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>(
let fun_id = methods.iter().find(|method| method.0 == "__init__".into()).map(|method| method.2);
let ty = ctx.get_llvm_type(generator, signature.ret).into_pointer_type();
let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap();
let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").into();
let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").map(Into::into).unwrap();
// call `__init__` if there is one
if let Some(fun_id) = fun_id {
let mut sign = signature.clone();
@ -898,14 +920,14 @@ pub fn allocate_list<'ctx, G: CodeGenerator>(
let arr_str_ptr = ctx.builder.build_alloca(
arr_ty, format!("{}.addr", name.unwrap_or("list")).as_str()
);
).unwrap();
let list = ListValue::from_ptr_val(arr_str_ptr, size_t, Some("list"));
let length = ctx.builder.build_int_z_extend(
length,
size_t,
""
);
).unwrap();
list.store_size(ctx, generator, length);
list.create_data(ctx, ty, None);
@ -929,7 +951,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
let body_bb = ctx.ctx.append_basic_block(current, "listcomp.body");
let cont_bb = ctx.ctx.append_basic_block(current, "listcomp.cont");
ctx.builder.build_unconditional_branch(init_bb);
ctx.builder.build_unconditional_branch(init_bb).unwrap();
ctx.builder.position_at_end(init_bb);
@ -939,7 +961,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
} else {
for bb in [test_bb, body_bb, cont_bb] {
ctx.builder.position_at_end(bb);
ctx.builder.build_unreachable();
ctx.builder.build_unreachable().unwrap();
}
return Ok(None)
@ -950,7 +972,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
let zero_32 = int32.const_zero();
let index = generator.gen_var_alloc(ctx, size_t.into(), Some("index.addr"))?;
ctx.builder.build_store(index, zero_size_t);
ctx.builder.build_store(index, zero_size_t).unwrap();
let elem_ty = ctx.get_llvm_type(generator, elt.custom.unwrap());
let is_range = ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range);
@ -960,22 +982,23 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
if is_range {
let iter_val = RangeValue::from_ptr_val(iter_val.into_pointer_value(), Some("range"));
let (start, stop, step) = destructure_range(ctx, iter_val);
let diff = ctx.builder.build_int_sub(stop, start, "diff");
let diff = ctx.builder.build_int_sub(stop, start, "diff").unwrap();
// add 1 to the length as the value is rounded to zero
// the length may be 1 more than the actual length if the division is exact, but the
// length is a upper bound only anyway so it does not matter.
let length = ctx.builder.build_int_signed_div(diff, step, "div");
let length = ctx.builder.build_int_add(length, int32.const_int(1, false), "add1");
let length = ctx.builder.build_int_signed_div(diff, step, "div").unwrap();
let length = ctx.builder.build_int_add(length, int32.const_int(1, false), "add1").unwrap();
// in case length is non-positive
let is_valid =
ctx.builder.build_int_compare(IntPredicate::SGT, length, zero_32, "check");
let is_valid = ctx.builder
.build_int_compare(IntPredicate::SGT, length, zero_32, "check")
.unwrap();
let list_alloc_size = ctx.builder.build_select(
is_valid,
ctx.builder.build_int_z_extend_or_bit_cast(length, size_t, "z_ext_len"),
ctx.builder.build_int_z_extend_or_bit_cast(length, size_t, "z_ext_len").unwrap(),
zero_size_t,
"listcomp.alloc_size"
);
).unwrap();
list = allocate_list(
generator,
ctx,
@ -986,27 +1009,25 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
list_content = list.get_data().get_ptr(ctx);
let i = generator.gen_store_target(ctx, target, Some("i.addr"))?.unwrap();
ctx.builder.build_store(i, ctx.builder.build_int_sub(start, step, "start_init"));
ctx.builder
.build_store(i, ctx.builder.build_int_sub(start, step, "start_init").unwrap())
.unwrap();
ctx.builder.build_conditional_branch(
gen_in_range_check(ctx, start, stop, step),
test_bb,
cont_bb,
);
ctx.builder
.build_conditional_branch(gen_in_range_check(ctx, start, stop, step), test_bb, cont_bb)
.unwrap();
ctx.builder.position_at_end(test_bb);
// add and test
let tmp = ctx.builder.build_int_add(
ctx.builder.build_load(i, "i").into_int_value(),
ctx.builder.build_load(i, "i").map(BasicValueEnum::into_int_value).unwrap(),
step,
"start_loop",
);
ctx.builder.build_store(i, tmp);
ctx.builder.build_conditional_branch(
gen_in_range_check(ctx, tmp, stop, step),
body_bb,
cont_bb,
);
).unwrap();
ctx.builder.build_store(i, tmp).unwrap();
ctx.builder
.build_conditional_branch(gen_in_range_check(ctx, tmp, stop, step), body_bb, cont_bb)
.unwrap();
ctx.builder.position_at_end(body_bb);
} else {
@ -1021,15 +1042,15 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
list_content = list.get_data().get_ptr(ctx);
let counter = generator.gen_var_alloc(ctx, size_t.into(), Some("counter.addr"))?;
// counter = -1
ctx.builder.build_store(counter, size_t.const_int(u64::MAX, true));
ctx.builder.build_unconditional_branch(test_bb);
ctx.builder.build_store(counter, size_t.const_int(u64::MAX, true)).unwrap();
ctx.builder.build_unconditional_branch(test_bb).unwrap();
ctx.builder.position_at_end(test_bb);
let tmp = ctx.builder.build_load(counter, "i").into_int_value();
let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc");
ctx.builder.build_store(counter, tmp);
let cmp = ctx.builder.build_int_compare(IntPredicate::SLT, tmp, length, "cmp");
ctx.builder.build_conditional_branch(cmp, body_bb, cont_bb);
let tmp = ctx.builder.build_load(counter, "i").map(BasicValueEnum::into_int_value).unwrap();
let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc").unwrap();
ctx.builder.build_store(counter, tmp).unwrap();
let cmp = ctx.builder.build_int_compare(IntPredicate::SLT, tmp, length, "cmp").unwrap();
ctx.builder.build_conditional_branch(cmp, body_bb, cont_bb).unwrap();
ctx.builder.position_at_end(body_bb);
let arr_ptr = ctx
@ -1042,7 +1063,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
// Emits the content of `cont_bb`
let emit_cont_bb = |ctx: &CodeGenContext<'ctx, '_>, generator: &dyn CodeGenerator, list: ListValue<'ctx>| {
ctx.builder.position_at_end(cont_bb);
list.store_size(ctx, generator, ctx.builder.build_load(index, "index").into_int_value());
list.store_size(ctx, generator, ctx.builder.build_load(index, "index").map(BasicValueEnum::into_int_value).unwrap());
};
for cond in ifs {
@ -1057,7 +1078,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
};
let result = generator.bool_to_i1(ctx, result);
let succ = ctx.ctx.append_basic_block(current, "then");
ctx.builder.build_conditional_branch(result, succ, test_bb);
ctx.builder.build_conditional_branch(result, succ, test_bb).unwrap();
ctx.builder.position_at_end(succ);
}
@ -1068,13 +1089,17 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
return Ok(None)
};
let i = ctx.builder.build_load(index, "i").into_int_value();
let elem_ptr = unsafe { ctx.builder.build_gep(list_content, &[i], "elem_ptr") };
let i = ctx.builder.build_load(index, "i").map(BasicValueEnum::into_int_value).unwrap();
let elem_ptr = unsafe { ctx.builder.build_gep(list_content, &[i], "elem_ptr") }.unwrap();
let val = elem.to_basic_value_enum(ctx, generator, elt.custom.unwrap())?;
ctx.builder.build_store(elem_ptr, val);
ctx.builder.build_store(elem_ptr, val).unwrap();
ctx.builder
.build_store(index, ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc"));
ctx.builder.build_unconditional_branch(test_bb);
.build_store(
index,
ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc").unwrap(),
)
.unwrap();
ctx.builder.build_unconditional_branch(test_bb).unwrap();
emit_cont_bb(ctx, generator, list);
@ -1133,8 +1158,9 @@ pub fn gen_binop_expr<'ctx, G: CodeGenerator>(
});
let res = ctx.builder
.build_call(pow_intr, &[left_val.into(), right_val.into()], "f_pow_i")
.try_as_basic_value()
.unwrap_left();
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(Some(res.into()))
} else {
let left_ty_enum = ctx.unifier.get_ty_immutable(left.custom.unwrap());
@ -1244,7 +1270,7 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>(
let len = v.load_ndims(ctx);
ctx.make_assert(
generator,
ctx.builder.build_int_compare(IntPredicate::SGT, len, llvm_usize.const_zero(), ""),
ctx.builder.build_int_compare(IntPredicate::SGT, len, llvm_usize.const_zero(), "").unwrap(),
"0:IndexError",
"too many indices for array: array is {0}-dimensional but 1 were indexed",
[Some(len), None, None],
@ -1302,7 +1328,7 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>(
ndarray.store_ndims(
ctx,
generator,
ctx.builder.build_int_sub(num_dims, llvm_usize.const_int(1, false), ""),
ctx.builder.build_int_sub(num_dims, llvm_usize.const_int(1, false), "").unwrap(),
);
let ndarray_num_dims = ndarray.load_ndims(ctx);
@ -1336,25 +1362,34 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>(
ctx.builder.build_call(
memcpy_fn,
&[
ctx.builder.build_bitcast(
ndarray.get_dims().get_ptr(ctx),
llvm_pi8,
"",
).into(),
ctx.builder.build_bitcast(
v_dims_src_ptr,
llvm_pi8,
"",
).into(),
ctx.builder.build_int_mul(
ndarray_num_dims.into(),
llvm_usize.size_of(),
"",
).into(),
ctx.builder
.build_bitcast(
ndarray.get_dims().get_ptr(ctx),
llvm_pi8,
"",
)
.map(Into::into)
.unwrap(),
ctx.builder
.build_bitcast(
v_dims_src_ptr,
llvm_pi8,
"",
)
.map(Into::into)
.unwrap(),
ctx.builder
.build_int_mul(
ndarray_num_dims.into(),
llvm_usize.size_of(),
"",
)
.map(Into::into)
.unwrap(),
llvm_i1.const_zero().into(),
],
"",
);
).unwrap();
let ndarray_num_elems = call_ndarray_calc_size(
generator,
@ -1373,25 +1408,34 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>(
ctx.builder.build_call(
memcpy_fn,
&[
ctx.builder.build_bitcast(
ndarray.get_data().get_ptr(ctx),
llvm_pi8,
"",
).into(),
ctx.builder.build_bitcast(
v_data_src_ptr,
llvm_pi8,
"",
).into(),
ctx.builder.build_int_mul(
ndarray_num_elems.into(),
llvm_ndarray_data_t.size_of().unwrap(),
"",
).into(),
ctx.builder
.build_bitcast(
ndarray.get_data().get_ptr(ctx),
llvm_pi8,
"",
)
.map(Into::into)
.unwrap(),
ctx.builder
.build_bitcast(
v_data_src_ptr,
llvm_pi8,
"",
)
.map(Into::into)
.unwrap(),
ctx.builder
.build_int_mul(
ndarray_num_elems.into(),
llvm_ndarray_data_t.size_of().unwrap(),
"",
)
.map(Into::into)
.unwrap(),
llvm_i1.const_zero().into(),
],
"",
);
).unwrap();
Ok(Some(v.get_ptr().into()))
}
@ -1442,7 +1486,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
}
}
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) {
Some((ptr, None, _)) => ctx.builder.build_load(*ptr, id.to_string().as_str()).into(),
Some((ptr, None, _)) => ctx.builder.build_load(*ptr, id.to_string().as_str()).map(Into::into).unwrap(),
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
None => {
let resolver = ctx.resolver.clone();
@ -1480,7 +1524,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
for (i, v) in elements.iter().enumerate() {
let elem_ptr = arr_ptr
.ptr_offset(ctx, generator, usize.const_int(i as u64, false), Some("elem_ptr"));
ctx.builder.build_store(elem_ptr, *v);
ctx.builder.build_store(elem_ptr, *v).unwrap();
}
arr_str_ptr.get_ptr().into()
}
@ -1500,18 +1544,18 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec();
let tuple_ty = ctx.ctx.struct_type(&element_ty, false);
let tuple_ptr = ctx.builder.build_alloca(tuple_ty, "tuple");
let tuple_ptr = ctx.builder.build_alloca(tuple_ty, "tuple").unwrap();
for (i, v) in element_val.into_iter().enumerate() {
unsafe {
let ptr = ctx.builder.build_in_bounds_gep(
tuple_ptr,
&[zero, int32.const_int(i as u64, false)],
"ptr",
);
ctx.builder.build_store(ptr, v);
).unwrap();
ctx.builder.build_store(ptr, v).unwrap();
}
}
ctx.builder.build_load(tuple_ptr, "tup_val").into()
ctx.builder.build_load(tuple_ptr, "tup_val").map(Into::into).unwrap()
}
ExprKind::Attribute { value, attr, .. } => {
// note that we would handle class methods directly in calls
@ -1548,18 +1592,18 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
let a_bb = ctx.ctx.append_basic_block(current, "a");
let b_bb = ctx.ctx.append_basic_block(current, "b");
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
ctx.builder.build_conditional_branch(left, a_bb, b_bb);
ctx.builder.build_conditional_branch(left, a_bb, b_bb).unwrap();
let (a, b) = match op {
Boolop::Or => {
ctx.builder.position_at_end(a_bb);
let a = ctx.ctx.i8_type().const_int(1, false);
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
ctx.builder.position_at_end(b_bb);
let b = if let Some(v) = generator.gen_expr(ctx, &values[1])? {
let b = v.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?.into_int_value();
let b = generator.bool_to_i8(ctx, b);
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
Some(b)
} else {
@ -1573,7 +1617,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
let a = if let Some(v) = generator.gen_expr(ctx, &values[1])? {
let a = v.to_basic_value_enum(ctx, generator, values[1].custom.unwrap())?.into_int_value();
let a = generator.bool_to_i8(ctx, a);
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
Some(a)
} else {
@ -1582,7 +1626,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
ctx.builder.position_at_end(b_bb);
let b = ctx.ctx.i8_type().const_zero();
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
(a, Some(b))
}
@ -1591,7 +1635,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
ctx.builder.position_at_end(cont_bb);
match (a, b) {
(Some(a), Some(b)) => {
let phi = ctx.builder.build_phi(ctx.ctx.i8_type(), "");
let phi = ctx.builder.build_phi(ctx.ctx.i8_type(), "").unwrap();
phi.add_incoming(&[(&a, a_bb), (&b, b_bb)]);
phi.as_basic_value().into()
}
@ -1614,22 +1658,22 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
let val = val.into_int_value();
match op {
ast::Unaryop::Invert | ast::Unaryop::Not => {
ctx.builder.build_not(val, "not").into()
ctx.builder.build_not(val, "not").map(Into::into).unwrap()
}
_ => val.into(),
}
} else if [ctx.primitives.int32, ctx.primitives.int64, ctx.primitives.uint32, ctx.primitives.uint64].contains(&ty) {
let val = val.into_int_value();
match op {
ast::Unaryop::USub => ctx.builder.build_int_neg(val, "neg").into(),
ast::Unaryop::Invert => ctx.builder.build_not(val, "not").into(),
ast::Unaryop::Not => ctx.builder.build_xor(val, val.get_type().const_all_ones(), "not").into(),
ast::Unaryop::USub => ctx.builder.build_int_neg(val, "neg").map(Into::into).unwrap(),
ast::Unaryop::Invert => ctx.builder.build_not(val, "not").map(Into::into).unwrap(),
ast::Unaryop::Not => ctx.builder.build_xor(val, val.get_type().const_all_ones(), "not").map(Into::into).unwrap(),
ast::Unaryop::UAdd => val.into(),
}
} else if ty == ctx.primitives.float {
let val = val.into_float_value();
match op {
ast::Unaryop::USub => ctx.builder.build_float_neg(val, "neg").into(),
ast::Unaryop::USub => ctx.builder.build_float_neg(val, "neg").map(Into::into).unwrap(),
ast::Unaryop::Not => ctx
.builder
.build_float_compare(
@ -1638,7 +1682,8 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
val.get_type().const_zero(),
"not",
)
.into(),
.map(Into::into)
.unwrap(),
_ => val.into(),
}
} else {
@ -1695,7 +1740,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
_ => unreachable!(),
};
ctx.builder.build_int_compare(op, lhs, rhs, "cmp")
ctx.builder.build_int_compare(op, lhs, rhs, "cmp").unwrap()
} else if ty == ctx.primitives.float {
let BasicValueEnum::FloatValue(lhs) = (match generator.gen_expr(ctx, lhs)? {
Some(v) => v.to_basic_value_enum(ctx, generator, lhs.custom.unwrap())?,
@ -1716,11 +1761,11 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
ast::Cmpop::GtE => inkwell::FloatPredicate::OGE,
_ => unreachable!(),
};
ctx.builder.build_float_compare(op, lhs, rhs, "cmp")
ctx.builder.build_float_compare(op, lhs, rhs, "cmp").unwrap()
} else {
unimplemented!()
};
Ok(prev?.map(|v| ctx.builder.build_and(v, current, "cmp")).or(Some(current)))
Ok(prev?.map(|v| ctx.builder.build_and(v, current, "cmp").unwrap()).or(Some(current)))
})?;
match cmp_val {
@ -1740,13 +1785,13 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
None
} else {
let llvm_ty = ctx.get_llvm_type(generator, body_ty);
Some(ctx.builder.build_alloca(llvm_ty, "if_exp_result"))
Some(ctx.builder.build_alloca(llvm_ty, "if_exp_result").unwrap())
};
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
let then_bb = ctx.ctx.append_basic_block(current, "then");
let else_bb = ctx.ctx.append_basic_block(current, "else");
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
ctx.builder.build_conditional_branch(test, then_bb, else_bb);
ctx.builder.build_conditional_branch(test, then_bb, else_bb).unwrap();
ctx.builder.position_at_end(then_bb);
let a = generator.gen_expr(ctx, body)?;
@ -1758,7 +1803,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
Some(ctx.builder.build_store(v, a))
}
};
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
}
ctx.builder.position_at_end(else_bb);
@ -1771,12 +1816,12 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
Some(ctx.builder.build_store(v, b))
}
};
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
}
ctx.builder.position_at_end(cont_bb);
if let Some(v) = result {
ctx.builder.build_load(v, "if_exp_val_load").into()
ctx.builder.build_load(v, "if_exp_val_load").map(Into::into).unwrap()
} else {
return Ok(None)
}
@ -1869,7 +1914,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
current_fun,
"unwrap_none_exception"
);
ctx.builder.build_unconditional_branch(exn_block);
ctx.builder.build_unconditional_branch(exn_block).unwrap();
ctx.builder.position_at_end(exn_block);
ctx.raise_exn(
generator,
@ -1886,12 +1931,12 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
Ok(Some(ctx.builder.build_load(
ptr,
"unwrap_none_unreachable_load"
).into()))
).map(Into::into).unwrap()))
}
Some(v) => Ok(Some(v)),
},
ValueEnum::Dynamic(BasicValueEnum::PointerValue(ptr)) => {
let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null");
let not_null = ctx.builder.build_is_not_null(ptr, "unwrap_not_null").unwrap();
ctx.make_assert(
generator,
not_null,
@ -1903,7 +1948,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
return Ok(Some(ctx.builder.build_load(
ptr,
"unwrap_some_load"
).into()))
).map(Into::into).unwrap()))
}
ValueEnum::Dynamic(_) => unreachable!("option must be static or ptr")
}
@ -1951,12 +1996,13 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
step,
zero,
"is_neg",
),
ctx.builder.build_int_sub(end, one, "e_min_one"),
ctx.builder.build_int_add(end, one, "e_add_one"),
).unwrap(),
ctx.builder.build_int_sub(end, one, "e_min_one").unwrap(),
ctx.builder.build_int_add(end, one, "e_add_one").unwrap(),
"final_e",
)
.into_int_value(),
.map(BasicValueEnum::into_int_value)
.unwrap(),
step,
);
let res_array_ret = allocate_list(generator, ctx, ty, length, Some("ret"));
@ -1985,19 +2031,20 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
raw_index,
generator.get_size_type(ctx.ctx),
"sext",
);
).unwrap();
// handle negative index
let is_negative = ctx.builder.build_int_compare(
IntPredicate::SLT,
raw_index,
generator.get_size_type(ctx.ctx).const_zero(),
"is_neg",
);
let adjusted = ctx.builder.build_int_add(raw_index, len, "adjusted");
).unwrap();
let adjusted = ctx.builder.build_int_add(raw_index, len, "adjusted").unwrap();
let index = ctx
.builder
.build_select(is_negative, adjusted, raw_index, "index")
.into_int_value();
.map(BasicValueEnum::into_int_value)
.unwrap();
// unsigned less than is enough, because negative index after adjustment is
// bigger than the length (for unsigned cmp)
let bound_check = ctx.builder.build_int_compare(
@ -2005,7 +2052,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
index,
len,
"inbound",
);
).unwrap();
ctx.make_assert(
generator,
bound_check,

View File

@ -11,9 +11,10 @@ use inkwell::{
memory_buffer::MemoryBuffer,
module::Module,
types::{BasicTypeEnum, IntType},
values::{ArrayValue, FloatValue, IntValue, PointerValue},
values::{ArrayValue, BasicValueEnum, CallSiteValue, FloatValue, IntValue, PointerValue},
AddressSpace, IntPredicate,
};
use itertools::Either;
use nac3parser::ast::Expr;
#[must_use]
@ -63,7 +64,7 @@ pub fn integer_power<'ctx>(
exp,
exp.get_type().const_zero(),
"assert_int_pow_ge_0",
);
).unwrap();
ctx.make_assert(
generator,
ge_zero,
@ -74,9 +75,10 @@ pub fn integer_power<'ctx>(
);
ctx.builder
.build_call(pow_fun, &[base.into(), exp.into()], "call_int_pow")
.try_as_basic_value()
.unwrap_left()
.into_int_value()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap()
}
pub fn calculate_len_for_slice_range<'ctx>(
@ -99,7 +101,7 @@ pub fn calculate_len_for_slice_range<'ctx>(
step,
step.get_type().const_zero(),
"range_step_ne",
);
).unwrap();
ctx.make_assert(
generator,
not_zero,
@ -110,10 +112,10 @@ pub fn calculate_len_for_slice_range<'ctx>(
);
ctx.builder
.build_call(len_func, &[start.into(), end.into(), step.into()], "calc_len")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap()
.into_int_value()
}
/// NOTE: the output value of the end index of this function should be compared ***inclusively***,
@ -168,7 +170,7 @@ pub fn handle_slice_indices<'ctx, G: CodeGenerator>(
let zero = int32.const_zero();
let one = int32.const_int(1, false);
let length = list.load_size(ctx, Some("length"));
let length = ctx.builder.build_int_truncate_or_bit_cast(length, int32, "leni32");
let length = ctx.builder.build_int_truncate_or_bit_cast(length, int32, "leni32").unwrap();
Ok(Some(match (start, end, step) {
(s, e, None) => (
if let Some(s) = s.as_ref() {
@ -188,7 +190,7 @@ pub fn handle_slice_indices<'ctx, G: CodeGenerator>(
} else {
length
};
ctx.builder.build_int_sub(e, one, "final_end")
ctx.builder.build_int_sub(e, one, "final_end").unwrap()
},
one,
),
@ -204,7 +206,7 @@ pub fn handle_slice_indices<'ctx, G: CodeGenerator>(
step,
step.get_type().const_zero(),
"range_step_ne",
);
).unwrap();
ctx.make_assert(
generator,
not_zero,
@ -213,8 +215,8 @@ pub fn handle_slice_indices<'ctx, G: CodeGenerator>(
[None, None, None],
ctx.current_loc,
);
let len_id = ctx.builder.build_int_sub(length, one, "lenmin1");
let neg = ctx.builder.build_int_compare(IntPredicate::SLT, step, zero, "step_is_neg");
let len_id = ctx.builder.build_int_sub(length, one, "lenmin1").unwrap();
let neg = ctx.builder.build_int_compare(IntPredicate::SLT, step, zero, "step_is_neg").unwrap();
(
match s {
Some(s) => {
@ -229,17 +231,20 @@ pub fn handle_slice_indices<'ctx, G: CodeGenerator>(
s,
length,
"s_eq_len",
),
).unwrap(),
neg,
"should_minus_one",
),
ctx.builder.build_int_sub(s, one, "s_min"),
).unwrap(),
ctx.builder.build_int_sub(s, one, "s_min").unwrap(),
s,
"final_start",
)
.into_int_value()
.map(BasicValueEnum::into_int_value)
.unwrap()
}
None => ctx.builder.build_select(neg, len_id, zero, "stt").into_int_value(),
None => ctx.builder.build_select(neg, len_id, zero, "stt")
.map(BasicValueEnum::into_int_value)
.unwrap(),
},
match e {
Some(e) => {
@ -249,13 +254,16 @@ pub fn handle_slice_indices<'ctx, G: CodeGenerator>(
ctx.builder
.build_select(
neg,
ctx.builder.build_int_add(e, one, "end_add_one"),
ctx.builder.build_int_sub(e, one, "end_sub_one"),
ctx.builder.build_int_add(e, one, "end_add_one").unwrap(),
ctx.builder.build_int_sub(e, one, "end_sub_one").unwrap(),
"final_end",
)
.into_int_value()
.map(BasicValueEnum::into_int_value)
.unwrap()
}
None => ctx.builder.build_select(neg, zero, len_id, "end").into_int_value(),
None => ctx.builder.build_select(neg, zero, len_id, "end")
.map(BasicValueEnum::into_int_value)
.unwrap(),
},
step,
)
@ -286,10 +294,10 @@ pub fn handle_slice_index_bound<'ctx, G: CodeGenerator>(
Ok(Some(ctx
.builder
.build_call(func, &[i.into(), length.into()], "bounded_ind")
.try_as_basic_value()
.left()
.unwrap()
.into_int_value()))
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap()))
}
/// This function handles 'end' **inclusively**.
@ -335,17 +343,17 @@ pub fn list_slice_assignment<'ctx>(
dest_arr_ptr,
elem_ptr_type,
"dest_arr_ptr_cast",
);
).unwrap();
let dest_len = dest_arr.load_size(ctx, Some("dest.len"));
let dest_len = ctx.builder.build_int_truncate_or_bit_cast(dest_len, int32, "srclen32");
let dest_len = ctx.builder.build_int_truncate_or_bit_cast(dest_len, int32, "srclen32").unwrap();
let src_arr_ptr = src_arr.get_data().get_ptr(ctx);
let src_arr_ptr = ctx.builder.build_pointer_cast(
src_arr_ptr,
elem_ptr_type,
"src_arr_ptr_cast",
);
).unwrap();
let src_len = src_arr.load_size(ctx, Some("src.len"));
let src_len = ctx.builder.build_int_truncate_or_bit_cast(src_len, int32, "srclen32");
let src_len = ctx.builder.build_int_truncate_or_bit_cast(src_len, int32, "srclen32").unwrap();
// index in bound and positive should be done
// assert if dest.step == 1 then len(src) <= len(dest) else len(src) == len(dest), and
@ -357,12 +365,13 @@ pub fn list_slice_assignment<'ctx>(
src_idx.2,
zero,
"is_neg",
),
ctx.builder.build_int_sub(src_idx.1, one, "e_min_one"),
ctx.builder.build_int_add(src_idx.1, one, "e_add_one"),
).unwrap(),
ctx.builder.build_int_sub(src_idx.1, one, "e_min_one").unwrap(),
ctx.builder.build_int_add(src_idx.1, one, "e_add_one").unwrap(),
"final_e",
)
.into_int_value();
.map(BasicValueEnum::into_int_value)
.unwrap();
let dest_end = ctx.builder
.build_select(
ctx.builder.build_int_compare(
@ -370,12 +379,13 @@ pub fn list_slice_assignment<'ctx>(
dest_idx.2,
zero,
"is_neg",
),
ctx.builder.build_int_sub(dest_idx.1, one, "e_min_one"),
ctx.builder.build_int_add(dest_idx.1, one, "e_add_one"),
).unwrap(),
ctx.builder.build_int_sub(dest_idx.1, one, "e_min_one").unwrap(),
ctx.builder.build_int_add(dest_idx.1, one, "e_add_one").unwrap(),
"final_e",
)
.into_int_value();
.map(BasicValueEnum::into_int_value)
.unwrap();
let src_slice_len =
calculate_len_for_slice_range(generator, ctx, src_idx.0, src_end, src_idx.2);
let dest_slice_len =
@ -385,21 +395,21 @@ pub fn list_slice_assignment<'ctx>(
src_slice_len,
dest_slice_len,
"slice_src_eq_dest",
);
).unwrap();
let src_slt_dest = ctx.builder.build_int_compare(
IntPredicate::SLT,
src_slice_len,
dest_slice_len,
"slice_src_slt_dest",
);
).unwrap();
let dest_step_eq_one = ctx.builder.build_int_compare(
IntPredicate::EQ,
dest_idx.2,
dest_idx.2.get_type().const_int(1, false),
"slice_dest_step_eq_one",
);
let cond_1 = ctx.builder.build_and(dest_step_eq_one, src_slt_dest, "slice_cond_1");
let cond = ctx.builder.build_or(src_eq_dest, cond_1, "slice_cond");
).unwrap();
let cond_1 = ctx.builder.build_and(dest_step_eq_one, src_slt_dest, "slice_cond_1").unwrap();
let cond = ctx.builder.build_or(src_eq_dest, cond_1, "slice_cond").unwrap();
ctx.make_assert(
generator,
cond,
@ -429,27 +439,31 @@ pub fn list_slice_assignment<'ctx>(
BasicTypeEnum::StructType(t) => t.size_of().unwrap(),
_ => unreachable!(),
};
ctx.builder.build_int_truncate_or_bit_cast(s, int32, "size")
ctx.builder.build_int_truncate_or_bit_cast(s, int32, "size").unwrap()
}
.into(),
];
ctx.builder
.build_call(slice_assign_fun, args.as_slice(), "slice_assign")
.try_as_basic_value()
.unwrap_left()
.into_int_value()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap()
};
// update length
let need_update =
ctx.builder.build_int_compare(IntPredicate::NE, new_len, dest_len, "need_update");
let need_update = ctx.builder
.build_int_compare(IntPredicate::NE, new_len, dest_len, "need_update")
.unwrap();
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
let update_bb = ctx.ctx.append_basic_block(current, "update");
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
ctx.builder.build_conditional_branch(need_update, update_bb, cont_bb);
ctx.builder.build_conditional_branch(need_update, update_bb, cont_bb).unwrap();
ctx.builder.position_at_end(update_bb);
let new_len = ctx.builder.build_int_z_extend_or_bit_cast(new_len, size_ty, "new_len");
let new_len = ctx.builder
.build_int_z_extend_or_bit_cast(new_len, size_ty, "new_len")
.unwrap();
dest_arr.store_size(ctx, generator, new_len);
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
ctx.builder.position_at_end(cont_bb);
}
@ -466,9 +480,10 @@ pub fn call_isinf<'ctx>(
let ret = ctx.builder
.build_call(intrinsic_fn, &[v.into()], "isinf")
.try_as_basic_value()
.unwrap_left()
.into_int_value();
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap();
generator.bool_to_i1(ctx, ret)
}
@ -486,9 +501,10 @@ pub fn call_isnan<'ctx>(
let ret = ctx.builder
.build_call(intrinsic_fn, &[v.into()], "isnan")
.try_as_basic_value()
.unwrap_left()
.into_int_value();
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap();
generator.bool_to_i1(ctx, ret)
}
@ -507,9 +523,10 @@ pub fn call_gamma<'ctx>(
ctx.builder
.build_call(intrinsic_fn, &[v.into()], "gamma")
.try_as_basic_value()
.unwrap_left()
.into_float_value()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_float_value))
.map(Either::unwrap_left)
.unwrap()
}
/// Generates a call to `gammaln` in IR. Returns an `f64` representing the result.
@ -526,9 +543,10 @@ pub fn call_gammaln<'ctx>(
ctx.builder
.build_call(intrinsic_fn, &[v.into()], "gammaln")
.try_as_basic_value()
.unwrap_left()
.into_float_value()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_float_value))
.map(Either::unwrap_left)
.unwrap()
}
/// Generates a call to `j0` in IR. Returns an `f64` representing the result.
@ -545,9 +563,10 @@ pub fn call_j0<'ctx>(
ctx.builder
.build_call(intrinsic_fn, &[v.into()], "j0")
.try_as_basic_value()
.unwrap_left()
.into_float_value()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_float_value))
.map(Either::unwrap_left)
.unwrap()
}
/// Generates a call to `__nac3_ndarray_calc_size`. Returns an [IntValue] representing the
@ -592,9 +611,10 @@ pub fn call_ndarray_calc_size<'ctx>(
],
"",
)
.try_as_basic_value()
.unwrap_left()
.into_int_value()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap()
}
/// Generates a call to `__nac3_ndarray_init_dims`.
@ -638,15 +658,17 @@ pub fn call_ndarray_init_dims<'ctx>(
let shape_data = shape.get_data();
let ndarray_num_dims = ndarray.load_ndims(ctx);
ctx.builder.build_call(
ndarray_init_dims_fn,
&[
ndarray_dims.get_ptr(ctx).into(),
shape_data.get_ptr(ctx).into(),
ndarray_num_dims.into(),
],
"",
);
ctx.builder
.build_call(
ndarray_init_dims_fn,
&[
ndarray_dims.get_ptr(ctx).into(),
shape_data.get_ptr(ctx).into(),
ndarray_num_dims.into(),
],
"",
)
.unwrap();
}
/// Generates a call to `__nac3_ndarray_calc_nd_indices`.
@ -691,18 +713,20 @@ pub fn call_ndarray_calc_nd_indices<'ctx>(
llvm_usize,
ndarray_num_dims,
"",
);
).unwrap();
ctx.builder.build_call(
ndarray_calc_nd_indices_fn,
&[
index.into(),
ndarray_dims.get_ptr(ctx).into(),
ndarray_num_dims.into(),
indices.into(),
],
"",
);
ctx.builder
.build_call(
ndarray_calc_nd_indices_fn,
&[
index.into(),
ndarray_dims.get_ptr(ctx).into(),
ndarray_num_dims.into(),
indices.into(),
],
"",
)
.unwrap();
Ok(indices)
}
@ -766,9 +790,9 @@ fn call_ndarray_flatten_index_impl<'ctx>(
],
"",
)
.try_as_basic_value()
.map_left(|v| v.into_int_value())
.left()
.map(CallSiteValue::try_as_basic_value)
.map(|v| v.map_left(BasicValueEnum::into_int_value))
.map(Either::unwrap_left)
.unwrap();
Ok(index)
@ -828,8 +852,8 @@ pub fn call_ndarray_flatten_index_const<'ctx>(
&[ctx.ctx.i32_type().const_int(i as u64, false)],
""
)
};
ctx.builder.build_store(elem_ptr, v);
}.unwrap();
ctx.builder.build_store(elem_ptr, v).unwrap();
}
call_ndarray_flatten_index_impl(
@ -839,4 +863,4 @@ pub fn call_ndarray_flatten_index_const<'ctx>(
indices_alloca,
llvm_usize.const_int(indices_size as u64, false),
)
}
}

View File

@ -763,10 +763,9 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
&primitives,
arg.ty,
);
let alloca = builder.build_alloca(
local_type,
&format!("{}.addr", &arg.name.to_string()),
);
let alloca = builder
.build_alloca(local_type, &format!("{}.addr", &arg.name.to_string()))
.unwrap();
// Remap boolean parameters into i8
let param = if local_type.is_int_type() && param.is_int_value() {
@ -782,14 +781,14 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
param
};
builder.build_store(alloca, param);
builder.build_store(alloca, param).unwrap();
var_assignment.insert(arg.name, (alloca, None, 0));
}
let return_buffer = if has_sret {
Some(fn_val.get_nth_param(0).unwrap().into_pointer_value())
} else {
fn_type.get_return_type().map(|v| builder.build_alloca(v, "$ret"))
fn_type.get_return_type().map(|v| builder.build_alloca(v, "$ret").unwrap())
};
let static_values = {
@ -801,7 +800,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
*static_val = Some(v);
}
builder.build_unconditional_branch(body_bb);
builder.build_unconditional_branch(body_bb).unwrap();
builder.position_at_end(body_bb);
let (dibuilder, compile_unit) = module.create_debug_info_builder(
@ -895,7 +894,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
// after static analysis, only void functions can have no return at the end.
if !code_gen_context.is_terminated() {
code_gen_context.builder.build_return(None);
code_gen_context.builder.build_return(None).unwrap();
}
code_gen_context.builder.unset_current_debug_location();
@ -937,12 +936,14 @@ fn bool_to_i1<'ctx>(builder: &Builder<'ctx>, bool_value: IntValue<'ctx>) -> IntV
if bool_value.get_type().get_bit_width() == 1 {
bool_value
} else {
builder.build_int_compare(
IntPredicate::NE,
bool_value,
bool_value.get_type().const_zero(),
"tobool"
)
builder
.build_int_compare(
IntPredicate::NE,
bool_value,
bool_value.get_type().const_zero(),
"tobool",
)
.unwrap()
}
}
@ -955,16 +956,18 @@ fn bool_to_i8<'ctx>(
let value_bits = bool_value.get_type().get_bit_width();
match value_bits {
8 => bool_value,
1 => builder.build_int_z_extend(bool_value, ctx.i8_type(), "frombool"),
1 => builder.build_int_z_extend(bool_value, ctx.i8_type(), "frombool").unwrap(),
_ => bool_to_i8(
builder,
ctx,
builder.build_int_compare(
IntPredicate::NE,
bool_value,
bool_value.get_type().const_zero(),
""
)
builder
.build_int_compare(
IntPredicate::NE,
bool_value,
bool_value.get_type().const_zero(),
"",
)
.unwrap()
),
}
}
@ -990,9 +993,13 @@ fn gen_in_range_check<'ctx>(
stop: IntValue<'ctx>,
step: IntValue<'ctx>,
) -> IntValue<'ctx> {
let sign = ctx.builder.build_int_compare(IntPredicate::SGT, step, ctx.ctx.i32_type().const_zero(), "");
let lo = ctx.builder.build_select(sign, value, stop, "").into_int_value();
let hi = ctx.builder.build_select(sign, stop, value, "").into_int_value();
let sign = ctx.builder.build_int_compare(IntPredicate::SGT, step, ctx.ctx.i32_type().const_zero(), "").unwrap();
let lo = ctx.builder.build_select(sign, value, stop, "")
.map(BasicValueEnum::into_int_value)
.unwrap();
let hi = ctx.builder.build_select(sign, stop, value, "")
.map(BasicValueEnum::into_int_value)
.unwrap();
ctx.builder.build_int_compare(IntPredicate::SLT, lo, hi, "cmp")
ctx.builder.build_int_compare(IntPredicate::SLT, lo, hi, "cmp").unwrap()
}

View File

@ -47,7 +47,7 @@ pub fn gen_var<'ctx>(
ctx.builder.position_before(&ctx.init_bb.get_last_instruction().unwrap());
ctx.builder.set_current_debug_location(di_loc);
let ptr = ctx.builder.build_alloca(ty, name.unwrap_or(""));
let ptr = ctx.builder.build_alloca(ty, name.unwrap_or("")).unwrap();
ctx.builder.position_at_end(current);
ctx.builder.set_current_debug_location(di_loc);
@ -78,7 +78,7 @@ pub fn gen_array_var<'ctx, 'a, T: BasicType<'ctx>>(
ctx.builder.position_before(&ctx.init_bb.get_last_instruction().unwrap());
ctx.builder.set_current_debug_location(di_loc);
let ptr = ctx.builder.build_array_alloca(ty, size, name.unwrap_or(""));
let ptr = ctx.builder.build_array_alloca(ty, size, name.unwrap_or("")).unwrap();
ctx.builder.position_at_end(current);
ctx.builder.set_current_debug_location(di_loc);
@ -130,7 +130,7 @@ pub fn gen_store_target<'ctx, G: CodeGenerator>(
],
name.unwrap_or(""),
)
}
}.unwrap()
}
ExprKind::Subscript { value, slice, .. } => {
match ctx.unifier.get_ty_immutable(value.custom.unwrap()).as_ref() {
@ -147,31 +147,34 @@ pub fn gen_store_target<'ctx, G: CodeGenerator>(
.unwrap()
.to_basic_value_enum(ctx, generator, slice.custom.unwrap())?
.into_int_value();
let raw_index = ctx.builder.build_int_s_extend(
raw_index,
generator.get_size_type(ctx.ctx),
"sext",
);
let raw_index = ctx.builder
.build_int_s_extend(raw_index, generator.get_size_type(ctx.ctx), "sext")
.unwrap();
// handle negative index
let is_negative = ctx.builder.build_int_compare(
IntPredicate::SLT,
raw_index,
generator.get_size_type(ctx.ctx).const_zero(),
"is_neg",
);
let adjusted = ctx.builder.build_int_add(raw_index, len, "adjusted");
let is_negative = ctx.builder
.build_int_compare(
IntPredicate::SLT,
raw_index,
generator.get_size_type(ctx.ctx).const_zero(),
"is_neg",
)
.unwrap();
let adjusted = ctx.builder.build_int_add(raw_index, len, "adjusted").unwrap();
let index = ctx
.builder
.build_select(is_negative, adjusted, raw_index, "index")
.into_int_value();
.map(BasicValueEnum::into_int_value)
.unwrap();
// unsigned less than is enough, because negative index after adjustment is
// bigger than the length (for unsigned cmp)
let bound_check = ctx.builder.build_int_compare(
IntPredicate::ULT,
index,
len,
"inbound",
);
let bound_check = ctx.builder
.build_int_compare(
IntPredicate::ULT,
index,
len,
"inbound",
)
.unwrap();
ctx.make_assert(
generator,
bound_check,
@ -267,7 +270,7 @@ pub fn gen_assign<'ctx, G: CodeGenerator>(
}
}
let val = value.to_basic_value_enum(ctx, generator, target.custom.unwrap())?;
ctx.builder.build_store(ptr, val);
ctx.builder.build_store(ptr, val).unwrap();
}
};
Ok(())
@ -330,10 +333,12 @@ pub fn gen_for<G: CodeGenerator>(
};
let (start, stop, step) = destructure_range(ctx, iter_val);
ctx.builder.build_store(i, start);
ctx.builder.build_store(i, start).unwrap();
// Check "If step is zero, ValueError is raised."
let rangenez = ctx.builder.build_int_compare(IntPredicate::NE, step, int32.const_zero(), "");
let rangenez = ctx.builder
.build_int_compare(IntPredicate::NE, step, int32.const_zero(), "")
.unwrap();
ctx.make_assert(
generator,
rangenez,
@ -342,37 +347,46 @@ pub fn gen_for<G: CodeGenerator>(
[None, None, None],
ctx.current_loc
);
ctx.builder.build_unconditional_branch(cond_bb);
ctx.builder.build_unconditional_branch(cond_bb).unwrap();
{
ctx.builder.position_at_end(cond_bb);
ctx.builder.build_conditional_branch(
gen_in_range_check(
ctx,
ctx.builder.build_load(i, "").into_int_value(),
stop,
step
),
body_bb,
orelse_bb,
);
ctx.builder
.build_conditional_branch(
gen_in_range_check(
ctx,
ctx.builder.build_load(i, "").map(BasicValueEnum::into_int_value).unwrap(),
stop,
step,
),
body_bb,
orelse_bb,
)
.unwrap();
}
ctx.builder.position_at_end(incr_bb);
let next_i = ctx.builder.build_int_add(
ctx.builder.build_load(i, "").into_int_value(),
step,
"inc",
);
ctx.builder.build_store(i, next_i);
ctx.builder.build_unconditional_branch(cond_bb);
let next_i = ctx.builder
.build_int_add(
ctx.builder.build_load(i, "").map(BasicValueEnum::into_int_value).unwrap(),
step,
"inc",
)
.unwrap();
ctx.builder.build_store(i, next_i).unwrap();
ctx.builder.build_unconditional_branch(cond_bb).unwrap();
ctx.builder.position_at_end(body_bb);
ctx.builder.build_store(target_i, ctx.builder.build_load(i, "").into_int_value());
ctx.builder
.build_store(
target_i,
ctx.builder.build_load(i, "").map(BasicValueEnum::into_int_value).unwrap(),
)
.unwrap();
generator.gen_block(ctx, body.iter())?;
} else {
let index_addr = generator.gen_var_alloc(ctx, size_t.into(), Some("for.index.addr"))?;
ctx.builder.build_store(index_addr, size_t.const_zero());
ctx.builder.build_store(index_addr, size_t.const_zero()).unwrap();
let len = ctx
.build_gep_and_load(
iter_val.into_pointer_value(),
@ -380,24 +394,30 @@ pub fn gen_for<G: CodeGenerator>(
Some("len")
)
.into_int_value();
ctx.builder.build_unconditional_branch(cond_bb);
ctx.builder.build_unconditional_branch(cond_bb).unwrap();
ctx.builder.position_at_end(cond_bb);
let index = ctx.builder.build_load(index_addr, "for.index").into_int_value();
let cmp = ctx.builder.build_int_compare(IntPredicate::SLT, index, len, "cond");
ctx.builder.build_conditional_branch(cmp, body_bb, orelse_bb);
let index = ctx.builder
.build_load(index_addr, "for.index")
.map(BasicValueEnum::into_int_value)
.unwrap();
let cmp = ctx.builder.build_int_compare(IntPredicate::SLT, index, len, "cond").unwrap();
ctx.builder.build_conditional_branch(cmp, body_bb, orelse_bb).unwrap();
ctx.builder.position_at_end(incr_bb);
let index = ctx.builder.build_load(index_addr, "").into_int_value();
let inc = ctx.builder.build_int_add(index, size_t.const_int(1, true), "inc");
ctx.builder.build_store(index_addr, inc);
ctx.builder.build_unconditional_branch(cond_bb);
let index = ctx.builder.build_load(index_addr, "").map(BasicValueEnum::into_int_value).unwrap();
let inc = ctx.builder.build_int_add(index, size_t.const_int(1, true), "inc").unwrap();
ctx.builder.build_store(index_addr, inc).unwrap();
ctx.builder.build_unconditional_branch(cond_bb).unwrap();
ctx.builder.position_at_end(body_bb);
let arr_ptr = ctx
.build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero], Some("arr.addr"))
.into_pointer_value();
let index = ctx.builder.build_load(index_addr, "for.index").into_int_value();
let index = ctx.builder
.build_load(index_addr, "for.index")
.map(BasicValueEnum::into_int_value)
.unwrap();
let val = ctx.build_gep_and_load(arr_ptr, &[index], Some("val"));
generator.gen_assign(ctx, target, val.into())?;
generator.gen_block(ctx, body.iter())?;
@ -411,14 +431,14 @@ pub fn gen_for<G: CodeGenerator>(
}
if !ctx.is_terminated() {
ctx.builder.build_unconditional_branch(incr_bb);
ctx.builder.build_unconditional_branch(incr_bb).unwrap();
}
if !orelse.is_empty() {
ctx.builder.position_at_end(orelse_bb);
generator.gen_block(ctx, orelse.iter())?;
if !ctx.is_terminated() {
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
}
}
@ -476,12 +496,12 @@ pub fn gen_for_callback<'ctx, 'a, I, InitFn, CondFn, BodyFn, UpdateFn>(
// store loop bb information and restore it later
let loop_bb = ctx.loop_target.replace((update_bb, cont_bb));
ctx.builder.build_unconditional_branch(init_bb);
ctx.builder.build_unconditional_branch(init_bb).unwrap();
let loop_var = {
ctx.builder.position_at_end(init_bb);
let result = init(generator, ctx)?;
ctx.builder.build_unconditional_branch(cond_bb);
ctx.builder.build_unconditional_branch(cond_bb).unwrap();
result
};
@ -489,19 +509,17 @@ pub fn gen_for_callback<'ctx, 'a, I, InitFn, CondFn, BodyFn, UpdateFn>(
ctx.builder.position_at_end(cond_bb);
let cond = cond(generator, ctx, loop_var.clone())?;
assert_eq!(cond.get_type().get_bit_width(), ctx.ctx.bool_type().get_bit_width());
ctx.builder.build_conditional_branch(
cond,
body_bb,
cont_bb
);
ctx.builder
.build_conditional_branch(cond, body_bb, cont_bb)
.unwrap();
ctx.builder.position_at_end(body_bb);
body(generator, ctx, loop_var.clone())?;
ctx.builder.build_unconditional_branch(update_bb);
ctx.builder.build_unconditional_branch(update_bb).unwrap();
ctx.builder.position_at_end(update_bb);
update(generator, ctx, loop_var)?;
ctx.builder.build_unconditional_branch(cond_bb);
ctx.builder.build_unconditional_branch(cond_bb).unwrap();
ctx.builder.position_at_end(cont_bb);
ctx.loop_target = loop_bb;
@ -532,14 +550,14 @@ pub fn gen_while<G: CodeGenerator>(
if orelse.is_empty() { cont_bb } else { ctx.ctx.append_basic_block(current, "while.orelse") };
// store loop bb information and restore it later
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
ctx.builder.build_unconditional_branch(test_bb);
ctx.builder.build_unconditional_branch(test_bb).unwrap();
ctx.builder.position_at_end(test_bb);
let test = if let Some(v) = generator.gen_expr(ctx, test)? {
v.to_basic_value_enum(ctx, generator, test.custom.unwrap())?
} else {
for bb in [body_bb, cont_bb] {
ctx.builder.position_at_end(bb);
ctx.builder.build_unreachable();
ctx.builder.build_unreachable().unwrap();
}
return Ok(())
@ -548,7 +566,9 @@ pub fn gen_while<G: CodeGenerator>(
unreachable!()
};
ctx.builder.build_conditional_branch(generator.bool_to_i1(ctx, test), body_bb, orelse_bb);
ctx.builder
.build_conditional_branch(generator.bool_to_i1(ctx, test), body_bb, orelse_bb)
.unwrap();
ctx.builder.position_at_end(body_bb);
generator.gen_block(ctx, body.iter())?;
@ -559,13 +579,13 @@ pub fn gen_while<G: CodeGenerator>(
}
}
if !ctx.is_terminated() {
ctx.builder.build_unconditional_branch(test_bb);
ctx.builder.build_unconditional_branch(test_bb).unwrap();
}
if !orelse.is_empty() {
ctx.builder.position_at_end(orelse_bb);
generator.gen_block(ctx, orelse.iter())?;
if !ctx.is_terminated() {
ctx.builder.build_unconditional_branch(cont_bb);
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
}
}
for (k, (_, _, counter)) in &var_assignment {
@ -605,13 +625,15 @@ pub fn gen_if<G: CodeGenerator>(
} else {
ctx.ctx.append_basic_block(current, "if.orelse")
};
ctx.builder.build_unconditional_branch(test_bb);
ctx.builder.build_unconditional_branch(test_bb).unwrap();
ctx.builder.position_at_end(test_bb);
let test = generator
.gen_expr(ctx, test)
.and_then(|v| v.map(|v| v.to_basic_value_enum(ctx, generator, test.custom.unwrap())).transpose())?;
if let Some(BasicValueEnum::IntValue(test)) = test {
ctx.builder.build_conditional_branch(generator.bool_to_i1(ctx, test), body_bb, orelse_bb);
ctx.builder
.build_conditional_branch(generator.bool_to_i1(ctx, test), body_bb, orelse_bb)
.unwrap();
};
ctx.builder.position_at_end(body_bb);
generator.gen_block(ctx, body.iter())?;
@ -626,7 +648,7 @@ pub fn gen_if<G: CodeGenerator>(
if cont_bb.is_none() {
cont_bb = Some(ctx.ctx.append_basic_block(current, "cont"));
}
ctx.builder.build_unconditional_branch(cont_bb.unwrap());
ctx.builder.build_unconditional_branch(cont_bb.unwrap()).unwrap();
}
if !orelse.is_empty() {
ctx.builder.position_at_end(orelse_bb);
@ -635,7 +657,7 @@ pub fn gen_if<G: CodeGenerator>(
if cont_bb.is_none() {
cont_bb = Some(ctx.ctx.append_basic_block(current, "cont"));
}
ctx.builder.build_unconditional_branch(cont_bb.unwrap());
ctx.builder.build_unconditional_branch(cont_bb.unwrap()).unwrap();
}
}
if let Some(cont_bb) = cont_bb {
@ -661,7 +683,7 @@ pub fn final_proxy<'ctx>(
let prev = ctx.builder.get_insert_block().unwrap();
ctx.builder.position_at_end(block);
unsafe {
ctx.builder.build_store(*final_state, target.get_address().unwrap());
ctx.builder.build_store(*final_state, target.get_address().unwrap()).unwrap();
}
ctx.builder.position_at_end(prev);
final_targets.push(target);
@ -718,48 +740,43 @@ pub fn exn_constructor<'ctx>(
};
let exception_name = format!("{}:{}", ctx.resolver.get_exception_id(zelf_id), zelf_name);
unsafe {
let id_ptr = ctx.builder.build_in_bounds_gep(zelf, &[zero, zero], "exn.id");
let id_ptr = ctx.builder.build_in_bounds_gep(zelf, &[zero, zero], "exn.id").unwrap();
let id = ctx.resolver.get_string_id(&exception_name);
ctx.builder.build_store(id_ptr, int32.const_int(id as u64, false));
ctx.builder.build_store(id_ptr, int32.const_int(id as u64, false)).unwrap();
let empty_string = ctx.gen_const(generator, &Constant::Str(String::new()), ctx.primitives.str);
let ptr =
ctx.builder.build_in_bounds_gep(zelf, &[zero, int32.const_int(5, false)], "exn.msg");
let ptr = ctx.builder
.build_in_bounds_gep(zelf, &[zero, int32.const_int(5, false)], "exn.msg")
.unwrap();
let msg = if args.is_empty() {
empty_string.unwrap()
} else {
args.remove(0).1.to_basic_value_enum(ctx, generator, ctx.primitives.str)?
};
ctx.builder.build_store(ptr, msg);
ctx.builder.build_store(ptr, msg).unwrap();
for i in &[6, 7, 8] {
let value = if args.is_empty() {
ctx.ctx.i64_type().const_zero().into()
} else {
args.remove(0).1.to_basic_value_enum(ctx, generator, ctx.primitives.int64)?
};
let ptr = ctx.builder.build_in_bounds_gep(
zelf,
&[zero, int32.const_int(*i, false)],
"exn.param",
);
ctx.builder.build_store(ptr, value);
let ptr = ctx.builder
.build_in_bounds_gep(zelf, &[zero, int32.const_int(*i, false)], "exn.param")
.unwrap();
ctx.builder.build_store(ptr, value).unwrap();
}
// set file, func to empty string
for i in &[1, 4] {
let ptr = ctx.builder.build_in_bounds_gep(
zelf,
&[zero, int32.const_int(*i, false)],
"exn.str",
);
ctx.builder.build_store(ptr, empty_string.unwrap());
let ptr = ctx.builder
.build_in_bounds_gep(zelf, &[zero, int32.const_int(*i, false)], "exn.str")
.unwrap();
ctx.builder.build_store(ptr, empty_string.unwrap()).unwrap();
}
// set ints to zero
for i in &[2, 3] {
let ptr = ctx.builder.build_in_bounds_gep(
zelf,
&[zero, int32.const_int(*i, false)],
"exn.ints",
);
ctx.builder.build_store(ptr, zero);
let ptr = ctx.builder
.build_in_bounds_gep(zelf, &[zero, int32.const_int(*i, false)], "exn.ints")
.unwrap();
ctx.builder.build_store(ptr, zero).unwrap();
}
}
Ok(Some(zelf.into()))
@ -780,34 +797,26 @@ pub fn gen_raise<'ctx>(
let int32 = ctx.ctx.i32_type();
let zero = int32.const_zero();
let exception = exception.into_pointer_value();
let file_ptr = ctx.builder.build_in_bounds_gep(
exception,
&[zero, int32.const_int(1, false)],
"file_ptr",
);
let file_ptr = ctx.builder
.build_in_bounds_gep(exception, &[zero, int32.const_int(1, false)], "file_ptr")
.unwrap();
let filename = ctx.gen_string(generator, loc.file.0);
ctx.builder.build_store(file_ptr, filename);
let row_ptr = ctx.builder.build_in_bounds_gep(
exception,
&[zero, int32.const_int(2, false)],
"row_ptr",
);
ctx.builder.build_store(row_ptr, int32.const_int(loc.row as u64, false));
let col_ptr = ctx.builder.build_in_bounds_gep(
exception,
&[zero, int32.const_int(3, false)],
"col_ptr",
);
ctx.builder.build_store(col_ptr, int32.const_int(loc.column as u64, false));
ctx.builder.build_store(file_ptr, filename).unwrap();
let row_ptr = ctx.builder
.build_in_bounds_gep(exception, &[zero, int32.const_int(2, false)], "row_ptr")
.unwrap();
ctx.builder.build_store(row_ptr, int32.const_int(loc.row as u64, false)).unwrap();
let col_ptr = ctx.builder
.build_in_bounds_gep(exception, &[zero, int32.const_int(3, false)], "col_ptr")
.unwrap();
ctx.builder.build_store(col_ptr, int32.const_int(loc.column as u64, false)).unwrap();
let current_fun = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
let fun_name = ctx.gen_string(generator, current_fun.get_name().to_str().unwrap());
let name_ptr = ctx.builder.build_in_bounds_gep(
exception,
&[zero, int32.const_int(4, false)],
"name_ptr",
);
ctx.builder.build_store(name_ptr, fun_name);
let name_ptr = ctx.builder
.build_in_bounds_gep(exception, &[zero, int32.const_int(4, false)], "name_ptr")
.unwrap();
ctx.builder.build_store(name_ptr, fun_name).unwrap();
}
let raise = get_builtins(generator, ctx, "__nac3_raise");
@ -817,7 +826,7 @@ pub fn gen_raise<'ctx>(
let resume = get_builtins(generator, ctx, "__nac3_resume");
ctx.build_call_or_invoke(resume, &[], "resume");
}
ctx.builder.build_unreachable();
ctx.builder.build_unreachable().unwrap();
}
/// Generates IR for a `try` statement.
@ -844,7 +853,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
let dispatcher = ctx.ctx.append_basic_block(current_fun, "try.dispatch");
let mut dispatcher_end = dispatcher;
ctx.builder.position_at_end(dispatcher);
let exn = ctx.builder.build_phi(exception_type, "exn");
let exn = ctx.builder.build_phi(exception_type, "exn").unwrap();
ctx.builder.position_at_end(current_block);
let mut cleanup = None;
@ -868,8 +877,9 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
} else {
let return_target = ctx.ctx.append_basic_block(current_fun, "try.return_target");
ctx.builder.position_at_end(return_target);
let return_value = ctx.return_buffer.map(|v| ctx.builder.build_load(v, "$ret"));
ctx.builder.build_return(return_value.as_ref().map(|v| v as &dyn BasicValue));
let return_value = ctx.return_buffer
.map(|v| ctx.builder.build_load(v, "$ret").unwrap());
ctx.builder.build_return(return_value.as_ref().map(|v| v as &dyn BasicValue)).unwrap();
ctx.builder.position_at_end(current_block);
final_proxy(ctx, return_target, return_proxy, final_data.as_mut().unwrap());
}
@ -935,14 +945,16 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
} else {
let final_landingpad = ctx.ctx.append_basic_block(current_fun, "try.catch.final");
ctx.builder.position_at_end(final_landingpad);
ctx.builder.build_landing_pad(
ctx.ctx.struct_type(&[ptr_type.into(), exception_type], false),
personality,
&[],
true,
"try.catch.final",
);
ctx.builder.build_unconditional_branch(cleanup.unwrap());
ctx.builder
.build_landing_pad(
ctx.ctx.struct_type(&[ptr_type.into(), exception_type], false),
personality,
&[],
true,
"try.catch.final",
)
.unwrap();
ctx.builder.build_unconditional_branch(cleanup.unwrap()).unwrap();
ctx.builder.position_at_end(body);
ctx.unwind_target.replace(final_landingpad)
};
@ -956,7 +968,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
target: BasicBlock<'ctx>,
block: BasicBlock<'ctx>| {
ctx.builder.position_at_end(block);
ctx.builder.build_unconditional_branch(target);
ctx.builder.build_unconditional_branch(target).unwrap();
ctx.builder.position_at_end(body);
};
let redirect = if has_cleanup {
@ -972,9 +984,9 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
let break_proxy = ctx.ctx.append_basic_block(current_fun, "try.break");
let continue_proxy = ctx.ctx.append_basic_block(current_fun, "try.continue");
ctx.builder.position_at_end(break_proxy);
ctx.builder.build_call(end_catch, &[], "end_catch");
ctx.builder.build_call(end_catch, &[], "end_catch").unwrap();
ctx.builder.position_at_end(continue_proxy);
ctx.builder.build_call(end_catch, &[], "end_catch");
ctx.builder.build_call(end_catch, &[], "end_catch").unwrap();
ctx.builder.position_at_end(body);
redirect(ctx, break_target, break_proxy);
redirect(ctx, continue_target, continue_proxy);
@ -983,12 +995,12 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
}
let return_proxy = ctx.ctx.append_basic_block(current_fun, "try.return");
ctx.builder.position_at_end(return_proxy);
ctx.builder.build_call(end_catch, &[], "end_catch");
ctx.builder.build_call(end_catch, &[], "end_catch").unwrap();
let return_target = ctx.return_target.take().unwrap_or_else(|| {
let doreturn = ctx.ctx.append_basic_block(current_fun, "try.doreturn");
ctx.builder.position_at_end(doreturn);
let return_value = ctx.return_buffer.map(|v| ctx.builder.build_load(v, "$ret"));
ctx.builder.build_return(return_value.as_ref().map(|v| v as &dyn BasicValue));
let return_value = ctx.return_buffer.map(|v| ctx.builder.build_load(v, "$ret").unwrap());
ctx.builder.build_return(return_value.as_ref().map(|v| v as &dyn BasicValue)).unwrap();
doreturn
});
redirect(ctx, return_target, return_proxy);
@ -1003,12 +1015,14 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
ctx.builder.position_at_end(dispatcher);
unsafe {
let zero = ctx.ctx.i32_type().const_zero();
let exnid_ptr = ctx.builder.build_gep(
exn.as_basic_value().into_pointer_value(),
&[zero, zero],
"exnidptr",
);
Some(ctx.builder.build_load(exnid_ptr, "exnid"))
let exnid_ptr = ctx.builder
.build_gep(
exn.as_basic_value().into_pointer_value(),
&[zero, zero],
"exnidptr",
)
.unwrap();
Some(ctx.builder.build_load(exnid_ptr, "exnid").unwrap())
}
};
@ -1020,14 +1034,14 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
let exn_ty = ctx.get_llvm_type(generator, type_.as_ref().unwrap().custom.unwrap());
let exn_store = generator.gen_var_alloc(ctx, exn_ty, Some("try.exn_store.addr"))?;
ctx.var_assignment.insert(*name, (exn_store, None, 0));
ctx.builder.build_store(exn_store, exn.as_basic_value());
ctx.builder.build_store(exn_store, exn.as_basic_value()).unwrap();
}
generator.gen_block(ctx, body.iter())?;
let current = ctx.builder.get_insert_block().unwrap();
// only need to call end catch if not terminated
// otherwise, we already handled in return/break/continue/raise
if current.get_terminator().is_none() {
ctx.builder.build_call(end_catch, &[], "end_catch");
ctx.builder.build_call(end_catch, &[], "end_catch").unwrap();
}
post_handlers.push(current);
ctx.builder.position_at_end(dispatcher_end);
@ -1038,12 +1052,15 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
let expected_id = ctx
.builder
.build_load(exn_type.into_pointer_value(), "expected_id")
.into_int_value();
let result = ctx.builder.build_int_compare(IntPredicate::EQ, actual_id, expected_id, "exncheck");
ctx.builder.build_conditional_branch(result, handler_bb, dispatcher_cont);
.map(BasicValueEnum::into_int_value)
.unwrap();
let result = ctx.builder
.build_int_compare(IntPredicate::EQ, actual_id, expected_id, "exncheck")
.unwrap();
ctx.builder.build_conditional_branch(result, handler_bb, dispatcher_cont).unwrap();
dispatcher_end = dispatcher_cont;
} else {
ctx.builder.build_unconditional_branch(handler_bb);
ctx.builder.build_unconditional_branch(handler_bb).unwrap();
break;
}
}
@ -1066,21 +1083,22 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
has_cleanup,
"try.landingpad",
)
.into_struct_value();
.map(BasicValueEnum::into_struct_value)
.unwrap();
let exn_val = ctx.builder.build_extract_value(landingpad_value, 1, "exn").unwrap();
ctx.builder.build_unconditional_branch(dispatcher);
ctx.builder.build_unconditional_branch(dispatcher).unwrap();
exn.add_incoming(&[(&exn_val, landingpad)]);
if dispatcher_end.get_terminator().is_none() {
ctx.builder.position_at_end(dispatcher_end);
if let Some(cleanup) = cleanup {
ctx.builder.build_unconditional_branch(cleanup);
ctx.builder.build_unconditional_branch(cleanup).unwrap();
} else if let Some((_, outer_dispatcher, phi)) = ctx.outer_catch_clauses {
phi.add_incoming(&[(&exn_val, dispatcher_end)]);
ctx.builder.build_unconditional_branch(outer_dispatcher);
ctx.builder.build_unconditional_branch(outer_dispatcher).unwrap();
} else {
ctx.build_call_or_invoke(resume, &[], "resume");
ctx.builder.build_unreachable();
ctx.builder.build_unreachable().unwrap();
}
}
@ -1088,16 +1106,16 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
let tail = ctx.ctx.append_basic_block(current_fun, "try.tail");
if body.get_terminator().is_none() {
ctx.builder.position_at_end(body);
ctx.builder.build_unconditional_branch(tail);
ctx.builder.build_unconditional_branch(tail).unwrap();
}
if matches!(cleanup, Some(cleanup) if cleanup.get_terminator().is_none()) {
ctx.builder.position_at_end(cleanup.unwrap());
ctx.builder.build_unconditional_branch(tail);
ctx.builder.build_unconditional_branch(tail).unwrap();
}
for post_handler in post_handlers {
if post_handler.get_terminator().is_none() {
ctx.builder.position_at_end(post_handler);
ctx.builder.build_unconditional_branch(tail);
ctx.builder.build_unconditional_branch(tail).unwrap();
}
}
ctx.builder.position_at_end(tail);
@ -1108,7 +1126,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
generator.gen_block(ctx, finalbody.iter())?;
if !ctx.is_terminated() {
ctx.build_call_or_invoke(resume, &[], "resume");
ctx.builder.build_unreachable();
ctx.builder.build_unreachable().unwrap();
}
// normal path
@ -1119,22 +1137,22 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
ctx.builder.position_at_end(finalizer);
generator.gen_block(ctx, finalbody.iter())?;
if !ctx.is_terminated() {
let dest = ctx.builder.build_load(final_state, "final_dest");
ctx.builder.build_indirect_branch(dest, &final_targets);
let dest = ctx.builder.build_load(final_state, "final_dest").unwrap();
ctx.builder.build_indirect_branch(dest, &final_targets).unwrap();
}
for block in &final_paths {
if block.get_terminator().is_none() {
ctx.builder.position_at_end(*block);
ctx.builder.build_unconditional_branch(finalizer);
ctx.builder.build_unconditional_branch(finalizer).unwrap();
}
}
for block in [body].iter().chain(post_handlers.iter()) {
if block.get_terminator().is_none() {
ctx.builder.position_at_end(*block);
unsafe {
ctx.builder.build_store(final_state, tail.get_address().unwrap());
ctx.builder.build_store(final_state, tail.get_address().unwrap()).unwrap();
}
ctx.builder.build_unconditional_branch(finalizer);
ctx.builder.build_unconditional_branch(finalizer).unwrap();
}
}
ctx.builder.position_at_end(tail);
@ -1173,13 +1191,13 @@ pub fn gen_return<G: CodeGenerator>(
};
if let Some(return_target) = ctx.return_target {
if let Some(value) = value {
ctx.builder.build_store(ctx.return_buffer.unwrap(), value);
ctx.builder.build_store(ctx.return_buffer.unwrap(), value).unwrap();
}
ctx.builder.build_unconditional_branch(return_target);
ctx.builder.build_unconditional_branch(return_target).unwrap();
} else if ctx.need_sret {
// sret
ctx.builder.build_store(ctx.return_buffer.unwrap(), value.unwrap());
ctx.builder.build_return(None);
ctx.builder.build_store(ctx.return_buffer.unwrap(), value.unwrap()).unwrap();
ctx.builder.build_return(None).unwrap();
} else {
// Remap boolean return type into i1
let value = value.map(|v| {
@ -1200,7 +1218,7 @@ pub fn gen_return<G: CodeGenerator>(
}
});
let value = value.as_ref().map(|v| v as &dyn BasicValue);
ctx.builder.build_return(value);
ctx.builder.build_return(value).unwrap();
}
Ok(())
}
@ -1247,10 +1265,10 @@ pub fn gen_stmt<G: CodeGenerator>(
}
}
StmtKind::Continue { .. } => {
ctx.builder.build_unconditional_branch(ctx.loop_target.unwrap().0);
ctx.builder.build_unconditional_branch(ctx.loop_target.unwrap().0).unwrap();
}
StmtKind::Break { .. } => {
ctx.builder.build_unconditional_branch(ctx.loop_target.unwrap().1);
ctx.builder.build_unconditional_branch(ctx.loop_target.unwrap().1).unwrap();
}
StmtKind::If { .. } => generator.gen_if(ctx, stmt)?,
StmtKind::While { .. } => generator.gen_while(ctx, stmt)?,

View File

@ -25,10 +25,11 @@ use crate::{
use inkwell::{
attributes::{Attribute, AttributeLoc},
types::{BasicType, BasicMetadataTypeEnum},
values::{BasicValue, BasicMetadataValueEnum},
values::{BasicValue, BasicMetadataValueEnum, CallSiteValue},
FloatPredicate,
IntPredicate
};
use itertools::Either;
use crate::toplevel::numpy::gen_ndarray_identity;
type BuiltinInfo = Vec<(Arc<RwLock<TopLevelDef>>, Option<Stmt>)>;
@ -189,11 +190,10 @@ fn create_fn_by_intrinsic(
ctx.module.add_function(intrinsic_fn, fn_type, None)
});
let call = ctx.builder
.build_call(intrinsic_fn, args_val.as_slice(), name);
let val = call.try_as_basic_value()
.left()
let val = ctx.builder
.build_call(intrinsic_fn, args_val.as_slice(), name)
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(val.into())
}),
@ -267,11 +267,10 @@ fn create_fn_by_extern(
func
});
let call = ctx.builder
.build_call(intrinsic_fn, &args_val, name);
let val = call.try_as_basic_value()
.left()
let val = ctx.builder
.build_call(intrinsic_fn, &args_val, name)
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(val.into())
}),
@ -459,7 +458,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
unreachable!("option must be ptr")
};
Ok(Some(ctx.builder.build_is_not_null(ptr, "is_some").into()))
Ok(Some(ctx.builder
.build_is_not_null(ptr, "is_some")
.map(Into::into)
.unwrap()
))
},
)))),
loc: None,
@ -484,7 +487,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
unreachable!("option must be ptr")
};
Ok(Some(ctx.builder.build_is_null(ptr, "is_none").into()))
Ok(Some(ctx.builder
.build_is_null(ptr, "is_none")
.map(Into::into)
.unwrap()
))
},
)))),
loc: None,
@ -554,7 +561,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
ctx.ctx.i32_type(),
"zext",
)
.into(),
.map(Into::into)
.unwrap(),
)
} else if ctx.unifier.unioned(arg_ty, int32)
|| ctx.unifier.unioned(arg_ty, uint32)
@ -570,7 +578,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
ctx.ctx.i32_type(),
"trunc",
)
.into(),
.map(Into::into)
.unwrap(),
)
} else if ctx.unifier.unioned(arg_ty, float) {
let to_int64 = ctx
@ -579,13 +588,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
arg.into_float_value(),
ctx.ctx.i64_type(),
"",
);
)
.unwrap();
let val = ctx.builder
.build_int_truncate(
to_int64,
ctx.ctx.i32_type(),
"conv",
);
.build_int_truncate(to_int64, ctx.ctx.i32_type(), "conv")
.unwrap();
Some(val.into())
} else {
@ -632,7 +639,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
ctx.ctx.i64_type(),
"zext",
)
.into(),
.map(Into::into)
.unwrap(),
)
} else if ctx.unifier.unioned(arg_ty, int32) {
Some(
@ -642,7 +650,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
ctx.ctx.i64_type(),
"sext",
)
.into(),
.map(Into::into)
.unwrap(),
)
} else if ctx.unifier.unioned(arg_ty, int64)
|| ctx.unifier.unioned(arg_ty, uint64)
@ -656,7 +665,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
ctx.ctx.i64_type(),
"fptosi",
)
.into();
.map(Into::into)
.unwrap();
Some(val)
} else {
unreachable!()
@ -695,7 +705,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let res = if ctx.unifier.unioned(arg_ty, boolean) {
ctx.builder
.build_int_z_extend(arg.into_int_value(), ctx.ctx.i64_type(), "zext")
.into()
.map(Into::into)
.unwrap()
} else if ctx.unifier.unioned(arg_ty, int32)
|| ctx.unifier.unioned(arg_ty, uint32)
{
@ -705,34 +716,45 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
{
ctx.builder
.build_int_truncate(arg.into_int_value(), ctx.ctx.i32_type(), "trunc")
.into()
.map(Into::into)
.unwrap()
} else if ctx.unifier.unioned(arg_ty, float) {
let llvm_i32 = ctx.ctx.i32_type();
let llvm_i64 = ctx.ctx.i64_type();
let arg = arg.into_float_value();
let arg_gez = ctx.builder
.build_float_compare(FloatPredicate::OGE, arg, arg.get_type().const_zero(), "");
.build_float_compare(
FloatPredicate::OGE,
arg,
arg.get_type().const_zero(),
"",
)
.unwrap();
let to_int32 = ctx.builder
.build_float_to_signed_int(
arg,
llvm_i32,
""
);
"",
)
.unwrap();
let to_uint64 = ctx.builder
.build_float_to_unsigned_int(
arg,
llvm_i64,
""
);
"",
)
.unwrap();
let val = ctx.builder.build_select(
arg_gez,
ctx.builder.build_int_truncate(to_uint64, llvm_i32, ""),
to_int32,
"conv"
);
let val = ctx.builder
.build_select(
arg_gez,
ctx.builder.build_int_truncate(to_uint64, llvm_i32, "").unwrap(),
to_int32,
"conv",
)
.unwrap();
val
} else {
@ -774,11 +796,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
{
ctx.builder
.build_int_z_extend(arg.into_int_value(), ctx.ctx.i64_type(), "zext")
.into()
.map(Into::into)
.unwrap()
} else if ctx.unifier.unioned(arg_ty, int32) {
ctx.builder
.build_int_s_extend(arg.into_int_value(), ctx.ctx.i64_type(), "sext")
.into()
.map(Into::into)
.unwrap()
} else if ctx.unifier.unioned(arg_ty, int64)
|| ctx.unifier.unioned(arg_ty, uint64)
{
@ -788,27 +812,24 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let arg = arg.into_float_value();
let arg_gez = ctx.builder
.build_float_compare(FloatPredicate::OGE, arg, arg.get_type().const_zero(), "");
.build_float_compare(
FloatPredicate::OGE,
arg,
arg.get_type().const_zero(),
"",
)
.unwrap();
let to_int64 = ctx.builder
.build_float_to_signed_int(
arg,
llvm_i64,
""
);
.build_float_to_signed_int(arg, llvm_i64, "")
.unwrap();
let to_uint64 = ctx.builder
.build_float_to_unsigned_int(
arg,
llvm_i64,
""
);
.build_float_to_unsigned_int(arg, llvm_i64, "")
.unwrap();
let val = ctx.builder.build_select(
arg_gez,
to_uint64,
to_int64,
"conv"
);
let val = ctx.builder
.build_select(arg_gez, to_uint64, to_int64, "conv")
.unwrap();
val
} else {
@ -852,14 +873,16 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_signed_int_to_float(arg, ctx.ctx.f64_type(), "sitofp")
.into();
.map(Into::into)
.unwrap();
Some(val)
} else if [uint32, uint64].iter().any(|ty| ctx.unifier.unioned(arg_ty, *ty)) {
let arg = arg.into_int_value();
let val = ctx
.builder
.build_unsigned_int_to_float(arg, ctx.ctx.f64_type(), "uitofp")
.into();
.map(Into::into)
.unwrap();
Some(val)
} else if ctx.unifier.unioned(arg_ty, float) {
Some(arg)
@ -1002,11 +1025,12 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
let val_toint = ctx.builder
.build_float_to_signed_int(val.into_float_value(), llvm_i32, "round");
.build_float_to_signed_int(val.into_float_value(), llvm_i32, "round")
.unwrap();
Ok(Some(val_toint.into()))
}),
),
@ -1032,11 +1056,12 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
let val_toint = ctx.builder
.build_float_to_signed_int(val.into_float_value(), llvm_i64, "round");
.build_float_to_signed_int(val.into_float_value(), llvm_i64, "round")
.unwrap();
Ok(Some(val_toint.into()))
}),
),
@ -1061,8 +1086,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(Some(val))
}),
@ -1119,12 +1144,14 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
Some(step) => {
let step = step.into_int_value();
// assert step != 0, throw exception if not
let not_zero = ctx.builder.build_int_compare(
IntPredicate::NE,
step,
step.get_type().const_zero(),
"range_step_ne",
);
let not_zero = ctx.builder
.build_int_compare(
IntPredicate::NE,
step,
step.get_type().const_zero(),
"range_step_ne",
)
.unwrap();
ctx.make_assert(
generator,
not_zero,
@ -1146,20 +1173,24 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let ty = int32.array_type(3);
let ptr = generator.gen_var_alloc(ctx, ty.into(), Some("range")).unwrap();
unsafe {
let a = ctx.builder.build_in_bounds_gep(ptr, &[zero, zero], "start");
let b = ctx.builder.build_in_bounds_gep(
ptr,
&[zero, int32.const_int(1, false)],
"end",
);
let a = ctx.builder
.build_in_bounds_gep(ptr, &[zero, zero], "start")
.unwrap();
let b = ctx.builder
.build_in_bounds_gep(
ptr,
&[zero, int32.const_int(1, false)],
"end",
)
.unwrap();
let c = ctx.builder.build_in_bounds_gep(
ptr,
&[zero, int32.const_int(2, false)],
"step",
);
ctx.builder.build_store(a, start);
ctx.builder.build_store(b, stop);
ctx.builder.build_store(c, step);
ptr,
&[zero, int32.const_int(2, false)],
"step",
).unwrap();
ctx.builder.build_store(a, start).unwrap();
ctx.builder.build_store(b, stop).unwrap();
ctx.builder.build_store(c, step).unwrap();
}
Ok(Some(ptr.into()))
},
@ -1217,7 +1248,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
arg.into_int_value(),
"bool",
)
.into(),
.map(Into::into)
.unwrap(),
)
} else if ctx.unifier.unioned(arg_ty, int64) {
Some(
@ -1228,7 +1260,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
arg.into_int_value(),
"bool",
)
.into(),
.map(Into::into)
.unwrap(),
)
} else if ctx.unifier.unioned(arg_ty, float) {
let val = ctx
@ -1240,7 +1273,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
ctx.ctx.f64_type().const_zero(),
"bool",
)
.into();
.map(Into::into)
.unwrap();
Some(val)
} else {
unreachable!()
@ -1271,11 +1305,12 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
let val_toint = ctx.builder
.build_float_to_signed_int(val.into_float_value(), llvm_i32, "floor");
.build_float_to_signed_int(val.into_float_value(), llvm_i32, "floor")
.unwrap();
Ok(Some(val_toint.into()))
}),
),
@ -1301,11 +1336,12 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
let val_toint = ctx.builder
.build_float_to_signed_int(val.into_float_value(), llvm_i64, "floor");
.build_float_to_signed_int(val.into_float_value(), llvm_i64, "floor")
.unwrap();
Ok(Some(val_toint.into()))
}),
),
@ -1330,8 +1366,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(Some(val))
}),
@ -1358,11 +1394,12 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
let val_toint = ctx.builder
.build_float_to_signed_int(val.into_float_value(), llvm_i32, "ceil");
.build_float_to_signed_int(val.into_float_value(), llvm_i32, "ceil")
.unwrap();
Ok(Some(val_toint.into()))
}),
),
@ -1388,11 +1425,12 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
let val_toint = ctx.builder
.build_float_to_signed_int(val.into_float_value(), llvm_i64, "ceil");
.build_float_to_signed_int(val.into_float_value(), llvm_i64, "ceil")
.unwrap();
Ok(Some(val_toint.into()))
}),
),
@ -1417,8 +1455,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic_fn, &[arg.into()], "")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(Some(val))
}),
@ -1472,7 +1510,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
if len.get_type().get_bit_width() == 32 {
Some(len.into())
} else {
Some(ctx.builder.build_int_truncate(len, int32, "len2i32").into())
Some(ctx.builder
.build_int_truncate(len, int32, "len2i32")
.map(Into::into)
.unwrap()
)
}
}
TypeEnum::TNDArray { .. } => {
@ -1486,7 +1528,11 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
).into_int_value();
if len.get_type().get_bit_width() != 32 {
Some(ctx.builder.build_int_truncate(len, llvm_i32, "len").into())
Some(ctx.builder
.build_int_truncate(len, llvm_i32, "len")
.map(Into::into)
.unwrap()
)
} else {
Some(len.into())
}
@ -1553,8 +1599,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic, &[m_val.into(), n_val.into()], "min")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(val.into())
},
@ -1615,8 +1661,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let val = ctx
.builder
.build_call(intrinsic, &[m_val.into(), n_val.into()], "max")
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(val.into())
},
@ -1684,8 +1730,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
},
"abs",
)
.try_as_basic_value()
.left()
.map(CallSiteValue::try_as_basic_value)
.map(Either::unwrap_left)
.unwrap();
Ok(val.into())
},
@ -2079,7 +2125,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
let arg_ty = fun.0.args[0].ty;
let arg_val = args[0].1.clone().to_basic_value_enum(ctx, generator, arg_ty)?;
let alloca = generator.gen_var_alloc(ctx, arg_val.get_type(), Some("alloca_some")).unwrap();
ctx.builder.build_store(alloca, arg_val);
ctx.builder.build_store(alloca, arg_val).unwrap();
Ok(Some(alloca.into()))
},
)))),

View File

@ -1,5 +1,5 @@
use inkwell::{AddressSpace, IntPredicate, types::BasicType, values::{BasicValueEnum, PointerValue}};
use inkwell::values::{ArrayValue, IntValue};
use inkwell::values::{AggregateValueEnum, ArrayValue, IntValue};
use nac3parser::ast::StrRef;
use crate::{
codegen::{
@ -39,18 +39,14 @@ fn create_ndarray_const_shape<'ctx, 'a>(
assert!(llvm_ndarray_data_t.is_sized());
for i in 0..shape.get_type().len() {
let shape_dim = ctx.builder.build_extract_value(
shape,
i,
"",
).unwrap();
let shape_dim = ctx.builder
.build_extract_value(shape, i, "")
.map(BasicValueEnum::into_int_value)
.unwrap();
let shape_dim_gez = ctx.builder.build_int_compare(
IntPredicate::SGE,
shape_dim.into_int_value(),
llvm_usize.const_zero(),
""
);
let shape_dim_gez = ctx.builder
.build_int_compare(IntPredicate::SGE, shape_dim, llvm_usize.const_zero(), "")
.unwrap();
ctx.make_assert(
generator,
@ -80,10 +76,10 @@ fn create_ndarray_const_shape<'ctx, 'a>(
.get_dims()
.ptr_offset(ctx, generator, llvm_usize.const_int(i as u64, true), None);
let shape_dim = ctx.builder.build_extract_value(shape, i, "")
.map(|val| val.into_int_value())
.map(BasicValueEnum::into_int_value)
.unwrap();
ctx.builder.build_store(ndarray_dim, shape_dim);
ctx.builder.build_store(ndarray_dim, shape_dim).unwrap();
}
let ndarray_dims = ndarray.get_dims().get_ptr(ctx);
@ -167,30 +163,29 @@ fn call_ndarray_empty_impl<'ctx, 'a>(
ctx,
|generator, ctx| {
let i = generator.gen_var_alloc(ctx, llvm_usize.into(), None)?;
ctx.builder.build_store(i, llvm_usize.const_zero());
ctx.builder.build_store(i, llvm_usize.const_zero()).unwrap();
Ok(i)
},
|_, ctx, i_addr| {
let i = ctx.builder
.build_load(i_addr, "")
.into_int_value();
.map(BasicValueEnum::into_int_value)
.unwrap();
let shape_len = shape.load_size(ctx, None);
Ok(ctx.builder.build_int_compare(IntPredicate::ULT, i, shape_len, ""))
Ok(ctx.builder.build_int_compare(IntPredicate::ULT, i, shape_len, "").unwrap())
},
|generator, ctx, i_addr| {
let i = ctx.builder
.build_load(i_addr, "")
.into_int_value();
.map(BasicValueEnum::into_int_value)
.unwrap();
let shape_dim = shape.get_data().get(ctx, generator, i, None).into_int_value();
let shape_dim_gez = ctx.builder.build_int_compare(
IntPredicate::SGE,
shape_dim,
llvm_i32.const_zero(),
""
);
let shape_dim_gez = ctx.builder
.build_int_compare(IntPredicate::SGE, shape_dim, llvm_i32.const_zero(), "")
.unwrap();
ctx.make_assert(
generator,
@ -206,9 +201,10 @@ fn call_ndarray_empty_impl<'ctx, 'a>(
|_, ctx, i_addr| {
let i = ctx.builder
.build_load(i_addr, "")
.into_int_value();
let i = ctx.builder.build_int_add(i, llvm_usize.const_int(1, true), "");
ctx.builder.build_store(i_addr, i);
.map(BasicValueEnum::into_int_value)
.unwrap();
let i = ctx.builder.build_int_add(i, llvm_usize.const_int(1, true), "").unwrap();
ctx.builder.build_store(i_addr, i).unwrap();
Ok(())
},
@ -268,36 +264,39 @@ fn ndarray_fill_flattened<'ctx, 'a, ValueFn>(
ctx,
|generator, ctx| {
let i = generator.gen_var_alloc(ctx, llvm_usize.into(), None)?;
ctx.builder.build_store(i, llvm_usize.const_zero());
ctx.builder.build_store(i, llvm_usize.const_zero()).unwrap();
Ok(i)
},
|_, ctx, i_addr| {
let i = ctx.builder
.build_load(i_addr, "")
.into_int_value();
.map(BasicValueEnum::into_int_value)
.unwrap();
Ok(ctx.builder.build_int_compare(IntPredicate::ULT, i, ndarray_num_elems, ""))
Ok(ctx.builder.build_int_compare(IntPredicate::ULT, i, ndarray_num_elems, "").unwrap())
},
|generator, ctx, i_addr| {
let i = ctx.builder
.build_load(i_addr, "")
.into_int_value();
.map(BasicValueEnum::into_int_value)
.unwrap();
let elem = unsafe {
ndarray.get_data().ptr_to_data_flattened_unchecked(ctx, i, None)
};
let value = value_fn(generator, ctx, i)?;
ctx.builder.build_store(elem, value);
ctx.builder.build_store(elem, value).unwrap();
Ok(())
},
|_, ctx, i_addr| {
let i = ctx.builder
.build_load(i_addr, "")
.into_int_value();
let i = ctx.builder.build_int_add(i, llvm_usize.const_int(1, true), "");
ctx.builder.build_store(i_addr, i);
.map(BasicValueEnum::into_int_value)
.unwrap();
let i = ctx.builder.build_int_add(i, llvm_usize.const_int(1, true), "").unwrap();
ctx.builder.build_store(i_addr, i).unwrap();
Ok(())
},
@ -451,16 +450,18 @@ fn call_ndarray_full_impl<'ctx, 'a>(
ctx.module.add_function(memcpy_fn_name.as_str(), fn_type, None)
});
ctx.builder.build_call(
memcpy_fn,
&[
copy.into(),
fill_value.into(),
fill_value.get_type().size_of().unwrap().into(),
llvm_i1.const_zero().into(),
],
"",
);
ctx.builder
.build_call(
memcpy_fn,
&[
copy.into(),
fill_value.into(),
fill_value.get_type().size_of().unwrap().into(),
llvm_i1.const_zero().into(),
],
"",
)
.unwrap();
copy.into()
} else if fill_value.is_int_value() || fill_value.is_float_value() {
@ -494,18 +495,19 @@ fn call_ndarray_eye_impl<'ctx, 'a>(
let shape_addr = generator.gen_var_alloc(ctx, llvm_usize_2.into(), None)?;
let shape = ctx.builder.build_load(shape_addr, "")
.into_array_value();
let nrows = ctx.builder.build_int_z_extend_or_bit_cast(nrows, llvm_usize, "");
let shape = ctx.builder
.build_insert_value(shape, nrows, 0, "")
.map(|val| val.into_array_value())
.map(BasicValueEnum::into_array_value)
.unwrap();
let ncols = ctx.builder.build_int_z_extend_or_bit_cast(ncols, llvm_usize, "");
let nrows = ctx.builder.build_int_z_extend_or_bit_cast(nrows, llvm_usize, "").unwrap();
let shape = ctx.builder
.build_insert_value(shape, nrows, 0, "")
.map(AggregateValueEnum::into_array_value)
.unwrap();
let ncols = ctx.builder.build_int_z_extend_or_bit_cast(ncols, llvm_usize, "").unwrap();
let shape = ctx.builder
.build_insert_value(shape, ncols, 1, "")
.map(|val| val.into_array_value())
.map(AggregateValueEnum::into_array_value)
.unwrap();
let ndarray = create_ndarray_const_shape(generator, ctx, elem_ty, shape)?;
@ -526,22 +528,21 @@ fn call_ndarray_eye_impl<'ctx, 'a>(
None,
).into_int_value();
let col_with_offset = ctx.builder.build_int_add(
col,
ctx.builder.build_int_z_extend_or_bit_cast(offset, llvm_usize, ""),
""
);
let is_on_diag = ctx.builder.build_int_compare(
IntPredicate::EQ,
row,
col_with_offset,
""
);
let col_with_offset = ctx.builder
.build_int_add(
col,
ctx.builder.build_int_z_extend_or_bit_cast(offset, llvm_usize, "").unwrap(),
"",
)
.unwrap();
let is_on_diag = ctx.builder
.build_int_compare(IntPredicate::EQ, row, col_with_offset, "")
.unwrap();
let zero = ndarray_zero_value(generator, ctx, elem_ty);
let one = ndarray_one_value(generator, ctx, elem_ty);
let value = ctx.builder.build_select(is_on_diag, one, zero, "");
let value = ctx.builder.build_select(is_on_diag, one, zero, "").unwrap();
Ok(value)
},

View File

@ -16,7 +16,7 @@ lalrpop-util = "0.20"
log = "0.4"
unic-emoji-char = "0.9"
unic-ucd-ident = "0.9"
unicode_names2 = "1.0"
unicode_names2 = "1.2"
phf = { version = "0.11", features = ["macros"] }
ahash = "0.8"

View File

@ -10,10 +10,10 @@ nac3parser = { path = "../nac3parser" }
nac3core = { path = "../nac3core" }
[dependencies.clap]
version = "4.4"
version = "4.5"
features = ["derive"]
[dependencies.inkwell]
version = "0.2"
version = "0.4"
default-features = false
features = ["llvm14-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"]