15 #include "iredges_t.h"
19 #include "besched_t.h"
25 struct _dom_front_info_t {
29 static void compute_df_local(ir_node *bl, void *data)
31 pmap *df_map = ((dom_front_info_t *) data)->df_map;
32 ir_node *idom = get_Block_idom(bl);
35 for(i = 0, n = get_irn_arity(bl); i < n; ++i) {
37 /* The predecessor block */
38 ir_node *pred = get_nodes_block(get_irn_n(bl, i));
40 /* The dominance frontier set of the predecessor. */
41 pset *df = pmap_get(df_map, pred);
44 * Create the dominance frontier set of the predecessor
48 df = pset_new_ptr(16);
49 pmap_insert(df_map, pred, df);
53 if(pred != idom && bl)
54 pset_insert_ptr(df, bl);
58 static void compute_df_up(ir_node *bl, void *data)
60 pmap *df_map = ((dom_front_info_t *) data)->df_map;
63 for(y = get_Block_dominated_first(bl); y; y = get_Block_dominated_next(y)) {
65 pset *df = pmap_get(df_map, y);
67 for(w = pset_first(df); df; w = pset_next(df))
68 if(!block_dominates(bl, w) || bl == w)
69 pset_insert_ptr(df, w);
73 dom_front_info_t *be_compute_dominance_frontiers(ir_graph *irg)
75 dom_front_info_t *info = malloc(sizeof(*info));
77 info->df_map = pmap_create();
79 /* Perhaps both can we interwined */
80 dom_tree_walk_irg(irg, compute_df_local, NULL, info);
81 dom_tree_walk_irg(irg, NULL, compute_df_up, info);
85 void be_free_dominance_frontiers(dom_front_info_t *info)
89 for(ent = pmap_first(info->df_map); ent; ent = pmap_next(info->df_map))
92 pmap_destroy(info->df_map);
96 pset *be_get_dominance_frontier(dom_front_info_t *info, ir_node *block)
98 return pmap_get(info->df_map, block);
102 * Algorithm to place the Phi-Functions.
103 * @see Appel, Modern Compiler Implementation in Java, 2nd ed., p. 399ff
105 * This function takes an original node and a set of already placed
106 * copies of that node called @p copies. It places phi nodes at the
107 * iterated dominance frontiers of these copies and puts these phi nodes
108 * in the @p copies set, since they are another form of copies of the
111 * The rename phase (see below) is responsible for fixing up the usages
112 * of the original node.
114 * @param orig The original node.
115 * @param copies A set contianing nodes representing a copy of the
116 * original node. Each node must be inserted into the block's schedule.
117 * @param copy_blocks A set in which the blocks are recorded which
118 * contain a copy. This is just for efficiency in later phases (see
121 static void place_phi_functions(ir_node *orig, pset *copies,
122 pset *copy_blocks, dom_front_info_t *df_info)
125 ir_node *orig_block = get_nodes_block(orig);
126 ir_graph *irg = get_irn_irg(orig);
127 ir_mode *mode = get_irn_mode(orig);
128 pdeq *worklist = new_pdeq();
129 pset *phi_blocks = pset_new_ptr(8);
130 ir_node **ins = NULL;
134 * Allocate an array for all blocks where the copies and the original
135 * value were defined.
137 int n_orig_blocks = pset_count(copy_blocks) + 1;
138 ir_node **orig_blocks = malloc(n_orig_blocks * sizeof(orig_blocks[0]));
141 * Fill the array of definition blocks.
143 orig_blocks[0] = get_nodes_block(orig);
146 * Fill the worklist queue and the rest of the orig blocks array.
148 for(it = pset_first(copies), i = 1; it; it = pset_next(copies)) {
149 ir_node *copy_block = get_nodes_block(it);
151 assert(block_dominates(orig_block, copy_block)
152 && "The block of the copy must be dominated by the block of the value");
154 pdeq_putr(worklist, it);
155 orig_blocks[i++] = copy_block;
158 while(!pdeq_empty(worklist)) {
159 ir_node *irn = pdeq_getl(worklist);
160 ir_node *bl = get_nodes_block(irn);
162 int n_preds = get_irn_arity(bl);
163 pset *df = be_get_dominance_frontier(df_info, bl);
165 for(y = pset_first(df); y; y = pset_next(df)) {
167 if(!pset_find_ptr(phi_blocks, y)) {
172 * Set the orig node as the only operand of the
175 ins = realloc(ins, n_preds * sizeof(ins[0]));
176 for(i = 0; i < n_preds; ++i)
179 /* Insert phi node */
180 phi = new_r_Phi(irg, bl, n_preds, ins, mode);
183 * The phi node itself is also a copy of the original
184 * value. So put it in the copies set also, so that
185 * the rename phase can treat them right.
187 pset_insert_ptr(copies, phi);
188 pset_insert_ptr(copy_blocks, y);
190 /* Insert the phi node into the schedule */
191 sched_add_before(sched_first(y), phi);
193 /* Insert the phi node in the phi blocks set. */
194 pset_insert_ptr(phi_blocks, y);
197 * If orig or a copy of it were not defined in y,
198 * add y to the worklist.
200 for(i = 0; i < n_orig_blocks; ++i)
201 if(orig_blocks[i] == y) {
207 pdeq_putr(worklist, y);
213 del_pset(phi_blocks);
223 * Find the copy of the given original node whose value is 'active'
226 * The usage is given as a node and a position. Initially, the given operand
227 * points to a node for which copies were introduced. We have to find
228 * the valid copy for this usage. This is done by travering the
229 * dominance tree upwards. If the usage is a phi function, we start
230 * traversing from the predecessor block which corresponds to the phi
233 * @param usage The node which uses the original node.
234 * @param pos The number of the argument which corresponds to the
236 * @param copy_blocks A set containing all basic block in which copies
237 * of the original node are located.
238 * @param copies A set containing all node which are copies from the
240 * @return The valid copy for usage.
242 static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks)
246 curr_bl = get_nodes_block(usage);
249 * If the usage is in a phi node, search the copy in the
250 * predecessor denoted by pos.
253 curr_bl = get_nodes_block(get_irn_n(curr_bl, pos));
256 * Traverse the dominance tree upwards from the
257 * predecessor block of the usage.
259 while(curr_bl != NULL) {
262 * If this block contains a copy, search the block
263 * instruction by instruction.
265 if(pset_find_ptr(copy_blocks, curr_bl)) {
268 /* Look at each instruction from last to first. */
269 sched_foreach_reverse(curr_bl, irn) {
271 /* Take the first copy we find. */
272 if(pset_find_ptr(copies, irn))
276 assert(0 && "We must have encountered a copy");
279 /* If were not done yet, look in the immediate dominator */
280 curr_bl = get_Block_idom(curr_bl);
286 static void fix_usages(ir_node *orig, pset *copies, pset *copy_blocks)
290 const ir_edge_t *edge;
291 const ir_edge_t **outs;
293 /* Count the number of outs. */
294 foreach_out_edge(orig, edge)
298 * Put all outs into an array.
299 * This is neccessary, since the outs would be modified while
300 * interating on them what could bring the outs module in trouble.
302 outs = malloc(n_outs * sizeof(outs[0]));
303 foreach_out_edge(orig, edge)
307 * Search the valid def for each out and set it.
309 for(i = 0; i < n_outs; ++i) {
311 ir_node *irn = get_edge_src_irn(outs[i]);
312 int pos = get_edge_src_pos(outs[i]);
314 def = search_def(irn, pos, copies, copy_blocks);
315 set_irn_n(irn, pos, def);
321 void be_introduce_copies(dom_front_info_t *info, ir_node *orig, int n, ir_node *copy_nodes[])
323 pset *copies = pset_new_ptr(2 * n);
324 pset *copy_blocks = pset_new_ptr(2 * n);
325 int save_optimize = get_optimize();
329 for(i = 0; i < n; ++i) {
330 pset_insert_ptr(copies, copy_nodes[i]);
331 pset_insert_ptr(copy_blocks, get_nodes_block(copy_nodes[i]));
335 * Disable optimization so that the phi functions do not
341 * Place the phi functions and reroute the usages.
343 place_phi_functions(orig, copies, copy_blocks, info);
344 fix_usages(orig, copies, copy_blocks);
346 /* reset the optimizations */
347 set_optimize(save_optimize);
350 del_pset(copy_blocks);