@@ -4920,83 +4920,42 @@ struct assembler {
49204920};
49214921
49224922static void
4923- dfs (struct compiler * c , basicblock * b , struct assembler * a )
4923+ dfs (struct compiler * c , basicblock * b , struct assembler * a , int end )
49244924{
4925- int i ;
4926- struct instr * instr = NULL ;
4927-
4928- if (b -> b_seen )
4929- return ;
4930- b -> b_seen = 1 ;
4931- if (b -> b_next != NULL )
4932- dfs (c , b -> b_next , a );
4933- for (i = 0 ; i < b -> b_iused ; i ++ ) {
4934- instr = & b -> b_instr [i ];
4935- if (instr -> i_jrel || instr -> i_jabs )
4936- dfs (c , instr -> i_target , a );
4925+ int i , j ;
4926+
4927+ /* Get rid of recursion for normal control flow.
4928+ Since the number of blocks is limited, unused space in a_postorder
4929+ (from a_nblocks to end) can be used as a stack for still not ordered
4930+ blocks. */
4931+ for (j = end ; b && !b -> b_seen ; b = b -> b_next ) {
4932+ b -> b_seen = 1 ;
4933+ assert (a -> a_nblocks < j );
4934+ a -> a_postorder [-- j ] = b ;
4935+ }
4936+ while (j < end ) {
4937+ b = a -> a_postorder [j ++ ];
4938+ for (i = 0 ; i < b -> b_iused ; i ++ ) {
4939+ struct instr * instr = & b -> b_instr [i ];
4940+ if (instr -> i_jrel || instr -> i_jabs )
4941+ dfs (c , instr -> i_target , a , j );
4942+ }
4943+ assert (a -> a_nblocks < j );
4944+ a -> a_postorder [a -> a_nblocks ++ ] = b ;
49374945 }
4938- a -> a_postorder [a -> a_nblocks ++ ] = b ;
49394946}
49404947
4941- static int
4942- stackdepth_walk ( struct compiler * c , basicblock * b , int depth , int maxdepth )
4948+ Py_LOCAL_INLINE ( void )
4949+ stackdepth_push ( basicblock * * * sp , basicblock * b , int depth )
49434950{
4944- int i , new_depth , target_depth , effect ;
4945- struct instr * instr ;
4946- assert (!b -> b_seen || b -> b_startdepth == depth );
4947- if (b -> b_seen || b -> b_startdepth >= depth ) {
4948- return maxdepth ;
4949- }
4950- /* Guard against infinite recursion */
4951- b -> b_seen = 1 ;
4952- b -> b_startdepth = depth ;
4953- for (i = 0 ; i < b -> b_iused ; i ++ ) {
4954- instr = & b -> b_instr [i ];
4955- effect = stack_effect (instr -> i_opcode , instr -> i_oparg , 0 );
4956- if (effect == PY_INVALID_STACK_EFFECT ) {
4957- fprintf (stderr , "opcode = %d\n" , instr -> i_opcode );
4958- Py_FatalError ("PyCompile_OpcodeStackEffect()" );
4959- }
4960- new_depth = depth + effect ;
4961- if (new_depth > maxdepth ) {
4962- maxdepth = new_depth ;
4963- }
4964- assert (new_depth >= 0 ); /* invalid code or bug in stackdepth() */
4965- if (instr -> i_jrel || instr -> i_jabs ) {
4966- /* Recursively inspect jump target */
4967- effect = stack_effect (instr -> i_opcode , instr -> i_oparg , 1 );
4968- assert (effect != PY_INVALID_STACK_EFFECT );
4969- target_depth = depth + effect ;
4970- if (target_depth > maxdepth ) {
4971- maxdepth = target_depth ;
4972- }
4973- assert (target_depth >= 0 ); /* invalid code or bug in stackdepth() */
4974- if (instr -> i_opcode == CONTINUE_LOOP ) {
4975- /* Pops a variable number of values from the stack,
4976- * but the target should be already proceeding.
4977- */
4978- assert (instr -> i_target -> b_seen );
4979- assert (instr -> i_target -> b_startdepth <= depth );
4980- goto out ; /* remaining code is dead */
4981- }
4982- maxdepth = stackdepth_walk (c , instr -> i_target ,
4983- target_depth , maxdepth );
4984- }
4985- depth = new_depth ;
4986- if (instr -> i_opcode == JUMP_ABSOLUTE ||
4987- instr -> i_opcode == JUMP_FORWARD ||
4988- instr -> i_opcode == RETURN_VALUE ||
4989- instr -> i_opcode == RAISE_VARARGS ||
4990- instr -> i_opcode == BREAK_LOOP )
4991- {
4992- goto out ; /* remaining code is dead */
4993- }
4951+ /* XXX b->b_startdepth > depth only for the target of SETUP_FINALLY,
4952+ * SETUP_WITH and SETUP_ASYNC_WITH. */
4953+ assert (b -> b_startdepth < 0 || b -> b_startdepth >= depth );
4954+ if (b -> b_startdepth < depth ) {
4955+ assert (b -> b_startdepth < 0 );
4956+ b -> b_startdepth = depth ;
4957+ * (* sp )++ = b ;
49944958 }
4995- if (b -> b_next )
4996- maxdepth = stackdepth_walk (c , b -> b_next , depth , maxdepth );
4997- out :
4998- b -> b_seen = 0 ;
4999- return maxdepth ;
50004959}
50014960
50024961/* Find the flow path that needs the largest stack. We assume that
@@ -5005,16 +4964,79 @@ stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth)
50054964static int
50064965stackdepth (struct compiler * c )
50074966{
5008- basicblock * b , * entryblock ;
5009- entryblock = NULL ;
4967+ basicblock * b , * entryblock = NULL ;
4968+ basicblock * * stack , * * sp ;
4969+ int nblocks = 0 , maxdepth = 0 ;
50104970 for (b = c -> u -> u_blocks ; b != NULL ; b = b -> b_list ) {
5011- b -> b_seen = 0 ;
50124971 b -> b_startdepth = INT_MIN ;
50134972 entryblock = b ;
4973+ nblocks ++ ;
50144974 }
50154975 if (!entryblock )
50164976 return 0 ;
5017- return stackdepth_walk (c , entryblock , 0 , 0 );
4977+ stack = (basicblock * * )PyObject_Malloc (sizeof (basicblock * ) * nblocks );
4978+ if (!stack ) {
4979+ PyErr_NoMemory ();
4980+ return -1 ;
4981+ }
4982+
4983+ sp = stack ;
4984+ stackdepth_push (& sp , entryblock , 0 );
4985+ while (sp != stack ) {
4986+ b = * -- sp ;
4987+ int depth = b -> b_startdepth ;
4988+ assert (depth >= 0 );
4989+ basicblock * next = b -> b_next ;
4990+ for (int i = 0 ; i < b -> b_iused ; i ++ ) {
4991+ struct instr * instr = & b -> b_instr [i ];
4992+ int effect = stack_effect (instr -> i_opcode , instr -> i_oparg , 0 );
4993+ if (effect == PY_INVALID_STACK_EFFECT ) {
4994+ fprintf (stderr , "opcode = %d\n" , instr -> i_opcode );
4995+ Py_FatalError ("PyCompile_OpcodeStackEffect()" );
4996+ }
4997+ int new_depth = depth + effect ;
4998+ if (new_depth > maxdepth ) {
4999+ maxdepth = new_depth ;
5000+ }
5001+ assert (depth >= 0 ); /* invalid code or bug in stackdepth() */
5002+ if (instr -> i_jrel || instr -> i_jabs ) {
5003+ effect = stack_effect (instr -> i_opcode , instr -> i_oparg , 1 );
5004+ assert (effect != PY_INVALID_STACK_EFFECT );
5005+ int target_depth = depth + effect ;
5006+ if (target_depth > maxdepth ) {
5007+ maxdepth = target_depth ;
5008+ }
5009+ assert (target_depth >= 0 ); /* invalid code or bug in stackdepth() */
5010+ if (instr -> i_opcode == CONTINUE_LOOP ) {
5011+ /* Pops a variable number of values from the stack,
5012+ * but the target should be already proceeding.
5013+ */
5014+ assert (instr -> i_target -> b_startdepth >= 0 );
5015+ assert (instr -> i_target -> b_startdepth <= depth );
5016+ /* remaining code is dead */
5017+ next = NULL ;
5018+ break ;
5019+ }
5020+ stackdepth_push (& sp , instr -> i_target , target_depth );
5021+ }
5022+ depth = new_depth ;
5023+ if (instr -> i_opcode == JUMP_ABSOLUTE ||
5024+ instr -> i_opcode == JUMP_FORWARD ||
5025+ instr -> i_opcode == RETURN_VALUE ||
5026+ instr -> i_opcode == RAISE_VARARGS ||
5027+ instr -> i_opcode == BREAK_LOOP )
5028+ {
5029+ /* remaining code is dead */
5030+ next = NULL ;
5031+ break ;
5032+ }
5033+ }
5034+ if (next != NULL ) {
5035+ stackdepth_push (& sp , next , depth );
5036+ }
5037+ }
5038+ PyObject_Free (stack );
5039+ return maxdepth ;
50185040}
50195041
50205042static int
@@ -5320,7 +5342,7 @@ makecode(struct compiler *c, struct assembler *a)
53205342 Py_ssize_t nlocals ;
53215343 int nlocals_int ;
53225344 int flags ;
5323- int argcount , kwonlyargcount ;
5345+ int argcount , kwonlyargcount , maxdepth ;
53245346
53255347 tmp = dict_keys_inorder (c -> u -> u_consts , 0 );
53265348 if (!tmp )
@@ -5360,8 +5382,12 @@ makecode(struct compiler *c, struct assembler *a)
53605382
53615383 argcount = Py_SAFE_DOWNCAST (c -> u -> u_argcount , Py_ssize_t , int );
53625384 kwonlyargcount = Py_SAFE_DOWNCAST (c -> u -> u_kwonlyargcount , Py_ssize_t , int );
5385+ maxdepth = stackdepth (c );
5386+ if (maxdepth < 0 ) {
5387+ goto error ;
5388+ }
53635389 co = PyCode_New (argcount , kwonlyargcount ,
5364- nlocals_int , stackdepth ( c ) , flags ,
5390+ nlocals_int , maxdepth , flags ,
53655391 bytecode , consts , names , varnames ,
53665392 freevars , cellvars ,
53675393 c -> c_filename , c -> u -> u_name ,
@@ -5448,7 +5474,7 @@ assemble(struct compiler *c, int addNone)
54485474 }
54495475 if (!assemble_init (& a , nblocks , c -> u -> u_firstlineno ))
54505476 goto error ;
5451- dfs (c , entryblock , & a );
5477+ dfs (c , entryblock , & a , nblocks );
54525478
54535479 /* Can't modify the bytecode after computing jump offsets. */
54545480 assemble_jump_offsets (& a , c );
0 commit comments