convert opts to use the opt_manage framework
[libfirm] / ir / opt / code_placement.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief    Move nodes to a block where they will be executed the least
23  *           often.
24  * @author   Christian Schaefer, Goetz Lindenmaier, Sebastian Felis,
25  *           Michael Beck
26  * @version  $Id$
27  *
28  * The idea here is to push nodes as deep into the dominance tree as their
29  * dependencies allow. After pushing them back up out of as many loops as
30  * possible.
31  */
32 #include "config.h"
33
34 #include <stdbool.h>
35
36 #include "iroptimize.h"
37 #include "adt/pdeq.h"
38 #include "irnode_t.h"
39 #include "irouts.h"
40 #include "irgopt.h"
41 #include "irpass.h"
42 #include "opt_manage.h"
43
44 static bool is_block_reachable(ir_node *block)
45 {
46         return get_Block_dom_depth(block) >= 0;
47 }
48
49 /**
50  * Find the earliest correct block for node n.  --- Place n into the
51  * same Block as its dominance-deepest Input.
52  *
53  * move_out_of_loops() expects that place_floats_early() have placed
54  * all "living" nodes into a living block. That's why we must
55  * move nodes in dead block with "live" successors into a valid
56  * block.
57  * We move them just into the same block as its successor (or
58  * in case of a Phi into the effective use block). For Phi successors,
59  * this may still be a dead block, but then there is no real use, as
60  * the control flow will be dead later.
61  */
62 static void place_floats_early(ir_node *n, waitq *worklist)
63 {
64         int       i;
65         int       arity;
66         ir_node  *block;
67         int       new_depth;
68         ir_graph *irg;
69         ir_node  *start_block;
70         ir_node  *new_block;
71
72         /* we must not run into an infinite loop */
73         if (irn_visited_else_mark(n))
74                 return;
75
76         /* The algorithm relies on the fact that all predecessors of a block are
77          * moved up after a call to place_float_early of the predecessors
78          * (see the loop below).
79          * However we have to break cycles somewhere. Relying on the visited flag
80          * will result in nodes not being moved up despite their place_floats_early
81          * call.
82          * Instead we break cycles at pinned nodes which won't move anyway:
83          * This works because in firm each cycle contains a Phi or Block node
84          * (which are pinned)
85          */
86         if (get_irn_pinned(n) != op_pin_state_floats) {
87                 /* we can't move pinned nodes */
88                 arity = get_irn_arity(n);
89                 for (i = 0; i < arity; ++i) {
90                         ir_node *pred = get_irn_n(n, i);
91                         pdeq_putr(worklist, pred);
92                 }
93                 if (!is_Block(n))
94                         pdeq_putr(worklist, get_nodes_block(n));
95                 return;
96         }
97
98         block = get_nodes_block(n);
99
100         /* first move predecessors up */
101         arity = get_irn_arity(n);
102         place_floats_early(block, worklist);
103         for (i = 0; i < arity; ++i) {
104                 ir_node *pred = get_irn_n(n, i);
105                 place_floats_early(pred, worklist);
106         }
107
108         /* determine earliest point */
109         new_block = NULL;
110         new_depth = 0;
111         for (i = 0; i < arity; ++i) {
112                 ir_node *pred       = get_irn_n(n, i);
113                 ir_node *pred_block = get_nodes_block(pred);
114                 int      pred_depth = get_Block_dom_depth(pred_block);
115                 if (pred_depth > new_depth) {
116                         new_depth = pred_depth;
117                         new_block = pred_block;
118                 }
119         }
120
121         /* avoid moving nodes into the start block if we are not in the backend */
122         irg         = get_irn_irg(n);
123         start_block = get_irg_start_block(irg);
124         if (new_block == start_block && block != start_block &&
125             get_irg_phase_state(irg) != phase_backend) {
126                 assert(get_Block_n_cfg_outs(start_block) == 1);
127                 new_block = get_Block_cfg_out(start_block, 0);
128         }
129
130         /* Set the new block */
131         if (new_block != NULL)
132                 set_nodes_block(n, new_block);
133 }
134
135 /**
136  * Floating nodes form subgraphs that begin at nodes as Const, Load,
137  * Start, Call and that end at op_pin_state_pinned nodes as Store, Call.
138  * Place_early places all floating nodes reachable from its argument through
139  * floating nodes and adds all beginnings at op_pin_state_pinned nodes to the
140  * worklist.
141  *
142  * @param worklist   a worklist, used for the algorithm, empty on in/output
143  */
144 static void place_early(ir_graph *irg, waitq *worklist)
145 {
146         assert(worklist);
147         inc_irg_visited(irg);
148
149         /* this inits the worklist */
150         place_floats_early(get_irg_end(irg), worklist);
151
152         /* Work the content of the worklist. */
153         while (!waitq_empty(worklist)) {
154                 ir_node *n = (ir_node*)waitq_get(worklist);
155                 if (!irn_visited(n))
156                         place_floats_early(n, worklist);
157         }
158         set_irg_pinned(irg, op_pin_state_pinned);
159 }
160
161 /**
162  * Compute the deepest common dominator tree ancestor of block and dca.
163  *
164  * @param dca    the deepest common dominator tree ancestor so far,
165  *               might be NULL
166  * @param block  a block
167  *
168  * @return  the deepest common dominator tree ancestor of block and dca
169  */
170 static ir_node *calc_dom_dca(ir_node *dca, ir_node *block)
171 {
172         assert(block != NULL);
173
174         /* We found a first legal placement. */
175         if (!dca)
176                 return block;
177
178         /* Find a placement that is dominates both, dca and block. */
179         while (get_Block_dom_depth(block) > get_Block_dom_depth(dca))
180                 block = get_Block_idom(block);
181
182         while (get_Block_dom_depth(dca) > get_Block_dom_depth(block)) {
183                 dca = get_Block_idom(dca);
184         }
185
186         while (block != dca) {
187                 block = get_Block_idom(block); dca = get_Block_idom(dca);
188         }
189         return dca;
190 }
191
192 /**
193  * Deepest common dominance ancestor of DCA and CONSUMER of PRODUCER.
194  * I.e., DCA is the block where we might place PRODUCER.
195  * A data flow edge points from producer to consumer.
196  */
197 static ir_node *consumer_dom_dca(ir_node *dca, ir_node *consumer,
198                                  ir_node *producer)
199 {
200         /* Compute the last block into which we can place a node so that it is
201            before consumer. */
202         if (is_Phi(consumer)) {
203                 /* our consumer is a Phi-node, the effective use is in all those
204                    blocks through which the Phi-node reaches producer */
205                 ir_node *phi_block = get_nodes_block(consumer);
206                 int      arity     = get_irn_arity(consumer);
207                 int      i;
208
209                 for (i = 0;  i < arity; i++) {
210                         if (get_Phi_pred(consumer, i) == producer) {
211                                 ir_node *new_block = get_Block_cfgpred_block(phi_block, i);
212                                 if (is_Bad(new_block))
213                                         continue;
214
215                                 assert(is_block_reachable(new_block));
216                                 dca = calc_dom_dca(dca, new_block);
217                         }
218                 }
219         } else {
220                 dca = calc_dom_dca(dca, get_nodes_block(consumer));
221         }
222         return dca;
223 }
224
225 static inline int get_block_loop_depth(ir_node *block)
226 {
227         return get_loop_depth(get_irn_loop(block));
228 }
229
230 /**
231  * Move n to a block with less loop depth than its current block. The
232  * new block must be dominated by early.
233  *
234  * @param n      the node that should be moved
235  * @param early  the earliest block we can n move to
236  */
237 static void move_out_of_loops(ir_node *n, ir_node *early)
238 {
239         ir_node *block      = get_nodes_block(n);
240         ir_node *best       = block;
241         int      best_depth = get_block_loop_depth(best);
242
243         /* Find the region deepest in the dominator tree dominating
244            dca with the least loop nesting depth, but still dominated
245            by our early placement. */
246         while (block != early) {
247                 ir_node *idom       = get_Block_idom(block);
248                 int      idom_depth = get_block_loop_depth(idom);
249                 if (idom_depth < best_depth) {
250                         best       = idom;
251                         best_depth = idom_depth;
252                 }
253                 block = idom;
254         }
255         if (best != get_nodes_block(n))
256                 set_nodes_block(n, best);
257 }
258
259 /**
260  * Calculate the deepest common ancestor in the dominator tree of all nodes'
261  * blocks depending on node; our final placement has to dominate DCA.
262  *
263  * @param node  the definition node
264  * @param dca   the deepest common ancestor block so far, initially
265  *              NULL
266  *
267  * @return the deepest common dominator ancestor of all blocks of node's users
268  */
269 static ir_node *get_deepest_common_dom_ancestor(ir_node *node, ir_node *dca)
270 {
271         int i;
272
273         for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
274                 ir_node *succ = get_irn_out(node, i);
275
276                 /* keepalive edges are special and don't respect the dominance */
277                 if (is_End(succ))
278                         continue;
279
280                 if (is_Proj(succ)) {
281                         /* Proj nodes are in the same block as node, so
282                          * the users of Proj are our users. */
283                         dca = get_deepest_common_dom_ancestor(succ, dca);
284                 } else {
285                         assert(is_block_reachable(get_nodes_block(succ)));
286                         dca = consumer_dom_dca(dca, succ, node);
287                 }
288         }
289         return dca;
290 }
291
292 /**
293  * Put all the Proj nodes of a node into a given block.
294  *
295  * @param node   the mode_T node
296  * @param block  the block to put the Proj nodes to
297  */
298 static void set_projs_block(ir_node *node, ir_node *block)
299 {
300         int i;
301
302         for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
303                 ir_node *succ = get_irn_out(node, i);
304
305                 assert(is_Proj(succ));
306
307                 if (get_irn_mode(succ) == mode_T) {
308                         set_projs_block(succ, block);
309                 }
310                 set_nodes_block(succ, block);
311         }
312 }
313
314 /**
315  * Find the latest legal block for N and place N into the
316  * `optimal' Block between the latest and earliest legal block.
317  * The `optimal' block is the dominance-deepest block of those
318  * with the least loop-nesting-depth.  This places N out of as many
319  * loops as possible and then makes it as control dependent as
320  * possible.
321  */
322 static void place_floats_late(ir_node *n, pdeq *worklist)
323 {
324         int      n_outs;
325         int      i;
326         ir_node *block;
327         ir_node *dca;
328
329         if (irn_visited_else_mark(n))
330                 return;
331
332         n_outs = get_irn_n_outs(n);
333         /* break cycles at pinned nodes (see place place_floats_early) as to why */
334         if (get_irn_pinned(n) != op_pin_state_floats) {
335                 for (i = 0; i < n_outs; ++i) {
336                         ir_node *succ = get_irn_out(n, i);
337                         pdeq_putr(worklist, succ);
338                 }
339                 return;
340         }
341
342         /* place our users */
343         for (i = 0; i < n_outs; ++i) {
344                 ir_node *succ = get_irn_out(n, i);
345                 place_floats_late(succ, worklist);
346         }
347
348         /* no point in moving Projs around, they are moved with their predecessor */
349         if (is_Proj(n))
350                 return;
351         /* some nodes should simply stay in the startblock */
352         if (is_irn_start_block_placed(n)) {
353 #ifndef NDEBUG
354                 ir_graph *irg         = get_irn_irg(n);
355                 ir_node  *start_block = get_irg_start_block(irg);
356                 assert(get_nodes_block(n) == start_block);
357 #endif
358                 return;
359         }
360
361         block = get_nodes_block(n);
362         assert(is_block_reachable(block));
363
364         /* deepest common ancestor in the dominator tree of all nodes'
365            blocks depending on us; our final placement has to dominate
366            DCA. */
367         dca = get_deepest_common_dom_ancestor(n, NULL);
368         if (dca != NULL) {
369                 set_nodes_block(n, dca);
370                 move_out_of_loops(n, block);
371                 if (get_irn_mode(n) == mode_T) {
372                         set_projs_block(n, get_nodes_block(n));
373                 }
374         }
375 }
376
377 /**
378  * Place floating nodes on the given worklist as late as possible using
379  * the dominance tree.
380  *
381  * @param worklist   the worklist containing the nodes to place
382  */
383 static void place_late(ir_graph *irg, waitq *worklist)
384 {
385         assert(worklist);
386         inc_irg_visited(irg);
387
388         /* This fills the worklist initially. */
389         place_floats_late(get_irg_start_block(irg), worklist);
390
391         /* And now empty the worklist again... */
392         while (!waitq_empty(worklist)) {
393                 ir_node *n = (ir_node*)waitq_get(worklist);
394                 if (!irn_visited(n))
395                         place_floats_late(n, worklist);
396         }
397 }
398
399 /* Code Placement. */
400 static ir_graph_state_t do_codeplacement(ir_graph *irg)
401 {
402         waitq *worklist;
403
404         /* Handle graph state */
405         assert(get_irg_phase_state(irg) != phase_building);
406
407         /* Place all floating nodes as early as possible. This guarantees
408          a legal code placement. */
409         worklist = new_waitq();
410         place_early(irg, worklist);
411
412         /* While GCSE might place nodes in unreachable blocks,
413          * these are now placed in reachable blocks. */
414
415         /* Note: place_early changes only blocks, no data edges. So, the
416          * data out edges are still valid, no need to recalculate them here. */
417
418         /* Now move the nodes down in the dominator tree. This reduces the
419            unnecessary executions of the node. */
420         place_late(irg, worklist);
421
422         del_waitq(worklist);
423         return 0;
424 }
425
426 optdesc_t opt_codeplacement = {
427         "code-placement",
428         IR_GRAPH_STATE_NO_CRITICAL_EDGES |
429         IR_GRAPH_STATE_CONSISTENT_OUTS |
430         IR_GRAPH_STATE_CONSISTENT_DOMINANCE |
431         IR_GRAPH_STATE_CONSISTENT_LOOPINFO,
432         do_codeplacement,
433 };
434
435 void place_code(ir_graph *irg)
436 {
437         perform_irg_optimization(irg, &opt_codeplacement);
438 }
439
440 /**
441  * Wrapper for place_code() inside the place_code pass.
442  */
443 static void place_code_wrapper(ir_graph *irg)
444 {
445         set_opt_global_cse(1);
446         optimize_graph_df(irg);
447         place_code(irg);
448         set_opt_global_cse(0);
449 }
450
451 static ir_graph_state_t do_gcse(ir_graph *irg)
452 {
453         set_opt_global_cse(1);
454         optimize_graph_df(irg);
455         do_codeplacement(irg);
456         set_opt_global_cse(0);
457         return 0;
458 }
459
460 optdesc_t opt_gcse = {
461         "gcse",
462         IR_GRAPH_STATE_NO_CRITICAL_EDGES |
463         IR_GRAPH_STATE_CONSISTENT_OUTS |
464         IR_GRAPH_STATE_CONSISTENT_DOMINANCE |
465         IR_GRAPH_STATE_CONSISTENT_LOOPINFO,
466         do_gcse,
467 };
468
469 ir_graph_pass_t *place_code_pass(const char *name)
470 {
471         return def_graph_pass(name ? name : "place", place_code_wrapper);
472 }