Skip to content

[mypyc] Merge two ops and obsolete more old registry #9368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions mypyc/irbuild/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
from mypy.types import TupleType, get_proper_type

from mypyc.ir.ops import (
Value, TupleGet, TupleSet, PrimitiveOp, BasicBlock, OpDescription, Assign, LoadAddress
Value, TupleGet, TupleSet, BasicBlock, OpDescription, Assign, LoadAddress
)
from mypyc.ir.rtypes import RTuple, object_rprimitive, is_none_rprimitive, is_int_rprimitive
from mypyc.ir.func_ir import FUNC_CLASSMETHOD, FUNC_STATICMETHOD
from mypyc.primitives.registry import name_ref_ops, CFunctionDescription, builtin_names
from mypyc.primitives.registry import CFunctionDescription, builtin_names
from mypyc.primitives.generic_ops import iter_op
from mypyc.primitives.misc_ops import new_slice_op, ellipsis_op, type_op
from mypyc.primitives.list_ops import new_list_op, list_append_op, list_extend_op
Expand Down Expand Up @@ -49,11 +49,6 @@ def transform_name_expr(builder: IRBuilder, expr: NameExpr) -> Value:
return builder.true()
if fullname == 'builtins.False':
return builder.false()
if fullname in name_ref_ops:
# Use special access op for this particular name.
desc = name_ref_ops[fullname]
assert desc.result_type is not None
return builder.add(PrimitiveOp([], desc, expr.line))

