@@ -1554,7 +1554,9 @@ def _extract_switch_arms(expression, ir):
15541554 return None , None
15551555
15561556
1557- def _generate_optimized_ok_method_body (fields , ir , subexpressions ):
1557+ def _generate_optimized_ok_method_body (
1558+ fields , ir , subexpressions , allow_tail_form = False
1559+ ):
15581560 """Generates optimized C++ code for the Ok() method body.
15591561
15601562 This function optimizes validation logic for structures with conditional
@@ -1698,6 +1700,19 @@ def _generate_optimized_ok_method_body(fields, ir, subexpressions):
16981700 if total_entries < 2 :
16991701 group ["type" ] = "demoted_to_if"
17001702
1703+ # Find the last surviving switch group; only that one is eligible for
1704+ # tail-form case rewrites, since tail-form turns the switch into the
1705+ # function's exit and any later block would be unreachable.
1706+ last_switch_key = None
1707+ if allow_tail_form :
1708+ for key in reversed (ordered_keys ):
1709+ if groups [key ]["type" ] == "switch" :
1710+ last_switch_key = key
1711+ break
1712+ # Any non-switch block after a switch means that switch is
1713+ # not the last statement in Ok(); abandon tail-form.
1714+ break
1715+
17011716 blocks = []
17021717 for key in ordered_keys :
17031718 group = groups [key ]
@@ -1711,6 +1726,7 @@ def _generate_optimized_ok_method_body(fields, ir, subexpressions):
17111726 group ["known_check_required" ] = not _is_discriminant_provably_known (
17121727 group ["discrim_expr" ], fields
17131728 )
1729+ group ["tail_form" ] = key == last_switch_key
17141730 blocks .append (_emit_switch_block (group ))
17151731 elif group ["type" ] == "demoted_to_if" :
17161732 for field in group ["encounter_order" ]:
@@ -1765,7 +1781,8 @@ def _render_case_body(entries):
17651781def _emit_switch_block (group ):
17661782 """Emits a complete switch block from a collected switch group.
17671783
1768- Performs case-label sorting and identical-body coalescing:
1784+ Performs case-label sorting, identical-body coalescing, and (when the
1785+ switch is the last statement in Ok()) tail-form arm rewriting:
17691786
17701787 * Case labels within an arm are sorted by underlying numeric value, so
17711788 the C++ compiler is presented with monotonic case sequences and is
@@ -1775,31 +1792,63 @@ def _emit_switch_block(group):
17751792 multiple fields share an existence condition) are merged into a
17761793 single multi-label arm, so the compiler emits one body for all of
17771794 them rather than duplicating per case.
1795+ * When the switch is the function's tail and an arm validates a single
1796+ field with no residual, the arm body becomes `return field().Ok();`
1797+ instead of `if (!field().Ok()) return false; break;`. Trims one
1798+ conditional branch per qualifying arm — adds up across large
1799+ tagged-union schemas on Thumb-2 / MicroBlaze.
17781800 """
1779- body_to_labels = {}
1780- body_first_seen = {}
1801+ tail_form_enabled = group .get ("tail_form" , False )
1802+
1803+ # Group cases by rendered body (for identical-body coalescing). Track
1804+ # the original entries so we can decide tail-form eligibility per arm.
1805+ body_to_arm = {}
17811806 for case_str , case_entry in group ["cases_by_label" ].items ():
17821807 body = _render_case_body (case_entry ["entries" ])
1783- body_to_labels .setdefault (body , []).append ((case_entry ["sort_key" ], case_str ))
1784- if body not in body_first_seen :
1785- body_first_seen [body ] = case_entry ["sort_key" ]
1808+ arm = body_to_arm .setdefault (
1809+ body ,
1810+ {
1811+ "labels" : [],
1812+ "entries" : case_entry ["entries" ],
1813+ "first_sort_key" : case_entry ["sort_key" ],
1814+ },
1815+ )
1816+ arm ["labels" ].append ((case_entry ["sort_key" ], case_str ))
1817+ if case_entry ["sort_key" ] < arm ["first_sort_key" ]:
1818+ arm ["first_sort_key" ] = case_entry ["sort_key" ]
17861819
1787- arms = []
1788- for body , labels in body_to_labels .items ():
1789- labels .sort () # by (sort_key, case_str)
1790- arms .append ((body_first_seen [body ], labels , body ))
1791- arms .sort (key = lambda arm : arm [0 ])
1820+ sorted_arms = sorted (body_to_arm .values (), key = lambda a : a ["first_sort_key" ])
1821+ for arm in sorted_arms :
1822+ arm ["labels" ].sort ()
17921823
17931824 rendered_arms = []
1794- for _ , labels , body in arms :
1795- case_labels = "" .join (" case {}:\n " .format (cs ) for _ , cs in labels )
1796- rendered_arms .append (
1797- code_template .format_template (
1798- _TEMPLATES .ok_method_switch_arm ,
1799- case_labels = case_labels ,
1800- case_body = body ,
1801- )
1825+ for arm in sorted_arms :
1826+ case_labels = "" .join (
1827+ " case {}:\n " .format (cs ) for _ , cs in arm ["labels" ]
18021828 )
1829+ # Tail-form is eligible when the arm has a single bare-equality
1830+ # entry (one field, no residual). In that case the case body
1831+ # collapses to a single Ok() call we can return directly.
1832+ if (
1833+ tail_form_enabled
1834+ and len (arm ["entries" ]) == 1
1835+ and not arm ["entries" ][0 ][1 ] # no residual
1836+ ):
1837+ field = arm ["entries" ][0 ][0 ]
1838+ rendered_arms .append (
1839+ "{0} return {1}().Ok();\n " .format (
1840+ case_labels , _cpp_field_name (field .name .name .text )
1841+ )
1842+ )
1843+ else :
1844+ body = _render_case_body (arm ["entries" ])
1845+ rendered_arms .append (
1846+ code_template .format_template (
1847+ _TEMPLATES .ok_method_switch_arm ,
1848+ case_labels = case_labels ,
1849+ case_body = body ,
1850+ )
1851+ )
18031852
18041853 if group .get ("known_check_required" , True ):
18051854 known_check = (
@@ -1979,6 +2028,11 @@ def _generate_structure_definition(type_ir, ir, config: Config):
19792028 ],
19802029 ir ,
19812030 ok_subexpressions ,
2031+ # When the final group emitted is a switch and there is nothing
2032+ # after it (no [requires] clause), each case body's
2033+ # `if (!X().Ok()) return false; break;` can be rewritten as
2034+ # `return X().Ok();` — one fewer branch per case.
2035+ allow_tail_form = (requires_check == "" ),
19822036 )
19832037
19842038 class_forward_declarations = code_template .format_template (
0 commit comments