Start adding debug-records

This commit is contained in:
Sofia 2025-07-19 13:14:53 +03:00
parent 7c8a123945
commit e12d0be08b
5 changed files with 183 additions and 51 deletions

View File

@ -8,6 +8,7 @@ use crate::{
TerminatorKind, Type, TypeData, TerminatorKind, Type, TypeData,
debug_information::{ debug_information::{
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
InstructionDebugRecordData,
}, },
util::match_types, util::match_types,
}; };
@ -60,6 +61,7 @@ pub struct BlockHolder {
pub struct InstructionHolder { pub struct InstructionHolder {
pub(crate) value: InstructionValue, pub(crate) value: InstructionValue,
pub(crate) data: InstructionData, pub(crate) data: InstructionData,
pub(crate) record: Option<InstructionDebugRecordData>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -154,7 +156,11 @@ impl Builder {
let function = module.functions.get_unchecked_mut(block_val.0.1); let function = module.functions.get_unchecked_mut(block_val.0.1);
let block = function.blocks.get_unchecked_mut(block_val.1); let block = function.blocks.get_unchecked_mut(block_val.1);
let value = InstructionValue(block.value, block.instructions.len()); let value = InstructionValue(block.value, block.instructions.len());
block.instructions.push(InstructionHolder { value, data }); block.instructions.push(InstructionHolder {
value,
data,
record: None,
});
// Drop modules so that it is no longer mutable borrowed // Drop modules so that it is no longer mutable borrowed
// (check_instruction requires an immutable borrow). // (check_instruction requires an immutable borrow).
@ -195,6 +201,21 @@ impl Builder {
} }
} }
pub(crate) unsafe fn add_instruction_record(
&self,
value: &InstructionValue,
record: InstructionDebugRecordData,
) {
unsafe {
let mut modules = self.modules.borrow_mut();
let module = modules.get_unchecked_mut(value.0.0.0.0);
let function = module.functions.get_unchecked_mut(value.0.0.1);
let block = function.blocks.get_unchecked_mut(value.0.1);
let instr = block.instructions.get_unchecked_mut(value.1);
instr.record = Some(record)
}
}
pub(crate) unsafe fn set_debug_subprogram( pub(crate) unsafe fn set_debug_subprogram(
&self, &self,
value: &FunctionValue, value: &FunctionValue,

View File

@ -417,7 +417,6 @@ impl DebugScopeHolder {
impl DebugMetadataHolder { impl DebugMetadataHolder {
unsafe fn compile(&self, debug: &LLVMDebugInformation) -> LLVMMetadataRef { unsafe fn compile(&self, debug: &LLVMDebugInformation) -> LLVMMetadataRef {
dbg!(&self.program);
unsafe { unsafe {
match &self.data { match &self.data {
DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable( DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable(
@ -444,6 +443,7 @@ impl DebugMetadataHolder {
var.flags.as_llvm(), var.flags.as_llvm(),
var.alignment, var.alignment,
), ),
DebugMetadata::VarAssignment => todo!(),
} }
} }
} }
@ -822,6 +822,48 @@ impl InstructionHolder {
} }
} }
}; };
if let Some(record) = &self.record {
let debug = module.debug.as_ref().unwrap();
unsafe {
let mut addr = Vec::<u64>::new();
let expr =
LLVMDIBuilderCreateExpression(debug.builder, addr.as_mut_ptr(), addr.len());
let location = LLVMDIBuilderCreateDebugLocation(
module.context_ref,
record.location.line,
record.location.column,
*debug.programs.get(&record.scope).unwrap(),
null_mut(),
);
match record.kind {
DebugRecordKind::Declare(instruction_value) => {
dbg!(&self.value, &instruction_value);
LLVMDIBuilderInsertDeclareRecordBefore(
debug.builder,
module.values.get(&instruction_value).unwrap().value_ref,
*debug.metadata.get(&record.variable).unwrap(),
expr,
location,
val,
)
}
DebugRecordKind::Value(instruction_value) => {
LLVMDIBuilderInsertDbgValueRecordBefore(
debug.builder,
module.values.get(&instruction_value).unwrap().value_ref,
*debug.metadata.get(&record.variable).unwrap(),
expr,
location,
val,
)
}
};
}
}
if let Some(location) = &self.data.location { if let Some(location) = &self.data.location {
unsafe { unsafe {
// dbg!(&self.data.kind, LLVMGetValueKind(val)); // dbg!(&self.data.kind, LLVMGetValueKind(val));
@ -850,6 +892,26 @@ impl InstructionHolder {
value_ref: val, value_ref: val,
} }
} }
fn get_inner_value(&self) -> Option<InstructionValue> {
match &self.data.kind {
crate::Instr::Param(_) => None,
crate::Instr::Constant(_) => None,
crate::Instr::Add(_, _) => None,
crate::Instr::Sub(_, _) => None,
crate::Instr::Mult(_, _) => None,
crate::Instr::And(_, _) => None,
crate::Instr::Phi(_) => None,
crate::Instr::Alloca(_, _) => todo!(),
crate::Instr::Load(_, _) => None,
crate::Instr::Store(_, val) => Some(*val),
crate::Instr::ArrayAlloca(_, _) => None,
crate::Instr::GetElemPtr(_, _) => None,
crate::Instr::GetStructElemPtr(_, _) => None,
crate::Instr::ICmp(_, _, _) => None,
crate::Instr::FunctionCall(_, _) => None,
}
}
} }
impl TerminatorKind { impl TerminatorKind {

View File

@ -1,5 +1,7 @@
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
use crate::builder::InstructionValue;
#[derive(Debug, Clone, Hash, PartialEq, Eq)] #[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct DebugScopeValue(pub Vec<usize>); pub struct DebugScopeValue(pub Vec<usize>);
@ -153,6 +155,7 @@ impl DebugInformation {
match &metadata { match &metadata {
DebugMetadata::ParamVar(debug_param_variable) => todo!(), DebugMetadata::ParamVar(debug_param_variable) => todo!(),
DebugMetadata::LocalVar(debug_local_variable) => todo!(), DebugMetadata::LocalVar(debug_local_variable) => todo!(),
DebugMetadata::VarAssignment => todo!(),
} }
} }
@ -207,6 +210,7 @@ pub struct DebugLocation {
pub enum DebugMetadata { pub enum DebugMetadata {
ParamVar(DebugParamVariable), ParamVar(DebugParamVariable),
LocalVar(DebugLocalVariable), LocalVar(DebugLocalVariable),
VarAssignment,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -312,3 +316,17 @@ pub struct DebugSubprogramOptionals {
/// prototyped or not. /// prototyped or not.
pub flags: DwarfFlags, pub flags: DwarfFlags,
} }
#[derive(Clone)]
pub struct InstructionDebugRecordData {
pub scope: DebugProgramValue,
pub variable: DebugMetadataValue,
pub location: DebugLocation,
pub kind: DebugRecordKind,
}
#[derive(Clone, Copy)]
pub enum DebugRecordKind {
Declare(InstructionValue),
Value(InstructionValue),
}

View File

@ -8,6 +8,7 @@ use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue,
use debug::PrintableModule; use debug::PrintableModule;
use debug_information::{ use debug_information::{
DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
InstructionDebugRecordData,
}; };
use util::match_types; use util::match_types;
@ -275,6 +276,12 @@ impl InstructionValue {
} }
self self
} }
pub fn add_record(&self, block: &mut Block, record: InstructionDebugRecordData) {
unsafe {
block.builder.add_instruction_record(self, record);
}
}
} }
#[derive(Clone)] #[derive(Clone)]

