"""Transform IR to lower-level ops. Higher-level ops are used in earlier compiler passes, as they make various analyses, optimizations and transforms easier to implement. Later passes use lower-level ops, as they are easier to generate code from, and they help with lower-level optimizations. Lowering of various primitive ops is implemented in the mypyc.lower 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 from mypyc.lower.registry import lowering_registry from mypyc.options import CompilerOptions from mypyc.transform.ir_transform import IRTransform def lower_ir(ir: FuncIR, options: CompilerOptions) -> None: builder = LowLevelIRBuilder(None, options) visitor = LoweringVisitor(builder) visitor.transform_blocks(ir.blocks) ir.blocks = builder.blocks class LoweringVisitor(IRTransform): 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. lower_fn = lowering_registry[op.desc.name] return lower_fn(self.builder, op.args, op.line)