26 #include "iredges_t.h"
31 #include "besched_t.h"
38 #define DBG_MODULE firm_dbg_register("firm.be.irgmod")
39 #define DBG_LEVEL SET_LEVEL_0
41 struct _dom_front_info_t {
46 * A wrapper for get_Block_idom.
47 * This function returns the block itself, if the block is the start
48 * block. Returning NULL would make any != comparison true which
49 * suggests, that the start block is dominated by some other node.
50 * @param bl The block.
51 * @return The immediate dominator of the block.
53 static INLINE ir_node *get_idom(ir_node *bl)
55 ir_node *idom = get_Block_idom(bl);
56 return idom == NULL ? bl : idom;
59 static void compute_df(ir_node *n, pmap *df_map)
62 const ir_edge_t *edge;
63 pset *df = pset_new_ptr_default();
65 /* Add local dominance frontiers */
66 foreach_block_succ(n, edge) {
67 ir_node *y = edge->src;
70 pset_insert_ptr(df, y);
74 * Go recursively down the dominance tree and add all blocks
75 * int the dominance frontiers of the children, which are not
76 * dominated by the given block.
78 for(c = get_Block_dominated_first(n); c; c = get_Block_dominated_next(c)) {
82 compute_df(c, df_map);
83 df_c = pmap_get(df_map, c);
85 for(w = pset_first(df_c); w; w = pset_next(df_c)) {
87 pset_insert_ptr(df, w);
91 pmap_insert(df_map, n, df);
95 dom_front_info_t *be_compute_dominance_frontiers(ir_graph *irg)
97 dom_front_info_t *info = malloc(sizeof(*info));
100 info->df_map = pmap_create();
102 compute_df(get_irg_start_block(irg), info->df_map);
107 void be_free_dominance_frontiers(dom_front_info_t *info)
111 for(ent = pmap_first(info->df_map); ent; ent = pmap_next(info->df_map))
112 del_pset(ent->value);
114 pmap_destroy(info->df_map);
118 pset *be_get_dominance_frontier(dom_front_info_t *info, ir_node *block)
120 return pmap_get(info->df_map, block);
123 static void determine_phi_blocks(pset *copies, pset* copy_blocks, pset *phi_blocks, dom_front_info_t *df_info)
126 pdeq *worklist = new_pdeq();
127 firm_dbg_module_t *dbg = DBG_MODULE;
130 * Fill the worklist queue and the rest of the orig blocks array.
132 for(bl = pset_first(copy_blocks); bl; bl = pset_next(copy_blocks)) {
133 pdeq_putr(worklist, bl);
136 while(!pdeq_empty(worklist)) {
137 ir_node *bl = pdeq_getl(worklist);
138 pset *df = be_get_dominance_frontier(df_info, bl);
142 DBG((dbg, LEVEL_3, "dom front of %+F\n", bl));
143 for(y = pset_first(df); y; y = pset_next(df))
144 DBG((dbg, LEVEL_3, "\t%+F\n", y));
146 for(y = pset_first(df); y; y = pset_next(df)) {
147 if(!pset_find_ptr(phi_blocks, y)) {
148 pset_insert_ptr(phi_blocks, y);
151 * Clear the link field of a possible phi block, since
152 * the possibly created phi will be stored there. See,
155 set_irn_link(y, NULL);
157 if(!pset_find_ptr(copy_blocks, y))
158 pdeq_putr(worklist, y);
168 * Find the copy of the given original node whose value is 'active'
171 * The usage is given as a node and a position. Initially, the given operand
172 * points to a node for which copies were introduced. We have to find
173 * the valid copy for this usage. This is done by travering the
174 * dominance tree upwards. If the usage is a phi function, we start
175 * traversing from the predecessor block which corresponds to the phi
178 * @param usage The node which uses the original node.
179 * @param pos The position of the argument which corresponds to the original node.
180 * @param copies A set containing all node which are copies from the original node.
181 * @param copy_blocks A set containing all basic block in which copies of the original node are located.
182 * @param phis A set where all created phis are recorded.
183 * @param phi_blocks A set of all blocks where Phis shall be inserted (iterated dominance frontier).
184 * @param mode The mode for the Phi if one has to be created.
185 * @return The valid copy for usage.
187 static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks, pset *phis, pset *phi_blocks, ir_mode *mode)
191 firm_dbg_module_t *dbg = DBG_MODULE;
193 curr_bl = get_nodes_block(usage);
195 DBG((dbg, LEVEL_1, "Searching valid def for use %+F at pos %d\n", usage, pos));
197 * If the usage is in a phi node, search the copy in the
198 * predecessor denoted by pos.
201 curr_bl = get_Block_cfgpred_block(curr_bl, pos);
202 start_irn = sched_last(curr_bl);
204 start_irn = sched_prev(usage);
208 * Traverse the dominance tree upwards from the
209 * predecessor block of the usage.
211 while(curr_bl != NULL) {
214 * If this block contains a copy, search the block
215 * instruction by instruction.
217 if(pset_find_ptr(copy_blocks, curr_bl)) {
220 /* Look at each instruction from last to first. */
221 sched_foreach_reverse_from(start_irn, irn) {
223 /* Take the first copy we find. */
224 if(pset_find_ptr(copies, irn))
229 if(pset_find_ptr(phi_blocks, curr_bl)) {
230 ir_node *phi = get_irn_link(curr_bl);
233 int i, n_preds = get_irn_arity(curr_bl);
234 ir_graph *irg = get_irn_irg(curr_bl);
235 ir_node **ins = xmalloc(n_preds * sizeof(ins[0]));
237 for(i = 0; i < n_preds; ++i)
238 ins[i] = new_r_Unknown(irg, mode);
240 phi = new_r_Phi(irg, curr_bl, n_preds, ins, mode);
241 DBG((dbg, LEVEL_2, "\tcreating phi %+F in %+F\n", phi, curr_bl));
243 set_irn_link(curr_bl, phi);
244 sched_add_after(curr_bl, phi);
247 for(i = 0; i < n_preds; ++i) {
248 ir_node *arg = search_def(phi, i, copies, copy_blocks, phis, phi_blocks, mode);
249 DBG((dbg, LEVEL_2, "\t\t%+F(%d) -> %+F\n", phi, i, arg));
250 set_irn_n(phi, i, arg);
254 pset_insert_ptr(phis, phi);
260 /* If were not done yet, look in the immediate dominator */
261 curr_bl = get_Block_idom(curr_bl);
263 start_irn = sched_last(curr_bl);
269 static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset *phis, pset *ignore_uses)
271 firm_dbg_module_t *dbg = DBG_MODULE;
286 * Put all outs into an array.
287 * This is necessary, since the outs would be modified while
288 * iterating on them what could bring the outs module in trouble.
290 for(irn = pset_first(copies); irn; irn = pset_next(copies)) {
291 const ir_edge_t *edge;
292 foreach_out_edge(irn, edge) {
293 if(!pset_find_ptr(ignore_uses, get_edge_src_irn(edge))) {
295 tmp.irn = get_edge_src_irn(edge);
296 tmp.pos = get_edge_src_pos(edge);
297 obstack_grow(&obst, &tmp, sizeof(tmp));
302 outs = obstack_finish(&obst);
305 * Search the valid def for each out and set it.
307 for(i = 0; i < n_outs; ++i) {
308 ir_node *irn = outs[i].irn;
309 int pos = outs[i].pos;
310 ir_mode *mode = get_irn_mode(get_irn_n(irn, pos));
314 def = search_def(irn, pos, copies, copy_blocks, phis, phi_blocks, mode);
315 DBG((dbg, LEVEL_2, "\t%+F(%d) -> %+F\n", irn, pos, def));
318 set_irn_n(irn, pos, def);
321 obstack_free(&obst, NULL);
325 * Remove phis which are not necessary.
326 * During place_phi_functions() phi functions are put on the dominance
327 * frontiers blindly. However some of them will never be used (these
328 * have at least one predecessor which is NULL, see search_def() for
329 * this case). Since place_phi_functions() enters them into the
330 * schedule, we have to remove them from there.
332 * @param copies The set of all copies made (including the phi functions).
334 static void remove_odd_phis(pset *copies, pset *unused_copies)
338 for(irn = pset_first(copies); irn; irn = pset_next(copies)) {
343 assert(sched_is_scheduled(irn) && "phi must be scheduled");
344 for(i = 0, n = get_irn_arity(irn); i < n && !illegal; ++i)
345 illegal = get_irn_n(irn, i) == NULL;
352 for(irn = pset_first(unused_copies); irn; irn = pset_next(unused_copies)) {
357 void be_ssa_constr_phis_ignore(dom_front_info_t *info, int n, ir_node *nodes[], pset *phis, pset *ignore_uses)
359 pset *irns = pset_new_ptr(n);
362 for(i = 0; i < n; ++i)
363 pset_insert_ptr(irns, nodes[i]);
364 be_ssa_constr_set_phis_ignore(info, irns, phis, ignore_uses);
368 void be_ssa_constr_ignore(dom_front_info_t *info, int n, ir_node *nodes[], pset *ignore_uses)
370 be_ssa_constr_phis_ignore(info, n, nodes, NULL, ignore_uses);
373 void be_ssa_constr(dom_front_info_t *info, int n, ir_node *nodes[])
375 pset *empty_set = be_empty_set();
376 assert(pset_count(empty_set) == 0);
377 be_ssa_constr_ignore(info, n, nodes, empty_set);
380 void be_ssa_constr_set_phis_ignore(dom_front_info_t *df, pset *nodes, pset *phis, pset *ignore_uses)
382 int n = pset_count(nodes);
383 pset *blocks = pset_new_ptr(n);
384 pset *phi_blocks = pset_new_ptr(n);
385 int save_optimize = get_optimize();
386 int save_normalize = get_opt_normalize();
387 firm_dbg_module_t *dbg = DBG_MODULE;
391 firm_dbg_set_mask(dbg, DBG_LEVEL);
392 DBG((dbg, LEVEL_1, "Introducing following copies for:\n"));
395 for(irn = pset_first(nodes); irn; irn = pset_next(nodes)) {
396 ir_node *bl = get_nodes_block(irn);
397 pset_insert_ptr(blocks, bl);
398 DBG((dbg, LEVEL_1, "\t%+F in %+F\n", irn, bl));
402 * Disable optimization so that the phi functions do not
406 set_opt_normalize(0);
409 * Place the phi functions and reroute the usages.
411 determine_phi_blocks(nodes, blocks, phi_blocks, df);
412 fix_usages(nodes, blocks, phi_blocks, phis, ignore_uses);
414 /* reset the optimizations */
415 set_optimize(save_optimize);
416 set_opt_normalize(save_normalize);
418 del_pset(phi_blocks);
423 void be_ssa_constr_set_phis(dom_front_info_t *df, pset *nodes, pset *phis)
425 pset *empty_set = be_empty_set();
426 assert(pset_count(empty_set) == 0);
428 be_ssa_constr_set_phis_ignore(df, nodes,phis, empty_set);
431 void be_ssa_constr_set_ignore(dom_front_info_t *df, pset *nodes, pset *ignore_uses)
433 be_ssa_constr_set_phis_ignore(df, nodes, NULL, ignore_uses);
436 void be_ssa_constr_set(dom_front_info_t *info, pset *nodes)
438 pset *empty_set = be_empty_set();
439 assert(pset_count(empty_set) == 0);
440 be_ssa_constr_set_ignore(info, nodes, empty_set);