Add per-instruction source locations to the Cretonne IR.

Source locations are opaque 32-bit entities that can be used to
represent WebAssembly byte-code positions or some other source
identifier.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-20 16:42:30 -07:00
parent 16eb689dd1
commit b2a314a229
8 changed files with 156 additions and 24 deletions

View File

@@ -6,7 +6,7 @@
use entity::{PrimaryMap, EntityMap};
use ir;
use ir::{FunctionName, CallConv, Signature, DataFlowGraph, Layout};
use ir::{InstEncodings, ValueLocations, JumpTables, StackSlots, EbbOffsets};
use ir::{InstEncodings, ValueLocations, JumpTables, StackSlots, EbbOffsets, SourceLocs};
use ir::{Ebb, JumpTableData, JumpTable, StackSlotData, StackSlot, SigRef, ExtFuncData, FuncRef,
GlobalVarData, GlobalVar, HeapData, Heap};
use isa::TargetIsa;
@@ -56,6 +56,12 @@ pub struct Function {
/// computes it, and it can easily be recomputed by calling that function. It is not included
/// in the textual IL format.
pub offsets: EbbOffsets,
/// Source locations.
///
/// Track the original source location for each instruction. The source locations are not
/// interpreted by Cretonne, only preserved.
pub srclocs: SourceLocs,
}
impl Function {
@@ -73,6 +79,7 @@ impl Function {
encodings: EntityMap::new(),
locations: EntityMap::new(),
offsets: EntityMap::new(),
srclocs: EntityMap::new(),
}
}
@@ -88,6 +95,7 @@ impl Function {
self.encodings.clear();
self.locations.clear();
self.offsets.clear();
self.srclocs.clear();
}
/// Create a new empty, anonymous function with a native calling convention.

View File

@@ -17,6 +17,7 @@ mod globalvar;
mod heap;
mod memflags;
mod progpoint;
mod sourceloc;
mod trapcode;
mod valueloc;
@@ -34,6 +35,7 @@ pub use ir::jumptable::JumpTableData;
pub use ir::layout::{Layout, CursorBase, Cursor};
pub use ir::memflags::MemFlags;
pub use ir::progpoint::{ProgramPoint, ProgramOrder, ExpandedProgramPoint};
pub use ir::sourceloc::SourceLoc;
pub use ir::stackslot::{StackSlots, StackSlotKind, StackSlotData};
pub use ir::trapcode::TrapCode;
pub use ir::types::Type;
@@ -54,3 +56,6 @@ pub type InstEncodings = EntityMap<Inst, isa::Encoding>;
/// Code offsets for EBBs.
pub type EbbOffsets = EntityMap<Ebb, binemit::CodeOffset>;
/// Source locations for instructions.
pub type SourceLocs = EntityMap<Inst, SourceLoc>;

View File

@@ -0,0 +1,62 @@
//! Source locations.
//!
//! Cretonne tracks the original source location of each instruction, and preserves the source
//! location when instructions are transformed.
use std::fmt;
/// A source location.
///
/// This is an opaque 32-bit number attached to each Cretonne IL instruction. Cretonne does not
/// interpret source locations in any way, they are simply preserved from the input to the output.
///
/// The default source location uses the all-ones bit pattern `!0`. It is used for instructions
/// that can't be given a real source location.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SourceLoc(u32);
impl SourceLoc {
/// Create a new source location with the given bits.
pub fn new(bits: u32) -> SourceLoc {
SourceLoc(bits)
}
/// Is this the default source location?
pub fn is_default(self) -> bool {
self == Default::default()
}
/// Read the bits of this source location.
pub fn bits(self) -> u32 {
self.0
}
}
impl Default for SourceLoc {
fn default() -> SourceLoc {
SourceLoc(!0)
}
}
impl fmt::Display for SourceLoc {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_default() {
write!(f, "@-")
} else {
write!(f, "@{:04x}", self.0)
}
}
}
#[cfg(test)]
mod tests {
use ir::SourceLoc;
#[test]
fn display() {
assert_eq!(SourceLoc::default().to_string(), "@-");
assert_eq!(SourceLoc::new(0).to_string(), "@0000");
assert_eq!(SourceLoc::new(16).to_string(), "@0010");
assert_eq!(SourceLoc::new(0xabcdef).to_string(), "@abcdef");
}
}