[core] Refactor ModuleContext and Builder in CodeGenContext

Make those references to simplify gen_func_impl.
This commit is contained in:
2026-02-21 17:18:09 +08:00
parent fec151c8cd
commit bc3c7f0e21
20 changed files with 146 additions and 154 deletions

View File

@@ -150,7 +150,7 @@ impl<'a> ArtiqCodeGenerator<'a> {
store_name.map(|name| format!("{name}.addr")).as_deref(),
)?
.unwrap();
typed_store(&ctx.builder, end_store, max);
typed_store(ctx.builder, end_store, max);
}
Ok(())
@@ -275,7 +275,7 @@ impl CodeGenerator for ArtiqCodeGenerator<'_> {
let start = self
.gen_store_target(ctx, &start_expr, Some("start.addr"))?
.unwrap();
typed_store(&ctx.builder, start, now);
typed_store(ctx.builder, start, now);
Ok(Some(start_expr)) as Result<_, String>
},
|v| Ok(Some(v)),
@@ -288,7 +288,7 @@ impl CodeGenerator for ArtiqCodeGenerator<'_> {
custom: Some(ctx.primitives.int64),
};
let end = self.gen_store_target(ctx, &end_expr, Some("end.addr"))?.unwrap();
typed_store(&ctx.builder, end, now);
typed_store(ctx.builder, end, now);
self.end = Some(end_expr);
self.name_counter += 1;
self.parallel_mode = if python_id == self.special_ids.parallel {
@@ -485,7 +485,7 @@ fn format_rpc_arg<'ctx>(
_ => {
let arg_slot = gen_var(ctx, arg.get_type(), Some(&format!("rpc.arg{arg_idx}")));
typed_store(&ctx.builder, arg_slot, arg);
typed_store(ctx.builder, arg_slot, arg);
ctx.builder
.build_bit_cast(arg_slot, llvm_pi8, "rpc.arg")
@@ -521,7 +521,7 @@ fn format_rpc_ret<'ctx>(
ctx.declare_external("rpc_recv", Some(llvm_i32.into()), &[llvm_pi8.into()], false, &[]);
if ctx.unifier.unioned(ret_ty, ctx.primitives.none) {
ctx.build_call_or_invoke(&rpc_recv, &[llvm_pi8.const_null().into()], "rpc_recv");
let _ = ctx.build_call_or_invoke(&rpc_recv, &[llvm_pi8.const_null().into()], "rpc_recv");
return None;
}
@@ -1043,7 +1043,7 @@ fn polymorphic_print<'ctx>(
TypeEnum::TTuple { ty: tys, is_vararg_ctx: false } => {
let pvalue = {
let pvalue = gen_var(ctx, value.get_type(), None);
typed_store(&ctx.builder, pvalue, value);
typed_store(ctx.builder, pvalue, value);
pvalue
};

View File

@@ -1259,13 +1259,13 @@ impl Nac3 {
);
context_ref!(context);
let context = ModuleContext::new(context, "main", &self.codegen_options.target);
let mut context = ModuleContext::new(context, "main", &self.codegen_options.target);
let builder = context.ctx.create_builder();
let mut unifier_cache = vec![OnceCell::new(); top_level.unifiers.read().len()];
let (context, _, result) = gen_func_impl(
context,
builder,
let result = gen_func_impl(
&mut context,
&builder,
&mut generator,
&registry,
task,

View File

@@ -1322,7 +1322,7 @@ impl InnerResolver {
{
if self.global_value_ids.read().contains_key(&id) {
let enum_ty = EnumerateType::new(&ctx.inner);
let enum_ty = EnumerateType::new(ctx.inner);
let global = ctx.module.get_global(&id_str).unwrap_or_else(|| {
ctx.module.add_global(
enum_ty.inner.llvm_ty,
@@ -1412,7 +1412,7 @@ impl InnerResolver {
// }
// Note: This matches EnumerateType in enumerate.rs where the structure wraps
// the iterable pointer and start value.
let enum_ty = EnumerateType::new(&ctx.inner);
let enum_ty = EnumerateType::new(ctx.inner);
let enum_struct_ty = enum_ty.inner.llvm_ty;
let enum_struct_val = enum_struct_ty.const_named_struct(&[

View File

@@ -86,10 +86,10 @@ impl TimeFns for NowPinningTimeFns64 {
ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(2, false)], "now.lo.addr")
}
.unwrap();
typed_store(&ctx.builder, now_hiptr, time_hi)
typed_store(ctx.builder, now_hiptr, time_hi)
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
typed_store(&ctx.builder, now_loptr, time_lo)
typed_store(ctx.builder, now_loptr, time_lo)
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
}
@@ -143,10 +143,10 @@ impl TimeFns for NowPinningTimeFns64 {
.unwrap();
let time_lo = ctx.builder.build_int_truncate(time, i32_type, "time.lo").unwrap();
typed_store(&ctx.builder, now_hiptr, time_hi)
typed_store(ctx.builder, now_hiptr, time_hi)
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
typed_store(&ctx.builder, now_loptr, time_lo)
typed_store(ctx.builder, now_loptr, time_lo)
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
}
@@ -205,10 +205,10 @@ impl TimeFns for NowPinningTimeFns {
ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(1, false)], "now.lo.addr")
}
.unwrap();
typed_store(&ctx.builder, now_hiptr, time_hi)
typed_store(ctx.builder, now_hiptr, time_hi)
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
typed_store(&ctx.builder, now_loptr, time_lo)
typed_store(ctx.builder, now_loptr, time_lo)
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
}
@@ -252,10 +252,10 @@ impl TimeFns for NowPinningTimeFns {
ctx.builder.build_gep(now_hiptr, &[i32_type.const_int(1, false)], "now.lo.addr")
}
.unwrap();
typed_store(&ctx.builder, now_hiptr, time_hi)
typed_store(ctx.builder, now_hiptr, time_hi)
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
typed_store(&ctx.builder, now_loptr, time_lo)
typed_store(ctx.builder, now_loptr, time_lo)
.set_atomic_ordering(AtomicOrdering::SequentiallyConsistent)
.unwrap();
}

View File

@@ -830,8 +830,8 @@ pub fn call_numpy_max_min<'ctx>(
let extremum_idx = gen_var(ctx, ctx.size_t, None);
let first_value = ndarray.first_element(ctx);
typed_store(&ctx.builder, extremum, first_value);
typed_store(&ctx.builder, extremum_idx, zero);
typed_store(ctx.builder, extremum, first_value);
typed_store(ctx.builder, extremum_idx, zero);
// The first element is iterated, but this doesn't matter.
ndarray
@@ -884,8 +884,8 @@ pub fn call_numpy_max_min<'ctx>(
}
};
typed_store(&ctx.builder, extremum, new_extremum);
typed_store(&ctx.builder, extremum_idx, new_extremum_idx);
typed_store(ctx.builder, extremum, new_extremum);
typed_store(ctx.builder, extremum_idx, new_extremum_idx);
Ok(())
})

View File

@@ -198,7 +198,7 @@ impl<'ctx> CodeGenContext<'ctx, '_> {
/// See [`get_llvm_type`].
pub fn get_llvm_type(&mut self, ty: Type) -> BasicTypeEnum<'ctx> {
get_llvm_type(&self.inner, &mut self.unifier, &mut self.type_cache, ty)
get_llvm_type(self.inner, &mut self.unifier, &mut self.type_cache, ty)
}
/// Returns the type for performing memory allocation for the given `ty`.
@@ -208,13 +208,7 @@ impl<'ctx> CodeGenContext<'ctx, '_> {
/// See [`get_llvm_abi_type`].
pub fn get_llvm_abi_type(&mut self, ty: Type) -> BasicTypeEnum<'ctx> {
get_llvm_abi_type(
&self.inner,
&mut self.unifier,
&mut self.type_cache,
&self.primitives,
ty,
)
get_llvm_abi_type(self.inner, &mut self.unifier, &mut self.type_cache, &self.primitives, ty)
}
/// Generates an LLVM variable for a [constant value][value] with a given [type][ty].
@@ -451,7 +445,7 @@ impl<'ctx> CodeGenContext<'ctx, '_> {
let args: Vec<_> = args.iter().map(|v| (*v).into()).collect();
self.fn_store.do_call(
fun,
&self.builder,
self.builder,
&args,
|value, args| self.builder.build_call(value, args, call_name).unwrap(),
alloca,
@@ -463,7 +457,7 @@ impl<'ctx> CodeGenContext<'ctx, '_> {
self.ctx.append_basic_block(current, &format!("after.{call_name}"));
let result = self.fn_store.do_call(
fun,
&self.builder,
self.builder,
args,
|value, args| {
self.builder
@@ -479,6 +473,7 @@ impl<'ctx> CodeGenContext<'ctx, '_> {
}
/// Calls a declared function.
#[must_use]
pub fn build_call_or_invoke(
&self,
fun: &FunctionDecl<'ctx>,
@@ -489,6 +484,7 @@ impl<'ctx> CodeGenContext<'ctx, '_> {
}
/// Calls a declared function, ignoring unwind info.
#[must_use]
pub fn build_call(
&self,
fun: &FunctionDecl<'ctx>,
@@ -851,7 +847,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
let zero_32 = int32.const_zero();
let index = gen_var(ctx, size_t, Some("index.addr"));
typed_store(&ctx.builder, index, zero_size_t);
typed_store(ctx.builder, index, zero_size_t);
let elem_ty = elt.custom.unwrap();
let list;
@@ -893,7 +889,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
let i = generator.gen_store_target(ctx, target, Some("i.addr"))?.unwrap();
typed_store(
&ctx.builder,
ctx.builder,
i,
ctx.builder.build_int_sub(start, step, "start_init").unwrap(),
);
@@ -916,7 +912,7 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
"start_loop",
)
.unwrap();
typed_store(&ctx.builder, i, tmp);
typed_store(ctx.builder, i, tmp);
ctx.builder
.build_conditional_branch(
gen_in_range_check(ctx, tmp, stop, step),
@@ -937,14 +933,14 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
let counter = gen_var(ctx, size_t, Some("counter.addr"));
// counter = -1
typed_store(&ctx.builder, counter, size_t.const_all_ones());
typed_store(ctx.builder, counter, size_t.const_all_ones());
ctx.builder.build_unconditional_branch(test_bb).unwrap();
ctx.builder.position_at_end(test_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();
typed_store(&ctx.builder, counter, tmp);
typed_store(ctx.builder, counter, tmp);
let cmp = ctx.builder.build_int_compare(IntPredicate::SLT, tmp, length, "cmp").unwrap();
ctx.builder.build_conditional_branch(cmp, body_bb, cont_bb).unwrap();
@@ -982,9 +978,9 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
let i = ctx.builder.build_load(index, "i").map(BasicValueEnum::into_int_value).unwrap();
let elem_ptr = list.data(ctx).ptr_offset_unchecked(ctx, &i, Some("elem_ptr"));
let val = generator.gen_expr(ctx, elt)?.to_basic_value_enum(ctx)?;
typed_store(&ctx.builder, elem_ptr, val);
typed_store(ctx.builder, elem_ptr, val);
typed_store(
&ctx.builder,
ctx.builder,
index,
ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc").unwrap(),
);
@@ -1300,7 +1296,7 @@ pub fn gen_unaryop_expr_with_values<'ctx>(
.build_int_compare(IntPredicate::EQ, val, val.get_type().const_zero(), "not")
.unwrap();
bool_to_int_type(&ctx.builder, not, val.get_type()).into()
bool_to_int_type(ctx.builder, not, val.get_type()).into()
} else {
let llvm_i32 = ctx.i32;
@@ -1588,7 +1584,7 @@ pub fn gen_cmpop_expr_with_values<'ctx, G: CodeGenerator>(
|_, _ctx| Ok(eq_len),
|generator, ctx| {
let acc_addr = gen_var(ctx, ctx.i8, None);
typed_store(&ctx.builder, acc_addr, ctx.i8.const_all_ones());
typed_store(ctx.builder, acc_addr, ctx.i8.const_all_ones());
gen_for_callback_incrementing(
&mut (),
@@ -1620,8 +1616,8 @@ pub fn gen_cmpop_expr_with_values<'ctx, G: CodeGenerator>(
ctx,
|(), _ctx| Ok(bool_res),
|(), ctx| {
typed_store(&ctx.builder, acc_addr, false_);
hooks.build_break_branch(&ctx.builder);
typed_store(ctx.builder, acc_addr, false_);
hooks.build_break_branch(ctx.builder);
Ok(())
},
@@ -1676,7 +1672,7 @@ pub fn gen_cmpop_expr_with_values<'ctx, G: CodeGenerator>(
// Assume `true` by default
let cmp_addr = gen_var(ctx, llvm_i8, None);
typed_store(&ctx.builder, cmp_addr, llvm_i8.const_all_ones());
typed_store(ctx.builder, cmp_addr, llvm_i8.const_all_ones());
let current_bb = ctx.builder.get_insert_block().unwrap();
let post_foreach_cmp = ctx.ctx.insert_basic_block_after(current_bb, "foreach.cmp.end");
@@ -2031,7 +2027,7 @@ fn gen_ifexp_expr<'ctx, G: CodeGenerator>(
None => None,
Some(v) => {
let a = a.to_basic_value_enum(ctx)?;
Some(typed_store(&ctx.builder, v, a))
Some(typed_store(ctx.builder, v, a))
}
};
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
@@ -2042,7 +2038,7 @@ fn gen_ifexp_expr<'ctx, G: CodeGenerator>(
None => None,
Some(v) => {
let b = b.to_basic_value_enum(ctx)?;
Some(typed_store(&ctx.builder, v, b))
Some(typed_store(ctx.builder, v, b))
}
};
ctx.builder.build_unconditional_branch(cont_bb).unwrap();
@@ -2400,7 +2396,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
let llvm_ty = ctx.get_llvm_type(ty);
match ctx.var_assignment.get(id) {
Some(VarValue { ptr, static_value: None, .. }) => {
let val = typed_load(&ctx.builder, *ptr, llvm_ty, id.to_string().as_str());
let val = typed_load(ctx.builder, *ptr, llvm_ty, id.to_string().as_str());
Ok(RtValue::dynamic(ty, val))
}
Some(VarValue { static_value: Some(static_value), .. }) => {

View File

@@ -63,6 +63,7 @@ pub fn call_va_end<'ctx>(ctx: &CodeGenContext<'ctx, '_>, arglist: PointerValue<'
}
#[doc = llvm_doc!("va_stacksave")]
#[must_use]
pub fn call_stacksave<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
name: Option<&str>,
@@ -235,6 +236,7 @@ macro_rules! generate_llvm_intrinsic_fn {
///
/// * `src` - The value for which the absolute value is to be returned.
/// * `is_int_min_poison` - Whether `poison` is to be returned if `src` is `INT_MIN`.
#[must_use]
pub fn call_int_abs<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
src: IntValue<'ctx>,
@@ -272,6 +274,7 @@ generate_llvm_intrinsic_fn!(float call_float_round: "round"(val));
generate_llvm_intrinsic_fn!(float call_float_rint: "rint"(val));
#[doc = llvm_doc!("powi")]
#[must_use]
pub fn call_float_powi<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
val: FloatValue<'ctx>,
@@ -282,6 +285,7 @@ pub fn call_float_powi<'ctx>(
}
#[doc = llvm_doc!("ctpop")]
#[must_use]
pub fn call_int_ctpop<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
src: IntValue<'ctx>,

View File

@@ -231,10 +231,10 @@ impl TargetMachineOptions {
pub struct CodeGenContext<'ctx, 'a> {
/// The [`CoreContext`] instance which includes the module and target-specific information.
pub inner: ModuleContext<'ctx>,
pub inner: &'a mut ModuleContext<'ctx>,
/// The [`Builder`] instance for creating LLVM IR statements.
pub builder: Builder<'ctx>,
pub builder: &'a Builder<'ctx>,
/// The [`DebugInfoBuilder`], [compilation unit information][DICompileUnit], and
/// [scope information][DIScope] of this context.
pub debug_info: (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>, DIScope<'ctx>),
@@ -290,13 +290,13 @@ impl<'ctx> std::ops::Deref for CodeGenContext<'ctx, '_> {
type Target = ModuleContext<'ctx>;
fn deref(&self) -> &Self::Target {
&self.inner
self.inner
}
}
impl std::ops::DerefMut for CodeGenContext<'_, '_> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
self.inner
}
}
@@ -444,25 +444,18 @@ impl WorkerRegistry {
context_ref!(ctx);
let options = &self.codegen_options.target;
let mut context = ModuleContext::new(ctx, generator.get_name(), options);
let mut builder = context.ctx.create_builder();
let builder = context.ctx.create_builder();
let mut unifier_cache = vec![OnceCell::new(); self.top_level_ctx.unifiers.read().len()];
let mut errors = HashSet::new();
while let Some(task) = self.receiver.recv().unwrap() {
let (context_, builder_, result) =
gen_func(context, builder, generator, self, task, &mut unifier_cache);
builder = builder_;
context = match result {
Ok(_) => context_,
Err(e) => {
errors.insert(e);
ModuleContext::new(
context_.ctx,
&format!("{}_recover", generator.get_name()),
&self.codegen_options.target,
)
}
};
let result =
gen_func(&mut context, &builder, generator, self, task, &mut unifier_cache);
if let Err(e) = result {
errors.insert(e);
context =
ModuleContext::new(ctx, &format!("{}_recover", generator.get_name()), options);
}
*self.task_count.lock() -= 1;
self.wait_condvar.notify_all();
}
@@ -545,7 +538,7 @@ fn get_alloca_type<'ctx>(ctx: &mut CodeGenContext<'ctx, '_>, ty: Type) -> BasicT
let fields = fields_list
.iter()
.map(|f| {
get_llvm_type(&ctx.inner, &mut ctx.unifier, &mut ctx.type_cache, fields[&f.0].0)
get_llvm_type(ctx.inner, &mut ctx.unifier, &mut ctx.type_cache, fields[&f.0].0)
})
.collect_vec();
struct_type.set_body(&fields, false);
@@ -706,17 +699,18 @@ where
)]
pub fn gen_func_impl<
'ctx,
'a,
G: CodeGenerator,
F: FnOnce(&mut G, &mut CodeGenContext) -> Result<(), String>,
>(
mut ctx: ModuleContext<'ctx>,
builder: Builder<'ctx>,
ctx: &'a mut ModuleContext<'ctx>,
builder: &'a Builder<'ctx>,
generator: &mut G,
registry: &WorkerRegistry,
task: CodeGenTask,
unifier_cache: &mut [OnceCell<Unifier>],
codegen_function: F,
) -> (ModuleContext<'ctx>, Builder<'ctx>, Result<FunctionValue<'ctx>, String>) {
) -> Result<FunctionValue<'ctx>, String> {
let top_level_ctx = registry.top_level_ctx.clone();
let static_value_store = registry.static_value_store.clone();
let (mut unifier, primitives) = {
@@ -777,10 +771,10 @@ pub fn gen_func_impl<
(primitives.uint64, ctx.i64.into()),
(primitives.float, ctx.f64.into()),
(primitives.bool, ctx.i8.into()),
(primitives.str, { StringType::new(&ctx).llvm_ty(&ctx) }),
(primitives.range, RangeType::new(&ctx).llvm_ty(&ctx)),
(primitives.enumerate, EnumerateType::new(&ctx).llvm_ty(&ctx)),
(primitives.exception, { ExceptionType::new(&ctx).llvm_ty(&ctx) }),
(primitives.str, { StringType::new(ctx).llvm_ty(ctx) }),
(primitives.range, RangeType::new(ctx).llvm_ty(ctx)),
(primitives.enumerate, EnumerateType::new(ctx).llvm_ty(ctx)),
(primitives.exception, { ExceptionType::new(ctx).llvm_ty(ctx) }),
]
.iter()
.copied()
@@ -800,7 +794,7 @@ pub fn gen_func_impl<
let ret_type = if unifier.unioned(ret, primitives.none) {
None
} else {
Some(get_llvm_abi_type(&ctx, &mut unifier, &mut type_cache, &primitives, ret))
Some(get_llvm_abi_type(ctx, &mut unifier, &mut type_cache, &primitives, ret))
};
let params = args
@@ -815,7 +809,7 @@ pub fn gen_func_impl<
let params_type = params
.iter()
.map(|arg| {
get_llvm_abi_type(&ctx, &mut unifier, &mut type_cache, &primitives, arg.ty).into()
get_llvm_abi_type(ctx, &mut unifier, &mut type_cache, &primitives, arg.ty).into()
})
.collect_vec();
@@ -824,7 +818,7 @@ pub fn gen_func_impl<
// so we must redefine the function from scratch.
let (_, fn_val) = ctx.declare_internal(symbol, ret_type, &params_type, task.export_symbol);
if let Some(personality) = get_personality(&top_level_ctx, &ctx) {
if let Some(personality) = get_personality(&top_level_ctx, ctx) {
fn_val.set_personality_function(personality);
}
@@ -837,7 +831,7 @@ pub fn gen_func_impl<
for (n, arg) in params.iter().enumerate().filter(|(_, arg)| !arg.is_vararg) {
let param = fn_val.get_nth_param(n as u32).unwrap();
let local_type = get_llvm_type(&ctx, &mut unifier, &mut type_cache, arg.ty);
let local_type = get_llvm_type(ctx, &mut unifier, &mut type_cache, arg.ty);
let alloca =
builder.build_alloca(local_type, &format!("{}.addr", &arg.name.to_string())).unwrap();
@@ -847,7 +841,7 @@ pub fn gen_func_impl<
let param_val = param.into_int_value();
if expected_ty.get_bit_width() == 8 && param_val.get_type().get_bit_width() == 1 {
bool_to_int_type(&builder, param_val, ctx.i8)
bool_to_int_type(builder, param_val, ctx.i8)
} else {
param_val
}
@@ -856,7 +850,7 @@ pub fn gen_func_impl<
param
};
typed_store(&builder, alloca, param);
typed_store(builder, alloca, param);
var_assignment.insert(arg.name, VarValue::new(alloca));
}
@@ -875,7 +869,7 @@ pub fn gen_func_impl<
}
let exception_val = {
let exn_type = ExceptionType::new(&ctx).inner.llvm_ty;
let exn_type = ExceptionType::new(ctx).inner.llvm_ty;
let ptr = builder.build_alloca(exn_type, "exn").unwrap();
builder.build_pointer_cast(ptr, ctx.ptr, "exn").unwrap()
};
@@ -979,8 +973,7 @@ pub fn gen_func_impl<
code_gen_context.builder.unset_current_debug_location();
code_gen_context.debug_info.0.finalize();
let CodeGenContext { inner, builder, .. } = code_gen_context;
(inner, builder, result)
result
}
/// Generates LLVM IR for a function.
@@ -990,31 +983,34 @@ pub fn gen_func_impl<
/// * `generator` - The [`CodeGenerator`] for generating various program constructs.
/// * `registry` - The [`WorkerRegistry`] responsible for monitoring this function generation task.
/// * `task` - The [`CodeGenTask`] associated with this function generation task.
pub fn gen_func<'ctx, G: CodeGenerator>(
context: ModuleContext<'ctx>,
builder: Builder<'ctx>,
pub fn gen_func<'ctx, 'a, G: CodeGenerator>(
context: &'a mut ModuleContext<'ctx>,
builder: &'a Builder<'ctx>,
generator: &mut G,
registry: &WorkerRegistry,
task: CodeGenTask,
unifier_cache: &mut [OnceCell<Unifier>],
) -> (ModuleContext<'ctx>, Builder<'ctx>, Result<FunctionValue<'ctx>, String>) {
) -> Result<FunctionValue<'ctx>, String> {
let body = task.body.clone();
gen_func_impl(context, builder, generator, registry, task, unifier_cache, |generator, ctx| {
generator.gen_block(ctx, body.iter())
})
}
#[must_use]
pub fn bool_to_i1<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
bool_value: IntValue<'ctx>,
) -> IntValue<'ctx> {
bool_to_int_type(&ctx.builder, bool_value, ctx.i1)
bool_to_int_type(ctx.builder, bool_value, ctx.i1)
}
#[must_use]
pub fn bool_to_i8<'ctx>(
ctx: &CodeGenContext<'ctx, '_>,
bool_value: IntValue<'ctx>,
) -> IntValue<'ctx> {
bool_to_int_type(&ctx.builder, bool_value, ctx.i8)
bool_to_int_type(ctx.builder, bool_value, ctx.i8)
}
/// Converts the value of a boolean-like value `value` into an arbitrary [`IntType`].

