@@ -28,14 +28,23 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
28
28
{
29
29
zend_basic_block * blocks = cfg -> blocks ;
30
30
31
- {
32
- while (1 ) {
31
+ zend_worklist work ;
32
+ ALLOCA_FLAG (list_use_heap )
33
+ ZEND_WORKLIST_ALLOCA (& work , cfg -> blocks_count , list_use_heap );
34
+
35
+ zend_worklist_push (& work , b - cfg -> blocks );
36
+
37
+ while (zend_worklist_len (& work )) {
38
+ b = cfg -> blocks + zend_worklist_pop (& work );
39
+
40
+ bool finished = false;
41
+ while (!finished ) {
33
42
int i ;
34
43
35
44
b -> flags |= ZEND_BB_REACHABLE ;
36
45
if (b -> successors_count == 0 ) {
37
46
b -> flags |= ZEND_BB_EXIT ;
38
- return ;
47
+ break ;
39
48
}
40
49
41
50
for (i = 0 ; i < b -> successors_count ; i ++ ) {
@@ -90,20 +99,23 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
90
99
if (i == b -> successors_count - 1 ) {
91
100
/* Tail call optimization */
92
101
if (succ -> flags & ZEND_BB_REACHABLE ) {
93
- return ;
102
+ finished = true;
103
+ break ;
94
104
}
95
105
96
106
b = succ ;
97
107
break ;
98
108
} else {
99
109
/* Recursively check reachability */
100
110
if (!(succ -> flags & ZEND_BB_REACHABLE )) {
101
- zend_mark_reachable ( opcodes , cfg , succ );
111
+ zend_worklist_push ( & work , succ - cfg -> blocks );
102
112
}
103
113
}
104
114
}
105
115
}
106
116
}
117
+
118
+ ZEND_WORKLIST_FREE_ALLOCA (& work , list_use_heap );
107
119
}
108
120
/* }}} */
109
121
0 commit comments