Skip to content

Commit

Permalink
Merge pull request #1575 from cfallin/test-fixes
Browse files Browse the repository at this point in the history
MachInst backend: pass through SourceLoc information.
  • Loading branch information
cfallin authored Apr 24, 2020
2 parents 8501383 + b691770 commit 6cd92f9
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 19 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cranelift/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ gimli = { version = "0.20.0", default-features = false, features = ["write"], op
smallvec = { version = "1.0.0" }
thiserror = "1.0.4"
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.
# 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
Expand Down
3 changes: 3 additions & 0 deletions cranelift/codegen/src/machinst/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
"lower_branch_group: targets = {:?} branches = {:?}",
targets, branches
);
self.vcode.set_srcloc(self.srcloc(branches[0]));
backend.lower_branch_group(
&mut self,
&branches[..],
Expand All @@ -361,6 +362,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
let num_uses = self.num_uses[inst];
let side_effect = has_side_effect(self.f, inst);
if side_effect || num_uses > 0 {
self.vcode.set_srcloc(self.srcloc(inst));
backend.lower(&mut self, inst);
self.vcode.end_ir_inst();
} else {
Expand Down Expand Up @@ -389,6 +391,7 @@ impl<'func, I: VCodeInst> Lower<'func, I> {
"lower_branch_group: targets = {:?} branches = {:?}",
targets, branches
);
self.vcode.set_srcloc(self.srcloc(branches[0]));
backend.lower_branch_group(&mut self, &branches[..], &targets[..], fallthrough);
self.vcode.end_ir_inst();
branches.clear();
Expand Down
1 change: 0 additions & 1 deletion cranelift/codegen/src/machinst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@
//! ```

use crate::binemit::{CodeInfo, CodeOffset};
use crate::entity::SecondaryMap;
use crate::ir::condcodes::IntCC;
use crate::ir::{Function, Type};
use crate::result::CodegenResult;
Expand Down
108 changes: 107 additions & 1 deletion cranelift/codegen/src/machinst/sections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ impl MachSections {
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.
pub fn total_size(&self) -> CodeOffset {
if self.sections.len() == 0 {
Expand All @@ -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
/// receiver of section data.
pub trait MachSectionOutput {
Expand Down Expand Up @@ -143,6 +200,12 @@ pub trait MachSectionOutput {
/// Add a call return address record at the current offset.
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.
fn align_to(&mut self, align_to: CodeOffset) {
assert!(align_to.is_power_of_two());
Expand All @@ -168,8 +231,13 @@ pub struct MachSection {
pub relocs: Vec<MachReloc>,
/// Any trap records referring to this section.
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>,
/// 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 {
Expand All @@ -182,6 +250,8 @@ impl MachSection {
relocs: vec![],
traps: vec![],
call_sites: vec![],
srclocs: vec![],
cur_srcloc: None,
}
}

Expand Down Expand Up @@ -266,6 +336,23 @@ impl MachSectionOutput for MachSection {
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.
Expand Down Expand Up @@ -315,6 +402,10 @@ impl MachSectionOutput for MachSectionSize {
fn add_trap(&mut self, _: SourceLoc, _: TrapCode) {}

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.
Expand Down Expand Up @@ -352,3 +443,18 @@ pub struct MachCallSite {
/// The call's 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,
}
Loading

0 comments on commit 6cd92f9

Please sign in to comment.