Skip to content

Commit c94d8e3

Browse files
authored
[mypyc] Provide an easier way to define IR-to-IR transforms (#16998)
This makes it easy to define simple IR-to-IR transforms by subclassing `IRTansform` and overriding some visit methods. Add an implementation of a simple copy propagation optimization as an example. This will be used by the implementation of mypyc/mypyc#854, and this can also be used for various optimizations. The IR transform preserves the identities of ops that are not modified. This means that the old IR is no longer valid after the transform, but the transform can be fast since we don't need to allocate many objects if only a small subset of ops will be modified by a transform.
1 parent e0ad952 commit c94d8e3

File tree

7 files changed

+904
-17
lines changed

7 files changed

+904
-17
lines changed

mypyc/codegen/emitmodule.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
from mypyc.irbuild.prepare import load_type_map
5757
from mypyc.namegen import NameGenerator, exported_name
5858
from mypyc.options import CompilerOptions
59+
from mypyc.transform.copy_propagation import do_copy_propagation
5960
from mypyc.transform.exceptions import insert_exception_handling
6061
from mypyc.transform.refcount import insert_ref_count_opcodes
6162
from mypyc.transform.uninit import insert_uninit_checks
@@ -225,18 +226,16 @@ def compile_scc_to_ir(
225226
if errors.num_errors > 0:
226227
return modules
227228

228-
# Insert uninit checks.
229229
for module in modules.values():
230230
for fn in module.functions:
231+
# Insert uninit checks.
231232
insert_uninit_checks(fn)
232-
# Insert exception handling.
233-
for module in modules.values():
234-
for fn in module.functions:
233+
# Insert exception handling.
235234
insert_exception_handling(fn)
236-
# Insert refcount handling.
237-
for module in modules.values():
238-
for fn in module.functions:
235+
# Insert refcount handling.
239236
insert_ref_count_opcodes(fn)
237+
# Perform copy propagation optimization.
238+
do_copy_propagation(fn, compiler_options)
240239

241240
return modules
242241

mypyc/irbuild/builder.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def __init__(
160160
options: CompilerOptions,
161161
singledispatch_impls: dict[FuncDef, list[RegisterImplInfo]],
162162
) -> None:
163-
self.builder = LowLevelIRBuilder(current_module, errors, mapper, options)
163+
self.builder = LowLevelIRBuilder(errors, options)
164164
self.builders = [self.builder]
165165
self.symtables: list[dict[SymbolNode, SymbolTarget]] = [{}]
166166
self.runtime_args: list[list[RuntimeArg]] = [[]]
@@ -1111,9 +1111,7 @@ def flatten_classes(self, arg: RefExpr | TupleExpr) -> list[ClassIR] | None:
11111111
def enter(self, fn_info: FuncInfo | str = "") -> None:
11121112
if isinstance(fn_info, str):
11131113
fn_info = FuncInfo(name=fn_info)
1114-
self.builder = LowLevelIRBuilder(
1115-
self.current_module, self.errors, self.mapper, self.options
1116-
)
1114+
self.builder = LowLevelIRBuilder(self.errors, self.options)
11171115
self.builder.set_module(self.module_name, self.module_path)
11181116
self.builders.append(self.builder)
11191117
self.symtables.append({})

mypyc/irbuild/ll_builder.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@
126126
short_int_rprimitive,
127127
str_rprimitive,
128128
)
129-
from mypyc.irbuild.mapper import Mapper
130129
from mypyc.irbuild.util import concrete_arg_kind
131130
from mypyc.options import CompilerOptions
132131
from mypyc.primitives.bytes_ops import bytes_compare
@@ -220,12 +219,8 @@
220219

221220

222221
class LowLevelIRBuilder:
223-
def __init__(
224-
self, current_module: str, errors: Errors, mapper: Mapper, options: CompilerOptions
225-
) -> None:
226-
self.current_module = current_module
222+
def __init__(self, errors: Errors | None, options: CompilerOptions) -> None:
227223
self.errors = errors
228-
self.mapper = mapper
229224
self.options = options
230225
self.args: list[Register] = []
231226
self.blocks: list[BasicBlock] = []
@@ -2394,6 +2389,7 @@ def _create_dict(self, keys: list[Value], values: list[Value], line: int) -> Val
23942389
return self.call_c(dict_new_op, [], line)
23952390

23962391
def error(self, msg: str, line: int) -> None:
2392+
assert self.errors is not None, "cannot generate errors in this compiler phase"
23972393
self.errors.error(msg, self.module_path, line)
23982394

23992395

0 commit comments

Comments
 (0)