Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 53ec9f3

Browse files
authored
[mypyc] Support swapping operands and negating result and merge int NEQ (#9149)
This PR implements support for swapping operands and negating result when building logical ops mentioned in #9148 (comment). To demonstrate, NEQ is merged. Since it has no IR test, I built one in irbuild-int.test.
1 parent e1ac8b2 commit 53ec9f3

5 files changed

Lines changed: 56 additions & 8 deletions

File tree

mypyc/irbuild/ll_builder.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ def check_tagged_short_int(self, val: Value, line: int) -> Value:
573573

574574
def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value:
575575
"""Compare two tagged integers using given op"""
576-
op_type, c_func_desc = int_logical_op_mapping[op]
576+
op_type, c_func_desc, negate_result, swap_op = int_logical_op_mapping[op]
577577
result = self.alloc_temp(bool_rprimitive)
578578
short_int_block, int_block, out = BasicBlock(), BasicBlock(), BasicBlock()
579579
check_lhs = self.check_tagged_short_int(lhs, line)
@@ -592,8 +592,17 @@ def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value:
592592
self.add(Assign(result, eq, line))
593593
self.goto(out)
594594
self.activate_block(int_block)
595-
call = self.call_c(c_func_desc, [lhs, rhs], line)
596-
self.add(Assign(result, call, line))
595+
if swap_op:
596+
args = [rhs, lhs]
597+
else:
598+
args = [lhs, rhs]
599+
call = self.call_c(c_func_desc, args, line)
600+
if negate_result:
601+
# TODO: introduce UnaryIntOp?
602+
call_result = self.unary_op(call, "not", line)
603+
else:
604+
call_result = call
605+
self.add(Assign(result, call_result, line))
597606
self.goto_and_activate(out)
598607
return result
599608

mypyc/primitives/int_ops.py

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

9-
from typing import Dict, Tuple
9+
from typing import Dict, NamedTuple
1010
from mypyc.ir.ops import ERR_NEVER, ERR_MAGIC, BinaryIntOp
1111
from mypyc.ir.rtypes import (
1212
int_rprimitive, bool_rprimitive, float_rprimitive, object_rprimitive, short_int_rprimitive,
@@ -143,6 +143,18 @@ def int_unary_op(name: str, c_function_name: str) -> CFunctionDescription:
143143

144144
# integer comparsion operation implementation related:
145145

146+
# Description for building int logical ops
147+
# For each field:
148+
# binary_op_variant: identify which BinaryIntOp to use when operands are short integers
149+
# c_func_description: the C function to call when operands are tagged integers
150+
# c_func_negated: whether to negate the C function call's result
151+
# c_func_swap_operands: whether to swap lhs and rhs when call the function
152+
IntLogicalOpDescrption = NamedTuple(
153+
'IntLogicalOpDescrption', [('binary_op_variant', int),
154+
('c_func_description', CFunctionDescription),
155+
('c_func_negated', bool),
156+
('c_func_swap_operands', bool)])
157+
146158
# description for equal operation on two boxed tagged integers
147159
int_equal_ = c_custom_op(
148160
arg_types=[int_rprimitive, int_rprimitive],
@@ -159,6 +171,7 @@ def int_unary_op(name: str, c_function_name: str) -> CFunctionDescription:
159171
# provide mapping from textual op to short int's op variant and boxed int's description
160172
# note these are not complete implementations
161173
int_logical_op_mapping = {
162-
'==': (BinaryIntOp.EQ, int_equal_),
163-
'<': (BinaryIntOp.LT, int_less_than_)
164-
} # type: Dict[str, Tuple[int, CFunctionDescription]]
174+
'==': IntLogicalOpDescrption(BinaryIntOp.EQ, int_equal_, False, False),
175+
'!=': IntLogicalOpDescrption(BinaryIntOp.NEQ, int_equal_, True, False),
176+
'<': IntLogicalOpDescrption(BinaryIntOp.LT, int_less_than_, False, False)
177+
} # type: Dict[str, IntLogicalOpDescrption]

mypyc/test-data/irbuild-basic.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,7 @@ def lst(x):
13581358
L0:
13591359
r0 = len x :: list
13601360
r1 = 0
1361-
r2 = CPyTagged_IsNe(r0, r1)
1361+
r2 = r0 != r1
13621362
if r2 goto L1 else goto L2 :: bool
13631363
L1:
13641364
r3 = 1

mypyc/test-data/irbuild-int.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[case testIntNeq]
2+
def f(x: int, y: int) -> bool:
3+
return x != y
4+
[out]
5+
def f(x, y):
6+
x, y :: int
7+
r0 :: bool
8+
r1, r2, r3 :: native_int
9+
r4, r5, r6, r7 :: bool
10+
L0:
11+
r1 = 1
12+
r2 = x & r1
13+
r3 = 0
14+
r4 = r2 == r3
15+
if r4 goto L1 else goto L2 :: bool
16+
L1:
17+
r5 = x != y
18+
r0 = r5
19+
goto L3
20+
L2:
21+
r6 = CPyTagged_IsEq_(x, y)
22+
r7 = !r6
23+
r0 = r7
24+
L3:
25+
return r0

mypyc/test/test_irbuild.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
'irbuild-try.test',
2929
'irbuild-set.test',
3030
'irbuild-strip-asserts.test',
31+
'irbuild-int.test',
3132
]
3233

3334

0 commit comments

Comments
 (0)