@@ -62,11 +62,12 @@ def f(x: int) -> int:
6262 is_object_rprimitive , LiteralsMap , FuncSignature , VTableAttr , VTableMethod , VTableEntries ,
6363 NAMESPACE_TYPE , RaiseStandardError , LoadErrorValue , NO_TRACEBACK_LINE_NO , FuncDecl ,
6464 FUNC_NORMAL , FUNC_STATICMETHOD , FUNC_CLASSMETHOD ,
65- RUnion , is_optional_type , optional_value_type
65+ RUnion , is_optional_type , optional_value_type , is_short_int_rprimitive ,
6666)
6767from mypyc .ops_primitive import binary_ops , unary_ops , func_ops , method_ops , name_ref_ops
68+ from mypyc .ops_int import unsafe_short_add
6869from mypyc .ops_list import (
69- list_append_op , list_extend_op , list_len_op , list_get_item_op , list_set_item_op , new_list_op ,
70+ list_append_op , list_extend_op , list_len_op , new_list_op ,
7071)
7172from mypyc .ops_tuple import list_tuple_op
7273from mypyc .ops_dict import new_dict_op , dict_get_item_op , dict_set_item_op , dict_update_op
@@ -82,6 +83,7 @@ def f(x: int) -> int:
8283 error_catch_op , restore_exc_info_op , exc_matches_op , get_exc_value_op ,
8384 get_exc_info_op , keep_propagating_op ,
8485)
86+ from mypyc .rt_subtype import is_runtime_subtype
8587from mypyc .subtype import is_subtype
8688from mypyc .sametype import is_same_type , is_same_method_signature
8789from mypyc .crash import catch_errors
@@ -1649,9 +1651,15 @@ def for_loop_helper(self, index: Lvalue, expr: Expression,
16491651
16501652 self .goto_and_activate (increment_block )
16511653
1652- # Increment index register.
1653- self .assign (index_target , self .binary_op (self .read (index_target , line ),
1654- self .add (LoadInt (1 )), '+' , line ), line )
1654+ # Increment index register. If the range is known to fit in short ints, use
1655+ # short ints.
1656+ if is_short_int_rprimitive (start_reg .type ) and is_short_int_rprimitive (end_reg .type ):
1657+ new_val = self .primitive_op (
1658+ unsafe_short_add , [self .read (index_target , line ), self .add (LoadInt (1 ))], line )
1659+ else :
1660+ new_val = self .binary_op (
1661+ self .read (index_target , line ), self .add (LoadInt (1 )), '+' , line )
1662+ self .assign (index_target , new_val , line )
16551663
16561664 # Go back to loop condition check.
16571665 self .goto (condition_block )
@@ -1682,18 +1690,20 @@ def for_loop_helper(self, index: Lvalue, expr: Expression,
16821690 assert isinstance (target_list_type , Instance )
16831691 target_type = self .type_to_rtype (target_list_type .args [0 ])
16841692
1685- value_box = self .add (PrimitiveOp ([self .read (expr_target , line ),
1686- self .read (index_target , line )],
1687- list_get_item_op , line ))
1693+ value_box = self .translate_special_method_call (
1694+ self .read (expr_target , line ), '__getitem__' ,
1695+ [self .read (index_target , line )], None , line )
1696+ assert value_box
16881697
16891698 self .assign (self .get_assignment_target (index ),
16901699 self .unbox_or_cast (value_box , target_type , line ), line )
16911700
16921701 body_insts ()
16931702
16941703 self .goto_and_activate (increment_block )
1695- self .assign (index_target , self .binary_op (self .read (index_target , line ),
1696- self .add (LoadInt (1 )), '+' , line ), line )
1704+ self .assign (index_target , self .primitive_op (
1705+ unsafe_short_add ,
1706+ [self .read (index_target , line ), self .add (LoadInt (1 ))], line ), line )
16971707 self .goto (condition_block )
16981708
16991709 self .pop_loop_stack ()
@@ -1780,7 +1790,7 @@ def matching_primitive_op(self,
17801790 matching = desc
17811791 if matching :
17821792 target = self .primitive_op (matching , args , line )
1783- if result_type and not is_same_type (target .type , result_type ):
1793+ if result_type and not is_runtime_subtype (target .type , result_type ):
17841794 if is_none_rprimitive (result_type ):
17851795 # Special case None return. The actual result may actually be a bool
17861796 # and so we can't just coerce it.
@@ -2509,7 +2519,7 @@ def go(i: int, prev: Value) -> Value:
25092519 return go (0 , self .accept (e .operands [0 ]))
25102520
25112521 def add_bool_branch (self , value : Value , true : BasicBlock , false : BasicBlock ) -> None :
2512- if is_same_type (value .type , int_rprimitive ):
2522+ if is_runtime_subtype (value .type , int_rprimitive ):
25132523 zero = self .add (LoadInt (0 ))
25142524 value = self .binary_op (value , zero , '!=' , value .line )
25152525 elif is_same_type (value .type , list_rprimitive ):
@@ -3937,7 +3947,7 @@ def coerce(self, src: Value, target_type: RType, line: int, force: bool = False)
39373947 if src .type .is_unboxed and not target_type .is_unboxed :
39383948 return self .box (src )
39393949 if ((src .type .is_unboxed and target_type .is_unboxed )
3940- and not is_same_type (src .type , target_type )):
3950+ and not is_runtime_subtype (src .type , target_type )):
39413951 # To go from one unboxed type to another, we go through a boxed
39423952 # in-between value, for simplicity.
39433953 tmp = self .box (src )
0 commit comments