Merge pull request #1575 from cfallin/test-fixes
MachInst backend: pass through SourceLoc information.
This commit is contained in:
5
Cargo.lock
generated
5
Cargo.lock
generated
@@ -1538,12 +1538,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regalloc"
|
name = "regalloc"
|
||||||
version = "0.0.17"
|
version = "0.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89ce0cd835fa6e91bbf5d010beee19d0c2e97e4ad5e13c399a31122cfc83bdd6"
|
checksum = "c6d7df180ed313488abdbeec2e3398f16cbf5ea6ce20db968c8cd6fc410400a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ gimli = { version = "0.20.0", default-features = false, features = ["write"], op
|
|||||||
smallvec = { version = "1.0.0" }
|
smallvec = { version = "1.0.0" }
|
||||||
thiserror = "1.0.4"
|
thiserror = "1.0.4"
|
||||||
byteorder = { version = "1.3.2", default-features = false }
|
byteorder = { version = "1.3.2", default-features = false }
|
||||||
regalloc = "0.0.17"
|
regalloc = "0.0.18"
|
||||||
# It is a goal of the cranelift-codegen crate to have minimal external dependencies.
|
# It is a goal of the cranelift-codegen crate to have minimal external dependencies.
|
||||||
# Please don't add any unless they are essential to the task of creating binary
|
# Please don't add any unless they are essential to the task of creating binary
|
||||||
# machine code. Integration tests that need external dependencies can be
|
# machine code. Integration tests that need external dependencies can be
|
||||||
|
|||||||
@@ -345,6 +345,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
"lower_branch_group: targets = {:?} branches = {:?}",
|
"lower_branch_group: targets = {:?} branches = {:?}",
|
||||||
targets, branches
|
targets, branches
|
||||||
);
|
);
|
||||||
|
self.vcode.set_srcloc(self.srcloc(branches[0]));
|
||||||
backend.lower_branch_group(
|
backend.lower_branch_group(
|
||||||
&mut self,
|
&mut self,
|
||||||
&branches[..],
|
&branches[..],
|
||||||
@@ -361,6 +362,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
let num_uses = self.num_uses[inst];
|
let num_uses = self.num_uses[inst];
|
||||||
let side_effect = has_side_effect(self.f, inst);
|
let side_effect = has_side_effect(self.f, inst);
|
||||||
if side_effect || num_uses > 0 {
|
if side_effect || num_uses > 0 {
|
||||||
|
self.vcode.set_srcloc(self.srcloc(inst));
|
||||||
backend.lower(&mut self, inst);
|
backend.lower(&mut self, inst);
|
||||||
self.vcode.end_ir_inst();
|
self.vcode.end_ir_inst();
|
||||||
} else {
|
} else {
|
||||||
@@ -389,6 +391,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
|
|||||||
"lower_branch_group: targets = {:?} branches = {:?}",
|
"lower_branch_group: targets = {:?} branches = {:?}",
|
||||||
targets, branches
|
targets, branches
|
||||||
);
|
);
|
||||||
|
self.vcode.set_srcloc(self.srcloc(branches[0]));
|
||||||
backend.lower_branch_group(&mut self, &branches[..], &targets[..], fallthrough);
|
backend.lower_branch_group(&mut self, &branches[..], &targets[..], fallthrough);
|
||||||
self.vcode.end_ir_inst();
|
self.vcode.end_ir_inst();
|
||||||
branches.clear();
|
branches.clear();
|
||||||
|
|||||||
@@ -97,7 +97,6 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::binemit::{CodeInfo, CodeOffset};
|
use crate::binemit::{CodeInfo, CodeOffset};
|
||||||
use crate::entity::SecondaryMap;
|
|
||||||
use crate::ir::condcodes::IntCC;
|
use crate::ir::condcodes::IntCC;
|
||||||
use crate::ir::{Function, Type};
|
use crate::ir::{Function, Type};
|
||||||
use crate::result::CodegenResult;
|
use crate::result::CodegenResult;
|
||||||
|
|||||||
@@ -74,6 +74,11 @@ impl MachSections {
|
|||||||
sink.end_codegen();
|
sink.end_codegen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a list of source location mapping tuples in sorted-by-start-offset order.
|
||||||
|
pub fn get_srclocs_sorted<'a>(&'a self) -> MachSectionsSrcLocs<'a> {
|
||||||
|
MachSectionsSrcLocs::new(&self.sections)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the total required size for these sections.
|
/// Get the total required size for these sections.
|
||||||
pub fn total_size(&self) -> CodeOffset {
|
pub fn total_size(&self) -> CodeOffset {
|
||||||
if self.sections.len() == 0 {
|
if self.sections.len() == 0 {
|
||||||
@@ -90,6 +95,58 @@ impl MachSections {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator over the srclocs in each section.
|
||||||
|
/// Returns MachSrcLocs in an order sorted by start location.
|
||||||
|
pub struct MachSectionsSrcLocs<'a> {
|
||||||
|
sections: &'a [MachSection],
|
||||||
|
cur_section: usize,
|
||||||
|
cur_srcloc: usize,
|
||||||
|
// For validation:
|
||||||
|
last_offset: CodeOffset,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MachSectionsSrcLocs<'a> {
|
||||||
|
fn new(sections: &'a [MachSection]) -> MachSectionsSrcLocs<'a> {
|
||||||
|
MachSectionsSrcLocs {
|
||||||
|
sections,
|
||||||
|
cur_section: 0,
|
||||||
|
cur_srcloc: 0,
|
||||||
|
last_offset: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for MachSectionsSrcLocs<'a> {
|
||||||
|
type Item = &'a MachSrcLoc;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<&'a MachSrcLoc> {
|
||||||
|
// We simply iterate through sections and srcloc records in order. This produces a
|
||||||
|
// sorted order naturally because sections are in starting-offset-order, and srclocs
|
||||||
|
// are produced as a section is emitted into, so are in order as well.
|
||||||
|
|
||||||
|
// If we're out of sections, we're done.
|
||||||
|
if self.cur_section >= self.sections.len() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, make sure we have a srcloc in the current section left to return, and
|
||||||
|
// advance to the next section if not. Done if we run out of sections.
|
||||||
|
while self.cur_srcloc >= self.sections[self.cur_section].srclocs.len() {
|
||||||
|
self.cur_srcloc = 0;
|
||||||
|
self.cur_section += 1;
|
||||||
|
if self.cur_section >= self.sections.len() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let loc = &self.sections[self.cur_section].srclocs[self.cur_srcloc];
|
||||||
|
self.cur_srcloc += 1;
|
||||||
|
debug_assert!(loc.start >= self.last_offset);
|
||||||
|
self.last_offset = loc.start;
|
||||||
|
Some(loc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An abstraction over MachSection and MachSectionSize: some
|
/// An abstraction over MachSection and MachSectionSize: some
|
||||||
/// receiver of section data.
|
/// receiver of section data.
|
||||||
pub trait MachSectionOutput {
|
pub trait MachSectionOutput {
|
||||||
@@ -143,6 +200,12 @@ pub trait MachSectionOutput {
|
|||||||
/// Add a call return address record at the current offset.
|
/// Add a call return address record at the current offset.
|
||||||
fn add_call_site(&mut self, loc: SourceLoc, opcode: Opcode);
|
fn add_call_site(&mut self, loc: SourceLoc, opcode: Opcode);
|
||||||
|
|
||||||
|
/// Start the output for the given source-location at the current offset.
|
||||||
|
fn start_srcloc(&mut self, loc: SourceLoc);
|
||||||
|
|
||||||
|
/// End the output for the previously-given source-location at the current offset.
|
||||||
|
fn end_srcloc(&mut self);
|
||||||
|
|
||||||
/// Align up to the given alignment.
|
/// Align up to the given alignment.
|
||||||
fn align_to(&mut self, align_to: CodeOffset) {
|
fn align_to(&mut self, align_to: CodeOffset) {
|
||||||
assert!(align_to.is_power_of_two());
|
assert!(align_to.is_power_of_two());
|
||||||
@@ -168,8 +231,13 @@ pub struct MachSection {
|
|||||||
pub relocs: Vec<MachReloc>,
|
pub relocs: Vec<MachReloc>,
|
||||||
/// Any trap records referring to this section.
|
/// Any trap records referring to this section.
|
||||||
pub traps: Vec<MachTrap>,
|
pub traps: Vec<MachTrap>,
|
||||||
/// Any call site record referring to this section.
|
/// Any call site records referring to this section.
|
||||||
pub call_sites: Vec<MachCallSite>,
|
pub call_sites: Vec<MachCallSite>,
|
||||||
|
/// Any source location mappings referring to this section.
|
||||||
|
pub srclocs: Vec<MachSrcLoc>,
|
||||||
|
/// The current source location in progress (after `start_srcloc()` and before `end_srcloc()`).
|
||||||
|
/// This is a (start_offset, src_loc) tuple.
|
||||||
|
pub cur_srcloc: Option<(CodeOffset, SourceLoc)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachSection {
|
impl MachSection {
|
||||||
@@ -182,6 +250,8 @@ impl MachSection {
|
|||||||
relocs: vec![],
|
relocs: vec![],
|
||||||
traps: vec![],
|
traps: vec![],
|
||||||
call_sites: vec![],
|
call_sites: vec![],
|
||||||
|
srclocs: vec![],
|
||||||
|
cur_srcloc: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +336,23 @@ impl MachSectionOutput for MachSection {
|
|||||||
opcode,
|
opcode,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn start_srcloc(&mut self, loc: SourceLoc) {
|
||||||
|
self.cur_srcloc = Some((self.cur_offset_from_start(), loc));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_srcloc(&mut self) {
|
||||||
|
let (start, loc) = self
|
||||||
|
.cur_srcloc
|
||||||
|
.take()
|
||||||
|
.expect("end_srcloc() called without start_srcloc()");
|
||||||
|
let end = self.cur_offset_from_start();
|
||||||
|
// Skip zero-length extends.
|
||||||
|
debug_assert!(end >= start);
|
||||||
|
if end > start {
|
||||||
|
self.srclocs.push(MachSrcLoc { start, end, loc });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A MachSectionOutput implementation that records only size.
|
/// A MachSectionOutput implementation that records only size.
|
||||||
@@ -315,6 +402,10 @@ impl MachSectionOutput for MachSectionSize {
|
|||||||
fn add_trap(&mut self, _: SourceLoc, _: TrapCode) {}
|
fn add_trap(&mut self, _: SourceLoc, _: TrapCode) {}
|
||||||
|
|
||||||
fn add_call_site(&mut self, _: SourceLoc, _: Opcode) {}
|
fn add_call_site(&mut self, _: SourceLoc, _: Opcode) {}
|
||||||
|
|
||||||
|
fn start_srcloc(&mut self, _: SourceLoc) {}
|
||||||
|
|
||||||
|
fn end_srcloc(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A relocation resulting from a compilation.
|
/// A relocation resulting from a compilation.
|
||||||
@@ -352,3 +443,18 @@ pub struct MachCallSite {
|
|||||||
/// The call's opcode.
|
/// The call's opcode.
|
||||||
pub opcode: Opcode,
|
pub opcode: Opcode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A source-location mapping resulting from a compilation.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct MachSrcLoc {
|
||||||
|
/// The start of the region of code corresponding to a source location.
|
||||||
|
/// This is relative to the start of the function, not to the start of the
|
||||||
|
/// section.
|
||||||
|
pub start: CodeOffset,
|
||||||
|
/// The end of the region of code corresponding to a source location.
|
||||||
|
/// This is relative to the start of the section, not to the start of the
|
||||||
|
/// section.
|
||||||
|
pub end: CodeOffset,
|
||||||
|
/// The source location.
|
||||||
|
pub loc: SourceLoc,
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
//! See the main module comment in `mod.rs` for more details on the VCode-based
|
//! See the main module comment in `mod.rs` for more details on the VCode-based
|
||||||
//! backend pipeline.
|
//! backend pipeline.
|
||||||
|
|
||||||
|
use crate::entity::SecondaryMap;
|
||||||
use crate::ir;
|
use crate::ir;
|
||||||
|
use crate::ir::SourceLoc;
|
||||||
use crate::machinst::*;
|
use crate::machinst::*;
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
|
|
||||||
@@ -59,6 +61,10 @@ pub struct VCode<I: VCodeInst> {
|
|||||||
/// Lowered machine instructions in order corresponding to the original IR.
|
/// Lowered machine instructions in order corresponding to the original IR.
|
||||||
insts: Vec<I>,
|
insts: Vec<I>,
|
||||||
|
|
||||||
|
/// Source locations for each instruction. (`SourceLoc` is a `u32`, so it is
|
||||||
|
/// reasonable to keep one of these per instruction.)
|
||||||
|
srclocs: Vec<SourceLoc>,
|
||||||
|
|
||||||
/// Entry block.
|
/// Entry block.
|
||||||
entry: BlockIndex,
|
entry: BlockIndex,
|
||||||
|
|
||||||
@@ -115,13 +121,16 @@ pub struct VCodeBuilder<I: VCodeInst> {
|
|||||||
|
|
||||||
/// Current basic block instructions, in reverse order (because blocks are
|
/// Current basic block instructions, in reverse order (because blocks are
|
||||||
/// built bottom-to-top).
|
/// built bottom-to-top).
|
||||||
bb_insns: SmallVec<[I; 32]>,
|
bb_insns: SmallVec<[(I, SourceLoc); 32]>,
|
||||||
|
|
||||||
/// Current IR-inst instructions, in forward order.
|
/// Current IR-inst instructions, in forward order.
|
||||||
ir_inst_insns: SmallVec<[I; 4]>,
|
ir_inst_insns: SmallVec<[(I, SourceLoc); 4]>,
|
||||||
|
|
||||||
/// Start of succs for the current block in the concatenated succs list.
|
/// Start of succs for the current block in the concatenated succs list.
|
||||||
succ_start: usize,
|
succ_start: usize,
|
||||||
|
|
||||||
|
/// Current source location.
|
||||||
|
cur_srcloc: SourceLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: VCodeInst> VCodeBuilder<I> {
|
impl<I: VCodeInst> VCodeBuilder<I> {
|
||||||
@@ -133,6 +142,7 @@ impl<I: VCodeInst> VCodeBuilder<I> {
|
|||||||
bb_insns: SmallVec::new(),
|
bb_insns: SmallVec::new(),
|
||||||
ir_inst_insns: SmallVec::new(),
|
ir_inst_insns: SmallVec::new(),
|
||||||
succ_start: 0,
|
succ_start: 0,
|
||||||
|
cur_srcloc: SourceLoc::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,8 +189,8 @@ impl<I: VCodeInst> VCodeBuilder<I> {
|
|||||||
/// End the current IR instruction. Must be called after pushing any
|
/// End the current IR instruction. Must be called after pushing any
|
||||||
/// instructions and prior to ending the basic block.
|
/// instructions and prior to ending the basic block.
|
||||||
pub fn end_ir_inst(&mut self) {
|
pub fn end_ir_inst(&mut self) {
|
||||||
while let Some(i) = self.ir_inst_insns.pop() {
|
while let Some(pair) = self.ir_inst_insns.pop() {
|
||||||
self.bb_insns.push(i);
|
self.bb_insns.push(pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,8 +201,9 @@ impl<I: VCodeInst> VCodeBuilder<I> {
|
|||||||
let block_num = self.vcode.block_ranges.len() as BlockIndex;
|
let block_num = self.vcode.block_ranges.len() as BlockIndex;
|
||||||
// Push the instructions.
|
// Push the instructions.
|
||||||
let start_idx = self.vcode.insts.len() as InsnIndex;
|
let start_idx = self.vcode.insts.len() as InsnIndex;
|
||||||
while let Some(i) = self.bb_insns.pop() {
|
while let Some((i, loc)) = self.bb_insns.pop() {
|
||||||
self.vcode.insts.push(i);
|
self.vcode.insts.push(i);
|
||||||
|
self.vcode.srclocs.push(loc);
|
||||||
}
|
}
|
||||||
let end_idx = self.vcode.insts.len() as InsnIndex;
|
let end_idx = self.vcode.insts.len() as InsnIndex;
|
||||||
// Add the instruction index range to the list of blocks.
|
// Add the instruction index range to the list of blocks.
|
||||||
@@ -224,7 +235,12 @@ impl<I: VCodeInst> VCodeBuilder<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.ir_inst_insns.push(insn);
|
self.ir_inst_insns.push((insn, self.cur_srcloc));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the current source location.
|
||||||
|
pub fn set_srcloc(&mut self, srcloc: SourceLoc) {
|
||||||
|
self.cur_srcloc = srcloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the final VCode.
|
/// Build the final VCode.
|
||||||
@@ -286,6 +302,7 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
liveouts: abi.liveouts(),
|
liveouts: abi.liveouts(),
|
||||||
vreg_types: vec![],
|
vreg_types: vec![],
|
||||||
insts: vec![],
|
insts: vec![],
|
||||||
|
srclocs: vec![],
|
||||||
entry: 0,
|
entry: 0,
|
||||||
block_ranges: vec![],
|
block_ranges: vec![],
|
||||||
block_succ_range: vec![],
|
block_succ_range: vec![],
|
||||||
@@ -349,6 +366,7 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
block_ranges(result.target_map.elems(), result.insns.len());
|
block_ranges(result.target_map.elems(), result.insns.len());
|
||||||
let mut final_insns = vec![];
|
let mut final_insns = vec![];
|
||||||
let mut final_block_ranges = vec![(0, 0); self.num_blocks()];
|
let mut final_block_ranges = vec![(0, 0); self.num_blocks()];
|
||||||
|
let mut final_srclocs = vec![];
|
||||||
|
|
||||||
for block in &self.final_block_order {
|
for block in &self.final_block_order {
|
||||||
let (start, end) = block_ranges[*block as usize];
|
let (start, end) = block_ranges[*block as usize];
|
||||||
@@ -356,7 +374,10 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
|
|
||||||
if *block == self.entry {
|
if *block == self.entry {
|
||||||
// Start with the prologue.
|
// Start with the prologue.
|
||||||
final_insns.extend(self.abi.gen_prologue().into_iter());
|
let prologue = self.abi.gen_prologue();
|
||||||
|
let len = prologue.len();
|
||||||
|
final_insns.extend(prologue.into_iter());
|
||||||
|
final_srclocs.extend(iter::repeat(SourceLoc::default()).take(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in start..end {
|
for i in start..end {
|
||||||
@@ -368,13 +389,27 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is there a srcloc associated with this insn? Look it up based on original
|
||||||
|
// instruction index (if new insn corresponds to some original insn, i.e., is not
|
||||||
|
// an inserted load/spill/move).
|
||||||
|
let orig_iix = result.orig_insn_map[InstIx::new(i as u32)];
|
||||||
|
let srcloc = if orig_iix.is_invalid() {
|
||||||
|
SourceLoc::default()
|
||||||
|
} else {
|
||||||
|
self.srclocs[orig_iix.get() as usize]
|
||||||
|
};
|
||||||
|
|
||||||
// Whenever encountering a return instruction, replace it
|
// Whenever encountering a return instruction, replace it
|
||||||
// with the epilogue.
|
// with the epilogue.
|
||||||
let is_ret = insn.is_term() == MachTerminator::Ret;
|
let is_ret = insn.is_term() == MachTerminator::Ret;
|
||||||
if is_ret {
|
if is_ret {
|
||||||
final_insns.extend(self.abi.gen_epilogue().into_iter());
|
let epilogue = self.abi.gen_epilogue();
|
||||||
|
let len = epilogue.len();
|
||||||
|
final_insns.extend(epilogue.into_iter());
|
||||||
|
final_srclocs.extend(iter::repeat(srcloc).take(len));
|
||||||
} else {
|
} else {
|
||||||
final_insns.push(insn.clone());
|
final_insns.push(insn.clone());
|
||||||
|
final_srclocs.push(srcloc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,7 +417,10 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
final_block_ranges[*block as usize] = (final_start, final_end);
|
final_block_ranges[*block as usize] = (final_start, final_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug_assert!(final_insns.len() == final_srclocs.len());
|
||||||
|
|
||||||
self.insts = final_insns;
|
self.insts = final_insns;
|
||||||
|
self.srclocs = final_srclocs;
|
||||||
self.block_ranges = final_block_ranges;
|
self.block_ranges = final_block_ranges;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,6 +550,7 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
let code_section = sections.get_section(code_idx);
|
let code_section = sections.get_section(code_idx);
|
||||||
|
|
||||||
let flags = self.abi.flags();
|
let flags = self.abi.flags();
|
||||||
|
let mut cur_srcloc = SourceLoc::default();
|
||||||
for &block in &self.final_block_order {
|
for &block in &self.final_block_order {
|
||||||
let new_offset = I::align_basic_block(code_section.cur_offset_from_start());
|
let new_offset = I::align_basic_block(code_section.cur_offset_from_start());
|
||||||
while new_offset > code_section.cur_offset_from_start() {
|
while new_offset > code_section.cur_offset_from_start() {
|
||||||
@@ -523,8 +562,24 @@ impl<I: VCodeInst> VCode<I> {
|
|||||||
|
|
||||||
let (start, end) = self.block_ranges[block as usize];
|
let (start, end) = self.block_ranges[block as usize];
|
||||||
for iix in start..end {
|
for iix in start..end {
|
||||||
|
let srcloc = self.srclocs[iix as usize];
|
||||||
|
if srcloc != cur_srcloc {
|
||||||
|
if !cur_srcloc.is_default() {
|
||||||
|
code_section.end_srcloc();
|
||||||
|
}
|
||||||
|
if !srcloc.is_default() {
|
||||||
|
code_section.start_srcloc(srcloc);
|
||||||
|
}
|
||||||
|
cur_srcloc = srcloc;
|
||||||
|
}
|
||||||
|
|
||||||
self.insts[iix as usize].emit(code_section, flags);
|
self.insts[iix as usize].emit(code_section, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !cur_srcloc.is_default() {
|
||||||
|
code_section.end_srcloc();
|
||||||
|
cur_srcloc = SourceLoc::default();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sections
|
sections
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ use crate::compilation::{
|
|||||||
use crate::func_environ::{get_func_name, FuncEnvironment};
|
use crate::func_environ::{get_func_name, FuncEnvironment};
|
||||||
use crate::{CacheConfig, FunctionBodyData, ModuleLocal, ModuleTranslation, Tunables};
|
use crate::{CacheConfig, FunctionBodyData, ModuleLocal, ModuleTranslation, Tunables};
|
||||||
use cranelift_codegen::ir::{self, ExternalName};
|
use cranelift_codegen::ir::{self, ExternalName};
|
||||||
|
use cranelift_codegen::machinst::sections::MachSrcLoc;
|
||||||
use cranelift_codegen::print_errors::pretty_error;
|
use cranelift_codegen::print_errors::pretty_error;
|
||||||
use cranelift_codegen::{binemit, isa, Context};
|
use cranelift_codegen::{binemit, isa, Context};
|
||||||
use cranelift_entity::PrimaryMap;
|
use cranelift_entity::PrimaryMap;
|
||||||
@@ -207,13 +208,22 @@ fn get_function_address_map<'data>(
|
|||||||
) -> FunctionAddressMap {
|
) -> FunctionAddressMap {
|
||||||
let mut instructions = Vec::new();
|
let mut instructions = Vec::new();
|
||||||
|
|
||||||
|
if let Some(ref mcr) = &context.mach_compile_result {
|
||||||
|
// New-style backend: we have a `MachCompileResult` that will give us `MachSrcLoc` mapping
|
||||||
|
// tuples.
|
||||||
|
for &MachSrcLoc { start, end, loc } in mcr.sections.get_srclocs_sorted() {
|
||||||
|
instructions.push(InstructionAddressMap {
|
||||||
|
srcloc: loc,
|
||||||
|
code_offset: start as usize,
|
||||||
|
code_len: (end - start) as usize,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Old-style backend: we need to traverse the instruction/encoding info in the function.
|
||||||
let func = &context.func;
|
let func = &context.func;
|
||||||
let mut blocks = func.layout.blocks().collect::<Vec<_>>();
|
let mut blocks = func.layout.blocks().collect::<Vec<_>>();
|
||||||
blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase
|
blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase
|
||||||
|
|
||||||
// FIXME(#1523): New backend does not support debug info or instruction-address mapping
|
|
||||||
// yet.
|
|
||||||
if !isa.get_mach_backend().is_some() {
|
|
||||||
let encinfo = isa.encoding_info();
|
let encinfo = isa.encoding_info();
|
||||||
for block in blocks {
|
for block in blocks {
|
||||||
for (offset, inst, size) in func.inst_offsets(block, &encinfo) {
|
for (offset, inst, size) in func.inst_offsets(block, &encinfo) {
|
||||||
|
|||||||
Reference in New Issue
Block a user