Skip to content

Commit ea913ac

Browse files
authored
[mypyc] Obsolete several old-style registry functions (#9310)
This PR merges the generic in and op as well as misc builtins.bool op, and obsoletes unused old-style registry functions: call_void_emit, call_and_fail_emit, call_negative_bool_emit, negative_int_emit, call_negative_magic_emit. A test for generic in and misc builtins.bool is added.
1 parent 2e9afec commit ea913ac

10 files changed

+164
-142
lines changed

mypyc/irbuild/ll_builder.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -623,12 +623,12 @@ def unary_op(self,
623623
lreg: Value,
624624
expr_op: str,
625625
line: int) -> Value:
626-
call_c_ops_candidates = c_unary_ops.get(expr_op, [])
627-
target = self.matching_call_c(call_c_ops_candidates, [lreg], line)
628-
if target:
629-
return target
630626
ops = unary_ops.get(expr_op, [])
631627
target = self.matching_primitive_op(ops, [lreg], line)
628+
if target:
629+
return target
630+
call_c_ops_candidates = c_unary_ops.get(expr_op, [])
631+
target = self.matching_call_c(call_c_ops_candidates, [lreg], line)
632632
assert target, 'Unsupported unary operation: %s' % expr_op
633633
return target
634634

@@ -745,7 +745,7 @@ def add_bool_branch(self, value: Value, true: BasicBlock, false: BasicBlock) ->
745745
self.add_bool_branch(remaining, true, false)
746746
return
747747
elif not is_same_type(value.type, bool_rprimitive):
748-
value = self.primitive_op(bool_op, [value], value.line)
748+
value = self.call_c(bool_op, [value], value.line)
749749
self.add(Branch(value, true, false, Branch.BOOL_EXPR))
750750

751751
def call_c(self,

mypyc/primitives/generic_ops.py

+18-16
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
from mypyc.ir.ops import ERR_NEVER, ERR_MAGIC, ERR_NEG_INT
1313
from mypyc.ir.rtypes import object_rprimitive, int_rprimitive, bool_rprimitive, c_int_rprimitive
1414
from mypyc.primitives.registry import (
15-
binary_op, unary_op, custom_op, call_emit, simple_emit,
16-
call_negative_magic_emit, negative_int_emit,
15+
binary_op, custom_op, call_emit, simple_emit,
1716
c_binary_op, c_unary_op, c_method_op, c_function_op, c_custom_op
1817
)
1918

@@ -79,12 +78,15 @@
7978
emit=simple_emit('{dest} = PyNumber_Power({args[0]}, {args[1]}, Py_None);'),
8079
priority=0)
8180

82-
binary_op('in',
83-
arg_types=[object_rprimitive, object_rprimitive],
84-
result_type=bool_rprimitive,
85-
error_kind=ERR_MAGIC,
86-
emit=negative_int_emit('{dest} = PySequence_Contains({args[1]}, {args[0]});'),
87-
priority=0)
81+
c_binary_op(
82+
name='in',
83+
arg_types=[object_rprimitive, object_rprimitive],
84+
return_type=c_int_rprimitive,
85+
c_function_name='PySequence_Contains',
86+
error_kind=ERR_NEG_INT,
87+
truncated_type=bool_rprimitive,
88+
ordering=[1, 0],
89+
priority=0)
8890

8991
binary_op('is',
9092
arg_types=[object_rprimitive, object_rprimitive],
@@ -113,14 +115,14 @@
113115
error_kind=ERR_MAGIC,
114116
priority=0)
115117

116-
unary_op(op='not',
117-
arg_type=object_rprimitive,
118-
result_type=bool_rprimitive,
119-
error_kind=ERR_MAGIC,
120-
format_str='{dest} = not {args[0]}',
121-
emit=call_negative_magic_emit('PyObject_Not'),
122-
priority=0)
123-
118+
c_unary_op(
119+
name='not',
120+
arg_type=object_rprimitive,
121+
return_type=c_int_rprimitive,
122+
c_function_name='PyObject_Not',
123+
error_kind=ERR_NEG_INT,
124+
truncated_type=bool_rprimitive,
125+
priority=0)
124126

125127
# obj1[obj2]
126128
c_method_op(name='__getitem__',

mypyc/primitives/misc_ops.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
)
88
from mypyc.primitives.registry import (
99
simple_emit, unary_op, func_op, custom_op, call_emit, name_emit,
10-
call_negative_magic_emit, c_function_op, c_custom_op, load_address_op
10+
c_function_op, c_custom_op, load_address_op
1111
)
1212

1313

@@ -159,12 +159,13 @@
159159
emit=simple_emit('{dest} = Py_TYPE({args[0]}) == (PyTypeObject *){args[1]};'))
160160

