From 6ac89b9434e45e2685fafa680fc2350dad5655c0 Mon Sep 17 00:00:00 2001 From: Danial Awny Date: Mon, 13 Jul 2026 00:49:55 +0300 Subject: [PATCH 1/7] api small fix --- crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs b/crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs index bdab78050..bbf4b0c5c 100644 --- a/crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs +++ b/crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs @@ -606,7 +606,8 @@ pub unsafe fn debug_func_type( if let Some(ret) = ret_type { types.push(ret); - } + }else { + types.push(std::ptr::null_mut()); for p in params { types.push(*p); From 258e6b89425e4952a1f736826dc3ebcff2e55017 Mon Sep 17 00:00:00 2001 From: Danial Awny Date: Wed, 15 Jul 2026 17:51:23 +0300 Subject: [PATCH 2/7] term. fix --- .../cyrusc_codegen_llvm/src/builder/control_flow.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/cyrusc_codegen_llvm/src/builder/control_flow.rs b/crates/cyrusc_codegen_llvm/src/builder/control_flow.rs index 630d1a017..532b6cf4d 100644 --- a/crates/cyrusc_codegen_llvm/src/builder/control_flow.rs +++ b/crates/cyrusc_codegen_llvm/src/builder/control_flow.rs @@ -1078,8 +1078,11 @@ impl<'ll> CodeGenIRBuilder<'ll> { return; } + if self.blockreg.cur_block.unwrap().get_terminator().is_none() { + LLVMBuildBr(self.llvmbuilder.as_mut_ptr(), next_block); + } + self.blockreg.cur_block = None; - LLVMBuildBr(self.llvmbuilder.as_mut_ptr(), next_block); } } @@ -1088,8 +1091,12 @@ impl<'ll> CodeGenIRBuilder<'ll> { if !self.llvm_emit_check_block_branch() { return; } + + if self.blockreg.cur_block.unwrap().get_terminator().is_none() { + LLVMBuildCondBr(self.llvmbuilder.as_mut_ptr(), cond, then_block, else_block); + } + self.blockreg.cur_block = None; - LLVMBuildCondBr(self.llvmbuilder.as_mut_ptr(), cond, then_block, else_block); } } From dbed81646980b7274800b7d9cc4517fd54152980 Mon Sep 17 00:00:00 2001 From: Danial Awny Date: Wed, 15 Jul 2026 17:55:04 +0300 Subject: [PATCH 3/7] void* --- crates/cyrusc_codegen_llvm/src/builder/exprs.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/cyrusc_codegen_llvm/src/builder/exprs.rs b/crates/cyrusc_codegen_llvm/src/builder/exprs.rs index df5100bdf..8acd05d41 100644 --- a/crates/cyrusc_codegen_llvm/src/builder/exprs.rs +++ b/crates/cyrusc_codegen_llvm/src/builder/exprs.rs @@ -1133,7 +1133,7 @@ impl<'ll> CodeGenIRBuilder<'ll> { let cir_pointee_type = lhs_rvalue.ty.pointer_inner().unwrap().clone(); let pointee_type: BasicTypeEnum<'ll> = if cir_pointee_type.is_void() { - self.llvm_ctx.ptr_type(AddressSpace::default()).into() + self.llvm_ctx.i8_type().into() } else { self.emit_type(cir_pointee_type).try_into().unwrap() }; @@ -1153,7 +1153,7 @@ impl<'ll> CodeGenIRBuilder<'ll> { let cir_pointee_type = result_type.pointer_inner().unwrap().clone(); let pointee_type: BasicTypeEnum<'ll> = if cir_pointee_type.is_void() { - self.llvm_ctx.ptr_type(AddressSpace::default()).into() + self.llvm_ctx.i8_type().into() } else { self.emit_type(cir_pointee_type).try_into().unwrap() }; @@ -1186,7 +1186,7 @@ impl<'ll> CodeGenIRBuilder<'ll> { let cir_pointee_type = result_type.pointer_inner().unwrap().clone(); let pointee_type: BasicTypeEnum<'ll> = if cir_pointee_type.is_void() { - self.llvm_ctx.ptr_type(AddressSpace::default()).into() + self.llvm_ctx.i8_type().into() } else { self.emit_type(cir_pointee_type).try_into().unwrap() }; From 4906c9a57e31483a7a8388f7111b65f0d43e3981 Mon Sep 17 00:00:00 2001 From: Danial Awny Date: Wed, 15 Jul 2026 18:10:05 +0300 Subject: [PATCH 4/7] memory load and store operations --- .../cyrusc_codegen_llvm/src/builder/values.rs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/cyrusc_codegen_llvm/src/builder/values.rs b/crates/cyrusc_codegen_llvm/src/builder/values.rs index ae3ef96bd..8c2085fba 100644 --- a/crates/cyrusc_codegen_llvm/src/builder/values.rs +++ b/crates/cyrusc_codegen_llvm/src/builder/values.rs @@ -116,7 +116,10 @@ impl<'ll> CodeGenIRBuilder<'ll> { rvalue = InternalValue::new(rvalue.ty.clone(), InternalValueKind::RValue(widened.into())); } - self.llvmbuilder.build_store(ptr, rvalue.as_basic_value()).unwrap(); + let store_inst = self.llvmbuilder.build_store(ptr, rvalue.as_basic_value()).unwrap(); + if layout.align > 0 { + store_inst.set_alignment(layout.align).unwrap(); + } } pub(crate) fn widen_int_arg(&self, value: InternalValue<'ll>, signed: bool) -> InternalValue<'ll> { @@ -202,6 +205,21 @@ impl<'ll> CodeGenIRBuilder<'ll> { let ty: BasicTypeEnum<'ll> = self.emit_type(internal_value.ty.clone()).try_into().unwrap(); let basic_value = self.llvmbuilder.build_load(ty, pointer_value, "rvalue").unwrap(); + let load_inst = match basic_value { + BasicValueEnum::ArrayValue(val) => val.as_instruction(), + BasicValueEnum::IntValue(val) => val.as_instruction(), + BasicValueEnum::FloatValue(val) => val.as_instruction(), + BasicValueEnum::PointerValue(val) => val.as_instruction(), + BasicValueEnum::StructValue(val) => val.as_instruction(), + BasicValueEnum::VectorValue(val) => val.as_instruction(), + }; + if let Some(inst) = load_inst { + let layout = self.tctx.layout_of(&internal_value.ty); + if layout.align > 0 { + inst.set_alignment(layout.align).unwrap(); + } + } + if internal_value.ty.is_bool() { InternalValue::new( internal_value.ty, From e7f1469217cbf7fdb43831cf8e0372702127af7e Mon Sep 17 00:00:00 2001 From: Danial Awny Date: Wed, 15 Jul 2026 19:45:52 +0300 Subject: [PATCH 5/7] RAII --- .../src/builder/builder.rs | 44 +++++++++++++++++++ .../src/builder/intrinsics.rs | 4 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/crates/cyrusc_codegen_llvm/src/builder/builder.rs b/crates/cyrusc_codegen_llvm/src/builder/builder.rs index 8378583a3..f595a9eb0 100644 --- a/crates/cyrusc_codegen_llvm/src/builder/builder.rs +++ b/crates/cyrusc_codegen_llvm/src/builder/builder.rs @@ -24,6 +24,10 @@ use cyrusc_typed_ast::LabelID; use inkwell::{ basic_block::BasicBlock, builder::Builder, context::Context, module::Module, targets::TargetMachine, values::FunctionValue, + llvm_sys::{ + core::{LLVMGetCurrentDebugLocation2, LLVMSetCurrentDebugLocation2}, + prelude::LLVMMetadataRef, + }, }; use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; @@ -238,3 +242,43 @@ impl<'ll> Default for BlockRegistry<'ll> { } } } + +pub struct DebugLocationGuard<'a, 'll> { + builder: &'a CodeGenIRBuilder<'ll>, + saved_loc: Option, +} + +impl<'a, 'll> DebugLocationGuard<'a, 'll> { + pub fn new(builder: &'a CodeGenIRBuilder<'ll>) -> Self { + let saved_loc = if builder.dctx.is_some() { + unsafe { + let loc = LLVMGetCurrentDebugLocation2(builder.llvmbuilder.as_mut_ptr()); + if !loc.is_null() { + Some(loc) + } else { + None + } + } + } else { + None + }; + + if saved_loc.is_some() { + unsafe { + LLVMSetCurrentDebugLocation2(builder.llvmbuilder.as_mut_ptr(), std::ptr::null_mut()); + } + } + + Self { builder, saved_loc } + } +} + +impl<'a, 'll> Drop for DebugLocationGuard<'a, 'll> { + fn drop(&mut self) { + if let Some(loc) = self.saved_loc { + unsafe { + LLVMSetCurrentDebugLocation2(self.builder.llvmbuilder.as_mut_ptr(), loc); + } + } + } +} diff --git a/crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs b/crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs index e09145d08..8eaa03104 100644 --- a/crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs +++ b/crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs @@ -2,7 +2,7 @@ // Copyright (c) 2026 The Cyrus Language use crate::builder::{ - builder::CodeGenIRBuilder, + builder::{CodeGenIRBuilder, DebugLocationGuard}, values::{InternalValue, InternalValueKind}, }; use cyrusc_internal::cir::{ @@ -23,6 +23,7 @@ use inkwell::{ // These intrinsics published via builtin to user side. impl<'ll> CodeGenIRBuilder<'ll> { pub(crate) fn emit_builtin_call(&mut self, call: &CIRCall, builtin_spec: &TypedBuiltinSpec) -> InternalValue<'ll> { + let _guard = DebugLocationGuard::new(self); debug_assert!(builtin_spec.phase == TypedBuiltinPhase::Codegen); debug_assert!(builtin_spec.form == TypedBuiltinForm::Expr); @@ -189,6 +190,7 @@ impl<'ll> CodeGenIRBuilder<'ll> { } pub(crate) fn emit_intrinsic_panic(&mut self, args: &[CIRExpr], loc: Loc) -> InternalValue<'ll> { + let _guard = DebugLocationGuard::new(self); let cir_void_ptr = CIRType::Pointer(Box::new(CIRType::Plain(PlainType::Void))); let ptr_type = self.llvm_ctx.ptr_type(inkwell::AddressSpace::default()); From 54bba05af64f4bde33353cf5bd0cc4330590746d Mon Sep 17 00:00:00 2001 From: Danial Awny Date: Wed, 15 Jul 2026 19:48:11 +0300 Subject: [PATCH 6/7] syntax fix --- crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs b/crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs index bbf4b0c5c..39546cfc5 100644 --- a/crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs +++ b/crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs @@ -606,8 +606,9 @@ pub unsafe fn debug_func_type( if let Some(ret) = ret_type { types.push(ret); - }else { + } else { types.push(std::ptr::null_mut()); + } for p in params { types.push(*p); From cf164e9b8e965f760b6c9f95db2c1b1919cb7feb Mon Sep 17 00:00:00 2001 From: Danial Awny Date: Wed, 15 Jul 2026 21:07:38 +0300 Subject: [PATCH 7/7] flow1 --- .../src/builder/builder.rs | 22 +++++++++---------- .../src/builder/intrinsics.rs | 4 ++-- .../cyrusc_codegen_llvm/src/builder/values.rs | 1 + 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/crates/cyrusc_codegen_llvm/src/builder/builder.rs b/crates/cyrusc_codegen_llvm/src/builder/builder.rs index f595a9eb0..607ec8916 100644 --- a/crates/cyrusc_codegen_llvm/src/builder/builder.rs +++ b/crates/cyrusc_codegen_llvm/src/builder/builder.rs @@ -26,7 +26,7 @@ use inkwell::{ values::FunctionValue, llvm_sys::{ core::{LLVMGetCurrentDebugLocation2, LLVMSetCurrentDebugLocation2}, - prelude::LLVMMetadataRef, + prelude::{LLVMBuilderRef, LLVMMetadataRef}, }, }; use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; @@ -243,16 +243,16 @@ impl<'ll> Default for BlockRegistry<'ll> { } } -pub struct DebugLocationGuard<'a, 'll> { - builder: &'a CodeGenIRBuilder<'ll>, +pub struct DebugLocationGuard { + builder: LLVMBuilderRef, saved_loc: Option, } -impl<'a, 'll> DebugLocationGuard<'a, 'll> { - pub fn new(builder: &'a CodeGenIRBuilder<'ll>) -> Self { - let saved_loc = if builder.dctx.is_some() { +impl DebugLocationGuard { + pub fn new(builder_ref: LLVMBuilderRef, dctx_exists: bool) -> Self { + let saved_loc = if dctx_exists { unsafe { - let loc = LLVMGetCurrentDebugLocation2(builder.llvmbuilder.as_mut_ptr()); + let loc = LLVMGetCurrentDebugLocation2(builder_ref); if !loc.is_null() { Some(loc) } else { @@ -265,19 +265,19 @@ impl<'a, 'll> DebugLocationGuard<'a, 'll> { if saved_loc.is_some() { unsafe { - LLVMSetCurrentDebugLocation2(builder.llvmbuilder.as_mut_ptr(), std::ptr::null_mut()); + LLVMSetCurrentDebugLocation2(builder_ref, std::ptr::null_mut()); } } - Self { builder, saved_loc } + Self { builder: builder_ref, saved_loc } } } -impl<'a, 'll> Drop for DebugLocationGuard<'a, 'll> { +impl Drop for DebugLocationGuard { fn drop(&mut self) { if let Some(loc) = self.saved_loc { unsafe { - LLVMSetCurrentDebugLocation2(self.builder.llvmbuilder.as_mut_ptr(), loc); + LLVMSetCurrentDebugLocation2(self.builder, loc); } } } diff --git a/crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs b/crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs index 8eaa03104..96099ed35 100644 --- a/crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs +++ b/crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs @@ -23,7 +23,7 @@ use inkwell::{ // These intrinsics published via builtin to user side. impl<'ll> CodeGenIRBuilder<'ll> { pub(crate) fn emit_builtin_call(&mut self, call: &CIRCall, builtin_spec: &TypedBuiltinSpec) -> InternalValue<'ll> { - let _guard = DebugLocationGuard::new(self); + let _guard = DebugLocationGuard::new(self.llvmbuilder.as_mut_ptr(), self.dctx.is_some()); debug_assert!(builtin_spec.phase == TypedBuiltinPhase::Codegen); debug_assert!(builtin_spec.form == TypedBuiltinForm::Expr); @@ -190,7 +190,7 @@ impl<'ll> CodeGenIRBuilder<'ll> { } pub(crate) fn emit_intrinsic_panic(&mut self, args: &[CIRExpr], loc: Loc) -> InternalValue<'ll> { - let _guard = DebugLocationGuard::new(self); + let _guard = DebugLocationGuard::new(self.llvmbuilder.as_mut_ptr(), self.dctx.is_some()); let cir_void_ptr = CIRType::Pointer(Box::new(CIRType::Plain(PlainType::Void))); let ptr_type = self.llvm_ctx.ptr_type(inkwell::AddressSpace::default()); diff --git a/crates/cyrusc_codegen_llvm/src/builder/values.rs b/crates/cyrusc_codegen_llvm/src/builder/values.rs index 8c2085fba..16aafdec2 100644 --- a/crates/cyrusc_codegen_llvm/src/builder/values.rs +++ b/crates/cyrusc_codegen_llvm/src/builder/values.rs @@ -212,6 +212,7 @@ impl<'ll> CodeGenIRBuilder<'ll> { BasicValueEnum::PointerValue(val) => val.as_instruction(), BasicValueEnum::StructValue(val) => val.as_instruction(), BasicValueEnum::VectorValue(val) => val.as_instruction(), + _ => None, }; if let Some(inst) = load_inst { let layout = self.tctx.layout_of(&internal_value.ty);