(
mut self,
opts: &crate::compile::CompileOpts,
)
| 189 | |
| 190 | impl CodeInfo { |
| 191 | pub fn finalize_code( |
| 192 | mut self, |
| 193 | opts: &crate::compile::CompileOpts, |
| 194 | ) -> crate::InternalResult<CodeObject> { |
| 195 | // Constant folding passes |
| 196 | self.fold_binop_constants(); |
| 197 | self.remove_nops(); |
| 198 | self.fold_unary_negative(); |
| 199 | self.fold_binop_constants(); // re-run after unary folding: -1 + 2 → 1 |
| 200 | self.remove_nops(); // remove NOPs so tuple/list/set see contiguous LOADs |
| 201 | self.fold_tuple_constants(); |
| 202 | self.fold_list_constants(); |
| 203 | self.fold_set_constants(); |
| 204 | self.remove_nops(); // remove NOPs from collection folding |
| 205 | self.fold_const_iterable_for_iter(); |
| 206 | self.convert_to_load_small_int(); |
| 207 | self.remove_unused_consts(); |
| 208 | self.remove_nops(); |
| 209 | |
| 210 | // DCE always runs (removes dead code after terminal instructions) |
| 211 | self.dce(); |
| 212 | // Peephole optimizer creates superinstructions matching CPython |
| 213 | self.peephole_optimize(); |
| 214 | |
| 215 | // Phase 1: _PyCfg_OptimizeCodeUnit (flowgraph.c) |
| 216 | // Split blocks so each block has at most one branch as its last instruction |
| 217 | split_blocks_at_jumps(&mut self.blocks); |
| 218 | mark_except_handlers(&mut self.blocks); |
| 219 | label_exception_targets(&mut self.blocks); |
| 220 | // optimize_cfg: jump threading (before push_cold_blocks_to_end) |
| 221 | jump_threading(&mut self.blocks); |
| 222 | self.eliminate_unreachable_blocks(); |
| 223 | self.remove_nops(); |
| 224 | // TODO: insert_superinstructions disabled pending StoreFastLoadFast VM fix |
| 225 | push_cold_blocks_to_end(&mut self.blocks); |
| 226 | |
| 227 | // Phase 2: _PyCfg_OptimizedCfgToInstructionSequence (flowgraph.c) |
| 228 | normalize_jumps(&mut self.blocks); |
| 229 | inline_small_or_no_lineno_blocks(&mut self.blocks); |
| 230 | self.dce(); // re-run within-block DCE after normalize_jumps creates new instructions |
| 231 | self.eliminate_unreachable_blocks(); |
| 232 | resolve_line_numbers(&mut self.blocks); |
| 233 | duplicate_end_returns(&mut self.blocks); |
| 234 | self.dce(); // truncate after terminal in blocks that got return duplicated |
| 235 | self.eliminate_unreachable_blocks(); // remove now-unreachable last block |
| 236 | // optimize_load_fast: after normalize_jumps |
| 237 | self.optimize_load_fast_borrow(); |
| 238 | self.optimize_load_global_push_null(); |
| 239 | |
| 240 | let max_stackdepth = self.max_stackdepth()?; |
| 241 | |
| 242 | let Self { |
| 243 | flags, |
| 244 | source_path, |
| 245 | private: _, // private is only used during compilation |
| 246 | |
| 247 | mut blocks, |
| 248 | current_block: _, |
no test coverage detected