Add source location support to FuncCursor and EncCursor.

A cursor now also remembers a current source location which will be
assigned to all new instructions created with the cursor.

The old layout::Cursor can't support source locations because it doesn't
have a reference to the full ir::Function.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-21 10:38:11 -07:00
parent b2a314a229
commit 4d4da2dc60
9 changed files with 143 additions and 38 deletions

View File

@@ -358,6 +358,7 @@ def gen_xform_group(xgrp, fmt, type_sets):
'cfg: &mut ::flowgraph::ControlFlowGraph) -> ' 'cfg: &mut ::flowgraph::ControlFlowGraph) -> '
'bool {{'.format(xgrp.name), '}'): 'bool {{'.format(xgrp.name), '}'):
fmt.line('use ir::{InstBuilder, CursorBase};') fmt.line('use ir::{InstBuilder, CursorBase};')
fmt.line('let srcloc = func.srclocs[inst];')
# Group the xforms by opcode so we can generate a big switch. # Group the xforms by opcode so we can generate a big switch.
# Preserve ordering. # Preserve ordering.
@@ -372,8 +373,9 @@ def gen_xform_group(xgrp, fmt, type_sets):
with fmt.indented( with fmt.indented(
'ir::Opcode::{} => {{'.format(camel_name), '}'): 'ir::Opcode::{} => {{'.format(camel_name), '}'):
fmt.line( fmt.line(
'let pos = &mut ' 'let pos = &mut ir::Cursor::new'
'ir::Cursor::new(&mut func.layout)' '(&mut func.layout, &mut func.srclocs)'
'.with_srcloc(srcloc)'
'.at_inst(inst);') '.at_inst(inst);')
fmt.line('let dfg = &mut func.dfg;') fmt.line('let dfg = &mut func.dfg;')
for xform in xforms[camel_name]: for xform in xforms[camel_name]:

View File