View File

@@ -316,7 +316,7 @@ pub fn ndarray_dot<'ctx>(
let dtype_llvm = ctx.get_llvm_type(common_dtype);
let result = gen_var(ctx, dtype_llvm, Some("np_dot_result"));
typed_store(&ctx.builder, result, dtype_llvm.const_zero());
typed_store(ctx.builder, result, dtype_llvm.const_zero());
// Do dot product.
gen_for_callback(
@@ -357,7 +357,7 @@ pub fn ndarray_dot<'ctx>(
}
};
typed_store(&ctx.builder, result, new_result);
typed_store(ctx.builder, result, new_result);
Ok(())
},
|(), ctx, (a_iter, b_iter)| {

View File

@@ -65,8 +65,8 @@ fn get_var_builder<'ctx, T>(
);
let new_builder;
let builder = if late {
&ctx.builder
let builder: &Builder<'ctx> = if late {
ctx.builder
} else {
new_builder = ctx.ctx.create_builder();
// position before the last branching instruction...
@@ -267,7 +267,7 @@ pub fn gen_assign<'ctx, G: CodeGenerator>(
val
};
typed_store(&ctx.builder, ptr, val);
typed_store(ctx.builder, ptr, val);
}
}
Ok(())
@@ -288,7 +288,7 @@ pub fn gen_assign_target_list<'ctx, G: CodeGenerator>(
};
let do_assign_list = |generator: &mut G, ctx: &mut _, target, list: &ListValue<'ctx>| {
let ptr = generator.gen_store_target(ctx, target, Some("starred_target.addr"))?.unwrap();
typed_store(&ctx.builder, ptr, list.value);
typed_store(ctx.builder, ptr, list.value);
Ok::<_, String>(())
};
@@ -890,7 +890,7 @@ pub fn gen_for<G: CodeGenerator>(
codegen_unreachable!(ctx)
};
typed_store(&ctx.builder, i, start);
typed_store(ctx.builder, i, start);
Ok((i, target_i))
},
@@ -904,7 +904,7 @@ pub fn gen_for<G: CodeGenerator>(
},
|generator, ctx, _, (i, target_i)| {
typed_store(
&ctx.builder,
ctx.builder,
target_i,
ctx.builder.build_load(i, "").map(BasicValueEnum::into_int_value).unwrap(),
);
@@ -924,7 +924,7 @@ pub fn gen_for<G: CodeGenerator>(
"inc",
)
.unwrap();
typed_store(&ctx.builder, i, next_i);
typed_store(ctx.builder, i, next_i);
Ok(())
},
@@ -951,7 +951,7 @@ pub fn gen_for<G: CodeGenerator>(
let iterable_struct_ty =
ctx.ctx.struct_type(&[ctx.ptr.into(), ctx.size_t.into()], false);
let iterable_struct_val = typed_load(
&ctx.builder,
ctx.builder,
iterable_ptr,
iterable_struct_ty.into(),
"iterable_struct",
@@ -964,7 +964,7 @@ pub fn gen_for<G: CodeGenerator>(
let iterable_ty = iter_type_vars(params).nth(1).unwrap().ty;
let iterable_llvm_ty = ctx.get_llvm_type(iterable_ty);
let ag = typed_load(
&ctx.builder,
ctx.builder,
iterable_data_i8ptr.into_pointer_value(),
iterable_llvm_ty,
"iterable_struct",
@@ -1056,7 +1056,7 @@ pub fn gen_for<G: CodeGenerator>(
None,
|_, ctx| {
let index_addr = gen_var(ctx, size_t, Some("for.index.addr"));
typed_store(&ctx.builder, index_addr, size_t.const_zero());
typed_store(ctx.builder, index_addr, size_t.const_zero());
Ok(index_addr)
},
@@ -1095,7 +1095,7 @@ pub fn gen_for<G: CodeGenerator>(
.unwrap();
let inc =
ctx.builder.build_int_add(index, size_t.const_int(1, true), "inc").unwrap();
typed_store(&ctx.builder, index_addr, inc);
typed_store(ctx.builder, index_addr, inc);
Ok(())
},
@@ -1118,7 +1118,7 @@ pub fn gen_for<G: CodeGenerator>(
None,
|_, ctx| {
let index_addr = gen_var(ctx, size_t, Some("for.index.addr"));
typed_store(&ctx.builder, index_addr, size_t.const_zero());
typed_store(ctx.builder, index_addr, size_t.const_zero());
Ok(index_addr)
},
@@ -1182,7 +1182,7 @@ pub fn gen_for<G: CodeGenerator>(
.builder
.build_int_add(index, size_t.const_int(1, false), "inc")
.unwrap();
typed_store(&ctx.builder, index_addr, inc);
typed_store(ctx.builder, index_addr, inc);
Ok(())
},
@@ -1267,7 +1267,7 @@ where
label,
|_, ctx| {
let i_addr = gen_var(ctx, init_val_t, None);
typed_store(&ctx.builder, i_addr, init_val);
typed_store(ctx.builder, i_addr, init_val);
Ok(i_addr)
},
@@ -1290,7 +1290,7 @@ where
let incr_val =
ctx.builder.build_int_z_extend_or_bit_cast(incr_val, init_val_t, "").unwrap();
let i = ctx.builder.build_int_add(i, incr_val, "").unwrap();
typed_store(&ctx.builder, i_addr, i);
typed_store(ctx.builder, i_addr, i);
Ok(())
},
@@ -1354,7 +1354,7 @@ where
let i_addr = gen_var(ctx, init_val_t, None);
let start = start_fn(generator, ctx)?;
typed_store(&ctx.builder, i_addr, start);
typed_store(ctx.builder, i_addr, start);
let start = start_fn(generator, ctx)?;
let stop = stop_fn(generator, ctx)?;
@@ -1425,7 +1425,7 @@ where
};
let i = ctx.builder.build_int_add(i, incr_val, "").unwrap();
typed_store(&ctx.builder, i_addr, i);
typed_store(ctx.builder, i_addr, i);
Ok(())
},
@@ -1730,7 +1730,7 @@ pub fn final_proxy<'ctx>(
let prev = ctx.builder.get_insert_block().unwrap();
ctx.builder.position_at_end(block);
unsafe {
typed_store(&ctx.builder, *final_state, target.get_address().unwrap());
typed_store(ctx.builder, *final_state, target.get_address().unwrap());
}
ctx.builder.position_at_end(prev);
final_targets.push(target);
@@ -1836,10 +1836,10 @@ pub fn gen_raise<'ctx>(
let raise = get_builtins(ctx, "__nac3_raise");
let exception = ctx.builder.build_pointer_cast(exception.value, ctx.ptr, "").unwrap();
ctx.build_call_or_invoke(&raise, &[exception.into()], "raise");
let _ = ctx.build_call_or_invoke(&raise, &[exception.into()], "raise");
} else {
let resume = get_builtins(ctx, "__nac3_resume");
ctx.build_call_or_invoke(&resume, &[], "resume");
let _ = ctx.build_call_or_invoke(&resume, &[], "resume");
}
ctx.builder.build_unreachable().unwrap();
}
@@ -1994,9 +1994,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.build_call(&end_catch, &[], "end_catch");
let _ = ctx.build_call(&end_catch, &[], "end_catch");
ctx.builder.position_at_end(continue_proxy);
ctx.build_call(&end_catch, &[], "end_catch");
let _ = ctx.build_call(&end_catch, &[], "end_catch");
ctx.builder.position_at_end(body);
redirect(ctx, break_target, break_proxy);
redirect(ctx, continue_target, continue_proxy);
@@ -2005,7 +2005,7 @@ 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.build_call(&end_catch, &[], "end_catch");
let _ = ctx.build_call(&end_catch, &[], "end_catch");
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);
@@ -2036,14 +2036,14 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
let exn_ty = ctx.get_llvm_type(type_.as_ref().unwrap().custom.unwrap());
let exn_store = gen_var(ctx, exn_ty, Some("try.exn_store.addr"));
ctx.var_assignment.insert(*name, VarValue::new(exn_store));
typed_store(&ctx.builder, exn_store, exn.as_basic_value());
typed_store(ctx.builder, exn_store, exn.as_basic_value());
}
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.build_call(&end_catch, &[], "end_catch");
let _ = ctx.build_call(&end_catch, &[], "end_catch");
}
post_handlers.push(current);
ctx.builder.position_at_end(dispatcher_end);
@@ -2099,7 +2099,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
phi.add_incoming(&[(&exn_val, dispatcher_end)]);
ctx.builder.build_unconditional_branch(outer_dispatcher).unwrap();
} else {
ctx.build_call_or_invoke(&resume, &[], "resume");
let _ = ctx.build_call_or_invoke(&resume, &[], "resume");
ctx.builder.build_unreachable().unwrap();
}
}
@@ -2127,7 +2127,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
ctx.builder.position_at_end(cleanup);
generator.gen_block(ctx, finalbody.iter())?;
if !ctx.is_terminated() {
ctx.build_call_or_invoke(&resume, &[], "resume");
let _ = ctx.build_call_or_invoke(&resume, &[], "resume");
ctx.builder.build_unreachable().unwrap();
}
@@ -2152,7 +2152,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
if block.get_terminator().is_none() {
ctx.builder.position_at_end(*block);
unsafe {
typed_store(&ctx.builder, final_state, tail.get_address().unwrap());
typed_store(ctx.builder, final_state, tail.get_address().unwrap());
}
ctx.builder.build_unconditional_branch(finalizer).unwrap();
}
@@ -2334,9 +2334,9 @@ pub fn gen_with<'ctx, 'a, G: CodeGenerator>(
let break_proxy = ctx.ctx.append_basic_block(current_fun, "with.break");
let continue_proxy = ctx.ctx.append_basic_block(current_fun, "with.continue");
ctx.builder.position_at_end(break_proxy);
ctx.build_call(&end_catch, &[], "end_catch");
let _ = ctx.build_call(&end_catch, &[], "end_catch");
ctx.builder.position_at_end(continue_proxy);
ctx.build_call(&end_catch, &[], "end_catch");
let _ = ctx.build_call(&end_catch, &[], "end_catch");
ctx.builder.position_at_end(body);
redirect(ctx, break_target, break_proxy);
redirect(ctx, continue_target, continue_proxy);
@@ -2345,7 +2345,7 @@ pub fn gen_with<'ctx, 'a, G: CodeGenerator>(
}
let return_proxy = ctx.ctx.append_basic_block(current_fun, "with.return");
ctx.builder.position_at_end(return_proxy);
ctx.build_call(&end_catch, &[], "end_catch");
let _ = ctx.build_call(&end_catch, &[], "end_catch");
let return_target = ctx.return_target.take().unwrap_or_else(|| {
let doreturn = ctx.ctx.append_basic_block(current_fun, "with.doreturn");
ctx.builder.position_at_end(doreturn);
@@ -2386,7 +2386,7 @@ pub fn gen_with<'ctx, 'a, G: CodeGenerator>(
// exception path
ctx.builder.position_at_end(cleanup);
exit_gen_lambda(ctx, generator)?;
ctx.build_call_or_invoke(&resume, &[], "resume");
let _ = ctx.build_call_or_invoke(&resume, &[], "resume");
ctx.builder.build_unreachable().unwrap();
// normal path
@@ -2408,7 +2408,7 @@ pub fn gen_with<'ctx, 'a, G: CodeGenerator>(
if block.get_terminator().is_none() {
ctx.builder.position_at_end(*block);
unsafe {
typed_store(&ctx.builder, final_state, tail.get_address().unwrap());
typed_store(ctx.builder, final_state, tail.get_address().unwrap());
}
ctx.builder.build_unconditional_branch(finalizer).unwrap();
}
@@ -2450,7 +2450,7 @@ pub fn gen_return<G: CodeGenerator>(
if let Some(return_target) = ctx.return_target {
if let Some(value) = value {
typed_store(&ctx.builder, ctx.return_buffer.unwrap(), value);
typed_store(ctx.builder, ctx.return_buffer.unwrap(), value);
}
ctx.builder.build_unconditional_branch(return_target).unwrap();
} else {

View File

@@ -39,9 +39,7 @@ pub trait ArrayLikeIndexer<'ctx, Index = IntValue<'ctx>> {
name: Option<&str>,
) -> V {
let ptr = self.ptr_offset_unchecked(ctx, idx, name);
typed_load(&ctx.builder, ptr, self.item_type(), name.unwrap_or_default())
.try_into()
.unwrap()
typed_load(ctx.builder, ptr, self.item_type(), name.unwrap_or_default()).try_into().unwrap()
}
/// Loads the value at the `idx`-th index with bounds checking.
@@ -52,9 +50,7 @@ pub trait ArrayLikeIndexer<'ctx, Index = IntValue<'ctx>> {
name: Option<&str>,
) -> V {
let ptr = self.ptr_offset(ctx, idx, name);
typed_load(&ctx.builder, ptr, self.item_type(), name.unwrap_or_default())
.try_into()
.unwrap()
typed_load(ctx.builder, ptr, self.item_type(), name.unwrap_or_default()).try_into().unwrap()
}
/// Stores the `value` at the `idx`-th index without bounds checking.
@@ -66,7 +62,7 @@ pub trait ArrayLikeIndexer<'ctx, Index = IntValue<'ctx>> {
name: Option<&str>,
) {
let ptr = self.ptr_offset_unchecked(ctx, idx, name);
typed_store(&ctx.builder, ptr, value.as_basic_value_enum());
typed_store(ctx.builder, ptr, value.as_basic_value_enum());
}
/// Stores the `value` at the `idx`-th index with bounds checking.
@@ -78,7 +74,7 @@ pub trait ArrayLikeIndexer<'ctx, Index = IntValue<'ctx>> {
name: Option<&str>,
) {
let ptr = self.ptr_offset(ctx, idx, name);
typed_store(&ctx.builder, ptr, value.as_basic_value_enum());
typed_store(ctx.builder, ptr, value.as_basic_value_enum());
}
}

View File

@@ -180,7 +180,7 @@ where
let result = mapping(ctx, &in_scalars)?;
let p = out_nditer.curr_ptr(ctx);
typed_store(&ctx.builder, p, result);
typed_store(ctx.builder, p, result);
Ok(())
},

View File

@@ -184,7 +184,7 @@ impl<'ctx> NDArrayType<'ctx> {
let value = ctx.builder.build_select(be_one, ndone, ndzero, "value").unwrap();
let p = nditer.curr_ptr(ctx);
typed_store(&ctx.builder, p, value);
typed_store(ctx.builder, p, value);
Ok(())
})

View File

@@ -226,7 +226,7 @@ impl<'ctx> RustNDIndex<'ctx> {
match *self {
RustNDIndex::SingleElement(in_index) => {
let index_ptr = gen_var(ctx, ctx.i32, None);
typed_store(&ctx.builder, index_ptr, in_index);
typed_store(ctx.builder, index_ptr, in_index);
dst_ndindex.store(ctx, field!(data), index_ptr);
}
RustNDIndex::Slice(slice) => {

View File

@@ -97,7 +97,7 @@ impl<'ctx> NDIterValue<'ctx> {
#[must_use]
pub fn get_scalar(&self, ctx: &mut CodeGenContext<'ctx, '_>) -> BasicValueEnum<'ctx> {
let p = self.curr_ptr(ctx);
typed_load(&ctx.builder, p, self.ty.dtype, "value")
typed_load(ctx.builder, p, self.ty.dtype, "value")
}
/// Returns the current iteration index (i.e., how many elements have been iterated so far).
@@ -165,7 +165,7 @@ impl<'ctx> NDArrayValue<'ctx> {
{
let init = init.as_basic_value_enum();
let acc_ptr = gen_var(ctx, init.get_type(), None);
typed_store(&ctx.builder, acc_ptr, init);
typed_store(ctx.builder, acc_ptr, init);
gen_for_callback(
&mut (),
@@ -176,7 +176,7 @@ impl<'ctx> NDArrayValue<'ctx> {
|(), ctx, hooks, nditer| {
let acc = V::try_from(ctx.builder.build_load(acc_ptr, "").unwrap()).unwrap();
let acc = f(ctx, hooks, acc, nditer)?;
typed_store(&ctx.builder, acc_ptr, acc);
typed_store(ctx.builder, acc_ptr, acc);
Ok(())
},
|(), ctx, nditer| {

View File

@@ -77,7 +77,7 @@ fn matmul_at_least_2d<'ctx>(
dst.foreach(ctx, |ctx, _, hdl| {
let pdst_ij = hdl.curr_ptr(ctx);
typed_store(&ctx.builder, pdst_ij, dst_zero);
typed_store(ctx.builder, pdst_ij, dst_zero);
let indices = hdl.indices(ctx);
let i = indices.get_unchecked::<IntValue<'ctx>>(ctx, &at_row, None);
@@ -116,7 +116,7 @@ fn matmul_at_least_2d<'ctx>(
.expect("matmul: ndarray should contain primtives only");
// dst_[...]ij += x
let dst_ij = typed_load(&ctx.builder, pdst_ij, dst_dtype_llvm, "");
let dst_ij = typed_load(ctx.builder, pdst_ij, dst_dtype_llvm, "");
let dst_ij = gen_prim_binop_expr(
ctx,
(&Some(dst_dtype), dst_ij),
@@ -124,7 +124,7 @@ fn matmul_at_least_2d<'ctx>(
(&Some(dst_dtype), x),
)?
.expect("matmul: ndarray should contain primtives only");
typed_store(&ctx.builder, pdst_ij, dst_ij);
typed_store(ctx.builder, pdst_ij, dst_ij);
Ok(())
},

View File

@@ -192,7 +192,7 @@ impl<'ctx> NDArrayValue<'ctx> {
let dtype = value.get_type();
let ndarray = NDArrayType::new(ctx, dtype, 0).construct(ctx, name);
let data = gen_var(ctx, value.get_type(), Some("map_unsized"));
typed_store(&ctx.builder, data, value);
typed_store(ctx.builder, data, value);
let data = ctx.builder.build_pointer_cast(data, ctx.ptr, "").unwrap();
ndarray.store(ctx, field!(data), data);
ndarray
@@ -331,7 +331,7 @@ impl<'ctx> NDArrayValue<'ctx> {
// Probably best to implement in IRRT.
self.foreach(ctx, |ctx, _, nditer| {
let p = nditer.curr_ptr(ctx);
typed_store(&ctx.builder, p, value);
typed_store(ctx.builder, p, value);
Ok(())
})
.unwrap();
@@ -341,7 +341,7 @@ impl<'ctx> NDArrayValue<'ctx> {
#[must_use]
pub fn first_element(&self, ctx: &mut CodeGenContext<'ctx, '_>) -> BasicValueEnum<'ctx> {
let data = self.load(ctx, field!(data));
typed_load(&ctx.builder, data, self.ty.dtype, "first_element")
typed_load(ctx.builder, data, self.ty.dtype, "first_element")
}
}

View File

@@ -48,7 +48,7 @@ impl OptionType {
match value {
Some(v) => {
let value = self.alloca(ctx, name);
typed_store(&ctx.builder, value.value, v);
typed_store(ctx.builder, value.value, v);
value
}
None => self.map_value(ctx.ptr.const_null(), name),
@@ -73,6 +73,6 @@ impl<'ctx> OptionValue<'ctx> {
name: Option<&str>,
) -> BasicValueEnum<'ctx> {
let ty = self.ty.alloca_ty(ctx);
typed_load(&ctx.builder, self.value, ty, name.or(self.name).unwrap_or(""))
typed_load(ctx.builder, self.value, ty, name.or(self.name).unwrap_or(""))
}
}

View File

@@ -200,7 +200,7 @@ impl<'ctx, Value> StructField<'ctx, Value> {
Value: TryFrom<BasicValueEnum<'ctx>, Error: std::fmt::Debug>,
{
typed_load(
&ctx.builder,
ctx.builder,
self.ptr_by_gep(ctx, struct_ty, pobj, obj_name),
self.ty,
&obj_name.map(|name| format!("{name}.{}", self.name)).unwrap_or_default(),
@@ -220,7 +220,7 @@ impl<'ctx, Value> StructField<'ctx, Value> {
) where
Value: BasicValue<'ctx>,
{
typed_store(&ctx.builder, self.ptr_by_gep(ctx, struct_ty, pobj, obj_name), value);
typed_store(ctx.builder, self.ptr_by_gep(ctx, struct_ty, pobj, obj_name), value);
}
}

View File

@@ -773,7 +773,7 @@ impl<'a> BuiltinBuilder<'a> {
codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, obj, _, args| {
let (zelf_ty, zelf) = obj.unwrap();
let zelf = zelf.to_basic_value_enum(ctx, zelf_ty)?.into_pointer_value();
let zelf = EnumerateType::new(&ctx.inner).map_value(zelf, Some("enumerate"));
let zelf = EnumerateType::new(ctx.inner).map_value(zelf, Some("enumerate"));
let ty_i32 = ctx.primitives.int32;
let int32 = ctx.i32;
@@ -936,7 +936,7 @@ impl<'a> BuiltinBuilder<'a> {
let arg_ty = fun.0.args[0].ty;
let arg_val = args[0].1.clone().to_basic_value_enum(ctx, arg_ty)?;
let alloca = gen_var(ctx, arg_val.get_type(), Some("alloca_some"));
typed_store(&ctx.builder, alloca, arg_val);
typed_store(ctx.builder, alloca, arg_val);
Ok(Some(alloca.into()))
})))),
loc: None,
@@ -1884,7 +1884,7 @@ impl<'a> BuiltinBuilder<'a> {
},
|(), ctx| {
if let Some(hooks) = hooks {
hooks.build_break_branch(&ctx.builder);
hooks.build_break_branch(ctx.builder);
}
Ok(())
},