@@ -788,30 +788,6 @@ compiler_use_next_block(struct compiler *c, basicblock *block)
788788 return block ;
789789}
790790
791- static basicblock *
792- compiler_split_block (struct compiler * c , basicblock * b , int off )
793- {
794- basicblock * b2 = compiler_new_block (c );
795- if (b2 == NULL ) {
796- return NULL ;
797- }
798- assert (off < b -> b_iused );
799- int size = b -> b_iused - off ;
800- b2 -> b_instr = (struct instr * )PyObject_Malloc (sizeof (struct instr ) * size );
801- if (b2 -> b_instr == NULL ) {
802- PyErr_NoMemory ();
803- return NULL ;
804- }
805- b2 -> b_iused = b2 -> b_ialloc = size ;
806- memcpy (b2 -> b_instr , b -> b_instr + off , sizeof (struct instr ) * size );
807- b -> b_iused = off ;
808- b2 -> b_next = b -> b_next ;
809- b -> b_next = b2 ;
810- b -> b_return = 0 ;
811-
812- return b2 ;
813- }
814-
815791/* Returns the offset of the next instruction in the current block's
816792 b_instr array. Resizes the b_instr as necessary.
817793 Returns -1 on failure.
@@ -2412,6 +2388,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
24122388 ADDOP_I (c , COMPARE_OP ,
24132389 cmpop ((cmpop_ty )(asdl_seq_GET (e -> v .Compare .ops , n ))));
24142390 ADDOP_JABS (c , cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE , next );
2391+ NEXT_BLOCK (c );
24152392 basicblock * end = compiler_new_block (c );
24162393 if (end == NULL )
24172394 return 0 ;
@@ -2432,6 +2409,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
24322409 if (constant >= 0 ) {
24332410 if (constant == cond ) {
24342411 ADDOP_JABS (c , JUMP_ABSOLUTE , next );
2412+ NEXT_BLOCK (c );
24352413 }
24362414 return 1 ;
24372415 }
@@ -2443,6 +2421,7 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond)
24432421 /* general implementation */
24442422 VISIT (c , expr , e );
24452423 ADDOP_JABS (c , cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE , next );
2424+ NEXT_BLOCK (c );
24462425 return 1 ;
24472426}
24482427
@@ -2684,6 +2663,8 @@ compiler_while(struct compiler *c, stmt_ty s)
26842663
26852664 if (constant == -1 )
26862665 compiler_use_next_block (c , anchor );
2666+ else if (orelse != NULL )
2667+ NEXT_BLOCK (c );
26872668 compiler_pop_fblock (c , WHILE_LOOP , loop );
26882669
26892670 if (orelse != NULL ) /* what if orelse is just pass? */
@@ -2736,6 +2717,7 @@ compiler_break(struct compiler *c)
27362717 return 0 ;
27372718 if (info -> fb_type == WHILE_LOOP || info -> fb_type == FOR_LOOP ) {
27382719 ADDOP_JABS (c , JUMP_ABSOLUTE , info -> fb_exit );
2720+ NEXT_BLOCK (c );
27392721 return 1 ;
27402722 }
27412723 }
@@ -2750,6 +2732,7 @@ compiler_continue(struct compiler *c)
27502732
27512733 if (info -> fb_type == WHILE_LOOP || info -> fb_type == FOR_LOOP ) {
27522734 ADDOP_JABS (c , JUMP_ABSOLUTE , info -> fb_block );
2735+ NEXT_BLOCK (c );
27532736 return 1 ;
27542737 }
27552738 if (!compiler_unwind_fblock (c , info , 0 ))
@@ -2897,6 +2880,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
28972880 VISIT (c , expr , handler -> v .ExceptHandler .type );
28982881 ADDOP_I (c , COMPARE_OP , PyCmp_EXC_MATCH );
28992882 ADDOP_JABS (c , POP_JUMP_IF_FALSE , except );
2883+ NEXT_BLOCK (c );
29002884 }
29012885 ADDOP (c , POP_TOP );
29022886 if (handler -> v .ExceptHandler .name ) {
@@ -3511,6 +3495,7 @@ compiler_boolop(struct compiler *c, expr_ty e)
35113495 for (i = 0 ; i < n ; ++ i ) {
35123496 VISIT (c , expr , (expr_ty )asdl_seq_GET (s , i ));
35133497 ADDOP_JABS (c , jumpi , end );
3498+ NEXT_BLOCK (c );
35143499 }
35153500 VISIT (c , expr , (expr_ty )asdl_seq_GET (s , n ));
35163501 compiler_use_next_block (c , end );
@@ -5483,8 +5468,9 @@ optimize_jumps(struct compiler *c)
54835468 case JUMP_FORWARD :
54845469 case JUMP_ABSOLUTE :
54855470 assert (instr -> i_target != NULL );
5486- while (1 ) {
5487- /* Skip empty blocks */
5471+ int count = 10 ;
5472+ while (count -- ) {
5473+ /* Skip empty blocks. */
54885474 while (!instr -> i_target -> b_iused ) {
54895475 assert (instr -> i_target -> b_next );
54905476 instr -> i_target = instr -> i_target -> b_next ;
@@ -5495,7 +5481,7 @@ optimize_jumps(struct compiler *c)
54955481 break ;
54965482 }
54975483
5498- /* Replace jumps to unconditional jumps */
5484+ /* Replace jumps to unconditional jumps. */
54995485 if (UNCONDITIONAL_JUMP (tgt -> i_opcode )) {
55005486 if (instr -> i_opcode == JUMP_FORWARD ) {
55015487 /* JUMP_ABSOLUTE can go backwards */
@@ -5507,7 +5493,8 @@ optimize_jumps(struct compiler *c)
55075493 continue ;
55085494 }
55095495
5510- /* Replace JUMP_* to a RETURN into just a RETURN */
5496+ /* Replace JUMP_* to a RETURN into just a RETURN.
5497+ Arises in code like "return a if b else c". */
55115498 if (UNCONDITIONAL_JUMP (instr -> i_opcode )) {
55125499 if (tgt -> i_opcode == RETURN_VALUE ) {
55135500 * instr = * tgt ;
@@ -5537,32 +5524,16 @@ optimize_jumps(struct compiler *c)
55375524 if (JUMPS_ON_TRUE (tgt -> i_opcode ) == JUMPS_ON_TRUE (instr -> i_opcode )) {
55385525 /* The second jump will be taken iff the first is.
55395526 The current opcode inherits its target's
5540- stack effect */
5527+ stack effect. */
55415528 instr -> i_target = tgt -> i_target ;
55425529 continue ;
55435530 }
5544- else {
5531+ else if ( instr -> i_target -> b_iused == 1 ) {
55455532 /* The second jump is not taken if the first is (so
55465533 jump past it), and all conditional jumps pop their
55475534 argument when they're not taken (so change the
55485535 first jump to pop its argument when it's taken). */
5549- basicblock * b2 ;
5550- if (instr -> i_target -> b_iused > 1 ) {
5551- b2 = compiler_split_block (c , instr -> i_target , 1 );
5552- if (!b2 ) {
5553- PyErr_Clear ();
5554- break ;
5555- }
5556- /* Move b2 after b so it will be processed in future iterations */
5557- assert (c -> u -> u_blocks == b2 );
5558- c -> u -> u_blocks = b2 -> b_list ;
5559- b2 -> b_list = b -> b_list ;
5560- b -> b_list = b2 ;
5561- }
5562- else {
5563- b2 = instr -> i_target -> b_next ;
5564- }
5565- instr -> i_target = b2 ;
5536+ instr -> i_target = instr -> i_target -> b_next ;
55665537 instr -> i_opcode = instr -> i_opcode == JUMP_IF_TRUE_OR_POP ?
55675538 POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE ;
55685539 continue ;
0 commit comments