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,56 +413,70 @@ impl mir::Statement {
|
||||
match &self.0 {
|
||||
mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => {
|
||||
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(
|
||||
name.clone(),
|
||||
StackValue(
|
||||
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),
|
||||
),
|
||||
StackValue(stack_value, ty.get_type(scope.type_values, scope.types)),
|
||||
);
|
||||
if let Some(debug) = &scope.debug {
|
||||
let location = self.1.into_debug(scope.tokens).unwrap();
|
||||
debug.info.metadata(
|
||||
&debug.scope,
|
||||
DebugMetadata::LocalVar(DebugLocalVariable {
|
||||
name: name.clone(),
|
||||
location,
|
||||
ty: scope.debug_const_tys.get(&TypeKind::U32).unwrap().clone(),
|
||||
always_preserve: true,
|
||||
alignment: 32,
|
||||
flags: DwarfFlags,
|
||||
}),
|
||||
);
|
||||
match stack_value {
|
||||
StackValueKind::Immutable(_) => {}
|
||||
StackValueKind::Mutable(_) => {
|
||||
let location = self.1.into_debug(scope.tokens).unwrap();
|
||||
let var = debug.info.metadata(
|
||||
&debug.scope,
|
||||
DebugMetadata::LocalVar(DebugLocalVariable {
|
||||
name: name.clone(),
|
||||
location,
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user