View File

@ -5,9 +5,9 @@ use reid_lib::{
compile::CompiledModule, compile::CompiledModule,
debug_information::{ debug_information::{
DebugBasicType, DebugFileData, DebugInformation, DebugLocalVariable, DebugLocation, DebugBasicType, DebugFileData, DebugInformation, DebugLocalVariable, DebugLocation,
DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugProgramValue, DebugScopeValue, DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugProgramValue, DebugRecordKind,
DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramTypeData, DebugTypeData, DebugScopeValue, DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramTypeData,
DebugTypeValue, DwarfEncoding, DwarfFlags, DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags, InstructionDebugRecordData,
}, },
Block, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, Block, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr,
Module, NamedStruct, TerminatorKind as Term, Type, Module, NamedStruct, TerminatorKind as Term, Type,
@ -106,6 +106,16 @@ pub enum StackValueKind {
Any(InstructionValue), Any(InstructionValue),
} }
impl StackValueKind {
unsafe fn get_inner(&self) -> InstructionValue {
match &self {
StackValueKind::Immutable(val) => *val,
StackValueKind::Mutable(val) => *val,
StackValueKind::Any(val) => *val,
}
}
}
impl<'ctx, 'a> Scope<'ctx, 'a> { impl<'ctx, 'a> Scope<'ctx, 'a> {
fn with_block(&self, block: Block<'ctx>) -> Scope<'ctx, 'a> { fn with_block(&self, block: Block<'ctx>) -> Scope<'ctx, 'a> {
Scope { Scope {
@ -403,23 +413,20 @@ impl mir::Statement {
match &self.0 { match &self.0 {
mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => {
let value = expression.codegen(scope, &state).unwrap(); let value = expression.codegen(scope, &state).unwrap();
scope.stack_values.insert( let (stack_value, store) = match mutable {
name.clone(), false => (StackValueKind::Immutable(value), value),
StackValue(
match mutable {
false => StackValueKind::Immutable(value),
true => match ty { true => match ty {
// Struct is already allocated at initialization // Struct is already allocated at initialization
TypeKind::Array(_, _) => StackValueKind::Mutable(value), TypeKind::Array(_, _) => (StackValueKind::Mutable(value), value),
TypeKind::CustomType(n) => match scope TypeKind::CustomType(n) => {
.types match scope.types.get(scope.type_values.get(n).unwrap()).unwrap() {
.get(scope.type_values.get(n).unwrap())
.unwrap()
{
// Struct also is allocated at initialization // Struct also is allocated at initialization
TypeDefinitionKind::Struct(_) => StackValueKind::Mutable(value), TypeDefinitionKind::Struct(_) => {
}, (StackValueKind::Mutable(value), value)
_ => StackValueKind::Mutable({ }
}
}
_ => {
let alloca = scope let alloca = scope
.block .block
.build(Instr::Alloca( .build(Instr::Alloca(
@ -428,21 +435,25 @@ impl mir::Statement {
)) ))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location); .maybe_location(&mut scope.block, location);
scope let store = scope
.block .block
.build(Instr::Store(alloca, value)) .build(Instr::Store(alloca, value))
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location); .maybe_location(&mut scope.block, location);
alloca (StackValueKind::Mutable(alloca), store)
}), }
}, },
}, };
ty.get_type(scope.type_values, scope.types), scope.stack_values.insert(
), name.clone(),
StackValue(stack_value, ty.get_type(scope.type_values, scope.types)),
); );
if let Some(debug) = &scope.debug { if let Some(debug) = &scope.debug {
match stack_value {
StackValueKind::Immutable(_) => {}
StackValueKind::Mutable(_) => {
let location = self.1.into_debug(scope.tokens).unwrap(); let location = self.1.into_debug(scope.tokens).unwrap();
debug.info.metadata( let var = debug.info.metadata(
&debug.scope, &debug.scope,
DebugMetadata::LocalVar(DebugLocalVariable { DebugMetadata::LocalVar(DebugLocalVariable {
name: name.clone(), name: name.clone(),
@ -453,6 +464,19 @@ impl mir::Statement {
flags: DwarfFlags, flags: DwarfFlags,
}), }),
); );
dbg!(&store);
store.add_record(
&mut scope.block,
InstructionDebugRecordData {
variable: var,
location,
kind: DebugRecordKind::Declare(value),
scope: debug.scope,
},
);
}
StackValueKind::Any(_) => {}
}
} }
None None
} }