removed C99 features
[libfirm] / ir / be / beirgmod.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <stdlib.h>
6
7 #include "hashptr.h"
8 #include "pdeq.h"
9 #include "pset.h"
10 #include "pmap.h"
11 #include "util.h"
12 #include "debug.h"
13
14 #include "irflag_t.h"
15 #include "ircons_t.h"
16 #include "irnode_t.h"
17 #include "irmode_t.h"
18 #include "irdom_t.h"
19 #include "iredges_t.h"
20 #include "irgopt.h"
21
22 #include "be_t.h"
23 #include "bearch.h"
24 #include "besched_t.h"
25 #include "belive_t.h"
26 #include "benode_t.h"
27
28 #include "beirgmod.h"
29
30 #define DBG_MODULE firm_dbg_register("firm.be.irgmod")
31
32 struct _dom_front_info_t {
33   pmap *df_map;
34 };
35
36 static void compute_df_local(ir_node *bl, void *data)
37 {
38   pmap *df_map = ((dom_front_info_t *) data)->df_map;
39   ir_node *idom = get_Block_idom(bl);
40   pset *df = pmap_get(df_map, bl);
41   int i, n;
42
43   /*
44    * In the case that the immediate dominator is NULL, the
45    * block is the start block and its immediate dominator
46    * must be itself, else it is inserted into its own
47    * dominance frontier.
48    */
49   if(idom == NULL)
50         idom = bl;
51
52   /*
53    * Create a new dom frot set for this node,
54    * if none exists.
55    */
56   if(!df)
57         pmap_insert(df_map, bl, pset_new_ptr(16));
58
59   for(i = 0, n = get_irn_arity(bl); i < n; ++i) {
60
61     /* The predecessor block */
62     ir_node *pred = get_nodes_block(get_irn_n(bl, i));
63
64     /* The dominance frontier set of the predecessor. */
65     pset *df = pmap_get(df_map, pred);
66           if(!df) {
67                 df = pset_new_ptr(16);
68                 pmap_insert(df_map, pred, df);
69           }
70
71     assert(df && "dom front set must have been created for this node");
72
73     if(pred != idom && bl)
74       pset_insert_ptr(df, bl);
75   }
76 }
77
78 static void compute_df_up(ir_node *bl, void *data)
79 {
80   pmap *df_map = ((dom_front_info_t *) data)->df_map;
81   ir_node *y;
82
83   for(y = get_Block_dominated_first(bl); y; y = get_Block_dominated_next(y)) {
84     ir_node *w;
85     pset *df = pmap_get(df_map, y);
86
87     for(w = pset_first(df); w; w = pset_next(df))
88       if(!block_dominates(bl, w) || bl == w)
89         pset_insert_ptr(df, w);
90   }
91 }
92
93 dom_front_info_t *be_compute_dominance_frontiers(ir_graph *irg)
94 {
95   dom_front_info_t *info = malloc(sizeof(*info));
96
97   info->df_map = pmap_create();
98
99   /*
100    * This must be called as a post walker, since the dom front sets
101    * of all predecessors must be created when a block is reached.
102    */
103   dom_tree_walk_irg(irg, NULL, compute_df_local, info);
104   dom_tree_walk_irg(irg, NULL, compute_df_up, info);
105   return info;
106 }
107
108 void be_free_dominance_frontiers(dom_front_info_t *info)
109 {
110   pmap_entry *ent;
111
112   for(ent = pmap_first(info->df_map); ent; ent = pmap_next(info->df_map))
113     del_pset(ent->value);
114
115   pmap_destroy(info->df_map);
116   free(info);
117 }
118
119 pset *be_get_dominance_frontier(dom_front_info_t *info, ir_node *block)
120 {
121   return pmap_get(info->df_map, block);
122 }
123
124 /**
125  * Algorithm to place the Phi-Functions.
126  * @see Appel, Modern Compiler Implementation in Java, 2nd ed., p. 399ff
127  *
128  * This function takes an original node and a set of already placed
129  * copies of that node called @p copies. It places phi nodes at the
130  * iterated dominance frontiers of these copies and puts these phi nodes
131  * in the @p copies set, since they are another form of copies of the
132  * original value.
133  *
134  * The rename phase (see below) is responsible for fixing up the usages
135  * of the original node.
136  *
137  * @param orig The original node.
138  * @param copies A set contianing nodes representing a copy of the
139  * original node. Each node must be inserted into the block's schedule.
140  * @param copy_blocks A set in which the blocks are recorded which
141  * contain a copy. This is just for efficiency in later phases (see
142  * rename).
143  */
144 static void place_phi_functions(ir_node *orig, pset *copies,
145     pset *copy_blocks, dom_front_info_t *df_info)
146 {
147   int i;
148   ir_node *orig_block = get_nodes_block(orig);
149   ir_graph *irg = get_irn_irg(orig);
150   ir_mode *mode = get_irn_mode(orig);
151   pdeq *worklist = new_pdeq();
152   pset *phi_blocks = pset_new_ptr(8);
153   ir_node **ins = NULL;
154   void *it;
155   firm_dbg_module_t *dbg = DBG_MODULE;
156
157   /*
158    * Allocate an array for all blocks where the copies and the original
159    * value were defined.
160    */
161   int n_orig_blocks = pset_count(copy_blocks);
162   ir_node **orig_blocks = malloc(n_orig_blocks * sizeof(orig_blocks[0]));
163
164   /*
165    * Fill the worklist queue and the rest of the orig blocks array.
166    */
167   for(it = pset_first(copies), i = 0; it; it = pset_next(copies)) {
168     ir_node *copy_block = get_nodes_block(it);
169
170         /* FIXED_DANIEL
171          * Not true anymore, since phis can be copies of a value.
172          * Not all Phis are dominated by their args
173          *
174     if(!block_dominates(orig_block, copy_block)) {
175         assert(block_dominates(orig_block, copy_block)
176                 && "The block of the copy must be dominated by the block of the value");
177     }
178     */
179
180     pdeq_putr(worklist, copy_block);
181     orig_blocks[i++] = copy_block;
182   }
183
184   while(!pdeq_empty(worklist)) {
185     ir_node *bl = pdeq_getl(worklist);
186     ir_node *y;
187     pset *df = be_get_dominance_frontier(df_info, bl);
188
189     DBG((dbg, LEVEL_3, "dom front of %+F\n", bl));
190     for(y = pset_first(df); y; y = pset_next(df))
191             DBG((dbg, LEVEL_3, "\t%+F\n", y));
192
193     for(y = pset_first(df); y; y = pset_next(df)) {
194       int n_preds = get_irn_arity(y);
195
196       if(!pset_find_ptr(phi_blocks, y)) {
197         ir_node *phi;
198         int insert = 1;
199
200         /*
201          * Set the orig node as the only operand of the
202          * phi node.
203          */
204         ins = realloc(ins, n_preds * sizeof(ins[0]));
205         for(i = 0; i < n_preds; ++i)
206           ins[i] = orig;
207
208         /* Insert phi node */
209         phi = new_r_Phi(irg, y, n_preds, ins, mode);
210         DBG((dbg, LEVEL_2, "    inserting phi %+F with %d args in block %+F\n",
211               phi, n_preds, y));
212
213         /*
214          * The phi node itself is also a copy of the original
215          * value. So put it in the copies set also, so that
216          * the rename phase can treat them right.
217          */
218         pset_insert_ptr(copies, phi);
219         pset_insert_ptr(copy_blocks, y);
220
221         /*
222          * Insert the phi node into the schedule if it
223          * can occur there (PhiM's are not to put into a schedule.
224          */
225         if(to_appear_in_schedule(phi))
226           sched_add_before(sched_first(y), phi);
227
228         /* Insert the phi node in the phi blocks set. */
229         pset_insert_ptr(phi_blocks, y);
230
231         /*
232          * If orig or a copy of it were not defined in y,
233          * add y to the worklist.
234          */
235         for(i = 0; i < n_orig_blocks; ++i)
236           if(orig_blocks[i] == y) {
237             insert = 0;
238             break;
239           }
240
241         if(insert)
242           pdeq_putr(worklist, y);
243
244       }
245     }
246   }
247
248   del_pset(phi_blocks);
249   del_pdeq(worklist);
250
251   free(orig_blocks);
252
253   if(ins)
254     free(ins);
255 }
256
257 /**
258  * Find the copy of the given original node whose value is 'active'
259  * at a usage.
260  *
261  * The usage is given as a node and a position. Initially, the given operand
262  * points to a node for which copies were introduced. We have to find
263  * the valid copy for this usage. This is done by travering the
264  * dominance tree upwards. If the usage is a phi function, we start
265  * traversing from the predecessor block which corresponds to the phi
266  * usage.
267  *
268  * @param usage The node which uses the original node.
269  * @param pos The number of the argument which corresponds to the
270  * original node.
271  * @param copy_blocks A set containing all basic block in which copies
272  * of the original node are located.
273  * @param copies A set containing all node which are copies from the
274  * original node.
275  * @return The valid copy for usage.
276  */
277 static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks)
278 {
279   ir_node *curr_bl;
280   ir_node *start_irn;
281   firm_dbg_module_t *dbg = DBG_MODULE;
282   firm_dbg_set_mask(dbg, -1);
283
284   curr_bl = get_nodes_block(usage);
285
286
287   DBG((dbg, LEVEL_1, "Searching valid def for use %+F at pos %d\n", usage, pos));
288   /*
289    * If the usage is in a phi node, search the copy in the
290    * predecessor denoted by pos.
291    */
292   if(is_Phi(usage)) {
293     curr_bl = get_Block_cfgpred_block(curr_bl, pos);
294     start_irn = sched_last(curr_bl);
295   } else {
296     start_irn = sched_prev(usage);
297   }
298
299   /*
300    * Traverse the dominance tree upwards from the
301    * predecessor block of the usage.
302    */
303   while(curr_bl != NULL) {
304
305     /*
306      * If this block contains a copy, search the block
307      * instruction by instruction.
308      */
309     if(pset_find_ptr(copy_blocks, curr_bl)) {
310       ir_node *irn;
311
312       /* Look at each instruction from last to first. */
313       for(irn = start_irn; !is_Block(irn); irn = sched_prev(irn)) {
314
315         /* Take the first copy we find. */
316
317         DBG((dbg, LEVEL_1, "Is %F a copy?\n", irn));
318         if(pset_find_ptr(copies, irn))
319           return irn;
320       }
321     }
322
323     /* If were not done yet, look in the immediate dominator */
324     curr_bl = get_Block_idom(curr_bl);
325     if(curr_bl)
326       start_irn = sched_last(curr_bl);
327   }
328
329   assert(0 && "Did not find a valid def");
330   return NULL;
331 }
332
333 static void fix_usages(ir_node *orig, pset *copies, pset *copy_blocks)
334 {
335   int i = 0;
336   int n_outs = 0;
337   const ir_edge_t *edge;
338   firm_dbg_module_t *dbg = DBG_MODULE;
339
340   struct {
341     ir_node *irn;
342     int pos;
343   } *outs;
344
345   /* Count the number of outs. */
346   foreach_out_edge(orig, edge)
347     n_outs++;
348
349   /*
350    * Put all outs into an array.
351    * This is neccessary, since the outs would be modified while
352    * interating on them what could bring the outs module in trouble.
353    */
354   DBG((dbg, LEVEL_2, "  Users of %+F\n", orig));
355   outs = malloc(n_outs * sizeof(outs[0]));
356   foreach_out_edge(orig, edge) {
357     outs[i].irn = get_edge_src_irn(edge);
358     outs[i].pos = get_edge_src_pos(edge);
359     i += 1;
360   }
361
362   /*
363    * Search the valid def for each out and set it.
364    */
365   for(i = 0; i < n_outs; ++i) {
366     ir_node *def;
367     ir_node *irn = outs[i].irn;
368     int pos = outs[i].pos;
369
370     DBG((dbg, LEVEL_2, "    %+F(%d) -> ???\n", irn, pos));
371     def = search_def(irn, pos, copies, copy_blocks);
372     DBG((dbg, LEVEL_2, "    %+F(%d) -> %+F\n", irn, pos, def));
373
374     if(def != NULL)
375       set_irn_n(irn, pos, def);
376   }
377
378   free(outs);
379 }
380
381 struct phi_collect_info {
382   const ir_node *orig;
383   pset *copies;
384   pset *copy_blocks;
385 };
386
387 static void add_all_phis_walker(ir_node *irn, void *data)
388 {
389   if(is_Phi(irn)) {
390     int i, o, n;
391     struct phi_collect_info *info = data;
392
393     /*
394      * Look at all operands of the phi. If one of them is the original
395      * node, insert the phi into the copies and copy_blocks set.
396      */
397     for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
398       if(get_irn_n(irn, i) == info->orig) {
399         pset_insert_ptr(info->copies, irn);
400         pset_insert_ptr(info->copy_blocks, get_nodes_block(irn));
401
402                 /* FIXED_DANIEL
403                  * If a phi is a copy insert all its args as copies too.
404                  * Else setting the phi-args will fail in serach_def */
405         for(o=0; o<n; ++o) {
406                 const ir_node *arg = get_irn_n(irn, o);
407                 pset_insert_ptr(info->copies, arg);
408                 pset_insert_ptr(info->copy_blocks, get_nodes_block(arg));
409         }
410
411         break;
412       }
413     }
414
415
416   }
417 }
418
419 /**
420  * Add all phis using a node to a set.
421  * @param orig        The node the phis shall use.
422  * @param copies      The set where the phis shall be put into.
423  * @param copy_blocks The set the blocks of the phis shall be put into.
424  */
425 static void add_all_phis_using(const ir_node *orig, pset *copies, pset *copy_blocks)
426 {
427   struct phi_collect_info info;
428
429   info.copies      = copies;
430   info.copy_blocks = copy_blocks;
431   info.orig        = orig;
432   irg_walk_graph(get_irn_irg(orig), add_all_phis_walker, NULL, &info);
433 }
434
435 void be_introduce_copies(dom_front_info_t *info, ir_node *orig, int n, ir_node *copy_nodes[])
436 {
437   pset *copies = pset_new_ptr(2 * n);
438   pset *copy_blocks = pset_new_ptr(2 * n);
439   int save_optimize = get_optimize();
440   int save_normalize = get_opt_normalize();
441   firm_dbg_module_t *dbg = DBG_MODULE;
442   int i;
443
444   firm_dbg_set_mask(dbg, -1);
445   DBG((dbg, LEVEL_1, "Introducing following copies of %+F\n", orig));
446
447   /* Fill the sets. */
448   pset_insert_ptr(copies, orig);
449   pset_insert_ptr(copy_blocks, get_nodes_block(orig));
450
451   /*
452    * All phis using the original value are also copies of it
453    * and must be present in the copies set.
454    */
455   add_all_phis_using(orig, copies, copy_blocks);
456
457   for(i = 0; i < n; ++i) {
458     DBG((dbg, LEVEL_1,
459           "  %+F in block %+F\n", copy_nodes[i], get_nodes_block(copy_nodes[i])));
460     pset_insert_ptr(copies, copy_nodes[i]);
461     pset_insert_ptr(copy_blocks, get_nodes_block(copy_nodes[i]));
462   }
463
464   /*
465    * Disable optimization so that the phi functions do not
466    * disappear.
467    */
468   set_optimize(0);
469   set_opt_normalize(0);
470
471   /*
472    * Place the phi functions and reroute the usages.
473    */
474   place_phi_functions(orig, copies, copy_blocks, info);
475   fix_usages(orig, copies, copy_blocks);
476
477   /* reset the optimizations */
478   set_optimize(save_optimize);
479   set_opt_normalize(save_normalize);
480
481   del_pset(copies);
482   del_pset(copy_blocks);
483 }