Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions crates/cyrusc_codegen_llvm/src/builder/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{LLVMBuilderRef, LLVMMetadataRef},
},
};
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};

Expand Down Expand Up @@ -238,3 +242,43 @@ impl<'ll> Default for BlockRegistry<'ll> {
}
}
}

pub struct DebugLocationGuard {
builder: LLVMBuilderRef,
saved_loc: Option<LLVMMetadataRef>,
}

impl DebugLocationGuard {
pub fn new(builder_ref: LLVMBuilderRef, dctx_exists: bool) -> Self {
let saved_loc = if dctx_exists {
unsafe {
let loc = LLVMGetCurrentDebugLocation2(builder_ref);
if !loc.is_null() {
Some(loc)
} else {
None
}
}
} else {
None
};

if saved_loc.is_some() {
unsafe {
LLVMSetCurrentDebugLocation2(builder_ref, std::ptr::null_mut());
}
}

Self { builder: builder_ref, saved_loc }
}
}

impl Drop for DebugLocationGuard {
fn drop(&mut self) {
if let Some(loc) = self.saved_loc {
unsafe {
LLVMSetCurrentDebugLocation2(self.builder, loc);
}
}
}
}
11 changes: 9 additions & 2 deletions crates/cyrusc_codegen_llvm/src/builder/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -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);
}
}

Expand Down
6 changes: 3 additions & 3 deletions crates/cyrusc_codegen_llvm/src/builder/exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
};
Expand All @@ -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()
};
Expand Down Expand Up @@ -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()
};
Expand Down
4 changes: 3 additions & 1 deletion crates/cyrusc_codegen_llvm/src/builder/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -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.llvmbuilder.as_mut_ptr(), self.dctx.is_some());
debug_assert!(builtin_spec.phase == TypedBuiltinPhase::Codegen);
debug_assert!(builtin_spec.form == TypedBuiltinForm::Expr);

Expand Down Expand Up @@ -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.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());
Expand Down
21 changes: 20 additions & 1 deletion crates/cyrusc_codegen_llvm/src/builder/values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -202,6 +205,22 @@ 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(),
_ => None,
};
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,
Expand Down
2 changes: 2 additions & 0 deletions crates/cyrusc_codegen_llvm/src/llvm/debug_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +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 {
Expand Down
Loading