52
52
#define DEBUG_PRINT (...)
53
53
#endif
54
54
55
- static void mark_edge_feasible (scdf_ctx * ctx , int from , const int * to_ptr , int suc_num ) {
56
- int to = * to_ptr ;
57
- if (suc_num < 2 ) {
58
- int edge = from * 2 + suc_num ;
59
- if (zend_bitset_in (ctx -> feasible_edges , edge )) {
60
- /* We already handled this edge */
61
- return ;
62
- }
55
+ static void mark_edge_feasible (scdf_ctx * ctx , int from , int to ) {
56
+ uint32_t edge = scdf_edge (& ctx -> ssa -> cfg , from , to );
63
57
64
- DEBUG_PRINT ("Marking edge %d->%d (successor %d) feasible\n" , from , to , suc_num );
65
- zend_bitset_incl (ctx -> feasible_edges , edge );
66
- } else {
67
- if (!ctx -> feasible_edges_ht ) {
68
- ALLOC_HASHTABLE (ctx -> feasible_edges_ht );
69
- zend_hash_init (ctx -> feasible_edges_ht , 0 , NULL , NULL , 0 );
70
- }
71
- if (!zend_hash_index_add_empty_element (
72
- ctx -> feasible_edges_ht , (zend_long ) (intptr_t ) to_ptr )) {
73
- /* We already handled this edge */
74
- return ;
75
- }
76
- DEBUG_PRINT ("Marking edge %d->%d (successor %d) feasible\n" , from , to , suc_num );
58
+ if (zend_bitset_in (ctx -> feasible_edges , edge )) {
59
+ /* We already handled this edge */
60
+ return ;
77
61
}
78
62
63
+ DEBUG_PRINT ("Marking edge %d->%d feasible\n" , from , to );
64
+ zend_bitset_incl (ctx -> feasible_edges , edge );
65
+
79
66
if (!zend_bitset_in (ctx -> executable_blocks , to )) {
80
67
if (!zend_bitset_in (ctx -> block_worklist , to )) {
81
68
DEBUG_PRINT ("Adding block %d to worklist\n" , to );
@@ -120,24 +107,29 @@ static void handle_instr(scdf_ctx *ctx, int block_num, zend_op *opline, zend_ssa
120
107
// TODO For now consider all edges feasible
121
108
int s ;
122
109
for (s = 0 ; s < block -> successors_count ; s ++ ) {
123
- mark_edge_feasible (ctx , block_num , & block -> successors [s ], s );
110
+ mark_edge_feasible (ctx , block_num , block -> successors [s ]);
124
111
}
125
112
} else {
126
113
zend_bool suc [2 ] = {0 };
127
114
if (get_feasible_successors (ctx , block , opline , ssa_op , suc )) {
128
115
if (suc [0 ]) {
129
- mark_edge_feasible (ctx , block_num , & block -> successors [0 ], 0 );
116
+ mark_edge_feasible (ctx , block_num , block -> successors [0 ]);
130
117
}
131
118
if (suc [1 ]) {
132
- mark_edge_feasible (ctx , block_num , & block -> successors [1 ], 1 );
119
+ mark_edge_feasible (ctx , block_num , block -> successors [1 ]);
133
120
}
134
121
}
135
122
}
136
123
}
137
124
}
138
125
139
126
void scdf_init (scdf_ctx * ctx , zend_op_array * op_array , zend_ssa * ssa , void * extra_ctx ) {
140
- zend_ulong * bitsets ;
127
+ uint32_t edges_count = 0 ;
128
+ int b ;
129
+
130
+ for (b = 0 ; b < ssa -> cfg .blocks_count ; b ++ ) {
131
+ edges_count += ssa -> cfg .blocks [b ].predecessors_count ;
132
+ }
141
133
142
134
ctx -> op_array = op_array ;
143
135
ctx -> ssa = ssa ;
@@ -147,32 +139,20 @@ void scdf_init(scdf_ctx *ctx, zend_op_array *op_array, zend_ssa *ssa, void *extr
147
139
ctx -> phi_var_worklist_len = zend_bitset_len (ssa -> vars_count );
148
140
ctx -> block_worklist_len = zend_bitset_len (ssa -> cfg .blocks_count );
149
141
150
- bitsets = safe_emalloc (
151
- ctx -> instr_worklist_len + ctx -> phi_var_worklist_len + 4 * ctx -> block_worklist_len ,
152
- sizeof (zend_ulong ), 0 );
142
+ ctx -> instr_worklist = ecalloc (
143
+ ctx -> instr_worklist_len + ctx -> phi_var_worklist_len + 2 * ctx -> block_worklist_len + zend_bitset_len ( edges_count ) ,
144
+ sizeof (zend_ulong ));
153
145
154
- ctx -> instr_worklist = bitsets ;
155
146
ctx -> phi_var_worklist = ctx -> instr_worklist + ctx -> instr_worklist_len ;
156
147
ctx -> block_worklist = ctx -> phi_var_worklist + ctx -> phi_var_worklist_len ;
157
148
ctx -> executable_blocks = ctx -> block_worklist + ctx -> block_worklist_len ;
158
149
ctx -> feasible_edges = ctx -> executable_blocks + ctx -> block_worklist_len ;
159
- ctx -> feasible_edges_ht = NULL ;
160
-
161
- zend_bitset_clear (ctx -> instr_worklist , ctx -> instr_worklist_len );
162
- zend_bitset_clear (ctx -> phi_var_worklist , ctx -> phi_var_worklist_len );
163
- zend_bitset_clear (ctx -> block_worklist , ctx -> block_worklist_len );
164
- zend_bitset_clear (ctx -> executable_blocks , ctx -> block_worklist_len );
165
- zend_bitset_clear (ctx -> feasible_edges , ctx -> block_worklist_len * 2 );
166
150
167
151
zend_bitset_incl (ctx -> block_worklist , 0 );
168
152
zend_bitset_incl (ctx -> executable_blocks , 0 );
169
153
}
170
154
171
155
void scdf_free (scdf_ctx * ctx ) {
172
- if (ctx -> feasible_edges_ht ) {
173
- zend_hash_destroy (ctx -> feasible_edges_ht );
174
- efree (ctx -> feasible_edges_ht );
175
- }
176
156
efree (ctx -> instr_worklist );
177
157
}
178
158
@@ -225,7 +205,7 @@ void scdf_solve(scdf_ctx *ctx, const char *name) {
225
205
226
206
if (block -> len == 0 ) {
227
207
/* Zero length blocks don't have a last instruction that would normally do this */
228
- mark_edge_feasible (ctx , i , & block -> successors [0 ], 0 );
208
+ mark_edge_feasible (ctx , i , block -> successors [0 ]);
229
209
}
230
210
}
231
211
}
0 commit comments