From a0197d8d1e2c6c3c5e8a2fcd303f67ef14b39c77 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 14 Aug 2024 11:12:41 +0200 Subject: [PATCH] Add peephole optimizer for final AST tuning. We use this to remove two statement constructs that the main optimizer may leave behind: 1. `default()` 2. `(*self).__error = __error; __error = (*self).__error;` The second case is a quite specific situation that eventually, once we have CFG/DFG tracking, the main optimizer should be able to cover more generically. However, for now, it's just not nice to always have these blocks in the generated C++ code, so adding this special case seems useful. Couples notes on (2): - Per #1592, case 2 may also have overhead. Closes #1592. - Technically, this optimization isn't always correct: subsequent code could assume that `(*self).__error` is set, whereas after removal it's not (or not to the expected value). However, `__error` is strictly-internal state, and we know that we don't use it any different, so this seems ok until we have more general optimizer logic. --- hilti/toolchain/include/ast/node.h | 21 ++++ hilti/toolchain/src/compiler/optimizer.cc | 102 ++++++++++++++++++ .../opt.hlt | 8 ++ .../opt.hlt | 4 + .../hilti.optimization.unimplemented_hook/log | 2 + .../opt.hlt | 2 - .../log | 19 ++++ .../opt.hlt | 31 +----- .../log | 23 ++++ .../opt.hlt | 33 ------ .../spicy.optimization.unused-functions/log | 27 +++++ .../opt.hlt | 48 +-------- .../spicy.optimization.unused-types/log | 47 ++++++++ .../spicy.optimization.unused-types/opt.hlt | 83 +------------- tests/Baseline/spicy.rt.debug-trace/.stderr | 5 +- .../output | 2 +- .../optimization/peephole-default-void.hlt | 12 +++ .../optimization/peephole-error-push-pop.hlt | 19 ++++ tests/spicy/types/bytes/parse-length.spicy | 4 + 19 files changed, 299 insertions(+), 193 deletions(-) create mode 100644 tests/Baseline/hilti.optimization.peephole-default-void/opt.hlt create mode 100644 tests/Baseline/hilti.optimization.peephole-error-push-pop/opt.hlt create mode 100644 tests/hilti/optimization/peephole-default-void.hlt create mode 100644 tests/hilti/optimization/peephole-error-push-pop.hlt diff --git a/hilti/toolchain/include/ast/node.h b/hilti/toolchain/include/ast/node.h index 0771d01d0f..ad8cdb353d 100644 --- a/hilti/toolchain/include/ast/node.h +++ b/hilti/toolchain/include/ast/node.h @@ -456,6 +456,27 @@ 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..d9c32e6e74 100644 --- a/hilti/toolchain/src/compiler/optimizer.cc +++ b/hilti/toolchain/src/compiler/optimizer.cc @@ -907,6 +907,101 @@ struct ConstantFoldingVisitor : OptimizerVisitor { } }; +/** + * Visitor running on the final, optimized AST to perform additional peephole + * optimizations. Will run repeatedly until it performs no further changes. + */ +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 of the form `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; + } + } + } + } +}; + // This visitor collects requirement attributes in the AST and toggles unused features. class FeatureRequirementsVisitor : public visitor::MutatingPreOrder { public: @@ -1494,6 +1589,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.peephole-default-void/opt.hlt b/tests/Baseline/hilti.optimization.peephole-default-void/opt.hlt new file mode 100644 index 0000000000..783c4b6086 --- /dev/null +++ b/tests/Baseline/hilti.optimization.peephole-default-void/opt.hlt @@ -0,0 +1,8 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +module Test { + + +public function void foo() { +} + +} diff --git a/tests/Baseline/hilti.optimization.peephole-error-push-pop/opt.hlt b/tests/Baseline/hilti.optimization.peephole-error-push-pop/opt.hlt new file mode 100644 index 0000000000..e244e143bf --- /dev/null +++ b/tests/Baseline/hilti.optimization.peephole-error-push-pop/opt.hlt @@ -0,0 +1,4 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +module Test { + +} 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 b1dcca1e17..0d0e69d683 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 4acb68b8f0..797aae34aa 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 18afe87204..394863e5f0 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 7051adbb38..071e6e636f 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 cb0fa1a05e..937893397b 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 5e81d57d41..637066b030 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 eb07bae400..b4e3f2062a 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 a9430daf50..a95b0314ac 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 f2ae95977d..931d64939c 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/hilti/optimization/peephole-default-void.hlt b/tests/hilti/optimization/peephole-default-void.hlt new file mode 100644 index 0000000000..b7e189a268 --- /dev/null +++ b/tests/hilti/optimization/peephole-default-void.hlt @@ -0,0 +1,12 @@ +# @TEST-EXEC: hiltic -p %INPUT >opt.hlt +# @TEST-EXEC: btest-diff opt.hlt +# +# @TEST-DOC: Test removal of no-op `default()` statements + +module Test { + +public function void foo() { + default(); +} + +} diff --git a/tests/hilti/optimization/peephole-error-push-pop.hlt b/tests/hilti/optimization/peephole-error-push-pop.hlt new file mode 100644 index 0000000000..23a4828c88 --- /dev/null +++ b/tests/hilti/optimization/peephole-error-push-pop.hlt @@ -0,0 +1,19 @@ +# @TEST-EXEC: hiltic -V -p %INPUT >opt.hlt +# @TEST-EXEC: btest-diff opt.hlt +# +# @TEST-DOC: Test removal of redundant __error assignments. + +module Test { + +type Foo = struct { + method void test(); + int<64> __error; # name is internal, hence compiling with -V; type does not matter +}; + +function void Foo::test() { + local int<64> __error; + (*self).__error = __error; + __error = (*self).__error; +} + +} 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;