Skip to content

Commit ac6dc18

Browse files
authored
[mypyc] Try adjusting error kinds for all blocks (#15262)
`adjust_error_kinds()` should be run over every block, but the old impl. of `insert_exception_handling()` would stop iterating over blocks once it generated a default error handler. This made sense for its original purpose, but unfortunately limits the effectiveness of `adjust_error_kinds()`. Changing `insert_exception_handling()` to loop over every block no matter what also means we can get rid of the weird GetAttr special casing in the branch emit logic (stumbling across that is what made me investigate in the first place!). This reduces self-compile LOC by 1.1% in my experiments (avoiding error branches sometimes eliminates register assignments or on-error decrefs... according to my brief look through the C diff between master and this patch). | Revision | Self-compile C LOC | |--------|--------| | PR | 2 265 486 (**-1.1%**) | | Master (905c2cb) | 2 290 748 | Notable removals in the diff (other than the all of the label renumbering) ...[^1] ![image](https://github.com/python/mypy/assets/63936253/3efee503-0c63-441f-9ce8-2e4d7083d5e5) ![image](https://github.com/python/mypy/assets/63936253/06136e2a-4315-40aa-9ca5-ec72bbd7ac45) [^1]: apologies for the screenshots, this diff was generated during a SSH session so copying and pasting is a real pain.
1 parent f66199f commit ac6dc18

File tree

2 files changed

+4
-13
lines changed

2 files changed

+4
-13
lines changed

mypyc/codegen/emitfunc.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,6 @@ def visit_goto(self, op: Goto) -> None:
197197

198198
def visit_branch(self, op: Branch) -> None:
199199
true, false = op.true, op.false
200-
if op.op == Branch.IS_ERROR and isinstance(op.value, GetAttr) and not op.negated:
201-
op2 = op.value
202-
if op2.class_type.class_ir.is_always_defined(op2.attr):
203-
# Getting an always defined attribute never fails, so the branch can be omitted.
204-
if false is not self.next_block:
205-
self.emit_line(f"goto {self.label(false)};")
206-
return
207200
negated = op.negated
208201
negated_rare = False
209202
if true is self.next_block and op.traceback_entry is None:

mypyc/transform/exceptions.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@ def insert_exception_handling(ir: FuncIR) -> None:
4343
# Generate error block if any ops may raise an exception. If an op
4444
# fails without its own error handler, we'll branch to this
4545
# block. The block just returns an error value.
46-
error_label = None
46+
error_label: BasicBlock | None = None
4747
for block in ir.blocks:
4848
adjust_error_kinds(block)
49-
can_raise = any(op.can_raise() for op in block.ops)
50-
if can_raise:
51-
error_label = add_handler_block(ir)
52-
break
49+
if error_label is None and any(op.can_raise() for op in block.ops):
50+
error_label = add_default_handler_block(ir)
5351
if error_label:
5452
ir.blocks = split_blocks_at_errors(ir.blocks, error_label, ir.traceback_name)
5553

5654

57-
def add_handler_block(ir: FuncIR) -> BasicBlock:
55+
def add_default_handler_block(ir: FuncIR) -> BasicBlock:
5856
block = BasicBlock()
5957
ir.blocks.append(block)
6058
op = LoadErrorValue(ir.ret_type)

0 commit comments

Comments
 (0)