@@ -321,7 +321,7 @@ def set_item(x: Value, y: Value, z: Value, line: int) -> None:
321321 if val is not None :
322322 return val
323323
324- list_ops = builder .maybe_spill ( builder . new_list_op ([], gen .line ) )
324+ list_ops = builder .new_list_op ([], gen .line )
325325
326326 loop_params = list (zip (gen .indices , gen .sequences , gen .condlists , gen .is_async ))
327327
@@ -357,7 +357,7 @@ def translate_set_comprehension(builder: IRBuilder, gen: GeneratorExpr) -> Value
357357 if raise_error_if_contains_unreachable_names (builder , gen ):
358358 return builder .none ()
359359
360- set_ops = builder .maybe_spill ( builder . new_set_op ([], gen .line ) )
360+ set_ops = builder .new_set_op ([], gen .line )
361361 loop_params = list (zip (gen .indices , gen .sequences , gen .condlists , gen .is_async ))
362362
363363 def gen_inner_stmts () -> None :
@@ -687,7 +687,7 @@ def gen_step(self) -> None:
687687 def gen_cleanup (self ) -> None :
688688 """Generate post-loop cleanup (if needed)."""
689689
690- def load_len (self , expr : Value | AssignmentTarget ) -> Value :
690+ def load_len (self , expr : Value ) -> Value :
691691 """A helper to get collection length, used by several subclasses."""
692692 return self .builder .builder .builtin_len (
693693 self .builder .read (expr , self .line ), self .line , use_pyssize_t = True
@@ -702,13 +702,11 @@ def need_cleanup(self) -> bool:
702702 return True
703703
704704 def init (self , expr_reg : Value , target_type : RType ) -> None :
705- # Define targets to contain the expression, along with the iterator that will be used
706- # for the for-loop. If we are inside of a generator function, spill these into the
707- # private generator frame.
705+ # Define a target containing the iterator used by the for-loop. The generator spill
706+ # transform will promote it to the private generator frame if needed.
708707 builder = self .builder
709708 iter_reg = builder .primitive_op (iter_op , [expr_reg ], self .line )
710- builder .maybe_spill (expr_reg )
711- self .iter_target = builder .maybe_spill (iter_reg )
709+ self .iter_target = iter_reg
712710 self .target_type = target_type
713711
714712 def gen_condition (self ) -> None :
@@ -751,10 +749,9 @@ def need_cleanup(self) -> bool:
751749 return True
752750
753751 def init (self , expr_reg : Value , target_type : RType ) -> None :
754- # Define target to contains the generator expression. It's also the iterator.
755- # If we are inside a generator function, spill these into the private generator frame.
756- builder = self .builder
757- self .iter_target = builder .maybe_spill (expr_reg )
752+ # The generator expression is also the iterator. The generator spill transform will
753+ # promote it to the private generator frame if needed.
754+ self .iter_target = expr_reg
758755 self .target_type = target_type
759756
760757 def gen_condition (self ) -> None :
@@ -807,14 +804,11 @@ class ForAsyncIterable(ForGenerator):
807804 """Generate IR for an async for loop."""
808805
809806 def init (self , expr_reg : Value , target_type : RType ) -> None :
810- # Define targets to contain the expression, along with the
811- # iterator that will be used for the for-loop. We are inside
812- # of a generator function, so we will spill these into
813- # the private generator frame.
807+ # Define a target containing the iterator used by the for-loop. The generator spill
808+ # transform will promote it to the private generator frame if needed.
814809 builder = self .builder
815810 iter_reg = builder .call_c (aiter_op , [expr_reg ], self .line )
816- builder .maybe_spill (expr_reg )
817- self .iter_target = builder .maybe_spill (iter_reg )
811+ self .iter_target = iter_reg
818812 self .target_type = target_type
819813 self .stop_reg = Register (bool_rprimitive )
820814
@@ -894,7 +888,7 @@ class ForSequence(ForGenerator):
894888 Supports iterating in both forward and reverse.
895889 """
896890
897- length_reg : Value | AssignmentTarget | None
891+ length_reg : Value | None
898892
899893 def init (
900894 self , expr_reg : Value , target_type : RType , reverse : bool , length : Value | None = None
@@ -907,13 +901,12 @@ def init(
907901 # Record a Value indicating the length of the sequence, if known at compile time.
908902 self .length = length
909903 self .reverse = reverse
910- # Define target to contain the expression, along with the index that will be used
911- # for the for-loop. If we are inside of a generator function, spill these into the
912- # private generator frame.
913- self .expr_target = builder .maybe_spill (expr_reg )
904+ # The generator spill transform will promote loop state to the private generator frame
905+ # if needed.
906+ self .expr_target = expr_reg
914907 if is_immutable_rprimitive (expr_reg .type ):
915908 # If the expression is an immutable type, we can load the length just once.
916- self .length_reg = builder . maybe_spill ( self .length or self .load_len (self .expr_target ) )
909+ self .length_reg = self .length or self .load_len (self .expr_target )
917910 else :
918911 # Otherwise, even if the length is known, we must recalculate the length
919912 # at every iteration for compatibility with python semantics.
@@ -926,7 +919,7 @@ def init(
926919 else :
927920 len_val = self .load_len (self .expr_target )
928921 index_reg = builder .builder .int_sub (len_val , 1 )
929- self .index_target = builder .maybe_spill_assignable (index_reg )
922+ self .index_target = builder .ensure_register (index_reg )
930923 self .target_type = target_type
931924
932925 def gen_condition (self ) -> None :
@@ -1010,15 +1003,15 @@ def init(self, expr_reg: Value, target_type: RType) -> None:
10101003 builder = self .builder
10111004 self .target_type = target_type
10121005
1013- # Spill some values so they can be read across yield.
1014- self .expr_target = builder . maybe_spill ( expr_reg )
1006+ # The generator spill transform will promote loop state that crosses a yield.
1007+ self .expr_target = expr_reg
10151008 offset = Integer (0 )
1016- self .offset_target = builder .maybe_spill_assignable (offset )
1017- self .size = builder . maybe_spill ( self .load_len (self .expr_target ) )
1009+ self .offset_target = builder .ensure_register (offset )
1010+ self .size = self .load_len (self .expr_target )
10181011
10191012 # For dict class (not a subclass) this is the dictionary itself.
10201013 iter_reg = builder .call_c (self .dict_iter_op , [expr_reg ], self .line )
1021- self .iter_target = builder . maybe_spill ( iter_reg )
1014+ self .iter_target = iter_reg
10221015
10231016 def gen_condition (self ) -> None :
10241017 """Get next key/value pair, set new offset, and check if we should continue."""
@@ -1132,7 +1125,7 @@ def init(self, start_reg: Value, end_reg: Value, step: int) -> None:
11321125 self .start_reg = start_reg
11331126 self .end_reg = end_reg
11341127 self .step = step
1135- self .end_target = builder . maybe_spill ( end_reg )
1128+ self .end_target = end_reg
11361129 if is_short_int_rprimitive (start_reg .type ) and is_short_int_rprimitive (end_reg .type ):
11371130 index_type : RType = short_int_rprimitive
11381131 elif is_fixed_width_rtype (end_reg .type ):
@@ -1141,7 +1134,7 @@ def init(self, start_reg: Value, end_reg: Value, step: int) -> None:
11411134 index_type = int_rprimitive
11421135 index_reg = Register (index_type , line = self .line )
11431136 builder .assign (index_reg , start_reg , self .line )
1144- self .index_reg = builder . maybe_spill_assignable ( index_reg )
1137+ self .index_reg = index_reg
11451138 # Initialize loop index to 0. Assert that the index target is assignable.
11461139 self .index_target : Register | AssignmentTarget = builder .get_assignment_target (self .index )
11471140 builder .assign (self .index_target , builder .read (self .index_reg , self .line ), self .line )
@@ -1195,7 +1188,7 @@ def init(self) -> None:
11951188 # Create a register to store the state of the loop index and
11961189 # initialize this register along with the loop index to 0.
11971190 zero = Integer (0 )
1198- self .index_reg = builder .maybe_spill_assignable (zero )
1191+ self .index_reg = builder .ensure_register (zero )
11991192 self .index_target : Register | AssignmentTarget = builder .get_assignment_target (self .index )
12001193
12011194 def gen_step (self ) -> None :
0 commit comments