From d600b873364d9a799b67ccd6054f4aa69ef3d1c0 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 24 Nov 2019 21:02:27 +0800 Subject: mir_opt_test - Const propagation test, extra parsing --- src/parse/token.cpp | 6 +++ tools/mir_opt_test/parser.cpp | 83 +++++++++++++++++++++++++++++++++++-- tools/mir_opt_test/tests/trivial.rs | 23 ++++++++++ 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/src/parse/token.cpp b/src/parse/token.cpp index f9ecd028..5feafc39 100644 --- a/src/parse/token.cpp +++ b/src/parse/token.cpp @@ -504,6 +504,12 @@ struct EscapedString { case TOK_LIFETIME: if( tok.m_data.is_String() ) os << "\"" << EscapedString(tok.str()) << "\""; + else if( tok.m_data.is_IString() ) + os << "\"" << tok.istr() << "\""; + else if( tok.m_data.is_None() ) + ; + else + os << "?inner?"; break; case TOK_INTEGER: if( tok.m_data.is_Integer() ) diff --git a/tools/mir_opt_test/parser.cpp b/tools/mir_opt_test/parser.cpp index d86d124b..864fd2a9 100644 --- a/tools/mir_opt_test/parser.cpp +++ b/tools/mir_opt_test/parser.cpp @@ -14,6 +14,7 @@ namespace { HIR::Path parse_path(TokenStream& lex); HIR::TypeRef parse_type(TokenStream& lex); MIR::LValue parse_lvalue(TokenStream& lex, const ::std::map& name_map); + MIR::LValue parse_param(TokenStream& lex, const ::std::map& name_map); bool consume_if(TokenStream& lex, eTokenType tok) { if( lex.lookahead(0) == tok ) { @@ -221,6 +222,8 @@ namespace { } break; // Start of a path (lvalue) + case TOK_LT: + case TOK_DOUBLE_LT: case TOK_DOUBLE_COLON: lex.putback(mv$(tok)); src = parse_lvalue(lex, val_name_map); @@ -231,7 +234,7 @@ namespace { auto& vals = src.as_Tuple().vals; while( lex.lookahead(0) != TOK_PAREN_CLOSE ) { - vals.push_back(parse_lvalue(lex, val_name_map)); + vals.push_back(parse_param(lex, val_name_map)); if( !consume_if(lex, TOK_COMMA) ) break; } @@ -287,6 +290,8 @@ namespace { { auto dst = parse_lvalue(lex, val_name_map); GET_CHECK_TOK(tok, lex, TOK_EQUAL); + + // - Call target MIR::CallTarget target; if( lex.lookahead(0) == TOK_PAREN_OPEN ) { @@ -305,15 +310,18 @@ namespace { target = ::MIR::CallTarget::make_Path( parse_path(lex) ); } + // - Arguments ::std::vector args; GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN); while( lex.lookahead(0) != TOK_PAREN_CLOSE ) { - args.push_back(parse_lvalue(lex, val_name_map)); + args.push_back(parse_param(lex, val_name_map)); if( !consume_if(lex, TOK_COMMA) ) break; } GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE); + + // - Target blocks GET_CHECK_TOK(tok, lex, TOK_FATARROW); auto ret_bb = parse_bb_name(lex); GET_CHECK_TOK(tok, lex, TOK_RWORD_ELSE); @@ -321,6 +329,55 @@ namespace { bb.terminator = ::MIR::Terminator::make_Call({ ret_bb, panic_bb, mv$(dst), mv$(target), mv$(args) }); } + else if( tok.istr() == "IF" ) + { + auto v = parse_lvalue(lex, val_name_map); + GET_CHECK_TOK(tok, lex, TOK_FATARROW); + auto bb0 = parse_bb_name(lex); + GET_CHECK_TOK(tok, lex, TOK_RWORD_ELSE); + auto bb1 = parse_bb_name(lex); + + bb.terminator = ::MIR::Terminator::make_If({ mv$(v), bb0, bb1 }); + } + else if( tok.istr() == "SWITCH" ) + { + auto v = parse_lvalue(lex, val_name_map); + ::std::vector targets; + + if( lex.lookahead(0) == TOK_IDENT ) + { + GET_CHECK_TOK(tok, lex, TOK_IDENT); + if( tok.istr() == "str" ) + { + TODO(lex.point_span(), "MIR terminator - SwitchValue - str"); + } + else if( tok.istr() == "sint" ) + { + TODO(lex.point_span(), "MIR terminator - SwitchValue - signed"); + } + else if( tok.istr() == "uint" ) + { + TODO(lex.point_span(), "MIR terminator - SwitchValue - unsigned"); + } + else + { + TODO(lex.point_span(), "MIR terminator - SwitchValue - unknown " << tok); + } + } + else + { + GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN); + while( lex.lookahead(0) != TOK_BRACE_CLOSE ) + { + targets.push_back(parse_bb_name(lex)); + if( !consume_if(lex, TOK_COMMA) ) + break; + } + GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE); + + bb.terminator = ::MIR::Terminator::make_Switch({ mv$(v), targets }); + } + } else { TODO(lex.point_span(), "MIR terminator - " << tok.istr()); @@ -428,8 +485,22 @@ namespace { GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE); return HIR::TypeRef(mv$(tys)); } break; + case TOK_IDENT: + if( tok.istr() == "dyn" ) + { + TODO(lex.point_span(), tok); + } + else if( tok.istr() == "bool" ) return HIR::TypeRef(HIR::CoreType::Bool); + else if( tok.istr() == "str" ) return HIR::TypeRef(HIR::CoreType::Str ); + else if( tok.istr() == "u8" ) return HIR::TypeRef(HIR::CoreType::U8); + else if( tok.istr() == "i8" ) return HIR::TypeRef(HIR::CoreType::I8); + else + { + TODO(lex.point_span(), tok); + } + break; default: - TODO(lex.point_span(), "parse_type - " << tok); + TODO(lex.point_span(), tok); } } MIR::LValue::Storage parse_lvalue_root(TokenStream& lex, const ::std::map& name_map) @@ -476,4 +547,10 @@ namespace { } } } + + MIR::LValue parse_param(TokenStream& lex, const ::std::map& name_map) + { + // Can be any constant, or an LValue + return parse_lvalue(lex, name_map); + } } diff --git a/tools/mir_opt_test/tests/trivial.rs b/tools/mir_opt_test/tests/trivial.rs index f2f125b8..80d78620 100644 --- a/tools/mir_opt_test/tests/trivial.rs +++ b/tools/mir_opt_test/tests/trivial.rs @@ -1,3 +1,4 @@ +// No-op test #[test="test_trivial"] fn test_trivial() { @@ -39,6 +40,7 @@ fn dce_exp() } RETURN; } +// Inlining #[test="inlining_exp"] fn inlining() { @@ -61,3 +63,24 @@ fn inlining_exp() ASSIGN retval = (); } RETURN; } + +// Constant propagation leading to DCE +#[test="constprop_exp"] +fn constprop() +{ + let v1: bool; + bb0: { + ASSIGN v1 = true; + } IF v1 => bb1 else bb2; + bb1: { + ASSIGN retval = (); + } RETURN; + bb2: { + } DIVERGE; +} +fn constprop_exp() +{ + bb0: { + ASSIGN retval = (); + } RETURN; +} -- cgit v1.2.3