Skip to content

Commit 952c616

Browse files
authored
[mypyc] Refactor: move tagged int related code to mypyc.lower.int_ops (#17052)
1 parent afdd9d5 commit 952c616

File tree

4 files changed

+87
-83
lines changed

4 files changed

+87
-83
lines changed

mypyc/irbuild/expression.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@
9595
from mypyc.primitives.bytes_ops import bytes_slice_op
9696
from mypyc.primitives.dict_ops import dict_get_item_op, dict_new_op, dict_set_item_op
9797
from mypyc.primitives.generic_ops import iter_op
98-
from mypyc.primitives.int_ops import int_comparison_op_mapping
9998
from mypyc.primitives.list_ops import list_append_op, list_extend_op, list_slice_op
10099
from mypyc.primitives.misc_ops import ellipsis_op, get_module_dict_op, new_slice_op, type_op
101100
from mypyc.primitives.registry import CFunctionDescription, builtin_names
@@ -814,7 +813,7 @@ def translate_is_none(builder: IRBuilder, expr: Expression, negated: bool) -> Va
814813
def transform_basic_comparison(
815814
builder: IRBuilder, op: str, left: Value, right: Value, line: int
816815
) -> Value:
817-
if is_fixed_width_rtype(left.type) and op in int_comparison_op_mapping:
816+
if is_fixed_width_rtype(left.type) and op in ComparisonOp.signed_ops:
818817
if right.type == left.type:
819818
if left.type.is_signed:
820819
op_id = ComparisonOp.signed_ops[op]
@@ -831,7 +830,7 @@ def transform_basic_comparison(
831830
)
832831
elif (
833832
is_fixed_width_rtype(right.type)
834-
and op in int_comparison_op_mapping
833+
and op in ComparisonOp.signed_ops
835834
and isinstance(left, Integer)
836835
):
837836
if right.type.is_signed:

mypyc/irbuild/ll_builder.py

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@
159159
int64_divide_op,
160160
int64_mod_op,
161161
int64_to_int_op,
162-
int_comparison_op_mapping,
163162
int_to_int32_op,
164163
int_to_int64_op,
165164
ssize_t_to_int_op,
@@ -1413,50 +1412,6 @@ def check_tagged_short_int(self, val: Value, line: int, negated: bool = False) -
14131412
check = self.comparison_op(bitwise_and, zero, op, line)
14141413
return check
14151414

1416-
def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value:
1417-
"""Compare two tagged integers using given operator (value context)."""
1418-
# generate fast binary logic ops on short ints
1419-
if (is_short_int_rprimitive(lhs.type) or is_short_int_rprimitive(rhs.type)) and op in (
1420-
"==",
1421-
"!=",
1422-
):
1423-
quick = True
1424-
else:
1425-
quick = is_short_int_rprimitive(lhs.type) and is_short_int_rprimitive(rhs.type)
1426-
if quick:
1427-
return self.comparison_op(lhs, rhs, int_comparison_op_mapping[op][0], line)
1428-
op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op]
1429-
result = Register(bool_rprimitive)
1430-
short_int_block, int_block, out = BasicBlock(), BasicBlock(), BasicBlock()
1431-
check_lhs = self.check_tagged_short_int(lhs, line, negated=True)
1432-
if op in ("==", "!="):
1433-
self.add(Branch(check_lhs, int_block, short_int_block, Branch.BOOL))
1434-
else:
1435-
# for non-equality logical ops (less/greater than, etc.), need to check both sides
1436-
short_lhs = BasicBlock()
1437-
self.add(Branch(check_lhs, int_block, short_lhs, Branch.BOOL))
1438-
self.activate_block(short_lhs)
1439-
check_rhs = self.check_tagged_short_int(rhs, line, negated=True)
1440-
self.add(Branch(check_rhs, int_block, short_int_block, Branch.BOOL))
1441-
self.activate_block(int_block)
1442-
if swap_op:
1443-
args = [rhs, lhs]
1444-
else:
1445-
args = [lhs, rhs]
1446-
call = self.call_c(c_func_desc, args, line)
1447-
if negate_result:
1448-
# TODO: introduce UnaryIntOp?
1449-
call_result = self.unary_op(call, "not", line)
1450-
else:
1451-
call_result = call
1452-
self.add(Assign(result, call_result, line))
1453-
self.goto(out)
1454-
self.activate_block(short_int_block)
1455-
eq = self.comparison_op(lhs, rhs, op_type, line)
1456-
self.add(Assign(result, eq, line))
1457-
self.goto_and_activate(out)
1458-
return result
1459-
14601415
def compare_strings(self, lhs: Value, rhs: Value, op: str, line: int) -> Value:
14611416
"""Compare two strings"""
14621417
compare_result = self.call_c(unicode_compare, [lhs, rhs], line)

mypyc/lower/int_ops.py

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,113 @@
1+
"""Convert tagged int primitive ops to lower-level ops."""
2+
13
from __future__ import annotations
24

3-
from mypyc.ir.ops import Value
5+
from typing import NamedTuple
6+
7+
from mypyc.ir.ops import Assign, BasicBlock, Branch, ComparisonOp, Register, Value
8+
from mypyc.ir.rtypes import bool_rprimitive, is_short_int_rprimitive
49
from mypyc.irbuild.ll_builder import LowLevelIRBuilder
510
from mypyc.lower.registry import lower_binary_op
11+
from mypyc.primitives.int_ops import int_equal_, int_less_than_
12+
from mypyc.primitives.registry import CFunctionDescription
13+
14+
15+
# Description for building int comparison ops
16+
#
17+
# Fields:
18+
# binary_op_variant: identify which IntOp to use when operands are short integers
19+
# c_func_description: the C function to call when operands are tagged integers
20+
# c_func_negated: whether to negate the C function call's result
21+
# c_func_swap_operands: whether to swap lhs and rhs when call the function
22+
class IntComparisonOpDescription(NamedTuple):
23+
binary_op_variant: int
24+
c_func_description: CFunctionDescription
25+
c_func_negated: bool
26+
c_func_swap_operands: bool
27+
28+
29+
# Provide mapping from textual op to short int's op variant and boxed int's description.
30+
# Note that these are not complete implementations and require extra IR.
31+
int_comparison_op_mapping: dict[str, IntComparisonOpDescription] = {
32+
"==": IntComparisonOpDescription(ComparisonOp.EQ, int_equal_, False, False),
33+
"!=": IntComparisonOpDescription(ComparisonOp.NEQ, int_equal_, True, False),
34+
"<": IntComparisonOpDescription(ComparisonOp.SLT, int_less_than_, False, False),
35+
"<=": IntComparisonOpDescription(ComparisonOp.SLE, int_less_than_, True, True),
36+
">": IntComparisonOpDescription(ComparisonOp.SGT, int_less_than_, False, True),
37+
">=": IntComparisonOpDescription(ComparisonOp.SGE, int_less_than_, True, False),
38+
}
39+
40+
41+
def compare_tagged(self: LowLevelIRBuilder, lhs: Value, rhs: Value, op: str, line: int) -> Value:
42+
"""Compare two tagged integers using given operator (value context)."""
43+
# generate fast binary logic ops on short ints
44+
if (is_short_int_rprimitive(lhs.type) or is_short_int_rprimitive(rhs.type)) and op in (
45+
"==",
46+
"!=",
47+
):
48+
quick = True
49+
else:
50+
quick = is_short_int_rprimitive(lhs.type) and is_short_int_rprimitive(rhs.type)
51+
if quick:
52+
return self.comparison_op(lhs, rhs, int_comparison_op_mapping[op][0], line)
53+
op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op]
54+
result = Register(bool_rprimitive)
55+
short_int_block, int_block, out = BasicBlock(), BasicBlock(), BasicBlock()
56+
check_lhs = self.check_tagged_short_int(lhs, line, negated=True)
57+
if op in ("==", "!="):
58+
self.add(Branch(check_lhs, int_block, short_int_block, Branch.BOOL))
59+
else:
60+
# for non-equality logical ops (less/greater than, etc.), need to check both sides
61+
short_lhs = BasicBlock()
62+
self.add(Branch(check_lhs, int_block, short_lhs, Branch.BOOL))
63+
self.activate_block(short_lhs)
64+
check_rhs = self.check_tagged_short_int(rhs, line, negated=True)
65+
self.add(Branch(check_rhs, int_block, short_int_block, Branch.BOOL))
66+
self.activate_block(int_block)
67+
if swap_op:
68+
args = [rhs, lhs]
69+
else:
70+
args = [lhs, rhs]
71+
call = self.call_c(c_func_desc, args, line)
72+
if negate_result:
73+
# TODO: introduce UnaryIntOp?
74+
call_result = self.unary_op(call, "not", line)
75+
else:
76+
call_result = call
77+
self.add(Assign(result, call_result, line))
78+
self.goto(out)
79+
self.activate_block(short_int_block)
80+
eq = self.comparison_op(lhs, rhs, op_type, line)
81+
self.add(Assign(result, eq, line))
82+
self.goto_and_activate(out)
83+
return result
684

785

886
@lower_binary_op("int_eq")
987
def lower_int_eq(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
10-
return builder.compare_tagged(args[0], args[1], "==", line)
88+
return compare_tagged(builder, args[0], args[1], "==", line)
1189

1290

1391
@lower_binary_op("int_ne")
1492
def lower_int_ne(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
15-
return builder.compare_tagged(args[0], args[1], "!=", line)
93+
return compare_tagged(builder, args[0], args[1], "!=", line)
1694

1795

1896
@lower_binary_op("int_lt")
1997
def lower_int_lt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
20-
return builder.compare_tagged(args[0], args[1], "<", line)
98+
return compare_tagged(builder, args[0], args[1], "<", line)
2199

22100

23101
@lower_binary_op("int_le")
24102
def lower_int_le(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
25-
return builder.compare_tagged(args[0], args[1], "<=", line)
103+
return compare_tagged(builder, args[0], args[1], "<=", line)
26104

27105

28106
@lower_binary_op("int_gt")
29107
def lower_int_gt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
30-
return builder.compare_tagged(args[0], args[1], ">", line)
108+
return compare_tagged(builder, args[0], args[1], ">", line)
31109

32110

33111
@lower_binary_op("int_ge")
34112
def lower_int_ge(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value:
35-
return builder.compare_tagged(args[0], args[1], ">=", line)
113+
return compare_tagged(builder, args[0], args[1], ">=", line)

mypyc/primitives/int_ops.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@
1010

1111
from __future__ import annotations
1212

13-
from typing import NamedTuple
14-
1513
from mypyc.ir.ops import (
1614
ERR_ALWAYS,
1715
ERR_MAGIC,
1816
ERR_MAGIC_OVERLAPPING,
1917
ERR_NEVER,
20-
ComparisonOp,
2118
PrimitiveDescription,
2219
)
2320
from mypyc.ir.rtypes import (
@@ -196,20 +193,6 @@ def int_unary_op(name: str, c_function_name: str) -> CFunctionDescription:
196193
# Primitives related to integer comparison operations:
197194

198195

199-
# Description for building int comparison ops
200-
#
201-
# Fields:
202-
# binary_op_variant: identify which IntOp to use when operands are short integers
203-
# c_func_description: the C function to call when operands are tagged integers
204-
# c_func_negated: whether to negate the C function call's result
205-
# c_func_swap_operands: whether to swap lhs and rhs when call the function
206-
class IntComparisonOpDescription(NamedTuple):
207-
binary_op_variant: int
208-
c_func_description: CFunctionDescription
209-
c_func_negated: bool
210-
c_func_swap_operands: bool
211-
212-
213196
# Equals operation on two boxed tagged integers
214197
int_equal_ = custom_op(
215198
arg_types=[int_rprimitive, int_rprimitive],
@@ -226,17 +209,6 @@ class IntComparisonOpDescription(NamedTuple):
226209
error_kind=ERR_NEVER,
227210
)
228211

229-
# Provide mapping from textual op to short int's op variant and boxed int's description.
230-
# Note that these are not complete implementations and require extra IR.
231-
int_comparison_op_mapping: dict[str, IntComparisonOpDescription] = {
232-
"==": IntComparisonOpDescription(ComparisonOp.EQ, int_equal_, False, False),
233-
"!=": IntComparisonOpDescription(ComparisonOp.NEQ, int_equal_, True, False),
234-
"<": IntComparisonOpDescription(ComparisonOp.SLT, int_less_than_, False, False),
235-
"<=": IntComparisonOpDescription(ComparisonOp.SLE, int_less_than_, True, True),
236-
">": IntComparisonOpDescription(ComparisonOp.SGT, int_less_than_, False, True),
237-
">=": IntComparisonOpDescription(ComparisonOp.SGE, int_less_than_, True, False),
238-
}
239-
240212
int64_divide_op = custom_op(
241213
arg_types=[int64_rprimitive, int64_rprimitive],
242214
return_type=int64_rprimitive,

0 commit comments

Comments
 (0)