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