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