diff --git a/hilti/toolchain/include/ast/node.h b/hilti/toolchain/include/ast/node.h index 0771d01d0f..018392b532 100644 --- a/hilti/toolchain/include/ast/node.h +++ b/hilti/toolchain/include/ast/node.h @@ -456,6 +456,26 @@ class Node { return n; } + /** + * Returns the subsequent sibling of given child node. This skips over null children. + * + * @param n child whose sibling to return + * @return sibling of *n*, or null if *n* is the last child or not child at all + **/ + Node* sibling(Node* n) const { + auto i = std::find(_children.begin(), _children.end(), n); + if ( i == _children.end() ) + return nullptr; + + while ( true ) { + if ( ++i == _children.end() ) + return nullptr; + + if ( *i ) + return *i; + } + } + /** * Adds a child node. The node will be appended to the end of the current * list of children, and its parent will be set to the current node. If the diff --git a/hilti/toolchain/src/compiler/optimizer.cc b/hilti/toolchain/src/compiler/optimizer.cc index 7a8d5b2295..bdd4dbee6a 100644 --- a/hilti/toolchain/src/compiler/optimizer.cc +++ b/hilti/toolchain/src/compiler/optimizer.cc @@ -907,6 +907,126 @@ struct ConstantFoldingVisitor : OptimizerVisitor { } }; +/** + * Visitor running on the final, optimized AST to perform additional peephole + * optimizations. Will run repeatedly until no further optimizations. + */ +struct PeepholeOptimizer : visitor::MutatingPostOrder { + using visitor::MutatingPostOrder::MutatingPostOrder; + + // Returns true if statement is `(*self).__error = __error`. + bool isErrorPush(statement::Expression* n) { + auto assign = n->expression()->tryAs(); + if ( ! assign ) + return false; + + auto lhs = assign->target()->tryAs(); + if ( ! lhs ) + return false; + + auto op0 = lhs->op0()->tryAs(); + if ( ! op0 ) + return false; + + auto op1 = lhs->op1()->tryAs(); + if ( ! (op1 && op1->id() == "__error") ) + return false; + + auto self = op0->op0()->tryAs(); + if ( ! (self && self->id() == "self") ) + return false; + + auto rhs = assign->source()->tryAs(); + if ( ! (rhs && rhs->id() == "__error") ) + return false; + + return true; + } + + // Returns true if statement is `__error == (*self).__error`. + bool isErrorPop(statement::Expression* n) { + auto assign = n->expression()->tryAs(); + if ( ! assign ) + return false; + + auto lhs = assign->target()->tryAs(); + if ( ! (lhs && lhs->id() == "__error") ) + return false; + + auto rhs = assign->source()->tryAs(); + if ( ! rhs ) + return false; + + auto op0 = rhs->op0()->tryAs(); + if ( ! op0 ) + return false; + + auto op1 = rhs->op1()->tryAs(); + if ( ! (op1 && op1->id() == "__error") ) + return false; + + auto self = op0->op0()->tryAs(); + if ( ! (self && self->id() == "self") ) + return false; + + return true; + } + + void operator()(statement::Expression* n) final { + // Remove expression statements that are just `default`. + if ( auto ctor = n->expression()->tryAs(); + ctor && ctor->ctor()->isA() && ctor->type()->type()->isA() ) { + recordChange(n, "removing default statement"); + n->parent()->removeChild(n); + return; + } + + // Remove statement pairs of the form: + // + // (*self).__error = __error; + // __error = (*self).__error; + // + // These will be left behind by the optimizer if a hook call got optimized out in between them. + if ( isErrorPush(n) && n->parent() ) { + auto parent = n->parent(); + if ( auto sibling = parent->sibling(n) ) { + if ( auto stmt = sibling->tryAs(); stmt && isErrorPop(stmt) ) { + recordChange(n, "removing unneeded error push/pop statements"); + parent->removeChild(n); + parent->removeChild(sibling); + return; + } + } + } + } +}; + +/* +(*self).__error = __error; +__error = (*self).__error; +- statement::Expression [parent @s:600002ac3d40] [@s:600002af86e0] +[debug/ast-final] - expression::Assign [parent @s:600002af86e0] (non-const) (resolved) +[@e:600002af8690] [debug/ast-final] - operator_::struct_::MemberNonConst [parent +@e:600002af8690] (non-const) (resolved) [@o:600002d9b000] [debug/ast-final] - QualifiedType + [parent @o:600002d9b000] [@q:60000227a840] [debug/ast-final] - +type::Optional [parent +@q:60000227a840] (resolved) [@t:600003bb> [debug/ast-final] - QualifiedType [parent @t:600003bb2490] [@q:600002279880] [debug/ast-final] - type::Name + [debug/ast-final] - +operator_::value_reference::Deref [parent @o:600002d9b000] (non-const) (resolved) +[@o:600002d9afa0] [debug/ast-final] - QualifiedType [parent +@o:600002d9afa0] [@q:60000227aed0] [debug/ast-final] - expression::Name [parent @o:600002d9afa0] (non-const) +(resolved) > [debug/ast-final] - expression::Member [parent @o:600002d9b000] +(const) (resolved) [@e:600002279ce0] [debug/ast-final] - QualifiedType [parent @e:600002279ce0] [@q:600002279e30] [debug/ast-final] - type::Member + [parent @q:600002279e30] (resolved) +[@t:600003ec6d60] [debug/ast-final] - expression::Name [parent @e:600002af8690] +(non-cons +*/ + // This visitor collects requirement attributes in the AST and toggles unused features. class FeatureRequirementsVisitor : public visitor::MutatingPreOrder { public: @@ -1494,6 +1614,13 @@ void detail::optimizer::optimize(Builder* builder, ASTRoot* root) { ++round; } + while ( true ) { + auto v = PeepholeOptimizer(builder, hilti::logging::debug::Optimizer); + visitor::visit(v, root); + if ( ! v.isModified() ) + break; + } + // Clear cached information which might become outdated due to edits. auto v = hilti::visitor::PreOrder(); for ( auto n : hilti::visitor::range(v, root, {}) ) diff --git a/tests/Baseline/hilti.optimization.unimplemented_hook/log b/tests/Baseline/hilti.optimization.unimplemented_hook/log index 1a89574535..d4cdcfb9c1 100644 --- a/tests/Baseline/hilti.optimization.unimplemented_hook/log +++ b/tests/Baseline/hilti.optimization.unimplemented_hook/log @@ -11,3 +11,5 @@ [debug/optimizer] [unimplemented_hook.hlt:21:5-21:35] declaration::Field "hook void unimplemented_void();" -> null [debug/optimizer] removing field for unused method Foo::X::unimplemented_int64 [debug/optimizer] [unimplemented_hook.hlt:22:5-22:49] declaration::Field "hook optional> unimplemented_int64();" -> null +[debug/optimizer] [unimplemented_hook.hlt:29:1-29:27] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unimplemented_hook.hlt:35:1-35:22] statement::Expression "default();" -> removing default statement diff --git a/tests/Baseline/hilti.optimization.unimplemented_hook/opt.hlt b/tests/Baseline/hilti.optimization.unimplemented_hook/opt.hlt index 90d1083576..8a2af793ea 100644 --- a/tests/Baseline/hilti.optimization.unimplemented_hook/opt.hlt +++ b/tests/Baseline/hilti.optimization.unimplemented_hook/opt.hlt @@ -18,8 +18,6 @@ method hook void X::implemented() { } global_implemented(); -default(); x.implemented(); -default(); } diff --git a/tests/Baseline/spicy.optimization.default-parser-functions/log b/tests/Baseline/spicy.optimization.default-parser-functions/log index bcf4fcfd2c..8498b8611e 100644 --- a/tests/Baseline/spicy.optimization.default-parser-functions/log +++ b/tests/Baseline/spicy.optimization.default-parser-functions/log @@ -174,6 +174,15 @@ [debug/optimizer] [] expression::Name "__feat%foo@@P2%uses_stream" -> expression::Ctor "False" (inlining constant) [debug/optimizer] [] expression::Ternary "False ? (*self).__filters : Null" -> expression::Ctor "Null" [debug/optimizer] [] expression::Ternary "False ? (*self).__filters : Null" -> expression::Ctor "Null" +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null @@ -330,6 +339,11 @@ [debug/optimizer] [default-parser-functions.spicy:14:18-14:24] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [default-parser-functions.spicy:14:18-14:24] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [default-parser-functions.spicy:14:18-14:24] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [default-parser-functions.spicy:14:18-14:24] statement::Expression "default();" -> removing default statement +[debug/optimizer] [default-parser-functions.spicy:14:18-14:24] statement::Expression "default();" -> removing default statement +[debug/optimizer] [default-parser-functions.spicy:14:18-14:24] statement::Expression "default();" -> removing default statement +[debug/optimizer] [default-parser-functions.spicy:14:18-14:24] statement::Expression "default();" -> removing default statement +[debug/optimizer] [default-parser-functions.spicy:14:18-14:24] statement::Expression "default();" -> removing default statement [debug/optimizer] [default-parser-functions.spicy:16:18-21:1] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [default-parser-functions.spicy:16:18-21:1] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null [debug/optimizer] [default-parser-functions.spicy:16:18-21:1] declaration::Field "hook void __on_0x25_done();" -> null @@ -349,8 +363,13 @@ [debug/optimizer] [default-parser-functions.spicy:16:18-21:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [default-parser-functions.spicy:16:18-21:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [default-parser-functions.spicy:16:18-21:1] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [default-parser-functions.spicy:16:18-21:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [default-parser-functions.spicy:16:18-21:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [default-parser-functions.spicy:16:18-21:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [default-parser-functions.spicy:16:18-21:1] statement::Expression "default();" -> removing default statement [debug/optimizer] [default-parser-functions.spicy:17:5-17:13] declaration::Field "hook void __on_x(uint<8> __dd);" -> null [debug/optimizer] [default-parser-functions.spicy:17:5-17:13] operator_::struct_::MemberCall "(*self).__on_x((*self).x)" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [default-parser-functions.spicy:17:5-17:13] statement::Expression "default();" -> removing default statement [debug/optimizer] [spicy_rt.hlt:28:5-28:76] declaration::Field "method void connect_mime_type(string mime_type, string scope) &internal;" -> null (removing unused member) [debug/optimizer] [spicy_rt.hlt:29:5-29:75] declaration::Field "method void connect_mime_type(bytes mime_type, string scope) &internal;" -> null (removing unused member) [debug/optimizer] removing field for unused method foo::P0::__on_0x25_confirmed diff --git a/tests/Baseline/spicy.optimization.default-parser-functions/opt.hlt b/tests/Baseline/spicy.optimization.default-parser-functions/opt.hlt index 274ea7734e..56afcfbbcf 100644 --- a/tests/Baseline/spicy.optimization.default-parser-functions/opt.hlt +++ b/tests/Baseline/spicy.optimization.default-parser-functions/opt.hlt @@ -61,35 +61,21 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__P1_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::P1::__parse_foo__P1_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/default-parser-functions.spicy:14:18-14:24" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; @@ -169,9 +155,6 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) @@ -180,15 +163,9 @@ method method tuple, int<64>, const iterator, optiona } catch ( hilti::SystemException __except ) { (*self).__on_0x25_error(hilti::exception_what(__except)); - (*self).__error = __error; - default(); - __error = (*self).__error; throw; } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } @@ -206,9 +183,6 @@ method method tuple, int<64>, const iterator, optiona # End parsing production: Variable: x -> uint<8> - (*self).__error = __error; - default(); - __error = (*self).__error; # "<...>/default-parser-functions.spicy:18:8-18:12" # Begin parsing production: Variable: y -> uint<8> @@ -223,9 +197,6 @@ method method tuple, int<64>, const iterator, optiona (*self).__error = __error; (*self).__on_y((*self).y); __error = (*self).__error; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; diff --git a/tests/Baseline/spicy.optimization.feature_requirements/log b/tests/Baseline/spicy.optimization.feature_requirements/log index c4d473594e..dcbdfa8731 100644 --- a/tests/Baseline/spicy.optimization.feature_requirements/log +++ b/tests/Baseline/spicy.optimization.feature_requirements/log @@ -439,6 +439,16 @@ [debug/optimizer] [] expression::Name "__feat%foo@@X7%uses_random_access" -> expression::Ctor "False" (inlining constant) [debug/optimizer] [] expression::Name "__feat%foo@@X7%uses_random_access" -> expression::Ctor "False" (inlining constant) [debug/optimizer] [] expression::Name "__feat%foo@@X7%uses_stream" -> expression::Ctor "False" (inlining constant) +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements [debug/optimizer] [] statement::If "if ( False ) { (*(*self).data).close(); }" -> null [debug/optimizer] [] statement::If "if ( False ) { (*(*self).data).close(); }" -> null [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null @@ -830,6 +840,11 @@ [debug/optimizer] [feature_requirements.spicy:32:11-34:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [feature_requirements.spicy:32:11-34:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [feature_requirements.spicy:32:11-34:1] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [feature_requirements.spicy:32:11-34:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:32:11-34:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:32:11-34:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:32:11-34:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:32:11-34:1] statement::Expression "default();" -> removing default statement [debug/optimizer] [feature_requirements.spicy:36:18-40:1] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [feature_requirements.spicy:36:18-40:1] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null [debug/optimizer] [feature_requirements.spicy:36:18-40:1] declaration::Field "hook void __on_0x25_done();" -> null @@ -849,6 +864,10 @@ [debug/optimizer] [feature_requirements.spicy:36:18-40:1] operator_::struct_::MemberCall "(*self).__on_0x25_error(hilti::exception_what(__except))" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [feature_requirements.spicy:36:18-40:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [feature_requirements.spicy:36:18-40:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [feature_requirements.spicy:36:18-40:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:36:18-40:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:36:18-40:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:36:18-40:1] statement::Expression "default();" -> removing default statement [debug/optimizer] [feature_requirements.spicy:43:11-46:1] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [feature_requirements.spicy:43:11-46:1] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null [debug/optimizer] [feature_requirements.spicy:43:11-46:1] declaration::Field "hook void __on_0x25_done();" -> null @@ -868,6 +887,10 @@ [debug/optimizer] [feature_requirements.spicy:43:11-46:1] operator_::struct_::MemberCall "(*self).__on_0x25_error(hilti::exception_what(__except))" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [feature_requirements.spicy:43:11-46:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [feature_requirements.spicy:43:11-46:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [feature_requirements.spicy:43:11-46:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:43:11-46:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:43:11-46:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [feature_requirements.spicy:43:11-46:1] statement::Expression "default();" -> removing default statement [debug/optimizer] [feature_requirements.spicy:49:1-51:2] declaration::Type "type X7 = struct { optional __error &always-emit &internal; method tuple, int<64>, const iterator, optional> __parse_foo__X7_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error); } &on-heap;" -> null (removing unused type) [debug/optimizer] [feature_requirements.spicy:49:11-51:1] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [feature_requirements.spicy:49:11-51:1] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null diff --git a/tests/Baseline/spicy.optimization.feature_requirements/opt.hlt b/tests/Baseline/spicy.optimization.feature_requirements/opt.hlt index 21ca6a6fb0..88474937aa 100644 --- a/tests/Baseline/spicy.optimization.feature_requirements/opt.hlt +++ b/tests/Baseline/spicy.optimization.feature_requirements/opt.hlt @@ -150,9 +150,6 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) @@ -160,28 +157,18 @@ method method tuple, int<64>, const iterator, optiona } catch ( hilti::SystemException __except ) { - default(); spicy_rt::filter_forward_eod(self); - (*self).__error = __error; - default(); - __error = (*self).__error; throw; } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::X4::__parse_foo__X4_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/feature_requirements.spicy:32:11-34:1" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; spicy_rt::filter_forward_eod(self); @@ -292,28 +279,18 @@ method method tuple, int<64>, const iterator, optiona } catch ( hilti::SystemException __except ) { - default(); spicy_rt::filter_disconnect(self); - (*self).__error = __error; - default(); - __error = (*self).__error; throw; } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::X5::__parse_foo__X5_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/feature_requirements.spicy:36:18-40:1" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; spicy_rt::filter_disconnect(self); @@ -404,28 +381,18 @@ method method tuple, int<64>, const iterator, optiona } catch ( hilti::SystemException __except ) { - default(); (*(*self).data).close(); - (*self).__error = __error; - default(); - __error = (*self).__error; throw; } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::X6::__parse_foo__X6_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/feature_requirements.spicy:43:11-46:1" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; (*(*self).data).close(); diff --git a/tests/Baseline/spicy.optimization.unused-functions/log b/tests/Baseline/spicy.optimization.unused-functions/log index d4b51d664e..f8633ec344 100644 --- a/tests/Baseline/spicy.optimization.unused-functions/log +++ b/tests/Baseline/spicy.optimization.unused-functions/log @@ -272,6 +272,18 @@ [debug/optimizer] [] expression::Name "__feat%foo@@F%uses_random_access" -> expression::Ctor "False" (inlining constant) [debug/optimizer] [] expression::Name "__feat%foo@@F%uses_random_access" -> expression::Ctor "False" (inlining constant) [debug/optimizer] [] expression::Name "__feat%foo@@F%uses_stream" -> expression::Ctor "False" (inlining constant) +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null @@ -498,6 +510,11 @@ [debug/optimizer] [unused-functions.spicy:21:17-21:23] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-functions.spicy:21:17-21:23] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-functions.spicy:21:17-21:23] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-functions.spicy:21:17-21:23] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:21:17-21:23] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:21:17-21:23] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:21:17-21:23] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:21:17-21:23] statement::Expression "default();" -> removing default statement [debug/optimizer] [unused-functions.spicy:24:10-24:16] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [unused-functions.spicy:24:10-24:16] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null [debug/optimizer] [unused-functions.spicy:24:10-24:16] declaration::Field "hook void __on_0x25_done();" -> null @@ -519,6 +536,11 @@ [debug/optimizer] [unused-functions.spicy:24:10-24:16] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-functions.spicy:24:10-24:16] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-functions.spicy:24:10-24:16] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-functions.spicy:24:10-24:16] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:24:10-24:16] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:24:10-24:16] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:24:10-24:16] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:24:10-24:16] statement::Expression "default();" -> removing default statement [debug/optimizer] [unused-functions.spicy:25:17-27:1] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [unused-functions.spicy:25:17-27:1] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null [debug/optimizer] [unused-functions.spicy:25:17-27:1] declaration::Field "hook void __on_0x25_done();" -> null @@ -540,6 +562,11 @@ [debug/optimizer] [unused-functions.spicy:25:17-27:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-functions.spicy:25:17-27:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-functions.spicy:25:17-27:1] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-functions.spicy:25:17-27:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:25:17-27:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:25:17-27:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:25:17-27:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-functions.spicy:25:17-27:1] statement::Expression "default();" -> removing default statement [debug/optimizer] [unused-functions.spicy:30:1-32:2] declaration::Type "type F = struct { optional __error &always-emit &internal; method tuple, int<64>, const iterator, optional> __parse_foo__F_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error); } &on-heap;" -> null (removing unused type) [debug/optimizer] [unused-functions.spicy:30:10-32:1] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [unused-functions.spicy:30:10-32:1] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null diff --git a/tests/Baseline/spicy.optimization.unused-functions/opt.hlt b/tests/Baseline/spicy.optimization.unused-functions/opt.hlt index 872c9ecc52..f46e77936e 100644 --- a/tests/Baseline/spicy.optimization.unused-functions/opt.hlt +++ b/tests/Baseline/spicy.optimization.unused-functions/opt.hlt @@ -82,35 +82,21 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__B_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::B::__parse_foo__B_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/unused-functions.spicy:21:17-21:23" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; @@ -184,35 +170,21 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__C_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::C::__parse_foo__C_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/unused-functions.spicy:24:10-24:16" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; @@ -227,26 +199,15 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__D_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } @@ -261,9 +222,6 @@ method method tuple, int<64>, const iterator, optiona (__cur, __lah, __lahe, __error) = (*__transient__anon).__parse_stage1(__data, __begin, __cur, __trim, __lah, __lahe, __error); # End parsing production: Unit: foo__C_2 -> - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; diff --git a/tests/Baseline/spicy.optimization.unused-types/log b/tests/Baseline/spicy.optimization.unused-types/log index cd1a8e8513..0572d7478e 100644 --- a/tests/Baseline/spicy.optimization.unused-types/log +++ b/tests/Baseline/spicy.optimization.unused-types/log @@ -506,6 +506,27 @@ [debug/optimizer] [] expression::Name "__feat%foo@@Pub3%uses_random_access" -> expression::Ctor "False" (inlining constant) [debug/optimizer] [] expression::Name "__feat%foo@@Pub3%uses_random_access" -> expression::Ctor "False" (inlining constant) [debug/optimizer] [] expression::Name "__feat%foo@@Pub3%uses_stream" -> expression::Ctor "False" (inlining constant) +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements +[debug/optimizer] [] statement::Expression "(*self).__error = __error;" -> removing unneeded error push/pop statements [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null [debug/optimizer] [] statement::If "if ( False ) { (*__unit).__begin = begin(__ncur); }" -> null @@ -877,6 +898,11 @@ [debug/optimizer] [unused-types.spicy:16:20-16:26] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:16:20-16:26] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:16:20-16:26] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-types.spicy:16:20-16:26] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:16:20-16:26] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:16:20-16:26] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:16:20-16:26] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:16:20-16:26] statement::Expression "default();" -> removing default statement [debug/optimizer] [unused-types.spicy:19:1-19:21] declaration::Type "type Priv2 = struct { optional __error &always-emit &internal; method tuple, int<64>, const iterator, optional> __parse_foo__Priv2_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error); } &on-heap;" -> null (removing unused type) [debug/optimizer] [unused-types.spicy:19:14-19:20] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [unused-types.spicy:19:14-19:20] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null @@ -972,6 +998,11 @@ [debug/optimizer] [unused-types.spicy:27:14-27:20] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:27:14-27:20] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:27:14-27:20] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-types.spicy:27:14-27:20] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:27:14-27:20] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:27:14-27:20] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:27:14-27:20] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:27:14-27:20] statement::Expression "default();" -> removing default statement [debug/optimizer] [unused-types.spicy:28:14-28:20] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [unused-types.spicy:28:14-28:20] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null [debug/optimizer] [unused-types.spicy:28:14-28:20] declaration::Field "hook void __on_0x25_done();" -> null @@ -993,6 +1024,11 @@ [debug/optimizer] [unused-types.spicy:28:14-28:20] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:28:14-28:20] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:28:14-28:20] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-types.spicy:28:14-28:20] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:28:14-28:20] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:28:14-28:20] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:28:14-28:20] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:28:14-28:20] statement::Expression "default();" -> removing default statement [debug/optimizer] [unused-types.spicy:29:20-32:1] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [unused-types.spicy:29:20-32:1] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null [debug/optimizer] [unused-types.spicy:29:20-32:1] declaration::Field "hook void __on_0x25_done();" -> null @@ -1014,8 +1050,14 @@ [debug/optimizer] [unused-types.spicy:29:20-32:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:29:20-32:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:29:20-32:1] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-types.spicy:29:20-32:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:29:20-32:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:29:20-32:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:29:20-32:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:29:20-32:1] statement::Expression "default();" -> removing default statement [debug/optimizer] [unused-types.spicy:31:5-31:13] declaration::Field "hook void __on_x(value_ref __dd);" -> null [debug/optimizer] [unused-types.spicy:31:5-31:13] operator_::struct_::MemberCall "(*self).__on_x((*self).x)" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-types.spicy:31:5-31:13] statement::Expression "default();" -> removing default statement [debug/optimizer] [unused-types.spicy:35:1-35:30] declaration::Type "type Priv7 = enum { A = 0, B = 1, C = 2 };" -> null (removing unused type) [debug/optimizer] [unused-types.spicy:43:22-46:1] declaration::Field "hook optional __str__();" -> null [debug/optimizer] [unused-types.spicy:43:22-46:1] declaration::Field "hook void __on_0x25_confirmed() &needed-by-feature="synchronization";" -> null @@ -1038,6 +1080,11 @@ [debug/optimizer] [unused-types.spicy:43:22-46:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:43:22-46:1] operator_::struct_::MemberCall "(*self).__on_0x25_finally()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) [debug/optimizer] [unused-types.spicy:43:22-46:1] operator_::struct_::MemberCall "(*self).__on_0x25_init()" -> expression::Ctor "default()" (replacing call to unimplemented method with default value) +[debug/optimizer] [unused-types.spicy:43:22-46:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:43:22-46:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:43:22-46:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:43:22-46:1] statement::Expression "default();" -> removing default statement +[debug/optimizer] [unused-types.spicy:43:22-46:1] statement::Expression "default();" -> removing default statement [debug/optimizer] removing field for unused method foo::Priv10::__on_0x25_confirmed [debug/optimizer] removing field for unused method foo::Priv10::__on_0x25_done [debug/optimizer] removing field for unused method foo::Priv10::__on_0x25_error diff --git a/tests/Baseline/spicy.optimization.unused-types/opt.hlt b/tests/Baseline/spicy.optimization.unused-types/opt.hlt index ba7b2e1245..99122725de 100644 --- a/tests/Baseline/spicy.optimization.unused-types/opt.hlt +++ b/tests/Baseline/spicy.optimization.unused-types/opt.hlt @@ -136,35 +136,21 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__Pub2_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::Pub2::__parse_foo__Pub2_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/unused-types.spicy:16:20-16:26" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; @@ -247,35 +233,21 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__Priv5_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::Priv5::__parse_foo__Priv5_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/unused-types.spicy:27:14-27:20" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; @@ -290,35 +262,21 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__Priv6_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::Priv6::__parse_foo__Priv6_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/unused-types.spicy:28:14-28:20" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; @@ -333,26 +291,15 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__Pub3_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } @@ -374,12 +321,6 @@ method method tuple, int<64>, const iterator, optiona (__cur, __lah, __lahe, __error) = (*(*self).x).__parse_stage1(__data, __begin, __cur, __trim, __lah, __lahe, __error); # End parsing production: Unit: foo__Priv6_2 -> - (*self).__error = __error; - default(); - __error = (*self).__error; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; @@ -453,35 +394,21 @@ method method tuple, int<64>, const iterator, optiona try { hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); - (*self).__error = __error; - default(); - __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_foo__Priv10_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } - catch ( hilti::SystemException __except ) { - default(); - (*self).__error = __error; - default(); - __error = (*self).__error; + catch ( hilti::SystemException __except ) throw; - } - (*self).__error = __error; - default(); - __error = (*self).__error; return __result; } method method tuple, int<64>, const iterator, optional> foo::Priv10::__parse_foo__Priv10_stage2(inout value_ref __data, iterator __begin, copy view __cur, copy bool __trim, copy int<64> __lah, copy iterator __lahe, copy optional __error) { # "<...>/unused-types.spicy:43:22-46:1" local tuple, int<64>, const iterator, optional> __result; - (*self).__error = __error; - default(); - __error = (*self).__error; hilti::debugDedent("spicy"); __result = (__cur, __lah, __lahe, __error); return __result; diff --git a/tests/Baseline/spicy.rt.debug-trace/.stderr b/tests/Baseline/spicy.rt.debug-trace/.stderr index 5333374e6c..3e61fd9f14 100644 --- a/tests/Baseline/spicy.rt.debug-trace/.stderr +++ b/tests/Baseline/spicy.rt.debug-trace/.stderr @@ -16,7 +16,7 @@ [hilti-trace] : (__ncur, __lahead, __lahead_end, __error) = (*__unit).__parse_stage1(__data, begin(__ncur), __ncur, True, __lahead, __lahead_end, __error); [hilti-trace] : # "<...>/debug-trace.spicy:8:20-13:1" [hilti-trace] : local tuple, int<64>, const iterator, optional> __result; -[hilti-trace] : try { hilti::debug("spicy", "Mini::Test"); hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); (*self).__error = __error; (*self).__on_0x25_init(); __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_Mini__Test_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } catch ( hilti::SystemException __except ) { default(); (*self).__error = __error; default(); __error = (*self).__error; throw; } +[hilti-trace] : try { hilti::debug("spicy", "Mini::Test"); hilti::debugIndent("spicy"); local iterator __begin = begin(__cur); (*self).__error = __error; (*self).__on_0x25_init(); __error = (*self).__error; local strong_ref filtered = Null; if ( ! filtered ) __result = (*self).__parse_Mini__Test_stage2(__data, __begin, __cur, __trim, __lah, __lahe, __error); } catch ( hilti::SystemException __except ) { throw; } [hilti-trace] : hilti::debug("spicy", "Mini::Test"); [hilti-trace] : hilti::debugIndent("spicy"); [hilti-trace] : local iterator __begin = begin(__cur); @@ -72,9 +72,6 @@ [hilti-trace] : hilti::debugDedent("spicy"); [hilti-trace] : __result = (__cur, __lah, __lahe, __error); [hilti-trace] : return __result; -[hilti-trace] : (*self).__error = __error; -[hilti-trace] debug-trace.spicy:8:20-13:1: : default(); -[hilti-trace] : __error = (*self).__error; [hilti-trace] : return __result; [hilti-trace] : hilti::debugDedent("spicy-verbose"); [hilti-trace] : # End parsing production: Unit: Mini__Test -> f1 f2 diff --git a/tests/Baseline/spicy.types.sink.reassembler.wrong-init-seq/output b/tests/Baseline/spicy.types.sink.reassembler.wrong-init-seq/output index 0259ea0fc5..3e80a1dd70 100644 --- a/tests/Baseline/spicy.types.sink.reassembler.wrong-init-seq/output +++ b/tests/Baseline/spicy.types.sink.reassembler.wrong-init-seq/output @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[error] terminating with uncaught exception of type spicy::rt::SinkError: sink cannot update initial sequence number after activity has already been seen (<...>/wrong-init-seq.spicy:20:19-38:1) +[error] terminating with uncaught exception of type spicy::rt::SinkError: sink cannot update initial sequence number after activity has already been seen (<...>/wrong-init-seq.spicy:14:9-14:50) diff --git a/tests/spicy/types/bytes/parse-length.spicy b/tests/spicy/types/bytes/parse-length.spicy index f2ff438959..3e67259933 100644 --- a/tests/spicy/types/bytes/parse-length.spicy +++ b/tests/spicy/types/bytes/parse-length.spicy @@ -9,6 +9,10 @@ # # Ensure we don't get any look-ahead checks when parsing the literals, we don't need them here. # @TEST-EXEC: spicyc -p %INPUT | grep -vq 'if.*lah' +# +# Ensure our peephole optimizer removes `(*self).__error = __error; default(); __error = (*self).__error;` blocks +# @TEST-EXEC-FAIL: spicyc -p %INPUT | grep -q 'default()' +# @TEST-EXEC-FAIL: spicyc -p %INPUT | grep -v 'default()' | grep -A1 '(.self).__error = __error' | grep -q -B1 "__error = (.self).__error" module Test;