19 #include "iredges_t.h"
23 #include "besched_t.h"
29 #define DBG_MODULE firm_dbg_register("firm.be.irgmod")
31 struct _dom_front_info_t {
35 static void compute_df_local(ir_node *bl, void *data)
37 pmap *df_map = ((dom_front_info_t *) data)->df_map;
38 ir_node *idom = get_Block_idom(bl);
39 pset *df = pmap_get(df_map, bl);
43 * Create a new dom frot set for this node,
47 pmap_insert(df_map, bl, pset_new_ptr(16));
49 for(i = 0, n = get_irn_arity(bl); i < n; ++i) {
51 /* The predecessor block */
52 ir_node *pred = get_nodes_block(get_irn_n(bl, i));
54 /* The dominance frontier set of the predecessor. */
55 pset *df = pmap_get(df_map, pred);
57 df = pset_new_ptr(16);
58 pmap_insert(df_map, pred, df);
61 assert(df && "dom front set must have been created for this node");
63 if(pred != idom && bl)
64 pset_insert_ptr(df, bl);
68 static void compute_df_up(ir_node *bl, void *data)
70 pmap *df_map = ((dom_front_info_t *) data)->df_map;
73 for(y = get_Block_dominated_first(bl); y; y = get_Block_dominated_next(y)) {
75 pset *df = pmap_get(df_map, y);
77 for(w = pset_first(df); w; w = pset_next(df))
78 if(!block_dominates(bl, w) || bl == w)
79 pset_insert_ptr(df, w);
83 dom_front_info_t *be_compute_dominance_frontiers(ir_graph *irg)
85 dom_front_info_t *info = malloc(sizeof(*info));
87 info->df_map = pmap_create();
90 * This must be called as a post walker, since the dom front sets
91 * of all predecessors must be created when a block is reached.
93 dom_tree_walk_irg(irg, NULL, compute_df_local, info);
94 dom_tree_walk_irg(irg, NULL, compute_df_up, info);
98 void be_free_dominance_frontiers(dom_front_info_t *info)
102 for(ent = pmap_first(info->df_map); ent; ent = pmap_next(info->df_map))
103 del_pset(ent->value);
105 pmap_destroy(info->df_map);
109 pset *be_get_dominance_frontier(dom_front_info_t *info, ir_node *block)
111 return pmap_get(info->df_map, block);
115 * Algorithm to place the Phi-Functions.
116 * @see Appel, Modern Compiler Implementation in Java, 2nd ed., p. 399ff
118 * This function takes an original node and a set of already placed
119 * copies of that node called @p copies. It places phi nodes at the
120 * iterated dominance frontiers of these copies and puts these phi nodes
121 * in the @p copies set, since they are another form of copies of the
124 * The rename phase (see below) is responsible for fixing up the usages
125 * of the original node.
127 * @param orig The original node.
128 * @param copies A set contianing nodes representing a copy of the
129 * original node. Each node must be inserted into the block's schedule.
130 * @param copy_blocks A set in which the blocks are recorded which
131 * contain a copy. This is just for efficiency in later phases (see
134 static void place_phi_functions(ir_node *orig, pset *copies,
135 pset *copy_blocks, dom_front_info_t *df_info)
138 ir_node *orig_block = get_nodes_block(orig);
139 ir_graph *irg = get_irn_irg(orig);
140 ir_mode *mode = get_irn_mode(orig);
141 pdeq *worklist = new_pdeq();
142 pset *phi_blocks = pset_new_ptr(8);
143 ir_node **ins = NULL;
145 firm_dbg_module_t *dbg = DBG_MODULE;
148 * Allocate an array for all blocks where the copies and the original
149 * value were defined.
151 int n_orig_blocks = pset_count(copy_blocks) + 1;
152 ir_node **orig_blocks = malloc(n_orig_blocks * sizeof(orig_blocks[0]));
155 * Fill the array of definition blocks.
157 orig_blocks[0] = get_nodes_block(orig);
160 * Fill the worklist queue and the rest of the orig blocks array.
162 for(it = pset_first(copies), i = 1; it; it = pset_next(copies)) {
163 ir_node *copy_block = get_nodes_block(it);
165 if(!block_dominates(orig_block, copy_block)) {
166 assert(block_dominates(orig_block, copy_block)
167 && "The block of the copy must be dominated by the block of the value");
170 pdeq_putr(worklist, it);
171 orig_blocks[i++] = copy_block;
174 while(!pdeq_empty(worklist)) {
175 ir_node *irn = pdeq_getl(worklist);
176 ir_node *bl = get_nodes_block(irn);
178 int n_preds = get_irn_arity(bl);
179 pset *df = be_get_dominance_frontier(df_info, bl);
181 for(y = pset_first(df); y; y = pset_next(df)) {
183 if(!pset_find_ptr(phi_blocks, y)) {
188 * Set the orig node as the only operand of the
191 ins = realloc(ins, n_preds * sizeof(ins[0]));
192 for(i = 0; i < n_preds; ++i)
193 ins[0] = new_Unknown(mode);
195 /* Insert phi node */
196 phi = new_r_Phi(irg, bl, n_preds, ins, mode);
197 DBG((dbg, LEVEL_2, " inserting phi in block %+F\n", bl));
200 * The phi node itself is also a copy of the original
201 * value. So put it in the copies set also, so that
202 * the rename phase can treat them right.
204 pset_insert_ptr(copies, phi);
205 pset_insert_ptr(copy_blocks, y);
207 /* Insert the phi node into the schedule */
208 sched_add_before(sched_first(y), phi);
210 /* Insert the phi node in the phi blocks set. */
211 pset_insert_ptr(phi_blocks, y);
214 * If orig or a copy of it were not defined in y,
215 * add y to the worklist.
217 for(i = 0; i < n_orig_blocks; ++i)
218 if(orig_blocks[i] == y) {
224 pdeq_putr(worklist, y);
230 del_pset(phi_blocks);
240 * Find the copy of the given original node whose value is 'active'
243 * The usage is given as a node and a position. Initially, the given operand
244 * points to a node for which copies were introduced. We have to find
245 * the valid copy for this usage. This is done by travering the
246 * dominance tree upwards. If the usage is a phi function, we start
247 * traversing from the predecessor block which corresponds to the phi
250 * @param usage The node which uses the original node.
251 * @param pos The number of the argument which corresponds to the
253 * @param copy_blocks A set containing all basic block in which copies
254 * of the original node are located.
255 * @param copies A set containing all node which are copies from the
257 * @return The valid copy for usage.
259 static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks)
264 curr_bl = get_nodes_block(usage);
267 * If the usage is in a phi node, search the copy in the
268 * predecessor denoted by pos.
271 curr_bl = get_nodes_block(get_irn_n(curr_bl, pos));
274 * Traverse the dominance tree upwards from the
275 * predecessor block of the usage.
278 while(curr_bl != NULL) {
281 * If this block contains a copy, search the block
282 * instruction by instruction.
284 if(pset_find_ptr(copy_blocks, curr_bl)) {
287 /* Look at each instruction from last to first. */
288 for(irn = start_irn; !is_Block(irn); irn = sched_prev(irn)) {
290 /* Take the first copy we find. */
291 if(pset_find_ptr(copies, irn))
296 /* If were not done yet, look in the immediate dominator */
297 curr_bl = get_Block_idom(curr_bl);
299 start_irn = sched_last(curr_bl);
305 static void fix_usages(ir_node *orig, pset *copies, pset *copy_blocks)
309 const ir_edge_t *edge;
310 firm_dbg_module_t *dbg = DBG_MODULE;
317 /* Count the number of outs. */
318 foreach_out_edge(orig, edge)
322 * Put all outs into an array.
323 * This is neccessary, since the outs would be modified while
324 * interating on them what could bring the outs module in trouble.
326 DBG((dbg, LEVEL_2, " Users of %+F\n", orig));
327 outs = malloc(n_outs * sizeof(outs[0]));
328 foreach_out_edge(orig, edge) {
329 outs[i].irn = get_edge_src_irn(edge);
330 outs[i].pos = get_edge_src_pos(edge);
331 DBG((dbg, LEVEL_2, " %+F(%d)\n", outs[i].irn, outs[i].pos));
336 * Search the valid def for each out and set it.
338 for(i = 0; i < n_outs; ++i) {
340 ir_node *irn = outs[i].irn;
341 int pos = outs[i].pos;
343 def = search_def(irn, pos, copies, copy_blocks);
345 set_irn_n(irn, pos, def);
351 void be_introduce_copies(dom_front_info_t *info, ir_node *orig, int n, ir_node *copy_nodes[])
353 pset *copies = pset_new_ptr(2 * n);
354 pset *copy_blocks = pset_new_ptr(2 * n);
355 int save_optimize = get_optimize();
357 firm_dbg_module_t *dbg = DBG_MODULE;
359 firm_dbg_set_mask(dbg, -1);
360 DBG((dbg, LEVEL_1, "Introducing following copies of %+F\n", orig));
362 for(i = 0; i < n; ++i) {
364 " %+F in block %+F\n", copy_nodes[i], get_nodes_block(copy_nodes[i])));
365 pset_insert_ptr(copies, copy_nodes[i]);
366 pset_insert_ptr(copy_blocks, get_nodes_block(copy_nodes[i]));
370 * Disable optimization so that the phi functions do not
376 * Place the phi functions and reroute the usages.
378 place_phi_functions(orig, copies, copy_blocks, info);
379 fix_usages(orig, copies, copy_blocks);
381 /* reset the optimizations */
382 set_optimize(save_optimize);
385 del_pset(copy_blocks);