if isinstance(expr.node, Var) and expr.node.is_final:
value = builder.emit_load_final(
Expand Down
2 changes: 1 addition & 1 deletion mypyc/irbuild/for_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ def unsafe_index(
# since we want to use __getitem__ if we don't have an unsafe version,
# so we just check manually.
if is_list_rprimitive(target.type):
return builder.primitive_op(list_get_item_unsafe_op, [target, index], line)
return builder.call_c(list_get_item_unsafe_op, [target, index], line)
else:
return builder.gen_method_call(target, '__getitem__', [index], None, line)

Expand Down
8 changes: 2 additions & 6 deletions mypyc/irbuild/ll_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
STATIC_PREFIX
)
from mypyc.primitives.registry import (
method_ops, func_ops,
c_method_call_ops, CFunctionDescription, c_function_ops,
func_ops, c_method_call_ops, CFunctionDescription, c_function_ops,
c_binary_ops, c_unary_ops
)
from mypyc.primitives.list_ops import (
Expand Down Expand Up @@ -1025,13 +1024,10 @@ def translate_special_method_call(self,

Return None if no translation found; otherwise return the target register.
"""
ops = method_ops.get(name, [])
call_c_ops_candidates = c_method_call_ops.get(name, [])
call_c_op = self.matching_call_c(call_c_ops_candidates, [base_reg] + args,
line, result_type)
if call_c_op is not None:
return call_c_op
return self.matching_primitive_op(ops, [base_reg] + args, line, result_type=result_type)
return call_c_op

def translate_eq_cmp(self,
lreg: Value,
Expand Down
2 changes: 1 addition & 1 deletion mypyc/irbuild/statement.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def transform_import(builder: IRBuilder, node: Import) -> None:
base = name = node_id.split('.')[0]

# Python 3.7 has a nice 'PyImport_GetModule' function that we can't use :(
mod_dict = builder.primitive_op(get_module_dict_op, [], node.line)
mod_dict = builder.call_c(get_module_dict_op, [], node.line)
obj = builder.call_c(dict_get_item_op,
[mod_dict, builder.load_static_unicode(base)], node.line)
builder.gen_method_call(
Expand Down
12 changes: 5 additions & 7 deletions mypyc/primitives/list_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
c_int_rprimitive
)
from mypyc.primitives.registry import (
custom_op, load_address_op, call_emit, c_function_op, c_binary_op, c_method_op
custom_op, load_address_op, c_function_op, c_binary_op, c_method_op, c_custom_op
)


Expand Down Expand Up @@ -66,13 +66,11 @@ def emit_new(emitter: EmitterInterface, args: List[str], dest: str) -> None:

# This is unsafe because it assumes that the index is a non-negative short integer
# that is in-bounds for the list.
list_get_item_unsafe_op = custom_op(
name='__getitem__',
list_get_item_unsafe_op = c_custom_op(
arg_types=[list_rprimitive, short_int_rprimitive],
result_type=object_rprimitive,
error_kind=ERR_NEVER,
format_str='{dest} = {args[0]}[{args[1]}] :: unsafe list',
emit=call_emit('CPyList_GetItemUnsafe'))
return_type=object_rprimitive,
c_function_name='CPyList_GetItemUnsafe',
error_kind=ERR_NEVER)

# list[index] = obj
list_set_item_op = c_method_op(
Expand Down
9 changes: 4 additions & 5 deletions mypyc/primitives/misc_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
int_rprimitive, dict_rprimitive, c_int_rprimitive
)
from mypyc.primitives.registry import (
simple_emit, func_op, custom_op, call_emit,
simple_emit, func_op, custom_op,
c_function_op, c_custom_op, load_address_op
)

Expand Down Expand Up @@ -108,12 +108,11 @@
error_kind=ERR_MAGIC)

# Get the sys.modules dictionary
get_module_dict_op = custom_op(
name='get_module_dict',
get_module_dict_op = c_custom_op(
arg_types=[],
result_type=dict_rprimitive,
return_type=dict_rprimitive,
c_function_name='PyImport_GetModuleDict',
error_kind=ERR_NEVER,
emit=call_emit('PyImport_GetModuleDict'),
is_borrowed=True)

# isinstance(obj, cls)
Expand Down
67 changes: 0 additions & 67 deletions mypyc/primitives/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,6 @@
# Primitive ops for built-in functions (key is function name such as 'builtins.len')
func_ops = {} # type: Dict[str, List[OpDescription]]

# Primitive ops for built-in methods (key is method name such as 'builtins.list.append')
method_ops = {} # type: Dict[str, List[OpDescription]]

# Primitive ops for reading module attributes (key is name such as 'builtins.None')
name_ref_ops = {} # type: Dict[str, OpDescription]

# CallC op for method call(such as 'str.join')
c_method_call_ops = {} # type: Dict[str, List[CFunctionDescription]]

Expand Down Expand Up @@ -109,11 +103,6 @@ def emit(emitter: EmitterInterface, args: List[str], dest: str) -> None:
return emit


def call_emit(func: str) -> EmitCallback:
"""Construct a PrimitiveOp emit callback function that calls a C function."""
return simple_emit('{dest} = %s({comma_args});' % func)


def func_op(name: str,
arg_types: List[RType],
result_type: RType,
Expand Down Expand Up @@ -154,62 +143,6 @@ def func_op(name: str,
return desc


def method_op(name: str,
arg_types: List[RType],
result_type: Optional[RType],
error_kind: int,
emit: EmitCallback,
steals: StealsDescription = False,
is_borrowed: bool = False,
priority: int = 1) -> OpDescription:
"""Define a primitive op that replaces a method call.

Most arguments are similar to func_op().

This will be automatically generated by matching against the AST.

Args:
name: short name of the method (for example, 'append')
arg_types: argument types; the receiver is always the first argument
result_type: type of the result, None if void
"""
ops = method_ops.setdefault(name, [])
assert len(arg_types) > 0
args = ', '.join('{args[%d]}' % i
for i in range(1, len(arg_types)))
type_name = short_name(arg_types[0].name)
if name == '__getitem__':
format_str = '{dest} = {args[0]}[{args[1]}] :: %s' % type_name
else:
format_str = '{dest} = {args[0]}.%s(%s) :: %s' % (name, args, type_name)
desc = OpDescription(name, arg_types, result_type, False, error_kind, format_str, emit,
steals, is_borrowed, priority)
ops.append(desc)
return desc


def name_ref_op(name: str,
result_type: RType,
error_kind: int,
emit: EmitCallback,
is_borrowed: bool = False) -> OpDescription:
"""Define an op that is used to implement reading a module attribute.

This will be automatically generated by matching against the AST.

Most arguments are similar to func_op().

Args:
name: fully-qualified name (e.g. 'builtins.None')
"""
assert name not in name_ref_ops, 'already defined: %s' % name
format_str = '{dest} = %s' % short_name(name)
desc = OpDescription(name, [], result_type, False, error_kind, format_str, emit,
False, is_borrowed, 0)
name_ref_ops[name] = desc
return desc


def custom_op(arg_types: List[RType],
result_type: RType,
error_kind: int,
Expand Down
8 changes: 4 additions & 4 deletions mypyc/test-data/irbuild-basic.test
Original file line number Diff line number Diff line change
Expand Up @@ -1975,7 +1975,7 @@ L1:
r9 = r5 < r8 :: signed
if r9 goto L2 else goto L14 :: bool
L2:
r10 = r4[r5] :: unsafe list
r10 = CPyList_GetItemUnsafe(r4, r5)
r11 = unbox(int, r10)
x = r11
r13 = x & 1
Expand Down Expand Up @@ -2059,7 +2059,7 @@ L1:
r9 = r5 < r8 :: signed
if r9 goto L2 else goto L14 :: bool
L2:
r10 = r4[r5] :: unsafe list
r10 = CPyList_GetItemUnsafe(r4, r5)
r11 = unbox(int, r10)
x = r11
r13 = x & 1
Expand Down Expand Up @@ -2146,7 +2146,7 @@ L1:
r4 = r0 < r3 :: signed
if r4 goto L2 else goto L4 :: bool
L2:
r5 = l[r0] :: unsafe list
r5 = CPyList_GetItemUnsafe(l, r0)
r6 = unbox(tuple[int, int, int], r5)
r7 = r6[0]
x = r7
Expand All @@ -2168,7 +2168,7 @@ L5:
r16 = r12 < r15 :: signed
if r16 goto L6 else goto L8 :: bool
L6:
r17 = l[r12] :: unsafe list
r17 = CPyList_GetItemUnsafe(l, r12)
r18 = unbox(tuple[int, int, int], r17)
r19 = r18[0]
x0 = r19
Expand Down
8 changes: 4 additions & 4 deletions mypyc/test-data/irbuild-statements.test
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ L1:
r4 = r0 < r3 :: signed
if r4 goto L2 else goto L4 :: bool
L2:
r5 = ls[r0] :: unsafe list
r5 = CPyList_GetItemUnsafe(ls, r0)
r6 = unbox(int, r5)
x = r6
r7 = CPyTagged_Add(y, x)
Expand Down Expand Up @@ -849,7 +849,7 @@ L1:
r5 = r1 < r4 :: signed
if r5 goto L2 else goto L4 :: bool
L2:
r6 = a[r1] :: unsafe list
r6 = CPyList_GetItemUnsafe(a, r1)
r7 = unbox(int, r6)
x = r7
r8 = CPyTagged_Add(i, x)
Expand Down Expand Up @@ -932,7 +932,7 @@ L2:
r6 = PyIter_Next(r1)
if is_error(r6) goto L7 else goto L3
L3:
r7 = a[r0] :: unsafe list
r7 = CPyList_GetItemUnsafe(a, r0)
r8 = unbox(int, r7)
x = r8
r9 = unbox(bool, r6)
Expand Down Expand Up @@ -986,7 +986,7 @@ L3:
L4:
r9 = unbox(bool, r3)
x = r9
r10 = b[r1] :: unsafe list
r10 = CPyList_GetItemUnsafe(b, r1)
r11 = unbox(int, r10)
y = r11
x = 0
Expand Down