@@ -19,6 +19,7 @@ pub use ir::layout::Cursor as LayoutCursor;
/// encoding. /// encoding.
pub struct FuncCursor<'f> { pub struct FuncCursor<'f> {
pos: CursorPosition, pos: CursorPosition,
srcloc: ir::SourceLoc,
/// The referenced function. /// The referenced function.
pub func: &'f mut ir::Function, pub func: &'f mut ir::Function,
@@ -29,10 +30,16 @@ impl<'f> FuncCursor<'f> {
pub fn new(func: &'f mut ir::Function) -> FuncCursor<'f> { pub fn new(func: &'f mut ir::Function) -> FuncCursor<'f> {
FuncCursor { FuncCursor {
pos: CursorPosition::Nowhere, pos: CursorPosition::Nowhere,
srcloc: Default::default(),
func, func,
} }
} }
/// Use the source location of `inst` for future instructions.
pub fn use_srcloc(&mut self, inst: ir::Inst) {
self.srcloc = self.func.srclocs[inst];
}
/// Create an instruction builder that inserts an instruction at the current position. /// Create an instruction builder that inserts an instruction at the current position.
pub fn ins(&mut self) -> ir::InsertBuilder<&mut FuncCursor<'f>> { pub fn ins(&mut self) -> ir::InsertBuilder<&mut FuncCursor<'f>> {
ir::InsertBuilder::new(self) ir::InsertBuilder::new(self)
@@ -48,6 +55,14 @@ impl<'f> Cursor for FuncCursor<'f> {
self.pos = pos self.pos = pos
} }
fn srcloc(&self) -> ir::SourceLoc {
self.srcloc
}
fn set_srcloc(&mut self, srcloc: ir::SourceLoc) {
self.srcloc = srcloc;
}
fn layout(&self) -> &ir::Layout { fn layout(&self) -> &ir::Layout {
&self.func.layout &self.func.layout
} }
@@ -68,6 +83,9 @@ impl<'c, 'f> ir::InstInserterBase<'c> for &'c mut FuncCursor<'f> {
fn insert_built_inst(self, inst: ir::Inst, _: ir::Type) -> &'c mut ir::DataFlowGraph { fn insert_built_inst(self, inst: ir::Inst, _: ir::Type) -> &'c mut ir::DataFlowGraph {
self.insert_inst(inst); self.insert_inst(inst);
if !self.srcloc.is_default() {
self.func.srclocs[inst] = self.srcloc;
}
&mut self.func.dfg &mut self.func.dfg
} }
} }
@@ -80,6 +98,7 @@ impl<'c, 'f> ir::InstInserterBase<'c> for &'c mut FuncCursor<'f> {
/// public `pos.func` member. /// public `pos.func` member.
pub struct EncCursor<'f> { pub struct EncCursor<'f> {
pos: CursorPosition, pos: CursorPosition,
srcloc: ir::SourceLoc,
built_inst: Option<ir::Inst>, built_inst: Option<ir::Inst>,
/// The referenced function. /// The referenced function.
@@ -94,12 +113,18 @@ impl<'f> EncCursor<'f> {
pub fn new(func: &'f mut ir::Function, isa: &'f TargetIsa) -> EncCursor<'f> { pub fn new(func: &'f mut ir::Function, isa: &'f TargetIsa) -> EncCursor<'f> {
EncCursor { EncCursor {
pos: CursorPosition::Nowhere, pos: CursorPosition::Nowhere,
srcloc: Default::default(),
built_inst: None, built_inst: None,
func, func,
isa, isa,
} }
} }
/// Use the source location of `inst` for future instructions.
pub fn use_srcloc(&mut self, inst: ir::Inst) {
self.srcloc = self.func.srclocs[inst];
}
/// Create an instruction builder that will insert an encoded instruction at the current /// Create an instruction builder that will insert an encoded instruction at the current
/// position. /// position.
/// ///
@@ -134,6 +159,14 @@ impl<'f> Cursor for EncCursor<'f> {
self.pos = pos self.pos = pos
} }
fn srcloc(&self) -> ir::SourceLoc {
self.srcloc
}
fn set_srcloc(&mut self, srcloc: ir::SourceLoc) {
self.srcloc = srcloc;
}
fn layout(&self) -> &ir::Layout { fn layout(&self) -> &ir::Layout {
&self.func.layout &self.func.layout
} }
@@ -161,6 +194,10 @@ impl<'c, 'f> ir::InstInserterBase<'c> for &'c mut EncCursor<'f> {
self.insert_inst(inst); self.insert_inst(inst);
self.built_inst = Some(inst); self.built_inst = Some(inst);
if !self.srcloc.is_default() {
self.func.srclocs[inst] = self.srcloc;
}
// Assign an encoding. // Assign an encoding.
match self.isa.encode( match self.isa.encode(
&self.func.dfg, &self.func.dfg,

View File

@@ -7,7 +7,7 @@ use std::cmp;
use std::iter::{Iterator, IntoIterator}; use std::iter::{Iterator, IntoIterator};
use entity::EntityMap; use entity::EntityMap;
use packed_option::PackedOption; use packed_option::PackedOption;
use ir::{Ebb, Inst, Type, DataFlowGraph}; use ir::{Ebb, Inst, Type, DataFlowGraph, SourceLoc, SourceLocs};
use ir::builder::InstInserterBase; use ir::builder::InstInserterBase;
use ir::progpoint::{ProgramOrder, ExpandedProgramPoint}; use ir::progpoint::{ProgramOrder, ExpandedProgramPoint};
@@ -676,7 +676,10 @@ impl<'f> DoubleEndedIterator for Insts<'f> {
pub struct Cursor<'f> { pub struct Cursor<'f> {
/// Borrowed function layout. Public so it can be re-borrowed from this cursor. /// Borrowed function layout. Public so it can be re-borrowed from this cursor.
pub layout: &'f mut Layout, pub layout: &'f mut Layout,
/// Borrowed source locations.
pub srclocs: Option<&'f mut SourceLocs>,
pos: CursorPosition, pos: CursorPosition,
srcloc: SourceLoc,
} }
/// The possible positions of a cursor. /// The possible positions of a cursor.
@@ -703,12 +706,39 @@ pub trait CursorBase {
/// Set the current position. /// Set the current position.
fn set_position(&mut self, pos: CursorPosition); fn set_position(&mut self, pos: CursorPosition);
/// Get the source location that should be assigned to new instructions.
fn srcloc(&self) -> SourceLoc;
/// Set the source location that should be assigned to new instructions.
fn set_srcloc(&mut self, srcloc: SourceLoc);
/// Borrow a reference to the function layout that this cursor is navigating. /// Borrow a reference to the function layout that this cursor is navigating.
fn layout(&self) -> &Layout; fn layout(&self) -> &Layout;
/// Borrow a mutable reference to the function layout that this cursor is navigating. /// Borrow a mutable reference to the function layout that this cursor is navigating.
fn layout_mut(&mut self) -> &mut Layout; fn layout_mut(&mut self) -> &mut Layout;
/// Exchange this cursor for one with a set source location.
///
/// This is intended to be used as a builder method:
///
/// ```
/// # use cretonne::ir::{Function, Ebb, SourceLoc};
/// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, srcloc: SourceLoc) {
/// let mut pos = FuncCursor::new(func).with_srcloc(srcloc);
///
/// // Use `pos`...
/// }
/// ```
fn with_srcloc(mut self, srcloc: SourceLoc) -> Self
where
Self: Sized,
{
self.set_srcloc(srcloc);
self
}
/// Rebuild this cursor positioned at `pos`. /// Rebuild this cursor positioned at `pos`.
fn at_position(mut self, pos: CursorPosition) -> Self fn at_position(mut self, pos: CursorPosition) -> Self
where where
@@ -724,9 +754,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb, Inst}; /// # use cretonne::ir::{Function, Ebb, Inst};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, inst: Inst) { /// fn edit_func(func: &mut Function, inst: Inst) {
/// let mut pos = Cursor::new(&mut func.layout).at_inst(inst); /// let mut pos = FuncCursor::new(func).at_inst(inst);
/// ///
/// // Use `pos`... /// // Use `pos`...
/// } /// }
@@ -747,9 +777,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb, Inst}; /// # use cretonne::ir::{Function, Ebb, Inst};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) { /// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = Cursor::new(&mut func.layout).at_first_insertion_point(ebb); /// let mut pos = FuncCursor::new(func).at_first_insertion_point(ebb);
/// ///
/// // Use `pos`... /// // Use `pos`...
/// } /// }
@@ -768,9 +798,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb, Inst}; /// # use cretonne::ir::{Function, Ebb, Inst};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) { /// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = Cursor::new(&mut func.layout).at_first_inst(ebb); /// let mut pos = FuncCursor::new(func).at_first_inst(ebb);
/// ///
/// // Use `pos`... /// // Use `pos`...
/// } /// }
@@ -789,9 +819,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb, Inst}; /// # use cretonne::ir::{Function, Ebb, Inst};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) { /// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = Cursor::new(&mut func.layout).at_last_inst(ebb); /// let mut pos = FuncCursor::new(func).at_last_inst(ebb);
/// ///
/// // Use `pos`... /// // Use `pos`...
/// } /// }
@@ -810,9 +840,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb, Inst}; /// # use cretonne::ir::{Function, Ebb, Inst};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, inst: Inst) { /// fn edit_func(func: &mut Function, inst: Inst) {
/// let mut pos = Cursor::new(&mut func.layout).after_inst(inst); /// let mut pos = FuncCursor::new(func).after_inst(inst);
/// ///
/// // Use `pos`... /// // Use `pos`...
/// } /// }
@@ -831,9 +861,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb, Inst}; /// # use cretonne::ir::{Function, Ebb, Inst};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) { /// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = Cursor::new(&mut func.layout).at_top(ebb); /// let mut pos = FuncCursor::new(func).at_top(ebb);
/// ///
/// // Use `pos`... /// // Use `pos`...
/// } /// }
@@ -852,9 +882,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb, Inst}; /// # use cretonne::ir::{Function, Ebb, Inst};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function, ebb: Ebb) { /// fn edit_func(func: &mut Function, ebb: Ebb) {
/// let mut pos = Cursor::new(&mut func.layout).at_bottom(ebb); /// let mut pos = FuncCursor::new(func).at_bottom(ebb);
/// ///
/// // Use `pos`... /// // Use `pos`...
/// } /// }
@@ -957,9 +987,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb}; /// # use cretonne::ir::{Function, Ebb};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function) { /// fn edit_func(func: &mut Function) {
/// let mut cursor = Cursor::new(&mut func.layout); /// let mut cursor = FuncCursor::new(func);
/// while let Some(ebb) = cursor.next_ebb() { /// while let Some(ebb) = cursor.next_ebb() {
/// // Edit ebb. /// // Edit ebb.
/// } /// }
@@ -990,9 +1020,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb}; /// # use cretonne::ir::{Function, Ebb};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function) { /// fn edit_func(func: &mut Function) {
/// let mut cursor = Cursor::new(&mut func.layout); /// let mut cursor = FuncCursor::new(func);
/// while let Some(ebb) = cursor.prev_ebb() { /// while let Some(ebb) = cursor.prev_ebb() {
/// // Edit ebb. /// // Edit ebb.
/// } /// }
@@ -1027,9 +1057,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb}; /// # use cretonne::ir::{Function, Ebb};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_ebb(func: &mut Function, ebb: Ebb) { /// fn edit_ebb(func: &mut Function, ebb: Ebb) {
/// let mut cursor = Cursor::new(&mut func.layout).at_top(ebb); /// let mut cursor = FuncCursor::new(func).at_top(ebb);
/// while let Some(inst) = cursor.next_inst() { /// while let Some(inst) = cursor.next_inst() {
/// // Edit instructions... /// // Edit instructions...
/// } /// }
@@ -1041,9 +1071,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb}; /// # use cretonne::ir::{Function, Ebb};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_func(func: &mut Function) { /// fn edit_func(func: &mut Function) {
/// let mut cursor = Cursor::new(&mut func.layout); /// let mut cursor = FuncCursor::new(func);
/// while let Some(ebb) = cursor.next_ebb() { /// while let Some(ebb) = cursor.next_ebb() {
/// while let Some(inst) = cursor.next_inst() { /// while let Some(inst) = cursor.next_inst() {
/// // Edit instructions... /// // Edit instructions...
@@ -1095,9 +1125,9 @@ pub trait CursorBase {
/// ///
/// ``` /// ```
/// # use cretonne::ir::{Function, Ebb}; /// # use cretonne::ir::{Function, Ebb};
/// # use cretonne::ir::layout::{Cursor, CursorBase}; /// # use cretonne::cursor::{Cursor, FuncCursor};
/// fn edit_ebb(func: &mut Function, ebb: Ebb) { /// fn edit_ebb(func: &mut Function, ebb: Ebb) {
/// let mut cursor = Cursor::new(&mut func.layout).at_bottom(ebb); /// let mut cursor = FuncCursor::new(func).at_bottom(ebb);
/// while let Some(inst) = cursor.prev_inst() { /// while let Some(inst) = cursor.prev_inst() {
/// // Edit instructions... /// // Edit instructions...
/// } /// }
@@ -1213,6 +1243,14 @@ impl<'f> CursorBase for Cursor<'f> {
self.pos = pos; self.pos = pos;
} }
fn srcloc(&self) -> SourceLoc {
self.srcloc
}
fn set_srcloc(&mut self, srcloc: SourceLoc) {
self.srcloc = srcloc
}
fn layout(&self) -> &Layout { fn layout(&self) -> &Layout {
self.layout self.layout
} }
@@ -1225,10 +1263,22 @@ impl<'f> CursorBase for Cursor<'f> {
impl<'f> Cursor<'f> { impl<'f> Cursor<'f> {
/// Create a new `Cursor` for `layout`. /// Create a new `Cursor` for `layout`.
/// The cursor holds a mutable reference to `layout` for its entire lifetime. /// The cursor holds a mutable reference to `layout` for its entire lifetime.
pub fn new(layout: &'f mut Layout) -> Cursor { pub fn new<SL: Into<Option<&'f mut SourceLocs>>>(
layout: &'f mut Layout,
srclocs: SL,
) -> Cursor<'f> {
Cursor { Cursor {
layout, layout,
srclocs: srclocs.into(),
pos: CursorPosition::Nowhere, pos: CursorPosition::Nowhere,
srcloc: Default::default(),
}
}
/// Use the source location of `inst` for future instructions.
pub fn use_srcloc(&mut self, inst: Inst) {
if let Some(ref mut ss) = self.srclocs {
self.srcloc = ss[inst];
} }
} }
} }
@@ -1263,6 +1313,13 @@ impl<'c, 'fc: 'c, 'fd> InstInserterBase<'fd> for LayoutCursorInserter<'c, 'fc, '
fn insert_built_inst(self, inst: Inst, _ctrl_typevar: Type) -> &'fd mut DataFlowGraph { fn insert_built_inst(self, inst: Inst, _ctrl_typevar: Type) -> &'fd mut DataFlowGraph {
self.pos.insert_inst(inst); self.pos.insert_inst(inst);
if !self.pos.srcloc.is_default() {
if let Some(ref mut ss) = self.pos.srclocs {
ss[inst] = self.pos.srcloc;
} else {
panic!("layout::Cursor missing a SourceLocs reference");
}
}
self.dfg self.dfg
} }
} }
@@ -1300,7 +1357,7 @@ mod tests {
} }
// Check backwards linkage with a cursor. // Check backwards linkage with a cursor.
let mut cur = Cursor::new(layout); let mut cur = Cursor::new(layout, None);
for &(ebb, insts) in ebbs.into_iter().rev() { for &(ebb, insts) in ebbs.into_iter().rev() {
assert_eq!(cur.prev_ebb(), Some(ebb)); assert_eq!(cur.prev_ebb(), Some(ebb));
for &inst in insts.into_iter().rev() { for &inst in insts.into_iter().rev() {
@@ -1356,7 +1413,7 @@ mod tests {
} }
// Test cursor positioning. // Test cursor positioning.
let mut cur = Cursor::new(&mut layout); let mut cur = Cursor::new(&mut layout, None);
assert_eq!(cur.position(), CursorPosition::Nowhere); assert_eq!(cur.position(), CursorPosition::Nowhere);
assert_eq!(cur.next_inst(), None); assert_eq!(cur.next_inst(), None);
assert_eq!(cur.position(), CursorPosition::Nowhere); assert_eq!(cur.position(), CursorPosition::Nowhere);
@@ -1474,7 +1531,7 @@ mod tests {
verify(&mut layout, &[(e1, &[i1, i2, i0])]); verify(&mut layout, &[(e1, &[i1, i2, i0])]);
// Test cursor positioning. // Test cursor positioning.
let mut cur = Cursor::new(&mut layout).at_top(e1); let mut cur = Cursor::new(&mut layout, None).at_top(e1);
assert_eq!(cur.position(), CursorPosition::Before(e1)); assert_eq!(cur.position(), CursorPosition::Before(e1));
assert_eq!(cur.prev_inst(), None); assert_eq!(cur.prev_inst(), None);
assert_eq!(cur.position(), CursorPosition::Before(e1)); assert_eq!(cur.position(), CursorPosition::Before(e1));
@@ -1594,7 +1651,7 @@ mod tests {
assert_eq!(layout.inst_ebb(i0), Some(e1)); assert_eq!(layout.inst_ebb(i0), Some(e1));
{ {
let mut cur = Cursor::new(&mut layout); let mut cur = Cursor::new(&mut layout, None);
assert_eq!(cur.next_ebb(), Some(e0)); assert_eq!(cur.next_ebb(), Some(e0));
assert_eq!(cur.next_inst(), None); assert_eq!(cur.next_inst(), None);
assert_eq!(cur.next_ebb(), Some(e1)); assert_eq!(cur.next_ebb(), Some(e1));
@@ -1622,7 +1679,7 @@ mod tests {
assert_eq!(layout.inst_ebb(i3), Some(e2)); assert_eq!(layout.inst_ebb(i3), Some(e2));
{ {
let mut cur = Cursor::new(&mut layout); let mut cur = Cursor::new(&mut layout, None);
assert_eq!(cur.next_ebb(), Some(e0)); assert_eq!(cur.next_ebb(), Some(e0));
assert_eq!(cur.next_inst(), Some(i1)); assert_eq!(cur.next_inst(), Some(i1));
assert_eq!(cur.next_inst(), None); assert_eq!(cur.next_inst(), None);

View File

@@ -62,7 +62,7 @@ fn legalize_entry_arguments(func: &mut Function, entry: Ebb) {
// Insert position for argument conversion code. // Insert position for argument conversion code.
// We want to insert instructions before the first instruction in the entry block. // We want to insert instructions before the first instruction in the entry block.
// If the entry block is empty, append instructions to it instead. // If the entry block is empty, append instructions to it instead.
let mut pos = Cursor::new(&mut func.layout).at_first_inst(entry); let mut pos = Cursor::new(&mut func.layout, &mut func.srclocs).at_first_inst(entry);
// Keep track of the argument types in the ABI-legalized signature. // Keep track of the argument types in the ABI-legalized signature.
let abi_types = &func.signature.argument_types; let abi_types = &func.signature.argument_types;
@@ -488,7 +488,8 @@ fn legalize_inst_arguments<ArgType>(
/// Returns `true` if any instructions were inserted. /// Returns `true` if any instructions were inserted.
pub fn handle_call_abi(mut inst: Inst, func: &mut Function, cfg: &ControlFlowGraph) -> bool { pub fn handle_call_abi(mut inst: Inst, func: &mut Function, cfg: &ControlFlowGraph) -> bool {
let dfg = &mut func.dfg; let dfg = &mut func.dfg;
let pos = &mut Cursor::new(&mut func.layout).at_inst(inst); let pos = &mut Cursor::new(&mut func.layout, &mut func.srclocs).at_inst(inst);
pos.use_srcloc(inst);
// Start by checking if the argument types already match the signature. // Start by checking if the argument types already match the signature.
let sig_ref = match check_call_signature(dfg, inst) { let sig_ref = match check_call_signature(dfg, inst) {
@@ -530,7 +531,8 @@ pub fn handle_call_abi(mut inst: Inst, func: &mut Function, cfg: &ControlFlowGra
pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph) -> bool { pub fn handle_return_abi(inst: Inst, func: &mut Function, cfg: &ControlFlowGraph) -> bool {
let dfg = &mut func.dfg; let dfg = &mut func.dfg;
let sig = &mut func.signature; let sig = &mut func.signature;
let pos = &mut Cursor::new(&mut func.layout).at_inst(inst); let pos = &mut Cursor::new(&mut func.layout, &mut func.srclocs).at_inst(inst);
pos.use_srcloc(inst);
// Check if the returned types already match the signature. // Check if the returned types already match the signature.
if check_return_signature(dfg, inst, sig) { if check_return_signature(dfg, inst, sig) {

View File

@@ -51,6 +51,7 @@ fn deref_addr(inst: ir::Inst, func: &mut ir::Function, base: ir::GlobalVar, offs
// detects any cycles in the `deref` globals. // detects any cycles in the `deref` globals.
let ptr_ty = func.dfg.value_type(func.dfg.first_result(inst)); let ptr_ty = func.dfg.value_type(func.dfg.first_result(inst));
let mut pos = FuncCursor::new(func).at_inst(inst); let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
let base_addr = pos.ins().global_addr(ptr_ty, base); let base_addr = pos.ins().global_addr(ptr_ty, base);
// TODO: We could probably set both `notrap` and `aligned` on this load instruction. // TODO: We could probably set both `notrap` and `aligned` on this load instruction.

View File

@@ -48,6 +48,7 @@ fn dynamic_addr(
let addr_ty = func.dfg.value_type(func.dfg.first_result(inst)); let addr_ty = func.dfg.value_type(func.dfg.first_result(inst));
let min_size = func.heaps[heap].min_size.into(); let min_size = func.heaps[heap].min_size.into();
let mut pos = FuncCursor::new(func).at_inst(inst); let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
// Start with the bounds check. Trap if `offset + size > bound`. // Start with the bounds check. Trap if `offset + size > bound`.
let bound_addr = pos.ins().global_addr(addr_ty, bound_gv); let bound_addr = pos.ins().global_addr(addr_ty, bound_gv);
@@ -99,6 +100,7 @@ fn static_addr(
let offset_ty = func.dfg.value_type(offset); let offset_ty = func.dfg.value_type(offset);
let addr_ty = func.dfg.value_type(func.dfg.first_result(inst)); let addr_ty = func.dfg.value_type(func.dfg.first_result(inst));
let mut pos = FuncCursor::new(func).at_inst(inst); let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
// Start with the bounds check. Trap if `offset + size > bound`. // Start with the bounds check. Trap if `offset + size > bound`.
if size > bound { if size > bound {
@@ -147,6 +149,7 @@ fn offset_addr(
func: &mut ir::Function, func: &mut ir::Function,
) { ) {
let mut pos = FuncCursor::new(func).at_inst(inst); let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
// Convert `offset` to `addr_ty`. // Convert `offset` to `addr_ty`.
if offset_ty != addr_ty { if offset_ty != addr_ty {

View File

@@ -138,6 +138,7 @@ fn expand_cond_trap(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFl
} }
let mut pos = FuncCursor::new(func).after_inst(inst); let mut pos = FuncCursor::new(func).after_inst(inst);
pos.use_srcloc(inst);
pos.ins().trap(code); pos.ins().trap(code);
pos.insert_ebb(new_ebb); pos.insert_ebb(new_ebb);
@@ -154,6 +155,7 @@ fn expand_fconst(inst: ir::Inst, func: &mut ir::Function, _cfg: &mut ControlFlow
// In the future, we may want to generate constant pool entries for these constants, but for // In the future, we may want to generate constant pool entries for these constants, but for
// now use an `iconst` and a bit cast. // now use an `iconst` and a bit cast.
let mut pos = FuncCursor::new(func).at_inst(inst); let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
let ival = match pos.func.dfg[inst] { let ival = match pos.func.dfg[inst] {
ir::InstructionData::UnaryIeee32 { ir::InstructionData::UnaryIeee32 {
opcode: ir::Opcode::F32const, opcode: ir::Opcode::F32const,

View File

@@ -120,7 +120,7 @@ fn split_any(
concat: Opcode, concat: Opcode,
) -> (Value, Value) { ) -> (Value, Value) {
let mut repairs = Vec::new(); let mut repairs = Vec::new();
let mut pos = ir::Cursor::new(layout).at_position(pos); let mut pos = ir::Cursor::new(layout, None).at_position(pos);
let result = split_value(dfg, &mut pos, value, concat, &mut repairs); let result = split_value(dfg, &mut pos, value, concat, &mut repairs);
// We have split the value requested, and now we may need to fix some EBB predecessors. // We have split the value requested, and now we may need to fix some EBB predecessors.

View File

@@ -148,8 +148,9 @@ impl<'a> Context<'a> {
self.divert.clear(); self.divert.clear();
// Now go through the instructions in `ebb` and color the values they define. // Now go through the instructions in `ebb` and color the values they define.
let mut pos = Cursor::new(&mut func.layout).at_top(ebb); let mut pos = Cursor::new(&mut func.layout, &mut func.srclocs).at_top(ebb);
while let Some(inst) = pos.next_inst() { while let Some(inst) = pos.next_inst() {
pos.use_srcloc(inst);
if let Some(constraints) = self.encinfo.operand_constraints(func.encodings[inst]) { if let Some(constraints) = self.encinfo.operand_constraints(func.encodings[inst]) {
self.visit_inst( self.visit_inst(
inst, inst,