Start adding debug-records
This commit is contained in:
		
							parent
							
								
									7c8a123945
								
							
						
					
					
						commit
						e12d0be08b
					
				| @ -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, | ||||||
|  | |||||||
| @ -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 { | ||||||
|  | |||||||
| @ -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), | ||||||
|  | } | ||||||
|  | |||||||
| @ -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)] | ||||||
|  | |||||||
| @ -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,56 +413,70 @@ 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(); | ||||||
|  |                 let (stack_value, store) = match mutable { | ||||||
|  |                     false => (StackValueKind::Immutable(value), value), | ||||||
|  |                     true => match ty { | ||||||
|  |                         // Struct is already allocated at initialization
 | ||||||
|  |                         TypeKind::Array(_, _) => (StackValueKind::Mutable(value), value), | ||||||
|  |                         TypeKind::CustomType(n) => { | ||||||
|  |                             match scope.types.get(scope.type_values.get(n).unwrap()).unwrap() { | ||||||
|  |                                 // Struct also is allocated at initialization
 | ||||||
|  |                                 TypeDefinitionKind::Struct(_) => { | ||||||
|  |                                     (StackValueKind::Mutable(value), value) | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         _ => { | ||||||
|  |                             let alloca = scope | ||||||
|  |                                 .block | ||||||
|  |                                 .build(Instr::Alloca( | ||||||
|  |                                     name.clone(), | ||||||
|  |                                     ty.get_type(scope.type_values, scope.types), | ||||||
|  |                                 )) | ||||||
|  |                                 .unwrap() | ||||||
|  |                                 .maybe_location(&mut scope.block, location); | ||||||
|  |                             let store = scope | ||||||
|  |                                 .block | ||||||
|  |                                 .build(Instr::Store(alloca, value)) | ||||||
|  |                                 .unwrap() | ||||||
|  |                                 .maybe_location(&mut scope.block, location); | ||||||
|  |                             (StackValueKind::Mutable(alloca), store) | ||||||
|  |                         } | ||||||
|  |                     }, | ||||||
|  |                 }; | ||||||
|                 scope.stack_values.insert( |                 scope.stack_values.insert( | ||||||
|                     name.clone(), |                     name.clone(), | ||||||
|                     StackValue( |                     StackValue(stack_value, ty.get_type(scope.type_values, scope.types)), | ||||||
|                         match mutable { |  | ||||||
|                             false => StackValueKind::Immutable(value), |  | ||||||
|                             true => match ty { |  | ||||||
|                                 // Struct is already allocated at initialization
 |  | ||||||
|                                 TypeKind::Array(_, _) => StackValueKind::Mutable(value), |  | ||||||
|                                 TypeKind::CustomType(n) => match scope |  | ||||||
|                                     .types |  | ||||||
|                                     .get(scope.type_values.get(n).unwrap()) |  | ||||||
|                                     .unwrap() |  | ||||||
|                                 { |  | ||||||
|                                     // Struct also is allocated at initialization
 |  | ||||||
|                                     TypeDefinitionKind::Struct(_) => StackValueKind::Mutable(value), |  | ||||||
|                                 }, |  | ||||||
|                                 _ => StackValueKind::Mutable({ |  | ||||||
|                                     let alloca = scope |  | ||||||
|                                         .block |  | ||||||
|                                         .build(Instr::Alloca( |  | ||||||
|                                             name.clone(), |  | ||||||
|                                             ty.get_type(scope.type_values, scope.types), |  | ||||||
|                                         )) |  | ||||||
|                                         .unwrap() |  | ||||||
|                                         .maybe_location(&mut scope.block, location); |  | ||||||
|                                     scope |  | ||||||
|                                         .block |  | ||||||
|                                         .build(Instr::Store(alloca, value)) |  | ||||||
|                                         .unwrap() |  | ||||||
|                                         .maybe_location(&mut scope.block, location); |  | ||||||
|                                     alloca |  | ||||||
|                                 }), |  | ||||||
|                             }, |  | ||||||
|                         }, |  | ||||||
|                         ty.get_type(scope.type_values, scope.types), |  | ||||||
|                     ), |  | ||||||
|                 ); |                 ); | ||||||
|                 if let Some(debug) = &scope.debug { |                 if let Some(debug) = &scope.debug { | ||||||
|                     let location = self.1.into_debug(scope.tokens).unwrap(); |                     match stack_value { | ||||||
|                     debug.info.metadata( |                         StackValueKind::Immutable(_) => {} | ||||||
|                         &debug.scope, |                         StackValueKind::Mutable(_) => { | ||||||
|                         DebugMetadata::LocalVar(DebugLocalVariable { |                             let location = self.1.into_debug(scope.tokens).unwrap(); | ||||||
|                             name: name.clone(), |                             let var = debug.info.metadata( | ||||||
|                             location, |                                 &debug.scope, | ||||||
|                             ty: scope.debug_const_tys.get(&TypeKind::U32).unwrap().clone(), |                                 DebugMetadata::LocalVar(DebugLocalVariable { | ||||||
|                             always_preserve: true, |                                     name: name.clone(), | ||||||
|                             alignment: 32, |                                     location, | ||||||
|                             flags: DwarfFlags, |                                     ty: scope.debug_const_tys.get(&TypeKind::U32).unwrap().clone(), | ||||||
|                         }), |                                     always_preserve: true, | ||||||
|                     ); |                                     alignment: 32, | ||||||
|  |                                     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 | ||||||
|             } |             } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user