diff --git a/mypyc/lower/registry.py b/mypyc/lower/registry.py index 3feedfc385ee..a20990fe39ae 100644 --- a/mypyc/lower/registry.py +++ b/mypyc/lower/registry.py @@ -1,20 +1,22 @@ from __future__ import annotations -from typing import Callable, Final +from typing import Callable, Final, Optional, TypeVar from mypyc.ir.ops import Value from mypyc.irbuild.ll_builder import LowLevelIRBuilder LowerFunc = Callable[[LowLevelIRBuilder, list[Value], int], Value] +LowerFuncOpt = Callable[[LowLevelIRBuilder, list[Value], int], Optional[Value]] +lowering_registry: Final[dict[str, LowerFuncOpt]] = {} -lowering_registry: Final[dict[str, LowerFunc]] = {} +LF = TypeVar("LF", LowerFunc, LowerFuncOpt) -def lower_primitive_op(name: str) -> Callable[[LowerFunc], LowerFunc]: +def lower_primitive_op(name: str) -> Callable[[LF], LF]: """Register a handler that generates low-level IR for a primitive op.""" - def wrapper(f: LowerFunc) -> LowerFunc: + def wrapper(f: LF) -> LF: assert name not in lowering_registry lowering_registry[name] = f return f diff --git a/mypyc/transform/ir_transform.py b/mypyc/transform/ir_transform.py index a631bd7352b5..326a5baca1e7 100644 --- a/mypyc/transform/ir_transform.py +++ b/mypyc/transform/ir_transform.py @@ -119,6 +119,9 @@ def visit_unreachable(self, op: Unreachable) -> None: self.add(op) def visit_assign(self, op: Assign) -> Value | None: + if op.src in self.op_map and self.op_map[op.src] is None: + # Special case: allow removing register initialization assignments + return None return self.add(op) def visit_assign_multi(self, op: AssignMulti) -> Value | None: diff --git a/mypyc/transform/lower.py b/mypyc/transform/lower.py index b717657095f9..f5768242aff1 100644 --- a/mypyc/transform/lower.py +++ b/mypyc/transform/lower.py @@ -9,6 +9,8 @@ package. """ +from __future__ import annotations + from mypyc.ir.func_ir import FuncIR from mypyc.ir.ops import PrimitiveOp, Value from mypyc.irbuild.ll_builder import LowLevelIRBuilder @@ -25,7 +27,7 @@ def lower_ir(ir: FuncIR, options: CompilerOptions) -> None: class LoweringVisitor(IRTransform): - def visit_primitive_op(self, op: PrimitiveOp) -> Value: + def visit_primitive_op(self, op: PrimitiveOp) -> Value | None: # The lowering implementation functions of various primitive ops are stored # in a registry, which is populated using function decorators. The name # of op (such as "int_eq") is used as the key.