From 990d8cb4481fcfdf69779f30ea6f0924ec58707e Mon Sep 17 00:00:00 2001 From: sofia Date: Fri, 18 Jul 2025 16:59:05 +0300 Subject: [PATCH] Fix around in debug information generation, fix subprogram not being set --- reid-llvm-lib/src/builder.rs | 4 +- reid-llvm-lib/src/compile.rs | 62 +++++++----- reid-llvm-lib/src/debug_information.rs | 134 ++++++++++++------------- reid-llvm-lib/src/lib.rs | 12 +-- reid/src/codegen.rs | 123 +++++++++++------------ reid/src/mir/mod.rs | 4 +- 6 files changed, 171 insertions(+), 168 deletions(-) diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index fb4e507..daf2389 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -8,7 +8,7 @@ use crate::{ TerminatorKind, Type, TypeData, debug_information::{ DebugFileData, DebugInformation, DebugLocation, DebugLocationValue, DebugMetadataValue, - DebugSubprogramValue, + DebugProgramValue, }, util::match_types, }; @@ -199,7 +199,7 @@ impl Builder { pub(crate) unsafe fn set_debug_subprogram( &self, value: &FunctionValue, - subprogram: DebugSubprogramValue, + subprogram: DebugProgramValue, ) { unsafe { let mut modules = self.modules.borrow_mut(); diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 6bd3ec5..e13b6d4 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -199,9 +199,9 @@ pub struct LLVMDebugInformation<'a> { debug: &'a DebugInformation, builder: LLVMDIBuilderRef, file_ref: LLVMMetadataRef, - scopes: &'a HashMap, + // scopes: &'a HashMap, types: &'a mut HashMap, - subprograms: &'a mut HashMap, + programs: &'a mut HashMap, metadata: &'a mut HashMap, } @@ -227,10 +227,9 @@ impl ModuleHolder { // Compile the contents - let mut scopes = HashMap::new(); let mut types = HashMap::new(); let mut metadata = HashMap::new(); - let mut subprograms = HashMap::new(); + let mut programs = HashMap::new(); let mut debug = if let Some(debug) = &self.debug_information { let di_builder = LLVMCreateDIBuilder(module_ref); @@ -277,10 +276,15 @@ impl ModuleHolder { 0, ); - let scope = debug.get_scopes(); - scope - .borrow() - .compile_scope(compile_unit, file_ref, &mut scopes, di_builder); + // let scope = debug.get_scopes(); + // scopes.insert(scope.borrow().value.clone(), compile_unit); + // for scope in &scope.borrow().inner_scopes { + // dbg!("hello"); + // scope.compile_scope(compile_unit, file_ref, &mut scopes, di_builder); + // } + // dbg!("after!"); + + programs.insert(DebugProgramValue(0), compile_unit); let debug = LLVMDebugInformation { builder: di_builder, @@ -288,8 +292,7 @@ impl ModuleHolder { file_ref, types: &mut types, metadata: &mut metadata, - subprograms: &mut subprograms, - scopes: &scopes, + programs: &mut programs, }; for ty in debug.debug.get_types().borrow().iter() { @@ -308,18 +311,22 @@ impl ModuleHolder { let mut functions = HashMap::new(); for function in &self.functions { - functions.insert( - function.value, - function.compile_signature(context, module_ref, &types, &debug), - ); + let func = function.compile_signature(context, module_ref, &types, &debug); + functions.insert(function.value, func); + + if let Some(debug) = &mut debug { + if let Some(program_value) = function.data.debug { + debug.programs.insert(program_value, func.metadata.unwrap()); + } + } } - // if let Some(debug) = &mut debug { - // for subprogram in debug.debug.get_subprograms().borrow().iter() { - // let meta_ref = subprogram.compile_debug(&functions, &debug); - // debug.subprograms.insert(subprogram.value.clone(), meta_ref); - // } - // } + if let Some(debug) = &mut debug { + for meta in debug.debug.get_metadata().borrow().iter() { + let meta_ref = meta.compile(&debug); + debug.metadata.insert(meta.value.clone(), meta_ref); + } + } let mut module = LLVMModule { builder, @@ -377,15 +384,16 @@ impl DebugScopeHolder { } impl DebugMetadataHolder { - unsafe fn compile_meta(&self, debug: &LLVMDebugInformation) -> LLVMMetadataRef { + unsafe fn compile(&self, debug: &LLVMDebugInformation) -> LLVMMetadataRef { + dbg!(&self.program); unsafe { match &self.data { DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable( debug.builder, - *debug.scopes.get(&self.scope).unwrap(), + *debug.programs.get(&self.program).unwrap(), into_cstring(param.name.clone()).as_ptr(), param.name.len(), - param.arg_idx, + param.arg_idx + 1, debug.file_ref, param.location.line, *debug.types.get(¶m.ty).unwrap(), @@ -493,9 +501,9 @@ impl FunctionHolder { let mangled_name = LLVMGetValueName2(function_ref, mangled_length_ptr); let mangled_length = *mangled_length_ptr; - Some(LLVMDIBuilderCreateFunction( + let subprogram = LLVMDIBuilderCreateFunction( debug.builder, - *debug.scopes.get(&subprogram.scope).unwrap(), + *debug.programs.get(&subprogram.outer_scope).unwrap(), into_cstring(subprogram.name.clone()).as_ptr(), subprogram.name.clone().len(), mangled_name, @@ -508,7 +516,9 @@ impl FunctionHolder { subprogram.opts.scope_line, subprogram.opts.flags.as_llvm(), subprogram.opts.is_optimized as i32, - )) + ); + LLVMSetSubprogram(function_ref, subprogram); + Some(subprogram) } else { None } diff --git a/reid-llvm-lib/src/debug_information.rs b/reid-llvm-lib/src/debug_information.rs index 03829ba..03fc710 100644 --- a/reid-llvm-lib/src/debug_information.rs +++ b/reid-llvm-lib/src/debug_information.rs @@ -7,7 +7,7 @@ use std::{ pub struct DebugScopeValue(pub Vec); #[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct DebugLocationValue(pub DebugScopeValue, pub usize); +pub struct DebugLocationValue(pub DebugProgramValue, pub usize); #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub struct DebugTypeValue(pub usize); @@ -15,8 +15,9 @@ pub struct DebugTypeValue(pub usize); #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub struct DebugMetadataValue(pub usize); +/// Represents either a subprogram, or the compilation context #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] -pub struct DebugSubprogramValue(pub usize); +pub struct DebugProgramValue(pub usize); #[derive(Debug, Clone)] pub struct DebugFileData { @@ -34,7 +35,7 @@ pub(crate) struct DebugScopeHolder { #[derive(Debug, Clone)] pub struct DebugMetadataHolder { - pub(crate) scope: DebugScopeValue, + pub(crate) program: DebugProgramValue, pub(crate) value: DebugMetadataValue, pub(crate) data: DebugMetadata, } @@ -47,7 +48,7 @@ pub struct DebugTypeHolder { #[derive(Debug, Clone)] pub struct DebugSubprogramHolder { - pub(crate) value: DebugSubprogramValue, + pub(crate) value: DebugProgramValue, pub(crate) data: DebugSubprogramData, } @@ -60,80 +61,73 @@ pub(crate) struct DebugLocationHolder { #[derive(Debug, Clone)] pub struct DebugInformation { pub file: DebugFileData, - scope: Rc>, - subprograms: Rc>>, + // scope: Rc>, + locations: Rc>>, + programs: Rc>>, metadata: Rc>>, types: Rc>>, } impl DebugInformation { - pub fn from_file(file: DebugFileData) -> (DebugInformation, DebugScopeValue) { - let scope_value = DebugScopeValue(Vec::new()); + pub fn from_file(file: DebugFileData) -> (DebugInformation, DebugProgramValue) { ( DebugInformation { file, - scope: Rc::new(RefCell::new(DebugScopeHolder { - value: scope_value.clone(), - inner_scopes: Vec::new(), - locations: Vec::new(), - location: None, - })), + // scope: Rc::new(RefCell::new(DebugScopeHolder { + // value: scope_value.clone(), + // inner_scopes: Vec::new(), + // locations: Vec::new(), + // location: None, + // })), + locations: Rc::new(RefCell::new(Vec::new())), metadata: Rc::new(RefCell::new(Vec::new())), - subprograms: Rc::new(RefCell::new(Vec::new())), + programs: Rc::new(RefCell::new(Vec::new())), types: Rc::new(RefCell::new(Vec::new())), }, - scope_value, + DebugProgramValue(0), ) } - pub fn inner_scope( - &self, - parent: &DebugScopeValue, - location: DebugLocation, - ) -> DebugScopeValue { - unsafe { - let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| { - for i in &parent.0 { - v = v.inner_scopes.get_unchecked_mut(*i); - } - v - }); + // pub fn inner_scope( + // &self, + // parent: &DebugScopeValue, + // location: DebugLocation, + // ) -> DebugScopeValue { + // unsafe { + // let mut outer_scope = RefMut::map(self.scope.borrow_mut(), |mut v| { + // for i in &parent.0 { + // v = v.inner_scopes.get_unchecked_mut(*i); + // } + // v + // }); - let mut arr = parent.0.clone(); - arr.push(parent.0.len()); - let value = DebugScopeValue(arr); + // let mut arr = parent.0.clone(); + // arr.push(parent.0.len()); + // let value = DebugScopeValue(arr); - outer_scope.inner_scopes.push(DebugScopeHolder { - value: value.clone(), - inner_scopes: Vec::new(), - locations: Vec::new(), - location: Some(location), - }); - value - } - } + // outer_scope.inner_scopes.push(DebugScopeHolder { + // value: value.clone(), + // inner_scopes: Vec::new(), + // locations: Vec::new(), + // location: Some(location), + // }); + // value + // } + // } pub fn location( &self, - scope_value: &DebugScopeValue, + program_value: &DebugProgramValue, line: u32, column: u32, ) -> DebugLocationValue { - unsafe { - let mut scope = RefMut::map(self.scope.borrow_mut(), |mut v| { - for i in &scope_value.0 { - v = v.inner_scopes.get_unchecked_mut(*i); - } - v - }); - let value = DebugLocationValue(scope_value.clone(), scope.locations.len()); - let location = DebugLocationHolder { - value: value.clone(), - location: DebugLocation { line, column }, - }; - scope.locations.push(location); - value - } + let value = DebugLocationValue(program_value.clone(), self.locations.borrow().len()); + let location = DebugLocationHolder { + value: value.clone(), + location: DebugLocation { line, column }, + }; + self.locations.borrow_mut().push(location); + value } pub fn debug_type(&self, kind: DebugTypeData) -> DebugTypeValue { @@ -146,11 +140,11 @@ impl DebugInformation { value } - pub fn metadata(&self, scope: &DebugScopeValue, kind: DebugMetadata) -> DebugMetadataValue { + pub fn metadata(&self, program: &DebugProgramValue, kind: DebugMetadata) -> DebugMetadataValue { let mut metadata = self.metadata.borrow_mut(); let value = DebugMetadataValue(metadata.len()); metadata.push(DebugMetadataHolder { - scope: scope.clone(), + program: *program, value: value.clone(), data: kind, }); @@ -164,9 +158,9 @@ impl DebugInformation { } } - pub fn subprogram(&self, kind: DebugSubprogramData) -> DebugSubprogramValue { - let mut subprogram = self.subprograms.borrow_mut(); - let value = DebugSubprogramValue(subprogram.len()); + pub fn subprogram(&self, kind: DebugSubprogramData) -> DebugProgramValue { + let mut subprogram = self.programs.borrow_mut(); + let value = DebugProgramValue(subprogram.len() + 1); subprogram.push(DebugSubprogramHolder { value: value.clone(), data: kind, @@ -178,23 +172,23 @@ impl DebugInformation { self.metadata.clone() } - pub fn get_scopes(&self) -> Rc> { - self.scope.clone() - } + // pub fn get_scopes(&self) -> Rc> { + // self.scope.clone() + // } pub fn get_subprograms(&self) -> Rc>> { - self.subprograms.clone() + self.programs.clone() } pub fn get_types(&self) -> Rc>> { self.types.clone() } - pub fn get_subprogram_data(&self, value: &DebugSubprogramValue) -> DebugSubprogramData { + pub fn get_subprogram_data(&self, value: &DebugProgramValue) -> DebugSubprogramData { unsafe { - self.subprograms + self.programs .borrow() - .get_unchecked(value.0) + .get_unchecked(value.0 - 1) .data .clone() } @@ -277,7 +271,7 @@ pub struct DebugSubprogramTypeData { } pub struct DebugSubprogramType { - pub params: Vec, + pub params: Vec, pub flags: DwarfFlags, } @@ -296,7 +290,7 @@ pub enum DwarfEncoding { pub struct DebugSubprogramData { /// Function name. pub name: String, - pub scope: DebugScopeValue, + pub outer_scope: DebugProgramValue, /// Used for line number. pub location: DebugLocation, /// Function type. diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 487f491..252f87f 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -8,7 +8,7 @@ use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, use debug::PrintableModule; use debug_information::{ DebugFileData, DebugInformation, DebugLocation, DebugLocationValue, DebugMetadataValue, - DebugScopeValue, DebugSubprogramValue, + DebugProgramValue, DebugScopeValue, }; use util::match_types; @@ -106,10 +106,10 @@ impl<'ctx> Module<'ctx> { pub fn create_debug_info( &mut self, file: DebugFileData, - ) -> (DebugInformation, DebugScopeValue) { - let (debug_info, scope) = DebugInformation::from_file(file); + ) -> (DebugInformation, DebugProgramValue) { + let (debug_info, program_value) = DebugInformation::from_file(file); self.debug_info = Some(debug_info.clone()); - (debug_info, scope) + (debug_info, program_value) } pub fn get_debug_info(&self) -> &Option { @@ -131,7 +131,7 @@ pub struct FunctionData { ret: Type, params: Vec, flags: FunctionFlags, - debug: Option, + debug: Option, } #[derive(Debug, Clone, Copy, Hash)] @@ -177,7 +177,7 @@ impl<'ctx> Function<'ctx> { } } - pub fn set_debug(&self, subprogram: DebugSubprogramValue) { + pub fn set_debug(&self, subprogram: DebugProgramValue) { unsafe { self.builder.set_debug_subprogram(&self.value, subprogram); } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index b3f3645..b43d40e 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -5,8 +5,8 @@ use reid_lib::{ compile::CompiledModule, debug_information::{ DebugBasicType, DebugFileData, DebugInformation, DebugLocation, DebugMetadata, - DebugMetadataValue, DebugParamVariable, DebugScopeValue, DebugSubprogramData, - DebugSubprogramOptionals, DebugSubprogramTypeData, DebugSubprogramValue, DebugTypeData, + DebugMetadataValue, DebugParamVariable, DebugProgramValue, DebugScopeValue, + DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramTypeData, DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags, }, Block, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, @@ -82,14 +82,18 @@ pub struct Scope<'ctx, 'a> { type_values: &'a HashMap, functions: &'a HashMap>, stack_values: HashMap, - debug: &'ctx DebugInformation, - debug_scope: DebugScopeValue, + debug: Option>, debug_const_tys: &'a HashMap, } +#[derive(Debug, Clone)] +pub struct Debug<'ctx> { + info: &'ctx DebugInformation, + scope: Option, +} + pub struct StackFunction<'ctx> { ir: Function<'ctx>, - debug: DebugSubprogramValue, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -114,8 +118,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> { types: self.types, type_values: self.type_values, stack_values: self.stack_values.clone(), - debug: self.debug, - debug_scope: self.debug_scope.clone(), + debug: self.debug.clone(), debug_const_tys: self.debug_const_tys, } } @@ -161,7 +164,7 @@ impl mir::Module { ) -> ModuleCodegen<'ctx> { let mut module = context.module(&self.name, self.is_main); - let (debug, debug_scope) = if let Some(path) = &self.path { + let (debug, compile_unit) = if let Some(path) = &self.path { module.create_debug_info(DebugFileData { name: path.file_name().unwrap().to_str().unwrap().to_owned(), directory: path.parent().unwrap().to_str().unwrap().to_owned(), @@ -240,68 +243,48 @@ impl mir::Module { ), }; - let fn_return_ty = debug_const_types.get(&TypeKind::U32).unwrap(); - - let debug_ty = debug.debug_type(DebugTypeData::Subprogram(DebugSubprogramTypeData { - parameters: vec![*fn_return_ty], - flags: DwarfFlags, - })); - - let subprogram = debug.subprogram(DebugSubprogramData { - name: function.name.clone(), - scope: debug_scope.clone(), - location: DebugLocation { line: 0, column: 0 }, - ty: debug_ty, - opts: DebugSubprogramOptionals { - is_local: !function.is_pub, - is_definition: true, - ..DebugSubprogramOptionals::default() - }, - }); - - func.set_debug(subprogram); - - functions.insert( - function.name.clone(), - StackFunction { - ir: func, - debug: subprogram, - }, - ); + functions.insert(function.name.clone(), StackFunction { ir: func }); } for mir_function in &self.functions { let function = functions.get(&mir_function.name).unwrap(); let mut entry = function.ir.block("entry"); - let location = match &mir_function.kind { - mir::FunctionDefinitionKind::Local(_, metadata) => { - metadata.into_debug(tokens).unwrap() - } - mir::FunctionDefinitionKind::Extern(_) => { - // TODO extern should probably still have a meta - DebugLocation { - ..Default::default() - } - } + // Insert debug information + let debug_scope = if let Some(location) = mir_function.signature().into_debug(tokens) { + // let debug_scope = debug.inner_scope(&outer_scope, location); + + let fn_param_ty = debug_const_types.get(&TypeKind::U32).unwrap(); + + let debug_ty = + debug.debug_type(DebugTypeData::Subprogram(DebugSubprogramTypeData { + parameters: vec![*fn_param_ty], + flags: DwarfFlags, + })); + + let subprogram = debug.subprogram(DebugSubprogramData { + name: mir_function.name.clone(), + outer_scope: compile_unit.clone(), + location, + ty: debug_ty, + opts: DebugSubprogramOptionals { + is_local: !mir_function.is_pub, + is_definition: true, + ..DebugSubprogramOptionals::default() + }, + }); + + function.ir.set_debug(subprogram); + + Some(subprogram) + } else { + None }; - let debug_scope = debug.inner_scope(&debug_scope, location); - + // Compile actual IR part let mut stack_values = HashMap::new(); for (i, (p_name, p_ty)) in mir_function.parameters.iter().enumerate() { - debug.metadata( - &debug_scope, - DebugMetadata::ParamVar(DebugParamVariable { - name: p_name.clone(), - arg_idx: i as u32, - location, - ty: *debug_const_types.get(&TypeKind::U32).unwrap(), - always_preserve: true, - flags: DwarfFlags, - }), - ); - + // Codegen actual parameters stack_values.insert( p_name.clone(), StackValue( @@ -309,6 +292,23 @@ impl mir::Module { p_ty.get_type(&type_values, &types), ), ); + + // Generate debug info + if let (Some(debug_scope), Some(location)) = + (&debug_scope, mir_function.signature().into_debug(tokens)) + { + debug.metadata( + &debug_scope, + DebugMetadata::ParamVar(DebugParamVariable { + name: p_name.clone(), + arg_idx: i as u32, + location, + ty: *debug_const_types.get(&TypeKind::U32).unwrap(), + always_preserve: true, + flags: DwarfFlags, + }), + ); + } } let mut scope = Scope { @@ -321,8 +321,7 @@ impl mir::Module { types: &types, type_values: &type_values, stack_values, - debug: &debug, - debug_scope: debug_scope, + debug: None, debug_const_tys: &debug_const_types, }; diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index f9682ab..4b913be 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -282,14 +282,14 @@ pub enum FunctionDefinitionKind { } impl FunctionDefinition { - fn block_meta(&self) -> Metadata { + pub fn block_meta(&self) -> Metadata { match &self.kind { FunctionDefinitionKind::Local(block, _) => block.meta.clone(), FunctionDefinitionKind::Extern(_) => Metadata::default(), } } - fn signature(&self) -> Metadata { + pub fn signature(&self) -> Metadata { match &self.kind { FunctionDefinitionKind::Local(_, metadata) => metadata.clone(), FunctionDefinitionKind::Extern(_) => Metadata::default(),