mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-21 22:34:34 +00:00
custom_insts: make SetDebugSrcLoc
have a range instead of just the starting location.
This commit is contained in:
parent
c5dcd035b1
commit
344605fde8
@ -680,13 +680,18 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
if span.is_dummy() {
|
||||
self.custom_inst(void_ty, CustomInst::ClearDebugSrcLoc);
|
||||
} else {
|
||||
let (file, line, col) = self.builder.file_line_col_for_op_line(span);
|
||||
let (file, line_col_range) = self.builder.file_line_col_range_for_debuginfo(span);
|
||||
let ((line_start, col_start), (line_end, col_end)) =
|
||||
(line_col_range.start, line_col_range.end);
|
||||
|
||||
self.custom_inst(
|
||||
void_ty,
|
||||
CustomInst::SetDebugSrcLoc {
|
||||
file: Operand::IdRef(file.file_name_op_string_id),
|
||||
line: Operand::IdRef(self.const_u32(line).def(self)),
|
||||
col: Operand::IdRef(self.const_u32(col).def(self)),
|
||||
line_start: Operand::IdRef(self.const_u32(line_start).def(self)),
|
||||
line_end: Operand::IdRef(self.const_u32(line_end).def(self)),
|
||||
col_start: Operand::IdRef(self.const_u32(col_start).def(self)),
|
||||
col_end: Operand::IdRef(self.const_u32(col_end).def(self)),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -696,7 +701,9 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
|
||||
if span.is_dummy() {
|
||||
self.emit().no_line();
|
||||
} else {
|
||||
let (file, line, col) = self.builder.file_line_col_for_op_line(span);
|
||||
let (file, line_col_range) = self.builder.file_line_col_range_for_debuginfo(span);
|
||||
let (line, col) = line_col_range.start;
|
||||
|
||||
self.emit().line(file.file_name_op_string_id, line, col);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ use std::assert_matches::assert_matches;
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter;
|
||||
use std::ops::Range;
|
||||
use std::str;
|
||||
use std::{fs::File, io::Write, path::Path};
|
||||
|
||||
@ -678,13 +679,28 @@ impl<'tcx> BuilderSpirv<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn file_line_col_for_op_line(&self, span: Span) -> (DebugFileSpirv<'tcx>, u32, u32) {
|
||||
let loc = self.source_map.lookup_char_pos(span.lo());
|
||||
(
|
||||
self.def_debug_file(loc.file),
|
||||
loc.line as u32,
|
||||
loc.col_display as u32,
|
||||
)
|
||||
pub fn file_line_col_range_for_debuginfo(
|
||||
&self,
|
||||
span: Span,
|
||||
) -> (DebugFileSpirv<'tcx>, Range<(u32, u32)>) {
|
||||
let (lo, hi) = (span.lo(), span.hi());
|
||||
|
||||
let lo_loc = self.source_map.lookup_char_pos(lo);
|
||||
let lo_line_col = (lo_loc.line as u32, lo_loc.col_display as u32);
|
||||
|
||||
// Only use `hi` if the span is actually a range within a file.
|
||||
let hi_line_col = if lo <= hi {
|
||||
let hi_loc = self.source_map.lookup_char_pos(hi);
|
||||
if lo_loc.file.start_pos == hi_loc.file.start_pos {
|
||||
(hi_loc.line as u32, hi_loc.col_display as u32)
|
||||
} else {
|
||||
lo_line_col
|
||||
}
|
||||
} else {
|
||||
lo_line_col
|
||||
};
|
||||
|
||||
(self.def_debug_file(lo_loc.file), lo_line_col..hi_line_col)
|
||||
}
|
||||
|
||||
fn def_debug_file(&self, sf: Lrc<SourceFile>) -> DebugFileSpirv<'tcx> {
|
||||
|
@ -124,18 +124,20 @@ impl<'a> CustomDecoration<'a> for ZombieDecoration<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Equivalent of `OpLine`, for the places where `rspirv` currently doesn't let
|
||||
/// us actually emit a real `OpLine`, the way generating SPIR-T directly might.
|
||||
/// Equivalent of `CustomInst::SetDebugSrcLoc` (see `crate::custom_insts`),
|
||||
/// for global definitions (i.e. outside functions), where limitations of
|
||||
/// `rspirv`/`spirt` prevent us from using anything other than decorations.
|
||||
//
|
||||
// NOTE(eddyb) by keeping `line`+`col`, we mimick `OpLine` limitations
|
||||
// (which could be lifted in the future using custom SPIR-T debuginfo).
|
||||
// NOTE(eddyb) `NonSemantic.Shader.DebugInfo`'s `DebugLine` has both start & end,
|
||||
// might be good to invest in SPIR-T being able to use NonSemantic debuginfo.
|
||||
// NOTE(eddyb) `CustomInst::SetDebugSrcLoc` is modelled after `DebugLine` from
|
||||
// `NonSemantic.Shader.DebugInfo`, might be good to invest in SPIR-T being able
|
||||
// to use `NonSemantic.Shader.DebugInfo` directly, in all situations.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct SrcLocDecoration<'a> {
|
||||
pub file_name: &'a str,
|
||||
pub line: u32,
|
||||
pub col: u32,
|
||||
pub line_start: u32,
|
||||
pub line_end: u32,
|
||||
pub col_start: u32,
|
||||
pub col_end: u32,
|
||||
}
|
||||
|
||||
impl<'a> CustomDecoration<'a> for SrcLocDecoration<'a> {
|
||||
@ -144,24 +146,33 @@ impl<'a> CustomDecoration<'a> for SrcLocDecoration<'a> {
|
||||
fn encode(self, w: &mut impl fmt::Write) -> fmt::Result {
|
||||
let Self {
|
||||
file_name,
|
||||
line,
|
||||
col,
|
||||
line_start,
|
||||
line_end,
|
||||
col_start,
|
||||
col_end,
|
||||
} = self;
|
||||
write!(w, "{file_name}:{line}:{col}")
|
||||
write!(
|
||||
w,
|
||||
"{file_name}:{line_start}:{col_start}-{line_end}:{col_end}"
|
||||
)
|
||||
}
|
||||
fn decode(s: &'a str) -> Self {
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct InvalidSrcLoc<'a>(&'a str);
|
||||
let err = InvalidSrcLoc(s);
|
||||
|
||||
let (s, col) = s.rsplit_once(':').ok_or(err).unwrap();
|
||||
let (s, line) = s.rsplit_once(':').ok_or(err).unwrap();
|
||||
let (s, col_end) = s.rsplit_once(':').ok_or(err).unwrap();
|
||||
let (s, line_end) = s.rsplit_once('-').ok_or(err).unwrap();
|
||||
let (s, col_start) = s.rsplit_once(':').ok_or(err).unwrap();
|
||||
let (s, line_start) = s.rsplit_once(':').ok_or(err).unwrap();
|
||||
let file_name = s;
|
||||
|
||||
Self {
|
||||
file_name,
|
||||
line: line.parse().unwrap(),
|
||||
col: col.parse().unwrap(),
|
||||
line_start: line_start.parse().unwrap(),
|
||||
line_end: line_end.parse().unwrap(),
|
||||
col_start: col_start.parse().unwrap(),
|
||||
col_end: col_end.parse().unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,12 +185,16 @@ impl<'tcx> SrcLocDecoration<'tcx> {
|
||||
return None;
|
||||
}
|
||||
|
||||
let (file, line, col) = builder.file_line_col_for_op_line(span);
|
||||
let (file, line_col_range) = builder.file_line_col_range_for_debuginfo(span);
|
||||
let ((line_start, col_start), (line_end, col_end)) =
|
||||
(line_col_range.start, line_col_range.end);
|
||||
|
||||
Some(Self {
|
||||
file_name: file.file_name,
|
||||
line,
|
||||
col,
|
||||
line_start,
|
||||
line_end,
|
||||
col_start,
|
||||
col_end,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -361,24 +376,37 @@ impl<'a> SpanRegenerator<'a> {
|
||||
.spv_debug_info
|
||||
.get_or_insert_with(|| SpvDebugInfo::collect(self.module));
|
||||
|
||||
let (file_id, line, col) = match inst.class.opcode {
|
||||
Op::Line => (
|
||||
inst.operands[0].unwrap_id_ref(),
|
||||
inst.operands[1].unwrap_literal_int32(),
|
||||
inst.operands[2].unwrap_literal_int32(),
|
||||
),
|
||||
let (file_id, line_start, line_end, col_start, col_end) = match inst.class.opcode {
|
||||
Op::Line => {
|
||||
let file = inst.operands[0].unwrap_id_ref();
|
||||
let line = inst.operands[1].unwrap_literal_int32();
|
||||
let col = inst.operands[2].unwrap_literal_int32();
|
||||
(file, line, line, col, col)
|
||||
}
|
||||
Op::ExtInst
|
||||
if Some(inst.operands[0].unwrap_id_ref())
|
||||
== spv_debug_info.custom_ext_inst_set_import =>
|
||||
{
|
||||
match CustomInst::decode(inst) {
|
||||
CustomInst::SetDebugSrcLoc { file, line, col } => (
|
||||
CustomInst::SetDebugSrcLoc {
|
||||
file,
|
||||
line_start,
|
||||
line_end,
|
||||
col_start,
|
||||
col_end,
|
||||
} => {
|
||||
let const_u32 = |operand: Operand| {
|
||||
spv_debug_info.id_to_op_constant_operand[&operand.unwrap_id_ref()]
|
||||
.unwrap_literal_int32()
|
||||
};
|
||||
(
|
||||
file.unwrap_id_ref(),
|
||||
spv_debug_info.id_to_op_constant_operand[&line.unwrap_id_ref()]
|
||||
.unwrap_literal_int32(),
|
||||
spv_debug_info.id_to_op_constant_operand[&col.unwrap_id_ref()]
|
||||
.unwrap_literal_int32(),
|
||||
),
|
||||
const_u32(line_start),
|
||||
const_u32(line_end),
|
||||
const_u32(col_start),
|
||||
const_u32(col_end),
|
||||
)
|
||||
}
|
||||
custom_inst @ CustomInst::ClearDebugSrcLoc => {
|
||||
unreachable!("src_loc_from_debug_inst({inst:?} => {custom_inst:?})")
|
||||
}
|
||||
@ -392,8 +420,10 @@ impl<'a> SpanRegenerator<'a> {
|
||||
.get(&file_id)
|
||||
.map(|&file_name| SrcLocDecoration {
|
||||
file_name,
|
||||
line,
|
||||
col,
|
||||
line_start,
|
||||
line_end,
|
||||
col_start,
|
||||
col_end,
|
||||
})
|
||||
}
|
||||
|
||||
@ -455,12 +485,18 @@ impl<'a> SpanRegenerator<'a> {
|
||||
pub fn src_loc_to_rustc(&mut self, src_loc: SrcLocDecoration<'_>) -> Option<Span> {
|
||||
let SrcLocDecoration {
|
||||
file_name,
|
||||
line,
|
||||
col,
|
||||
line_start,
|
||||
line_end,
|
||||
col_start,
|
||||
col_end,
|
||||
} = src_loc;
|
||||
|
||||
let file = self.regenerate_rustc_source_file(file_name)?;
|
||||
|
||||
// FIXME(eddyb) avoid some of the duplicated work when this closure is
|
||||
// called with `line`/`col` values that are near eachother - thankfully,
|
||||
// this code should only be hit on the error reporting path anyway.
|
||||
let line_col_to_bpos = |line: u32, col: u32| {
|
||||
let line_bpos_range = file.line_bounds(line.checked_sub(1)? as usize);
|
||||
|
||||
// Find the special cases (`MultiByteChar`s/`NonNarrowChar`s) in the line.
|
||||
@ -514,7 +550,12 @@ impl<'a> SpanRegenerator<'a> {
|
||||
cur_bpos.0 += mbc_nnc.as_ref().left().map_or(1, |mbc| mbc.bytes as u32);
|
||||
cur_col_display += mbc_nnc.as_ref().right().map_or(1, |nnc| nnc.width() as u32);
|
||||
}
|
||||
Some(cur_bpos)
|
||||
};
|
||||
|
||||
Some(Span::with_root_ctxt(cur_bpos, cur_bpos))
|
||||
Some(Span::with_root_ctxt(
|
||||
line_col_to_bpos(line_start, col_start)?,
|
||||
line_col_to_bpos(line_end, col_end)?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -109,10 +109,11 @@ macro_rules! def_custom_insts {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(eddyb) several of these are similar to `NonSemantic.Shader.DebugInfo.100`
|
||||
// instructions, but simpler (to aid implementation, for now).
|
||||
def_custom_insts! {
|
||||
// `OpLine` equivalent.
|
||||
// FIXME(eddyb) improve on this, by adding more information.
|
||||
0 => SetDebugSrcLoc { file, line, col },
|
||||
// `OpNoLine` equivalent.
|
||||
// Like `DebugLine` (from `NonSemantic.Shader.DebugInfo.100`) or `OpLine`.
|
||||
0 => SetDebugSrcLoc { file, line_start, line_end, col_start, col_end },
|
||||
// Like `DebugNoLine` (from `NonSemantic.Shader.DebugInfo.100`) or `OpNoLine`.
|
||||
1 => ClearDebugSrcLoc,
|
||||
}
|
||||
|
@ -86,7 +86,13 @@ impl Transformer for CustomDebuginfoToSpv<'_> {
|
||||
{
|
||||
if ext_set == self.custom_ext_inst_set {
|
||||
match CustomOp::decode(ext_inst).with_operands(&data_inst_def.inputs) {
|
||||
CustomInst::SetDebugSrcLoc { file, line, col } => {
|
||||
CustomInst::SetDebugSrcLoc {
|
||||
file,
|
||||
line_start: line,
|
||||
line_end: _,
|
||||
col_start: col,
|
||||
col_end: _,
|
||||
} => {
|
||||
let const_ctor = |v: Value| match v {
|
||||
Value::Const(ct) => &self.cx[ct].ctor,
|
||||
_ => unreachable!(),
|
||||
|
@ -213,8 +213,10 @@ impl UseOrigin<'_> {
|
||||
col,
|
||||
} => span_regen.src_loc_to_rustc(SrcLocDecoration {
|
||||
file_name: &cx[file_path.0],
|
||||
line,
|
||||
col,
|
||||
line_start: line,
|
||||
line_end: line,
|
||||
col_start: col,
|
||||
col_end: col,
|
||||
}),
|
||||
_ => None,
|
||||
})
|
||||
@ -251,8 +253,15 @@ impl UseOrigin<'_> {
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let (file, line, col) = match custom_op.with_operands(&debug_inst_def.inputs) {
|
||||
CustomInst::SetDebugSrcLoc { file, line, col } => (file, line, col),
|
||||
let (file, line_start, line_end, col_start, col_end) =
|
||||
match custom_op.with_operands(&debug_inst_def.inputs) {
|
||||
CustomInst::SetDebugSrcLoc {
|
||||
file,
|
||||
line_start,
|
||||
line_end,
|
||||
col_start,
|
||||
col_end,
|
||||
} => (file, line_start, line_end, col_start, col_end),
|
||||
CustomInst::ClearDebugSrcLoc => unreachable!(),
|
||||
};
|
||||
let const_ctor = |v: Value| match v {
|
||||
@ -276,8 +285,10 @@ impl UseOrigin<'_> {
|
||||
|
||||
span_regen.src_loc_to_rustc(SrcLocDecoration {
|
||||
file_name: &cx[const_str(file)],
|
||||
line: const_u32(line),
|
||||
col: const_u32(col),
|
||||
line_start: const_u32(line_start),
|
||||
line_end: const_u32(line_end),
|
||||
col_start: const_u32(col_start),
|
||||
col_end: const_u32(col_end),
|
||||
})
|
||||
})
|
||||
.or_else(|| from_attrs(func_attrs, span_regen)),
|
||||
|
@ -2,28 +2,28 @@ error: cannot memcpy dynamically sized data
|
||||
--> $CORE_SRC/intrinsics.rs:2460:9
|
||||
|
|
||||
2460 | copy(src, dst, count)
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: used from within `core::intrinsics::copy::<f32>`
|
||||
--> $CORE_SRC/intrinsics.rs:2447:21
|
||||
|
|
||||
2447 | pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||
| ^
|
||||
| ^^^^
|
||||
note: called by `ptr_copy::copy_via_raw_ptr`
|
||||
--> $DIR/ptr_copy.rs:28:18
|
||||
|
|
||||
28 | unsafe { core::ptr::copy(src, dst, 1) }
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: called by `ptr_copy::main`
|
||||
--> $DIR/ptr_copy.rs:33:5
|
||||
|
|
||||
33 | copy_via_raw_ptr(&i, o);
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: called by `main`
|
||||
--> $DIR/ptr_copy.rs:31:1
|
||||
|
|
||||
31 | #[spirv(fragment)]
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,35 +2,35 @@ error: constant arrays/structs cannot contain pointers to other constants
|
||||
--> $DIR/nested-ref-in-composite.rs:20:17
|
||||
|
|
||||
20 | *pair_out = pair_deep_load(&(&123, &3.14));
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: used from within `nested_ref_in_composite::main_pair`
|
||||
--> $DIR/nested-ref-in-composite.rs:20:17
|
||||
|
|
||||
20 | *pair_out = pair_deep_load(&(&123, &3.14));
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: called by `main_pair`
|
||||
--> $DIR/nested-ref-in-composite.rs:18:1
|
||||
|
|
||||
18 | #[spirv(fragment)]
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: constant arrays/structs cannot contain pointers to other constants
|
||||
--> $DIR/nested-ref-in-composite.rs:25:19
|
||||
|
|
||||
25 | *array3_out = array3_deep_load(&[&0, &1, &2]);
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: used from within `nested_ref_in_composite::main_array3`
|
||||
--> $DIR/nested-ref-in-composite.rs:25:19
|
||||
|
|
||||
25 | *array3_out = array3_deep_load(&[&0, &1, &2]);
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: called by `main_array3`
|
||||
--> $DIR/nested-ref-in-composite.rs:23:1
|
||||
|
|
||||
23 | #[spirv(fragment)]
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -4,12 +4,12 @@ note: used from within `allocate_const_scalar::main`
|
||||
--> $DIR/allocate_const_scalar.rs:15:20
|
||||
|
|
||||
15 | let _pointer = POINTER;
|
||||
| ^
|
||||
| ^^^^^^^
|
||||
note: called by `main`
|
||||
--> $DIR/allocate_const_scalar.rs:13:1
|
||||
|
|
||||
13 | #[spirv(fragment)]
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,18 +4,18 @@ error: cannot cast between pointer types
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:23:5
|
||||
|
|
||||
23 | f(&s.y);
|
||||
| ^
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: used from within `zst_member_ref_arg_broken::main_scalar`
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:23:5
|
||||
|
|
||||
23 | f(&s.y);
|
||||
| ^
|
||||
| ^^^^^^^
|
||||
note: called by `main_scalar`
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:21:1
|
||||
|
|
||||
21 | #[spirv(fragment)]
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot cast between pointer types
|
||||
from `*struct S<usize, usize> { u32, u32 }`
|
||||
@ -23,18 +23,18 @@ error: cannot cast between pointer types
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:28:5
|
||||
|
|
||||
28 | f(&s.y);
|
||||
| ^
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: used from within `zst_member_ref_arg_broken::main_scalar_pair`
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:28:5
|
||||
|
|
||||
28 | f(&s.y);
|
||||
| ^
|
||||
| ^^^^^^^
|
||||
note: called by `main_scalar_pair`
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:26:1
|
||||
|
|
||||
26 | #[spirv(fragment)]
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot cast between pointer types
|
||||
from `*struct (usize, usize) { u32, u32 }`
|
||||
@ -42,18 +42,18 @@ error: cannot cast between pointer types
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:33:5
|
||||
|
|
||||
33 | f(&s.y);
|
||||
| ^
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: used from within `zst_member_ref_arg_broken::main_scalar_scalar_pair_nested`
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:33:5
|
||||
|
|
||||
33 | f(&s.y);
|
||||
| ^
|
||||
| ^^^^^^^
|
||||
note: called by `main_scalar_scalar_pair_nested`
|
||||
--> $DIR/zst_member_ref_arg-broken.rs:31:1
|
||||
|
|
||||
31 | #[spirv(fragment)]
|
||||
| ^
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user