Skip to content

Commit dfcff68

Browse files
authored
[mypyc] Support unary_ops, add int_neg_op as an example (#8933)
Related mypyc/mypyc#709, mypyc/mypyc#734 Support unary ops and provide int_neg_op as an example.
1 parent 63f2fed commit dfcff68

File tree

6 files changed

+36
-16
lines changed

6 files changed

+36
-16
lines changed

mypyc/irbuild/ll_builder.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from mypyc.primitives.registry import (
3636
binary_ops, unary_ops, method_ops, func_ops,
3737
c_method_call_ops, CFunctionDescription, c_function_ops,
38-
c_binary_ops
38+
c_binary_ops, c_unary_ops
3939
)
4040
from mypyc.primitives.list_ops import (
4141
list_extend_op, list_len_op, new_list_op
@@ -555,6 +555,10 @@ def unary_op(self,
555555
lreg: Value,
556556
expr_op: str,
557557
line: int) -> Value:
558+
call_c_ops_candidates = c_unary_ops.get(expr_op, [])
559+
target = self.matching_call_c(call_c_ops_candidates, [lreg], line)
560+
if target:
561+
return target
558562
ops = unary_ops.get(expr_op, [])
559563
target = self.matching_primitive_op(ops, [lreg], line)
560564
assert target, 'Unsupported unary operation: %s' % expr_op

mypyc/primitives/int_ops.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
See also the documentation for mypyc.rtypes.int_rprimitive.
77
"""
88

9-
from mypyc.ir.ops import OpDescription, ERR_NEVER, ERR_MAGIC
9+
from mypyc.ir.ops import ERR_NEVER, ERR_MAGIC
1010
from mypyc.ir.rtypes import (
1111
int_rprimitive, bool_rprimitive, float_rprimitive, object_rprimitive, short_int_rprimitive,
1212
str_rprimitive, RType
1313
)
1414
from mypyc.primitives.registry import (
15-
name_ref_op, binary_op, unary_op, func_op, custom_op,
16-
simple_emit, call_emit, name_emit,
15+
name_ref_op, binary_op, func_op, custom_op,
16+
simple_emit, call_emit, name_emit, c_unary_op, CFunctionDescription
1717
)
1818

1919
# These int constructors produce object_rprimitives that then need to be unboxed
@@ -131,13 +131,12 @@ def int_compare_op(op: str, c_func_name: str) -> None:
131131
emit=simple_emit('{dest} = {args[0]} + {args[1]};'))
132132

133133

134-
def int_unary_op(op: str, c_func_name: str) -> OpDescription:
135-
return unary_op(op=op,
136-
arg_type=int_rprimitive,
137-
result_type=int_rprimitive,
138-
error_kind=ERR_NEVER,
139-
format_str='{dest} = %s{args[0]} :: int' % op,
140-
emit=call_emit(c_func_name))
134+
def int_unary_op(name: str, c_function_name: str) -> CFunctionDescription:
135+
return c_unary_op(name=name,
136+
arg_type=int_rprimitive,
137+
return_type=int_rprimitive,
138+
c_function_name=c_function_name,
139+
error_kind=ERR_NEVER)
141140

142141

143142
int_neg_op = int_unary_op('-', 'CPyTagged_Negate')

mypyc/primitives/registry.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@
7575
# CallC op for binary ops
7676
c_binary_ops = {} # type: Dict[str, List[CFunctionDescription]]
7777

78+
# CallC op for unary ops
79+
c_unary_ops = {} # type: Dict[str, List[CFunctionDescription]]
80+
7881

7982
def simple_emit(template: str) -> EmitCallback:
8083
"""Construct a simple PrimitiveOp emit callback function.
@@ -371,6 +374,19 @@ def c_binary_op(name: str,
371374
return desc
372375

373376

377+
def c_unary_op(name: str,
378+
arg_type: RType,
379+
return_type: RType,
380+
c_function_name: str,
381+
error_kind: int,
382+
steals: StealsDescription = False,
383+
priority: int = 1) -> CFunctionDescription:
384+
ops = c_unary_ops.setdefault(name, [])
385+
desc = CFunctionDescription(name, [arg_type], return_type,
386+
c_function_name, error_kind, steals, priority)
387+
ops.append(desc)
388+
return desc
389+
374390
# Import various modules that set up global state.
375391
import mypyc.primitives.int_ops # noqa
376392
import mypyc.primitives.str_ops # noqa

mypyc/test-data/analysis.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ L3:
539539
if r5 goto L4 else goto L5 :: bool
540540
L4:
541541
r6 = 1
542-
r7 = -r6 :: int
542+
r7 = CPyTagged_Negate(r6)
543543
restore_exc_info r1
544544
return r7
545545
L5:

mypyc/test-data/irbuild-basic.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ def f(n):
463463
r1 :: int
464464
L0:
465465
r0 = 1
466-
r1 = -r0 :: int
466+
r1 = CPyTagged_Negate(r0)
467467
return r1
468468

469469
[case testConditionalExpr]
@@ -1027,7 +1027,7 @@ L1:
10271027
r2 = x
10281028
goto L3
10291029
L2:
1030-
r3 = -x :: int
1030+
r3 = CPyTagged_Negate(x)
10311031
r2 = r3
10321032
L3:
10331033
return r2

mypyc/test/test_emitfunc.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from mypyc.ir.ops import (
99
Environment, BasicBlock, Goto, Return, LoadInt, Assign, IncRef, DecRef, Branch,
1010
Call, Unbox, Box, TupleGet, GetAttr, PrimitiveOp, RegisterOp,
11-
SetAttr, Op, Value
11+
SetAttr, Op, Value, CallC
1212
)
1313
from mypyc.ir.rtypes import (
1414
RTuple, RInstance, int_rprimitive, bool_rprimitive, list_rprimitive,
@@ -98,7 +98,8 @@ def test_int_sub(self) -> None:
9898
"cpy_r_r0 = CPyTagged_Subtract(cpy_r_m, cpy_r_k);")
9999

100100
def test_int_neg(self) -> None:
101-
self.assert_emit(PrimitiveOp([self.m], int_neg_op, 55),
101+
self.assert_emit(CallC(int_neg_op.c_function_name, [self.m], int_neg_op.return_type,
102+
int_neg_op.steals, int_neg_op.error_kind, 55),
102103
"cpy_r_r0 = CPyTagged_Negate(cpy_r_m);")
103104

104105
def test_list_len(self) -> None:

0 commit comments

Comments
 (0)