14 #include "iredges_t.h"
16 #include "besched_t.h"
19 struct _dom_front_info_t {
23 static void compute_df_local(ir_node *bl, void *data)
25 pmap *df_map = ((dom_front_info_t *) data)->df_map;
26 ir_node *idom = get_Block_idom(bl);
29 for(i = 0, n = get_irn_arity(bl); i < n; ++i) {
31 /* The predecessor block */
32 ir_node *pred = get_nodes_block(get_irn_n(bl, i));
34 /* The dominance frontier set of the predecessor. */
35 pset *df = pmap_get(df_map, pred);
38 * Create the dominance frontier set of the predecessor
42 df = pset_new_ptr(16);
43 pmap_insert(df_map, pred, df);
47 if(pred != idom && bl)
48 pset_insert_ptr(df, bl);
52 static void compute_df_up(ir_node *bl, void *data)
54 pmap *df_map = ((dom_front_info_t *) data)->df_map;
57 for(y = get_Block_dominated_first(bl); y; y = get_Block_dominated_next(y)) {
59 pset *df = pmap_get(df_map, y);
61 for(w = pset_first(df); df; w = pset_next(df))
62 if(!block_dominates(bl, w) || bl == w)
63 pset_insert_ptr(df, w);
67 dom_front_info_t *be_compute_dominance_frontiers(ir_graph *irg)
69 dom_front_info_t *info = malloc(sizeof(*info));
71 info->df_map = pmap_create();
73 /* Perhaps both can we interwined */
74 dom_tree_walk_irg(irg, compute_df_local, NULL, info);
75 dom_tree_walk_irg(irg, NULL, compute_df_up, info);
79 void be_free_dominance_frontiers(dom_front_info_t *info)
83 for(ent = pmap_first(info->df_map); ent; ent = pmap_next(info->df_map))
86 pmap_destroy(info->df_map);
90 pset *be_get_dominance_frontier(dom_front_info_t *info, ir_node *block)
92 return pmap_get(info->df_map, block);
96 * Algorithm to place the Phi-Functions.
97 * @see Appel, Modern Compiler Implementation in Java, 2nd ed., p. 399ff
99 * This function takes an original node and a set of already placed
100 * copies of that node called @p copies. It places phi nodes at the
101 * iterated dominance frontiers of these copies and puts these phi nodes
102 * in the @p copies set, since they are another form of copies of the
105 * The rename phase (see below) is responsible for fixing up the usages
106 * of the original node.
108 * @param orig The original node.
109 * @param copies A set contianing nodes representing a copy of the
110 * original node. Each node must be inserted into the block's schedule.
111 * @param copy_blocks A set in which the blocks are recorded which
112 * contain a copy. This is just for efficiency in later phases (see
115 static void place_phi_functions(ir_node *orig, pset *copies,
116 pset *copy_blocks, dom_front_info_t *df_info)
119 ir_node *orig_block = get_nodes_block(orig);
120 ir_graph *irg = get_irn_irg(orig);
121 ir_mode *mode = get_irn_mode(orig);
122 pdeq *worklist = new_pdeq();
123 pset *phi_blocks = pset_new_ptr(8);
124 ir_node **ins = NULL;
128 * Allocate an array for all blocks where the copies and the original
129 * value were defined.
131 int n_orig_blocks = pset_count(copy_blocks) + 1;
132 ir_node **orig_blocks = malloc(n_orig_blocks * sizeof(orig_blocks[0]));
135 * Fill the array of definition blocks.
137 orig_blocks[0] = get_nodes_block(orig);
140 * Fill the worklist queue and the rest of the orig blocks array.
142 for(it = pset_first(copies), i = 1; it; it = pset_next(copies)) {
143 ir_node *copy_block = get_nodes_block(it);
145 assert(block_dominates(orig_block, copy_block)
146 && "The block of the copy must be dominated by the block of the value");
148 pdeq_putr(worklist, it);
149 orig_blocks[i++] = copy_block;
152 while(!pdeq_empty(worklist)) {
153 ir_node *irn = pdeq_getl(worklist);
154 ir_node *bl = get_nodes_block(irn);
156 int n_preds = get_irn_arity(bl);
157 pset *df = be_get_dominance_frontier(df_info, bl);
159 for(y = pset_first(df); y; y = pset_next(df)) {
161 if(!pset_find_ptr(phi_blocks, y)) {
166 * Set the orig node as the only operand of the
169 ins = realloc(ins, n_preds * sizeof(ins[0]));
170 for(i = 0; i < n_preds; ++i)
173 /* Insert phi node */
174 phi = new_r_Phi(irg, bl, n_preds, ins, mode);
177 * The phi node itself is also a copy of the original
178 * value. So put it in the copies set also, so that
179 * the rename phase can treat them right.
181 pset_insert_ptr(copies, phi);
182 pset_insert_ptr(copy_blocks, y);
184 /* Insert the phi node into the schedule */
185 sched_add_before(sched_first(y), phi);
187 /* Insert the phi node in the phi blocks set. */
188 pset_insert_ptr(phi_blocks, y);
191 * If orig or a copy of it were not defined in y,
192 * add y to the worklist.
194 for(i = 0; i < n_orig_blocks; ++i)
195 if(orig_blocks[i] == y) {
201 pdeq_putr(worklist, y);
207 del_pset(phi_blocks);
217 * Find the copy of the given original node whose value is 'active'
220 * The usage is given as a node and a position. Initially, the given operand
221 * points to a node for which copies were introduced. We have to find
222 * the valid copy for this usage. This is done by travering the
223 * dominance tree upwards. If the usage is a phi function, we start
224 * traversing from the predecessor block which corresponds to the phi
227 * @param usage The node which uses the original node.
228 * @param pos The number of the argument which corresponds to the
230 * @param copy_blocks A set containing all basic block in which copies
231 * of the original node are located.
232 * @param copies A set containing all node which are copies from the
234 * @return The valid copy for usage.
236 static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks)
240 curr_bl = get_nodes_block(usage);
243 * If the usage is in a phi node, search the copy in the
244 * predecessor denoted by pos.
247 curr_bl = get_nodes_block(get_irn_n(curr_bl, pos));
250 * Traverse the dominance tree upwards from the
251 * predecessor block of the usage.
253 while(curr_bl != NULL) {
256 * If this block contains a copy, search the block
257 * instruction by instruction.
259 if(pset_find_ptr(copy_blocks, curr_bl)) {
262 /* Look at each instruction from last to first. */
263 sched_foreach_reverse(curr_bl, irn) {
265 /* Take the first copy we find. */
266 if(pset_find_ptr(copies, irn))
270 assert(0 && "We must have encountered a copy");
273 /* If were not done yet, look in the immediate dominator */
274 curr_bl = get_Block_idom(curr_bl);
281 static void fix_usages(ir_node *orig, pset *copies, pset *copy_blocks)
285 const ir_edge_t *edge;
286 const ir_edge_t **outs;
288 /* Count the number of outs. */
289 foreach_out_edge(orig, edge)
293 * Put all outs into an array.
294 * This is neccessary, since the outs would be modified while
295 * interating on them what could bring the outs module in trouble.
297 outs = malloc(n_outs * sizeof(outs[0]));
298 foreach_out_edge(orig, edge)
302 * Search the valid def for each out and set it.
304 for(i = 0; i < n_outs; ++i) {
306 ir_node *irn = get_edge_src_irn(outs[i]);
307 int pos = get_edge_src_pos(outs[i]);
309 def = search_def(irn, pos, copies, copy_blocks);
310 set_irn_n(irn, pos, def);
316 void be_introduce_copies(dom_front_info_t *info, ir_node *orig, int n, ir_node *copy_nodes[])
318 pset *copies = pset_new_ptr(2 * n);
319 pset *copy_blocks = pset_new_ptr(2 * n);
320 int save_optimize = get_optimize();
324 for(i = 0; i < n; ++i) {
325 pset_insert_ptr(copies, copy_nodes[i]);
326 pset_insert_ptr(copy_blocks, get_nodes_block(copy_nodes[i]));
330 * Disable optimization so that the phi functions do not
336 * Place the phi functions and reroute the usages.
338 place_phi_functions(orig, copies, copy_blocks, info);
339 fix_usages(orig, copies, copy_blocks);
341 /* reset the optimizations */
342 set_optimize(save_optimize);
345 del_pset(copy_blocks);