@@ -2031,7 +2031,6 @@ def normalize_jumps_in_block(
20312031 return backwards_jump
20322032
20332033 def normalize_jumps (self ) -> None :
2034- assert self .stage == ORDERED , self .stage
20352034 seen_blocks = set ()
20362035 new_blocks = {}
20372036 for block in self .ordered_blocks :
@@ -2379,6 +2378,26 @@ def convert_pseudo_conditional_jumps(self) -> None:
23792378 ),
23802379 ]
23812380
2381+ def finalize (self ) -> None :
2382+ """Perform final optimizations and normalization of flow graph."""
2383+ assert self .stage == ACTIVE , self .stage
2384+ self .stage = CLOSED
2385+
2386+ for block in self .ordered_blocks :
2387+ self .normalize_basic_block (block )
2388+
2389+ self .optimizeCFG ()
2390+
2391+ self .stage = CONSTS_CLOSED
2392+ self .trim_unused_consts ()
2393+ self .duplicate_exits_without_lineno ()
2394+ self .propagate_line_numbers ()
2395+ self .firstline = self .firstline or self .first_inst_lineno or 1
2396+ self .guarantee_lineno_for_exits ()
2397+
2398+ self .stage = ORDERED
2399+ self .stage = FINAL
2400+
23822401 def assemble_final_code (self ) -> None :
23832402 """Finish assembling code object components from the final graph."""
23842403 # see compile.c :: optimize_and_assemble_code_unit()
@@ -2393,6 +2412,8 @@ def assemble_final_code(self) -> None:
23932412 self .prepare_localsplus ()
23942413 self .convert_pseudo_ops ()
23952414
2415+ self .normalize_jumps ()
2416+
23962417 self .resolve_unconditional_jumps ()
23972418
23982419 self .optimize_load_fast ()
@@ -2446,8 +2467,11 @@ def normalize_jumps_in_block(
24462467 # the above code, since is_forward(target) won't have changed.
24472468 self .fetch_current ().emit (Instruction ("NOT_TAKEN" , 0 , 0 , last .loc ))
24482469 self .emit_with_loc ("JUMP_BACKWARD" , target , last .loc )
2470+ backwards_jump .startdepth = target .startdepth
2471+
24492472 last .opname = self ._reversed_jumps [last .opname ]
24502473 last .target = block .next
2474+
24512475 block .insert_next (backwards_jump )
24522476 return backwards_jump
24532477
@@ -2815,6 +2839,42 @@ def insert_superinstructions(self) -> None:
28152839 instr , next_instr , "STORE_FAST_STORE_FAST"
28162840 )
28172841
2842+ def optimizeCFG (self ) -> None :
2843+ """Optimize a well-formed CFG."""
2844+ except_handlers = self .compute_except_handlers ()
2845+
2846+ self .label_exception_targets ()
2847+
2848+ assert self .stage == CLOSED , self .stage
2849+
2850+ self .eliminate_empty_basic_blocks ()
2851+
2852+ self .inline_small_exit_blocks ()
2853+
2854+ optimizer = self .flow_graph_optimizer (self )
2855+ self .propagate_line_numbers ()
2856+ for block in self .ordered_blocks :
2857+ optimizer .optimize_basic_block (block )
2858+
2859+ self .remove_redundant_nops_and_pairs (optimizer )
2860+
2861+ for block in self .ordered_blocks :
2862+ # remove redundant nops
2863+ optimizer .clean_basic_block (block , - 1 )
2864+
2865+ self .remove_unreachable_basic_blocks ()
2866+ self .eliminate_empty_basic_blocks ()
2867+
2868+ self .remove_redundant_jumps (optimizer , False )
2869+
2870+ self .stage = OPTIMIZED
2871+
2872+ self .remove_unused_consts ()
2873+ self .add_checks_for_loads_of_uninitialized_variables ()
2874+ self .insert_superinstructions ()
2875+ self .push_cold_blocks_to_end (except_handlers , optimizer )
2876+ self .propagate_line_numbers ()
2877+
28182878 _const_opcodes : set [str ] = set (PyFlowGraph312 ._const_opcodes ) | {"LOAD_SMALL_INT" }
28192879
28202880
0 commit comments