Start adding debug-records
This commit is contained in:
		
							parent
							
								
									7c8a123945
								
							
						
					
					
						commit
						e12d0be08b
					
				| @ -8,6 +8,7 @@ use crate::{ | ||||
|     TerminatorKind, Type, TypeData, | ||||
|     debug_information::{ | ||||
|         DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, | ||||
|         InstructionDebugRecordData, | ||||
|     }, | ||||
|     util::match_types, | ||||
| }; | ||||
| @ -60,6 +61,7 @@ pub struct BlockHolder { | ||||
| pub struct InstructionHolder { | ||||
|     pub(crate) value: InstructionValue, | ||||
|     pub(crate) data: InstructionData, | ||||
|     pub(crate) record: Option<InstructionDebugRecordData>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| @ -154,7 +156,11 @@ impl Builder { | ||||
|             let function = module.functions.get_unchecked_mut(block_val.0.1); | ||||
|             let block = function.blocks.get_unchecked_mut(block_val.1); | ||||
|             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
 | ||||
|             // (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( | ||||
|         &self, | ||||
|         value: &FunctionValue, | ||||
|  | ||||
| @ -417,7 +417,6 @@ impl DebugScopeHolder { | ||||
| 
 | ||||
| impl DebugMetadataHolder { | ||||
|     unsafe fn compile(&self, debug: &LLVMDebugInformation) -> LLVMMetadataRef { | ||||
|         dbg!(&self.program); | ||||
|         unsafe { | ||||
|             match &self.data { | ||||
|                 DebugMetadata::ParamVar(param) => LLVMDIBuilderCreateParameterVariable( | ||||
| @ -444,6 +443,7 @@ impl DebugMetadataHolder { | ||||
|                     var.flags.as_llvm(), | ||||
|                     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 { | ||||
|             unsafe { | ||||
|                 // dbg!(&self.data.kind, LLVMGetValueKind(val));
 | ||||
| @ -850,6 +892,26 @@ impl InstructionHolder { | ||||
|             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 { | ||||
|  | ||||
| @ -1,5 +1,7 @@ | ||||
| use std::{cell::RefCell, rc::Rc}; | ||||
| 
 | ||||
| use crate::builder::InstructionValue; | ||||
| 
 | ||||
| #[derive(Debug, Clone, Hash, PartialEq, Eq)] | ||||
| pub struct DebugScopeValue(pub Vec<usize>); | ||||
| 
 | ||||
| @ -153,6 +155,7 @@ impl DebugInformation { | ||||
|         match &metadata { | ||||
|             DebugMetadata::ParamVar(debug_param_variable) => todo!(), | ||||
|             DebugMetadata::LocalVar(debug_local_variable) => todo!(), | ||||
|             DebugMetadata::VarAssignment => todo!(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -207,6 +210,7 @@ pub struct DebugLocation { | ||||
| pub enum DebugMetadata { | ||||
|     ParamVar(DebugParamVariable), | ||||
|     LocalVar(DebugLocalVariable), | ||||
|     VarAssignment, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| @ -312,3 +316,17 @@ pub struct DebugSubprogramOptionals { | ||||
|     /// prototyped or not.
 | ||||
|     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_information::{ | ||||
|     DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, | ||||
|     InstructionDebugRecordData, | ||||
| }; | ||||
| use util::match_types; | ||||
| 
 | ||||
| @ -275,6 +276,12 @@ impl InstructionValue { | ||||
|         } | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_record(&self, block: &mut Block, record: InstructionDebugRecordData) { | ||||
|         unsafe { | ||||
|             block.builder.add_instruction_record(self, record); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
|  | ||||
| @ -5,9 +5,9 @@ use reid_lib::{ | ||||
|     compile::CompiledModule, | ||||
|     debug_information::{ | ||||
|         DebugBasicType, DebugFileData, DebugInformation, DebugLocalVariable, DebugLocation, | ||||
|         DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugProgramValue, DebugScopeValue, | ||||
|         DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramTypeData, DebugTypeData, | ||||
|         DebugTypeValue, DwarfEncoding, DwarfFlags, | ||||
|         DebugMetadata, DebugMetadataValue, DebugParamVariable, DebugProgramValue, DebugRecordKind, | ||||
|         DebugScopeValue, DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramTypeData, | ||||
|         DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags, InstructionDebugRecordData, | ||||
|     }, | ||||
|     Block, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, | ||||
|     Module, NamedStruct, TerminatorKind as Term, Type, | ||||
| @ -106,6 +106,16 @@ pub enum StackValueKind { | ||||
|     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> { | ||||
|     fn with_block(&self, block: Block<'ctx>) -> Scope<'ctx, 'a> { | ||||
|         Scope { | ||||
| @ -403,23 +413,20 @@ impl mir::Statement { | ||||
|         match &self.0 { | ||||
|             mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { | ||||
|                 let value = expression.codegen(scope, &state).unwrap(); | ||||
|                 scope.stack_values.insert( | ||||
|                     name.clone(), | ||||
|                     StackValue( | ||||
|                         match mutable { | ||||
|                             false => StackValueKind::Immutable(value), | ||||
|                 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), | ||||
|                                 TypeKind::CustomType(n) => match scope | ||||
|                                     .types | ||||
|                                     .get(scope.type_values.get(n).unwrap()) | ||||
|                                     .unwrap() | ||||
|                                 { | ||||
|                         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), | ||||
|                                 }, | ||||
|                                 _ => StackValueKind::Mutable({ | ||||
|                                 TypeDefinitionKind::Struct(_) => { | ||||
|                                     (StackValueKind::Mutable(value), value) | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         _ => { | ||||
|                             let alloca = scope | ||||
|                                 .block | ||||
|                                 .build(Instr::Alloca( | ||||
| @ -428,21 +435,25 @@ impl mir::Statement { | ||||
|                                 )) | ||||
|                                 .unwrap() | ||||
|                                 .maybe_location(&mut scope.block, location); | ||||
|                                     scope | ||||
|                             let store = scope | ||||
|                                 .block | ||||
|                                 .build(Instr::Store(alloca, value)) | ||||
|                                 .unwrap() | ||||
|                                 .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 { | ||||
|                     match stack_value { | ||||
|                         StackValueKind::Immutable(_) => {} | ||||
|                         StackValueKind::Mutable(_) => { | ||||
|                             let location = self.1.into_debug(scope.tokens).unwrap(); | ||||
|                     debug.info.metadata( | ||||
|                             let var = debug.info.metadata( | ||||
|                                 &debug.scope, | ||||
|                                 DebugMetadata::LocalVar(DebugLocalVariable { | ||||
|                                     name: name.clone(), | ||||
| @ -453,6 +464,19 @@ impl mir::Statement { | ||||
|                                     flags: DwarfFlags, | ||||
|                                 }), | ||||
|                             ); | ||||
|                             dbg!(&store); | ||||
|                             store.add_record( | ||||
|                                 &mut scope.block, | ||||
|                                 InstructionDebugRecordData { | ||||
|                                     variable: var, | ||||
|                                     location, | ||||
|                                     kind: DebugRecordKind::Declare(value), | ||||
|                                     scope: debug.scope, | ||||
|                                 }, | ||||
|                             ); | ||||
|                         } | ||||
|                         StackValueKind::Any(_) => {} | ||||
|                     } | ||||
|                 } | ||||
|                 None | ||||
|             } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user