Skip to content

Commit

Permalink
[mypyc] Modify specializers and add int.__pow__ in test-data/fixture (#…
Browse files Browse the repository at this point in the history
…10448)

* Move simple tuple and list creation to new functions. Each specializer only 
  focus on one situation now.
* Add int.__pow__ in test-data/fixture
  • Loading branch information
97littleleaf11 committed May 25, 2021
1 parent 799e40c commit 7780482
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 21 deletions.
53 changes: 32 additions & 21 deletions mypyc/irbuild/specialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,6 @@ def dict_methods_fast_path(
if not (len(expr.args) == 1 and expr.arg_kinds == [ARG_POS]):
return None
arg = expr.args[0]

# Special case for simplest list comprehension, for example
# list(x for x in tmp_list)
# TODO: The following code should be moved to a new function after
# supporting multiple specialize functions
if not isinstance(callee, MemberExpr) and isinstance(arg, GeneratorExpr):
val = sequence_from_generator_preallocate_helper(
builder, arg,
empty_op_llbuilder=builder.builder.new_list_op_with_length,
set_item_op=new_list_set_item_op)
if val is not None:
return val

if not (isinstance(arg, CallExpr) and not arg.args
and isinstance(arg.callee, MemberExpr)):
return None
Expand All @@ -130,6 +117,38 @@ def dict_methods_fast_path(
return builder.call_c(dict_items_op, [obj], expr.line)


@specialize_function('builtins.list')
def translate_list_from_generator_call(
builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Optional[Value]:
# Special case for simplest list comprehension, for example
# list(f(x) for x in other_list/other_tuple)
# translate_list_comprehension() would take care of other cases if this fails.
if (len(expr.args) == 1
and expr.arg_kinds[0] == ARG_POS
and isinstance(expr.args[0], GeneratorExpr)):
return sequence_from_generator_preallocate_helper(
builder, expr.args[0],
empty_op_llbuilder=builder.builder.new_list_op_with_length,
set_item_op=new_list_set_item_op)
return None


@specialize_function('builtins.tuple')
def translate_tuple_from_generator_call(
builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Optional[Value]:
# Special case for simplest tuple creation from a generator, for example
# tuple(f(x) for x in other_list/other_tuple)
# translate_safe_generator_call() would take care of other cases if this fails.
if (len(expr.args) == 1
and expr.arg_kinds[0] == ARG_POS
and isinstance(expr.args[0], GeneratorExpr)):
return sequence_from_generator_preallocate_helper(
builder, expr.args[0],
empty_op_llbuilder=builder.builder.new_tuple_with_length,
set_item_op=new_tuple_set_item_op)
return None


@specialize_function('builtins.set')
def translate_set_from_generator_call(
builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Optional[Value]:
Expand Down Expand Up @@ -168,14 +187,6 @@ def translate_safe_generator_call(
+ [builder.accept(arg) for arg in expr.args[1:]]),
builder.node_type(expr), expr.line, expr.arg_kinds, expr.arg_names)
else:
if len(expr.args) == 1 and callee.fullname == "builtins.tuple":
val = sequence_from_generator_preallocate_helper(
builder, expr.args[0],
empty_op_llbuilder=builder.builder.new_tuple_with_length,
set_item_op=new_tuple_set_item_op)
if val is not None:
return val

return builder.call_refexpr_with_args(
expr, callee,
([translate_list_comprehension(builder, expr.args[0])]
Expand Down
1 change: 1 addition & 0 deletions mypyc/test-data/fixtures/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def __init__(self, x: object, base: int = 10) -> None: pass
def __add__(self, n: int) -> int: pass
def __sub__(self, n: int) -> int: pass
def __mul__(self, n: int) -> int: pass
def __pow__(self, n: int, modulo: Optional[int] = None) -> int: pass
def __floordiv__(self, x: int) -> int: pass
def __mod__(self, x: int) -> int: pass
def __neg__(self) -> int: pass
Expand Down
3 changes: 3 additions & 0 deletions mypyc/test-data/run-lists.test
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,6 @@ def test() -> None:
source_d = [True, False]
d = [not x for x in source_d]
assert d == [False, True]
source_e = [0, 1, 2]
e = list((x ** 2) for x in (y + 2 for y in source_e))
assert e == [4, 9, 16]

0 comments on commit 7780482

Please sign in to comment.