Skip to content

Commit 70eab9a

Browse files
authored
[mypyc] Refactor: use new-style primitives for unary ops (#18213)
1 parent e7c095a commit 70eab9a

File tree

7 files changed

+45
-29
lines changed

7 files changed

+45
-29
lines changed

mypyc/ir/ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ def __init__(
625625
assert error_kind == ERR_NEVER
626626

627627
def __repr__(self) -> str:
628-
return f"<PrimitiveDescription {self.name}>"
628+
return f"<PrimitiveDescription {self.name!r}: {self.arg_types}>"
629629

630630

631631
class PrimitiveOp(RegisterOp):

mypyc/irbuild/ll_builder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,8 +1601,8 @@ def unary_op(self, value: Value, expr_op: str, line: int) -> Value:
16011601
result = self.dunder_op(value, None, expr_op, line)
16021602
if result is not None:
16031603
return result
1604-
call_c_ops_candidates = unary_ops.get(expr_op, [])
1605-
target = self.matching_call_c(call_c_ops_candidates, [value], line)
1604+
primitive_ops_candidates = unary_ops.get(expr_op, [])
1605+
target = self.matching_primitive_op(primitive_ops_candidates, [value], line)
16061606
assert target, "Unsupported unary operation: %s" % expr_op
16071607
return target
16081608

mypyc/primitives/int_ops.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,7 @@
3131
str_rprimitive,
3232
void_rtype,
3333
)
34-
from mypyc.primitives.registry import (
35-
CFunctionDescription,
36-
binary_op,
37-
custom_op,
38-
function_op,
39-
load_address_op,
40-
unary_op,
41-
)
34+
from mypyc.primitives.registry import binary_op, custom_op, function_op, load_address_op, unary_op
4235

4336
# Constructors for builtins.int and native int types have the same behavior. In
4437
# interpreted mode, native int types are just aliases to 'int'.
@@ -176,7 +169,7 @@ def int_binary_op(
176169
int_binary_op("<<=", "CPyTagged_Lshift", error_kind=ERR_MAGIC)
177170

178171

179-
def int_unary_op(name: str, c_function_name: str) -> CFunctionDescription:
172+
def int_unary_op(name: str, c_function_name: str) -> PrimitiveDescription:
180173
return unary_op(
181174
name=name,
182175
arg_type=int_rprimitive,

mypyc/primitives/registry.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ class LoadAddressDescription(NamedTuple):
7979
# Primitive ops for binary operations
8080
binary_ops: dict[str, list[PrimitiveDescription]] = {}
8181

82-
# CallC op for unary ops
83-
unary_ops: dict[str, list[CFunctionDescription]] = {}
82+
# Primitive ops for unary ops
83+
unary_ops: dict[str, list[PrimitiveDescription]] = {}
8484

8585
builtin_names: dict[str, tuple[RType, str]] = {}
8686

@@ -327,8 +327,8 @@ def unary_op(
327327
is_borrowed: bool = False,
328328
priority: int = 1,
329329
is_pure: bool = False,
330-
) -> CFunctionDescription:
331-
"""Define a c function call op for an unary operation.
330+
) -> PrimitiveDescription:
331+
"""Define a primitive op for an unary operation.
332332
333333
This will be automatically generated by matching against the AST.
334334
@@ -338,19 +338,19 @@ def unary_op(
338338
if extra_int_constants is None:
339339
extra_int_constants = []
340340
ops = unary_ops.setdefault(name, [])
341-
desc = CFunctionDescription(
341+
desc = PrimitiveDescription(
342342
name,
343343
[arg_type],
344344
return_type,
345-
None,
346-
truncated_type,
347-
c_function_name,
348-
error_kind,
349-
steals,
350-
is_borrowed,
351-
ordering,
352-
extra_int_constants,
353-
priority,
345+
var_arg_type=None,
346+
truncated_type=truncated_type,
347+
c_function_name=c_function_name,
348+
error_kind=error_kind,
349+
steals=steals,
350+
is_borrowed=is_borrowed,
351+
ordering=ordering,
352+
extra_int_constants=extra_int_constants,
353+
priority=priority,
354354
is_pure=is_pure,
355355
)
356356
ops.append(desc)

mypyc/test-data/irbuild-int.test

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,31 @@ def int_to_int(n):
182182
L0:
183183
return n
184184

185-
[case testIntUnaryPlus]
185+
[case testIntUnaryOps]
186+
def unary_minus(n: int) -> int:
187+
x = -n
188+
return x
186189
def unary_plus(n: int) -> int:
187190
x = +n
188191
return x
192+
def unary_invert(n: int) -> int:
193+
x = ~n
194+
return x
189195
[out]
196+
def unary_minus(n):
197+
n, r0, x :: int
198+
L0:
199+
r0 = CPyTagged_Negate(n)
200+
x = r0
201+
return x
190202
def unary_plus(n):
191203
n, x :: int
192204
L0:
193205
x = n
194206
return x
207+
def unary_invert(n):
208+
n, r0, x :: int
209+
L0:
210+
r0 = CPyTagged_Invert(n)
211+
x = r0
212+
return x

mypyc/test/test_cheader.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,18 @@ def check_name(name: str) -> None:
2626
rf"\b{name}\b", header
2727
), f'"{name}" is used in mypyc.primitives but not declared in CPy.h'
2828

29-
for old_values in [registry.method_call_ops.values(), registry.unary_ops.values()]:
29+
for old_values in [registry.method_call_ops.values()]:
3030
for old_ops in old_values:
3131
if isinstance(old_ops, CFunctionDescription):
3232
old_ops = [old_ops]
3333
for old_op in old_ops:
3434
check_name(old_op.c_function_name)
3535

36-
for values in [registry.binary_ops.values(), registry.function_ops.values()]:
36+
for values in [
37+
registry.binary_ops.values(),
38+
registry.unary_ops.values(),
39+
registry.function_ops.values(),
40+
]:
3741
for ops in values:
3842
if isinstance(ops, PrimitiveDescription):
3943
ops = [ops]

mypyc/test/test_emitfunc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ def test_int_sub(self) -> None:
154154
)
155155

156156
def test_int_neg(self) -> None:
157+
assert int_neg_op.c_function_name is not None
157158
self.assert_emit(
158159
CallC(
159160
int_neg_op.c_function_name,

0 commit comments

Comments
 (0)