From ab7592d70dcbd2692b2b230423173d0adbc0559d Mon Sep 17 00:00:00 2001 From: Andrzej Janik Date: Sat, 30 Aug 2025 02:56:53 +0000 Subject: [PATCH] Small fixes to ptx parsing --- ptx_parser/src/lib.rs | 167 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 135 insertions(+), 32 deletions(-) diff --git a/ptx_parser/src/lib.rs b/ptx_parser/src/lib.rs index fb924e7..6e4e167 100644 --- a/ptx_parser/src/lib.rs +++ b/ptx_parser/src/lib.rs @@ -182,26 +182,29 @@ fn dot_ident<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<&'input } fn num<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<(&'input str, u32, bool)> { - any.verify_map(|(t, _)| { - Some(match t { - Token::Hex(s) => { - if s.ends_with('U') { - (&s[2..s.len() - 1], 16, true) - } else { - (&s[2..], 16, false) + trace( + "num", + any.verify_map(|(t, _)| { + Some(match t { + Token::Hex(s) => { + if s.ends_with('U') { + (&s[2..s.len() - 1], 16, true) + } else { + (&s[2..], 16, false) + } } - } - Token::Decimal(s) => { - let radix = if s.starts_with('0') { 8 } else { 10 }; - if s.ends_with('U') { - (&s[..s.len() - 1], radix, true) - } else { - (s, radix, false) + Token::Decimal(s) => { + let radix = if s.starts_with('0') { 8 } else { 10 }; + if s.ends_with('U') { + (&s[..s.len() - 1], radix, true) + } else { + (s, radix, false) + } } - } - _ => return None, - }) - }) + _ => return None, + }) + }), + ) .parse_next(stream) } @@ -290,13 +293,16 @@ fn u8<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult { } fn u32<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult { - take_error(num.map(|x| { - let (text, radix, _) = x; - match u32::from_str_radix(text, radix) { - Ok(x) => Ok(x), - Err(err) => Err((0, PtxError::from(err))), - } - })) + trace( + "u32", + take_error(num.map(|x| { + let (text, radix, _) = x; + match u32::from_str_radix(text, radix) { + Ok(x) => Ok(x), + Err(err) => Err((0, PtxError::from(err))), + } + })), + ) .parse_next(stream) } @@ -547,7 +553,9 @@ fn any_bit_type<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> { } fn section_label<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> { - alt((ident, dot_ident)).void().parse_next(stream) + trace("section_label", alt((ident, dot_ident))) + .void() + .parse_next(stream) } fn function<'a, 'input>( @@ -654,13 +662,13 @@ fn kernel_arguments<'a, 'input>( fn kernel_input<'a, 'input>( stream: &mut PtxParser<'a, 'input>, ) -> PResult> { - preceded(Token::DotParam, method_parameter(StateSpace::Param)).parse_next(stream) + preceded(Token::DotParam, method_parameter(StateSpace::Param, true)).parse_next(stream) } fn fn_input<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult> { dispatch! { any; - (Token::DotParam, _) => method_parameter(StateSpace::Param), - (Token::DotReg, _) => method_parameter(StateSpace::Reg), + (Token::DotParam, _) => method_parameter(StateSpace::Param, false), + (Token::DotReg, _) => method_parameter(StateSpace::Reg, false), _ => fail } .parse_next(stream) @@ -820,11 +828,30 @@ fn pragma<'a, 'input>(stream: &mut PtxParser<'a, 'input>) -> PResult<()> { fn method_parameter<'a, 'input: 'a>( state_space: StateSpace, + kernel_decl_rules: bool, ) -> impl Parser, Variable<&'input str>, ContextError> { + fn nvptx_kernel_declaration<'a, 'input>( + stream: &mut PtxParser<'a, 'input>, + ) -> PResult<(Option, Option, ScalarType, &'input str)> { + trace( + "nvptx_kernel_declaration", + ( + vector_prefix, + scalar_type, + opt((Token::DotPtr, Token::DotGlobal)), + opt(align.verify(|x| x.count_ones() == 1)), + ident, + ), + ) + .map(|(vector, type_, _, align, name)| (align, vector, type_, name)) + .parse_next(stream) + } trace( "method_parameter", move |stream: &mut PtxParser<'a, 'input>| { - let (align, vector, type_, name) = variable_declaration.parse_next(stream)?; + if kernel_decl_rules {} + let (align, vector, type_, name) = + alt((variable_declaration, nvptx_kernel_declaration)).parse_next(stream)?; let array_dimensions = if state_space != StateSpace::Reg { opt(array_dimensions).parse_next(stream)? } else { @@ -1751,10 +1778,12 @@ derive_parser!( DotTarget, #[token(".address_size")] DotAddressSize, - #[token(".action")] + #[token(".section")] DotSection, #[token(".file")] - DotFile + DotFile, + #[token(".ptr")] + DotPtr } #[derive(Copy, Clone, Display, PartialEq, Eq, Hash)] @@ -3775,6 +3804,7 @@ derive_parser!( mod tests { use crate::first_optional; use crate::parse_module_checked; + use crate::section; use crate::PtxError; use super::target; @@ -3997,4 +4027,77 @@ mod tests { PtxError::UnrecognizedDirective(".global .bad_type foo;") )); } + + #[test] + fn dwarf_line() { + let text = " + .section .debug_abbrev + { +.b8 1 // Abbreviation Code +.b8 17 // DW_TAG_compile_unit +.b8 1 // DW_CHILDREN_yes +.b8 37 // DW_AT_producer +.b8 8 // DW_FORM_string +.b8 19 // DW_AT_language +.b8 5 // DW_FORM_data2 +.b8 3 // DW_AT_name +.b8 8 // DW_FORM_string +.b8 16 // DW_AT_stmt_list +.b8 6 // DW_FORM_data4 +.b8 27 // DW_AT_comp_dir +.b8 8 // DW_FORM_string +.b8 0 // EOM(1) +.b8 0 // EOM(2) +.b8 2 // Abbreviation Code +.b8 46 // DW_TAG_subprogram +.b8 0 // DW_CHILDREN_no +.b8 3 // DW_AT_name +.b8 8 // DW_FORM_string +.b8 32 // DW_AT_inline +.b8 11 // DW_FORM_data1 +.b8 0 // EOM(1) +.b8 0 // EOM(2) +.b8 3 // Abbreviation Code +.b8 46 // DW_TAG_subprogram +.b8 1 // DW_CHILDREN_yes +.b8 17 // DW_AT_low_pc +.b8 1 // DW_FORM_addr +.b8 18 // DW_AT_high_pc +.b8 1 // DW_FORM_addr +.b8 49 // DW_AT_abstract_origin +.b8 19 // DW_FORM_ref4 +.b8 0 // EOM(1) +.b8 0 // EOM(2) +.b8 4 // Abbreviation Code +.b8 29 // DW_TAG_inlined_subroutine +.b8 0 // DW_CHILDREN_no +.b8 49 // DW_AT_abstract_origin +.b8 19 // DW_FORM_ref4 +.b8 17 // DW_AT_low_pc +.b8 1 // DW_FORM_addr +.b8 18 // DW_AT_high_pc +.b8 1 // DW_FORM_addr +.b8 88 // DW_AT_call_file +.b8 11 // DW_FORM_data1 +.b8 89 // DW_AT_call_line +.b8 11 // DW_FORM_data1 +.b8 87 // DW_AT_call_column +.b8 11 // DW_FORM_data1 +.b8 0 // EOM(1) +.b8 0 // EOM(2) +.b8 0 // EOM(3) + } +"; + let tokens = Token::lexer(text) + .map(|t| t.map(|t| (t, Span::default()))) + .collect::, _>>() + .unwrap(); + let mut errors = Vec::new(); + let stream = super::PtxParser { + input: &tokens[..], + state: PtxParserState::new(text, &mut errors), + }; + assert!(section.parse(stream).is_ok()); + assert_eq!(errors.len(), 0); + } }