161161
# bool(obj) with unboxed result
162-
bool_op = func_op(
163-
'builtins.bool',
162+
bool_op = c_function_op(
163+
name='builtins.bool',
164164
arg_types=[object_rprimitive],
165-
result_type=bool_rprimitive,
166-
error_kind=ERR_MAGIC,
167-
emit=call_negative_magic_emit('PyObject_IsTrue'))
165+
return_type=c_int_rprimitive,
166+
c_function_name='PyObject_IsTrue',
167+
error_kind=ERR_NEG_INT,
168+
truncated_type=bool_rprimitive)
168169

169170
# slice(start, stop, step)
170171
new_slice_op = c_function_op(

mypyc/primitives/registry.py

+1-40
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
from mypyc.ir.ops import (
4141
OpDescription, EmitterInterface, EmitCallback, StealsDescription, short_name
4242
)
43-
from mypyc.ir.rtypes import RType, bool_rprimitive
43+
from mypyc.ir.rtypes import RType
4444

4545
CFunctionDescription = NamedTuple(
4646
'CFunctionDescription', [('name', str),
@@ -125,45 +125,6 @@ def call_emit(func: str) -> EmitCallback:
125125
return simple_emit('{dest} = %s({comma_args});' % func)
126126

127127

128-
def call_void_emit(func: str) -> EmitCallback:
129-
return simple_emit('%s({comma_args});' % func)
130-
131-
132-
def call_and_fail_emit(func: str) -> EmitCallback:
133-
# This is a hack for our always failing operations like CPy_Raise,
134-
# since we want the optimizer to see that it always fails but we
135-
# don't have an ERR_ALWAYS yet.
136-
# TODO: Have an ERR_ALWAYS.
137-
return simple_emit('%s({comma_args}); {dest} = 0;' % func)
138-
139-
140-
def call_negative_bool_emit(func: str) -> EmitCallback:
141-
"""Construct an emit callback that calls a function and checks for negative return.
142-
143-
The negative return value is converted to a bool (true -> no error).
144-
"""
145-
return simple_emit('{dest} = %s({comma_args}) >= 0;' % func)
146-
147-
148-
def negative_int_emit(template: str) -> EmitCallback:
149-
"""Construct a simple PrimitiveOp emit callback function that checks for -1 return."""
150-
151-
def emit(emitter: EmitterInterface, args: List[str], dest: str) -> None:
152-
temp = emitter.temp_name()
153-
emitter.emit_line(template.format(args=args, dest='int %s' % temp,
154-
comma_args=', '.join(args)))
155-
emitter.emit_lines('if (%s < 0)' % temp,
156-
' %s = %s;' % (dest, emitter.c_error_value(bool_rprimitive)),
157-
'else',
158-
' %s = %s;' % (dest, temp))
159-
160-
return emit
161-
162-
163-
def call_negative_magic_emit(func: str) -> EmitCallback:
164-
return negative_int_emit('{dest} = %s({comma_args});' % func)
165-
166-
167128
def binary_op(op: str,
168129
arg_types: List[RType],
169130
result_type: RType,

mypyc/test-data/irbuild-basic.test

+47-23
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,20 @@ def f(x: object, y: object) -> str:
207207
def f(x, y):
208208
x, y :: object
209209
r0, r1 :: str
210-
r2 :: bool
211-
r3 :: str
210+
r2 :: int32
211+
r3 :: bool
212+
r4 :: str
212213
L0:
213214
r1 = PyObject_Str(x)
214-
r2 = bool r1 :: object
215-
if r2 goto L1 else goto L2 :: bool
215+
r2 = PyObject_IsTrue(r1)
216+
r3 = truncate r2: int32 to builtins.bool
217+
if r3 goto L1 else goto L2 :: bool
216218
L1:
217219
r0 = r1
218220
goto L3
219221
L2:
220-
r3 = PyObject_Str(y)
221-
r0 = r3
222+
r4 = PyObject_Str(y)
223+
r0 = r4
222224
L3:
223225
return r0
224226

@@ -288,18 +290,20 @@ def f(x: object, y: object) -> str:
288290
def f(x, y):
289291
x, y :: object
290292
r0, r1 :: str
291-
r2 :: bool
292-
r3 :: str
293+
r2 :: int32
294+
r3 :: bool
295+
r4 :: str
293296
L0:
294297
r1 = PyObject_Str(x)
295-
r2 = bool r1 :: object
296-
if r2 goto L2 else goto L1 :: bool
298+
r2 = PyObject_IsTrue(r1)
299+
r3 = truncate r2: int32 to builtins.bool
300+
if r3 goto L2 else goto L1 :: bool
297301
L1:
298302
r0 = r1
299303
goto L3
300304
L2:
301-
r3 = PyObject_Str(y)
302-
r0 = r3
305+
r4 = PyObject_Str(y)
306+
r0 = r4
303307
L3:
304308
return r0
305309

@@ -1315,10 +1319,12 @@ def lst(x: List[int]) -> int:
13151319
[out]
13161320
def obj(x):
13171321
x :: object
1318-
r0 :: bool
1322+
r0 :: int32
1323+
r1 :: bool
13191324
L0:
1320-
r0 = bool x :: object
1321-
if r0 goto L1 else goto L2 :: bool
1325+
r0 = PyObject_IsTrue(x)
1326+
r1 = truncate r0: int32 to builtins.bool
1327+
if r1 goto L1 else goto L2 :: bool
13221328
L1:
13231329
return 2
13241330
L2:
@@ -1444,15 +1450,17 @@ def opt_o(x):
14441450
r0 :: object
14451451
r1 :: bool
14461452
r2 :: object
1447-
r3 :: bool
1453+
r3 :: int32
1454+
r4 :: bool
14481455
L0:
14491456
r0 = builtins.None :: object
14501457
r1 = x is not r0
14511458
if r1 goto L1 else goto L3 :: bool
14521459
L1:
14531460
r2 = cast(object, x)
1454-
r3 = bool r2 :: object
1455-
if r3 goto L2 else goto L3 :: bool
1461+
r3 = PyObject_IsTrue(r2)
1462+
r4 = truncate r3: int32 to builtins.bool
1463+
if r4 goto L2 else goto L3 :: bool
14561464
L2:
14571465
return 2
14581466
L3:
@@ -2740,17 +2748,20 @@ L0:
27402748
def A.__ne__(self, rhs):
27412749
self :: __main__.A
27422750
rhs, r0, r1 :: object
2743-
r2, r3 :: bool
2744-
r4 :: object
2751+
r2 :: bool
2752+
r3 :: int32
2753+
r4 :: bool
2754+
r5 :: object
27452755
L0:
27462756
r0 = self.__eq__(rhs)
27472757
r1 = load_address _Py_NotImplementedStruct
27482758
r2 = r0 is r1
27492759
if r2 goto L2 else goto L1 :: bool
27502760
L1:
2751-
r3 = not r0
2752-
r4 = box(bool, r3)
2753-
return r4
2761+
r3 = PyObject_Not(r0)
2762+
r4 = truncate r3: int32 to builtins.bool
2763+
r5 = box(bool, r4)
2764+
return r5
27542765
L2:
27552766
return r1
27562767

@@ -3535,3 +3546,16 @@ def h(x):
35353546
L0:
35363547
r0 = PySequence_List(x)
35373548
return r0
3549+
3550+
[case testBoolFunction]
3551+
def f(x: object) -> bool:
3552+
return bool(x)
3553+
[out]
3554+
def f(x):
3555+
x :: object
3556+
r0 :: int32
3557+
r1 :: bool
3558+
L0:
3559+
r0 = PyObject_IsTrue(x)
3560+
r1 = truncate r0: int32 to builtins.bool
3561+
return r1

mypyc/test-data/irbuild-classes.test

+16-10
Original file line numberDiff line numberDiff line change
@@ -795,17 +795,20 @@ L0:
795795
def Base.__ne__(self, rhs):
796796
self :: __main__.Base
797797
rhs, r0, r1 :: object
798-
r2, r3 :: bool
799-
r4 :: object
798+
r2 :: bool
799+
r3 :: int32
800+
r4 :: bool
801+
r5 :: object
800802
L0:
801803
r0 = self.__eq__(rhs)
802804
r1 = load_address _Py_NotImplementedStruct
803805
r2 = r0 is r1
804806
if r2 goto L2 else goto L1 :: bool
805807
L1:
806-
r3 = not r0
807-
r4 = box(bool, r3)
808-
return r4
808+
r3 = PyObject_Not(r0)
809+
r4 = truncate r3: int32 to builtins.bool
810+
r5 = box(bool, r4)
811+
return r5
809812
L2:
810813
return r1
811814
def Derived.__eq__(self, other):
@@ -910,17 +913,20 @@ L0:
910913
def Derived.__ne__(self, rhs):
911914
self :: __main__.Derived
912915
rhs, r0, r1 :: object
913-
r2, r3 :: bool
914-
r4 :: object
916+
r2 :: bool
917+
r3 :: int32
918+
r4 :: bool
919+
r5 :: object
915920
L0:
916921
r0 = self.__eq__(rhs)
917922
r1 = load_address _Py_NotImplementedStruct
918923
r2 = r0 is r1
919924
if r2 goto L2 else goto L1 :: bool
920925
L1:
921-
r3 = not r0
922-
r4 = box(bool, r3)
923-
return r4
926+
r3 = PyObject_Not(r0)
927+
r4 = truncate r3: int32 to builtins.bool
928+
r5 = box(bool, r4)
929+
return r5
924930
L2:
925931
return r1
926932

mypyc/test-data/irbuild-lists.test

+17
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,20 @@ L0:
194194
r5 = box(short_int, 6)
195195
r6 = PyList_Append(r2, r5)
196196
return r2
197+
198+
[case testListIn]
199+
from typing import List
200+
def f(x: List[int], y: int) -> bool:
201+
return y in x
202+
[out]
203+
def f(x, y):
204+
x :: list
205+
y :: int
206+
r0 :: object
207+
r1 :: int32
208+
r2 :: bool
209+
L0:
210+
r0 = box(int, y)
211+
r1 = PySequence_Contains(x, r0)
212+
r2 = truncate r1: int32 to builtins.bool
213+
return r2

mypyc/test-data/irbuild-optional.test

+5-3
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,17 @@ def f(x):
9292
r0 :: object
9393
r1 :: bool
9494
r2 :: __main__.A
95-
r3 :: bool
95+
r3 :: int32
96+
r4 :: bool
9697
L0:
9798
r0 = builtins.None :: object
9899
r1 = x is not r0
99100
if r1 goto L1 else goto L3 :: bool
100101
L1:
101102
r2 = cast(__main__.A, x)
102-
r3 = bool r2 :: object
103-
if r3 goto L2 else goto L3 :: bool
103+
r3 = PyObject_IsTrue(r2)
104+
r4 = truncate r3: int32 to builtins.bool
105+
if r4 goto L2 else goto L3 :: bool
104106
L2:
105107
return 2
106108
L3:

0 commit comments

Comments
 (0)