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