Implement local reading for locals on stack
This commit is contained in:
parent
d8e9148c2e
commit
8edbbc45f7
3 changed files with 49 additions and 29 deletions
|
@ -17,7 +17,7 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
|
|||
let mut debug_context = cx
|
||||
.debug_context
|
||||
.as_mut()
|
||||
.map(|debug_context| FunctionDebugContext::new(debug_context, instance, func_id, &name, &sig));
|
||||
.map(|debug_context| FunctionDebugContext::new(debug_context, instance, func_id, &name));
|
||||
|
||||
// Make FunctionBuilder
|
||||
let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig);
|
||||
|
@ -61,6 +61,7 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
|
|||
let instance = fx.instance;
|
||||
let clif_comments = fx.clif_comments;
|
||||
let source_info_set = fx.source_info_set;
|
||||
let local_map = fx.local_map;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
crate::pretty_clif::write_clif_file(cx.tcx, "unopt", instance, &func, &clif_comments, None);
|
||||
|
@ -92,7 +93,7 @@ pub fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
|
|||
let isa = cx.module.isa();
|
||||
debug_context
|
||||
.as_mut()
|
||||
.map(|x| x.define(context, isa, &source_info_set));
|
||||
.map(|x| x.define(context, isa, &source_info_set, local_map));
|
||||
|
||||
// Clear context to make it usable for the next function
|
||||
context.clear();
|
||||
|
|
|
@ -5,7 +5,7 @@ use syntax::source_map::FileName;
|
|||
use cranelift::codegen::binemit::CodeOffset;
|
||||
|
||||
use gimli::write::{
|
||||
Address, AttributeValue, FileId, LineProgram, LineString, LineStringTable, Range, UnitEntryId,
|
||||
Address, AttributeValue, FileId, LineProgram, LineString, LineStringTable, UnitEntryId,
|
||||
};
|
||||
|
||||
fn line_program_add_file(
|
||||
|
|
|
@ -172,7 +172,6 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
|||
instance: Instance<'tcx>,
|
||||
func_id: FuncId,
|
||||
name: &str,
|
||||
_sig: &Signature,
|
||||
) -> Self {
|
||||
let mir = debug_context.tcx.instance_mir(instance.def);
|
||||
|
||||
|
@ -235,6 +234,7 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
|||
context: &Context,
|
||||
isa: &dyn cranelift::codegen::isa::TargetIsa,
|
||||
source_info_set: &indexmap::IndexSet<(Span, mir::SourceScope)>,
|
||||
local_map: HashMap<mir::Local, CPlace<'tcx>>,
|
||||
) {
|
||||
let end = self.create_debug_lines(context, isa, source_info_set);
|
||||
|
||||
|
@ -251,34 +251,53 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
|||
|
||||
let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap();
|
||||
|
||||
for (value_label, value_loc_ranges) in value_labels_ranges.iter() {
|
||||
let var_id = self.define_local(mir::Local::from_u32(value_label.as_u32()));
|
||||
for (local, _local_decl) in self.mir.local_decls.iter_enumerated() {
|
||||
let var_id = self.define_local(local);
|
||||
let value_label = cranelift::codegen::ir::ValueLabel::from_u32(local.as_u32());
|
||||
|
||||
let loc_list = LocationList(
|
||||
value_loc_ranges
|
||||
.iter()
|
||||
.map(|value_loc_range| Location::StartEnd {
|
||||
begin: Address::Symbol {
|
||||
symbol: self.symbol,
|
||||
addend: i64::from(value_loc_range.start),
|
||||
},
|
||||
end: Address::Symbol {
|
||||
symbol: self.symbol,
|
||||
addend: i64::from(value_loc_range.end),
|
||||
},
|
||||
data: Expression(
|
||||
translate_loc(value_loc_range.loc, &context.func.stack_slots).unwrap(),
|
||||
),
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
let loc_list_id = self.debug_context.dwarf.unit.locations.add(loc_list);
|
||||
let location = match local_map[&local].inner() {
|
||||
CPlaceInner::Var(_) => {
|
||||
if let Some(value_loc_ranges) = value_labels_ranges.get(&value_label) {
|
||||
let loc_list = LocationList(
|
||||
value_loc_ranges
|
||||
.iter()
|
||||
.map(|value_loc_range| Location::StartEnd {
|
||||
begin: Address::Symbol {
|
||||
symbol: self.symbol,
|
||||
addend: i64::from(value_loc_range.start),
|
||||
},
|
||||
end: Address::Symbol {
|
||||
symbol: self.symbol,
|
||||
addend: i64::from(value_loc_range.end),
|
||||
},
|
||||
data: Expression(
|
||||
translate_loc(value_loc_range.loc, &context.func.stack_slots).unwrap(),
|
||||
),
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
let loc_list_id = self.debug_context.dwarf.unit.locations.add(loc_list);
|
||||
|
||||
AttributeValue::LocationListRef(loc_list_id)
|
||||
} else {
|
||||
// FIXME set value labels for unused locals
|
||||
|
||||
AttributeValue::Exprloc(Expression(vec![]))
|
||||
}
|
||||
}
|
||||
CPlaceInner::Addr(_, _) => {
|
||||
// FIXME implement this (used by arguments and returns)
|
||||
|
||||
AttributeValue::Exprloc(Expression(vec![]))
|
||||
}
|
||||
CPlaceInner::Stack(stack_slot) => {
|
||||
AttributeValue::Exprloc(Expression(translate_loc(ValueLoc::Stack(*stack_slot), &context.func.stack_slots).unwrap()))
|
||||
}
|
||||
CPlaceInner::NoPlace => AttributeValue::Exprloc(Expression(vec![])),
|
||||
};
|
||||
|
||||
let var_entry = self.debug_context.dwarf.unit.get_mut(var_id);
|
||||
var_entry.set(
|
||||
gimli::DW_AT_location,
|
||||
AttributeValue::LocationListRef(loc_list_id),
|
||||
);
|
||||
var_entry.set(gimli::DW_AT_location, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue