Skip to content

Commit 82e39c4

Browse files
committed
[mypyc] feat: extend stararg fastpath from python#19629 with star2 fastpath
1 parent 2f0e0fe commit 82e39c4

File tree

3 files changed

+22
-21
lines changed

3 files changed

+22
-21
lines changed

mypyc/irbuild/ll_builder.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
from mypyc.primitives.bytes_ops import bytes_compare
128128
from mypyc.primitives.dict_ops import (
129129
dict_build_op,
130+
dict_copy_op,
130131
dict_new_op,
131132
dict_ssize_t_size_op,
132133
dict_update_in_display_op,
@@ -810,13 +811,21 @@ def _construct_varargs(
810811
star_result = self.primitive_op(list_tuple_op, [value], line)
811812
else:
812813
star_result = self.primitive_op(sequence_tuple_op, [value], line)
814+
if is_dict_rprimitive(args[1][0].type):
815+
# even faster fastpath for decorators
816+
return star_result, self.primitive_op(dict_copy_op, [args[1][0]], line)
813817
continue
814818
# elif ...: TODO extend this to optimize fn(*args, k=1, **kwargs) case
815819
# TODO optimize this case using the length utils - currently in review
816820
star_result = self.new_list_op(star_values, line)
817821
self.primitive_op(list_extend_op, [star_result, value], line)
818822
elif kind == ARG_STAR2:
819823
if star2_result is None:
824+
if len(args) == 1:
825+
# early exit with fastpath if the only arg is ARG_STAR2
826+
# TODO: can we maintain an empty tuple in memory and just reuse it again and again?
827+
return self.new_tuple([], line), self.primitive_op(dict_copy_op, [args[0][0]], line)
828+
820829
star2_result = self._create_dict(star2_keys, star2_values, line)
821830

822831
self.call_c(dict_update_in_display_op, [star2_result, value], line=line)

mypyc/primitives/dict_ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
)
5454

5555
# Construct a dictionary from another dictionary.
56-
function_op(
56+
dict_copy_op = function_op(
5757
name="builtins.dict",
5858
arg_types=[dict_rprimitive],
5959
return_type=dict_rprimitive,

mypyc/test-data/irbuild-generics.test

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,13 @@ def execute(func, args, kwargs):
167167
func :: object
168168
args :: tuple
169169
kwargs, r0 :: dict
170-
r1 :: i32
171-
r2 :: bit
172-
r3 :: object
173-
r4 :: int
170+
r1 :: object
171+
r2 :: int
174172
L0:
175-
r0 = PyDict_New()
176-
r1 = CPyDict_UpdateInDisplay(r0, kwargs)
177-
r2 = r1 >= 0 :: signed
178-
r3 = PyObject_Call(func, args, r0)
179-
r4 = unbox(int, r3)
180-
return r4
173+
r0 = PyDict_Copy(kwargs)
174+
r1 = PyObject_Call(func, args, r0)
175+
r2 = unbox(int, r1)
176+
return r2
181177
def f(x):
182178
x :: int
183179
L0:
@@ -703,10 +699,8 @@ def inner_deco_obj.__call__(__mypyc_self__, args, kwargs):
703699
r22, can_iter, r23, can_use_keys, r24, can_use_values :: list
704700
r25 :: object
705701
r26 :: dict
706-
r27 :: i32
707-
r28 :: bit
708-
r29 :: object
709-
r30 :: int
702+
r27 :: object
703+
r28 :: int
710704
L0:
711705
r0 = __mypyc_self__.__mypyc_env__
712706
r1 = var_object_size args
@@ -758,12 +752,10 @@ L9:
758752
r24 = CPyDict_Values(kwargs)
759753
can_use_values = r24
760754
r25 = r0.func
761-
r26 = PyDict_New()
762-
r27 = CPyDict_UpdateInDisplay(r26, kwargs)
763-
r28 = r27 >= 0 :: signed
764-
r29 = PyObject_Call(r25, args, r26)
765-
r30 = unbox(int, r29)
766-
return r30
755+
r26 = PyDict_Copy(kwargs)
756+
r27 = PyObject_Call(r25, args, r26)
757+
r28 = unbox(int, r27)
758+
return r28
767759
def deco(func):
768760
func :: object
769761
r0 :: __main__.deco_env

0 commit comments

Comments
 (0)