]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/tree-outof-ssa.c
This patch rewrites the old VEC macro-based interface into a new one based on the...
[thirdparty/gcc.git] / gcc / tree-outof-ssa.c
1 /* Convert a program in SSA form into Normal form.
2 Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Andrew Macleod <amacleod@redhat.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "ggc.h"
28 #include "basic-block.h"
29 #include "gimple-pretty-print.h"
30 #include "bitmap.h"
31 #include "tree-flow.h"
32 #include "dumpfile.h"
33 #include "diagnostic-core.h"
34 #include "ssaexpand.h"
35
36 /* FIXME: A lot of code here deals with expanding to RTL. All that code
37 should be in cfgexpand.c. */
38 #include "expr.h"
39
40
41
42 /* Used to hold all the components required to do SSA PHI elimination.
43 The node and pred/succ list is a simple linear list of nodes and
44 edges represented as pairs of nodes.
45
46 The predecessor and successor list: Nodes are entered in pairs, where
47 [0] ->PRED, [1]->SUCC. All the even indexes in the array represent
48 predecessors, all the odd elements are successors.
49
50 Rationale:
51 When implemented as bitmaps, very large programs SSA->Normal times were
52 being dominated by clearing the interference graph.
53
54 Typically this list of edges is extremely small since it only includes
55 PHI results and uses from a single edge which have not coalesced with
56 each other. This means that no virtual PHI nodes are included, and
57 empirical evidence suggests that the number of edges rarely exceed
58 3, and in a bootstrap of GCC, the maximum size encountered was 7.
59 This also limits the number of possible nodes that are involved to
60 rarely more than 6, and in the bootstrap of gcc, the maximum number
61 of nodes encountered was 12. */
62
63 typedef struct _elim_graph {
64 /* Size of the elimination vectors. */
65 int size;
66
67 /* List of nodes in the elimination graph. */
68 vec<int> nodes;
69
70 /* The predecessor and successor edge list. */
71 vec<int> edge_list;
72
73 /* Source locus on each edge */
74 vec<source_location> edge_locus;
75
76 /* Visited vector. */
77 sbitmap visited;
78
79 /* Stack for visited nodes. */
80 vec<int> stack;
81
82 /* The variable partition map. */
83 var_map map;
84
85 /* Edge being eliminated by this graph. */
86 edge e;
87
88 /* List of constant copies to emit. These are pushed on in pairs. */
89 vec<int> const_dests;
90 vec<tree> const_copies;
91
92 /* Source locations for any constant copies. */
93 vec<source_location> copy_locus;
94 } *elim_graph;
95
96
97 /* For an edge E find out a good source location to associate with
98 instructions inserted on edge E. If E has an implicit goto set,
99 use its location. Otherwise search instructions in predecessors
100 of E for a location, and use that one. That makes sense because
101 we insert on edges for PHI nodes, and effects of PHIs happen on
102 the end of the predecessor conceptually. */
103
104 static void
105 set_location_for_edge (edge e)
106 {
107 if (e->goto_locus)
108 {
109 set_curr_insn_location (e->goto_locus);
110 }
111 else
112 {
113 basic_block bb = e->src;
114 gimple_stmt_iterator gsi;
115
116 do
117 {
118 for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
119 {
120 gimple stmt = gsi_stmt (gsi);
121 if (is_gimple_debug (stmt))
122 continue;
123 if (gimple_has_location (stmt) || gimple_block (stmt))
124 {
125 set_curr_insn_location (gimple_location (stmt));
126 return;
127 }
128 }
129 /* Nothing found in this basic block. Make a half-assed attempt
130 to continue with another block. */
131 if (single_pred_p (bb))
132 bb = single_pred (bb);
133 else
134 bb = e->src;
135 }
136 while (bb != e->src);
137 }
138 }
139
140 /* Emit insns to copy SRC into DEST converting SRC if necessary. As
141 SRC/DEST might be BLKmode memory locations SIZEEXP is a tree from
142 which we deduce the size to copy in that case. */
143
144 static inline rtx
145 emit_partition_copy (rtx dest, rtx src, int unsignedsrcp, tree sizeexp)
146 {
147 rtx seq;
148
149 start_sequence ();
150
151 if (GET_MODE (src) != VOIDmode && GET_MODE (src) != GET_MODE (dest))
152 src = convert_to_mode (GET_MODE (dest), src, unsignedsrcp);
153 if (GET_MODE (src) == BLKmode)
154 {
155 gcc_assert (GET_MODE (dest) == BLKmode);
156 emit_block_move (dest, src, expr_size (sizeexp), BLOCK_OP_NORMAL);
157 }
158 else
159 emit_move_insn (dest, src);
160
161 seq = get_insns ();
162 end_sequence ();
163
164 return seq;
165 }
166
167 /* Insert a copy instruction from partition SRC to DEST onto edge E. */
168
169 static void
170 insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
171 {
172 tree var;
173 rtx seq;
174 if (dump_file && (dump_flags & TDF_DETAILS))
175 {
176 fprintf (dump_file,
177 "Inserting a partition copy on edge BB%d->BB%d :"
178 "PART.%d = PART.%d",
179 e->src->index,
180 e->dest->index, dest, src);
181 fprintf (dump_file, "\n");
182 }
183
184 gcc_assert (SA.partition_to_pseudo[dest]);
185 gcc_assert (SA.partition_to_pseudo[src]);
186
187 set_location_for_edge (e);
188 /* If a locus is provided, override the default. */
189 if (locus)
190 set_curr_insn_location (locus);
191
192 var = partition_to_var (SA.map, src);
193 seq = emit_partition_copy (SA.partition_to_pseudo[dest],
194 SA.partition_to_pseudo[src],
195 TYPE_UNSIGNED (TREE_TYPE (var)),
196 var);
197
198 insert_insn_on_edge (seq, e);
199 }
200
201 /* Insert a copy instruction from expression SRC to partition DEST
202 onto edge E. */
203
204 static void
205 insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
206 {
207 rtx seq, x;
208 enum machine_mode dest_mode, src_mode;
209 int unsignedp;
210 tree var;
211
212 if (dump_file && (dump_flags & TDF_DETAILS))
213 {
214 fprintf (dump_file,
215 "Inserting a value copy on edge BB%d->BB%d : PART.%d = ",
216 e->src->index,
217 e->dest->index, dest);
218 print_generic_expr (dump_file, src, TDF_SLIM);
219 fprintf (dump_file, "\n");
220 }
221
222 gcc_assert (SA.partition_to_pseudo[dest]);
223
224 set_location_for_edge (e);
225 /* If a locus is provided, override the default. */
226 if (locus)
227 set_curr_insn_location (locus);
228
229 start_sequence ();
230
231 var = SSA_NAME_VAR (partition_to_var (SA.map, dest));
232 src_mode = TYPE_MODE (TREE_TYPE (src));
233 dest_mode = GET_MODE (SA.partition_to_pseudo[dest]);
234 gcc_assert (src_mode == TYPE_MODE (TREE_TYPE (var)));
235 gcc_assert (!REG_P (SA.partition_to_pseudo[dest])
236 || dest_mode == promote_decl_mode (var, &unsignedp));
237
238 if (src_mode != dest_mode)
239 {
240 x = expand_expr (src, NULL, src_mode, EXPAND_NORMAL);
241 x = convert_modes (dest_mode, src_mode, x, unsignedp);
242 }
243 else if (src_mode == BLKmode)
244 {
245 x = SA.partition_to_pseudo[dest];
246 store_expr (src, x, 0, false);
247 }
248 else
249 x = expand_expr (src, SA.partition_to_pseudo[dest],
250 dest_mode, EXPAND_NORMAL);
251
252 if (x != SA.partition_to_pseudo[dest])
253 emit_move_insn (SA.partition_to_pseudo[dest], x);
254 seq = get_insns ();
255 end_sequence ();
256
257 insert_insn_on_edge (seq, e);
258 }
259
260 /* Insert a copy instruction from RTL expression SRC to partition DEST
261 onto edge E. */
262
263 static void
264 insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
265 source_location locus)
266 {
267 rtx seq;
268 if (dump_file && (dump_flags & TDF_DETAILS))
269 {
270 fprintf (dump_file,
271 "Inserting a temp copy on edge BB%d->BB%d : PART.%d = ",
272 e->src->index,
273 e->dest->index, dest);
274 print_simple_rtl (dump_file, src);
275 fprintf (dump_file, "\n");
276 }
277
278 gcc_assert (SA.partition_to_pseudo[dest]);
279
280 set_location_for_edge (e);
281 /* If a locus is provided, override the default. */
282 if (locus)
283 set_curr_insn_location (locus);
284
285 /* We give the destination as sizeexp in case src/dest are BLKmode
286 mems. Usually we give the source. As we result from SSA names
287 the left and right size should be the same (and no WITH_SIZE_EXPR
288 involved), so it doesn't matter. */
289 seq = emit_partition_copy (SA.partition_to_pseudo[dest],
290 src, unsignedsrcp,
291 partition_to_var (SA.map, dest));
292
293 insert_insn_on_edge (seq, e);
294 }
295
296 /* Insert a copy instruction from partition SRC to RTL lvalue DEST
297 onto edge E. */
298
299 static void
300 insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
301 {
302 tree var;
303 rtx seq;
304 if (dump_file && (dump_flags & TDF_DETAILS))
305 {
306 fprintf (dump_file,
307 "Inserting a temp copy on edge BB%d->BB%d : ",
308 e->src->index,
309 e->dest->index);
310 print_simple_rtl (dump_file, dest);
311 fprintf (dump_file, "= PART.%d\n", src);
312 }
313
314 gcc_assert (SA.partition_to_pseudo[src]);
315
316 set_location_for_edge (e);
317 /* If a locus is provided, override the default. */
318 if (locus)
319 set_curr_insn_location (locus);
320
321 var = partition_to_var (SA.map, src);
322 seq = emit_partition_copy (dest,
323 SA.partition_to_pseudo[src],
324 TYPE_UNSIGNED (TREE_TYPE (var)),
325 var);
326
327 insert_insn_on_edge (seq, e);
328 }
329
330
331 /* Create an elimination graph with SIZE nodes and associated data
332 structures. */
333
334 static elim_graph
335 new_elim_graph (int size)
336 {
337 elim_graph g = (elim_graph) xmalloc (sizeof (struct _elim_graph));
338
339 g->nodes.create (30);
340 g->const_dests.create (20);
341 g->const_copies.create (20);
342 g->copy_locus.create (10);
343 g->edge_list.create (20);
344 g->edge_locus.create (10);
345 g->stack.create (30);
346
347 g->visited = sbitmap_alloc (size);
348
349 return g;
350 }
351
352
353 /* Empty elimination graph G. */
354
355 static inline void
356 clear_elim_graph (elim_graph g)
357 {
358 g->nodes.truncate (0);
359 g->edge_list.truncate (0);
360 g->edge_locus.truncate (0);
361 }
362
363
364 /* Delete elimination graph G. */
365
366 static inline void
367 delete_elim_graph (elim_graph g)
368 {
369 sbitmap_free (g->visited);
370 g->stack.release ();
371 g->edge_list.release ();
372 g->const_copies.release ();
373 g->const_dests.release ();
374 g->nodes.release ();
375 g->copy_locus.release ();
376 g->edge_locus.release ();
377
378 free (g);
379 }
380
381
382 /* Return the number of nodes in graph G. */
383
384 static inline int
385 elim_graph_size (elim_graph g)
386 {
387 return g->nodes.length ();
388 }
389
390
391 /* Add NODE to graph G, if it doesn't exist already. */
392
393 static inline void
394 elim_graph_add_node (elim_graph g, int node)
395 {
396 int x;
397 int t;
398
399 FOR_EACH_VEC_ELT (g->nodes, x, t)
400 if (t == node)
401 return;
402 g->nodes.safe_push (node);
403 }
404
405
406 /* Add the edge PRED->SUCC to graph G. */
407
408 static inline void
409 elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus)
410 {
411 g->edge_list.safe_push (pred);
412 g->edge_list.safe_push (succ);
413 g->edge_locus.safe_push (locus);
414 }
415
416
417 /* Remove an edge from graph G for which NODE is the predecessor, and
418 return the successor node. -1 is returned if there is no such edge. */
419
420 static inline int
421 elim_graph_remove_succ_edge (elim_graph g, int node, source_location *locus)
422 {
423 int y;
424 unsigned x;
425 for (x = 0; x < g->edge_list.length (); x += 2)
426 if (g->edge_list[x] == node)
427 {
428 g->edge_list[x] = -1;
429 y = g->edge_list[x + 1];
430 g->edge_list[x + 1] = -1;
431 *locus = g->edge_locus[x / 2];
432 g->edge_locus[x / 2] = UNKNOWN_LOCATION;
433 return y;
434 }
435 *locus = UNKNOWN_LOCATION;
436 return -1;
437 }
438
439
440 /* Find all the nodes in GRAPH which are successors to NODE in the
441 edge list. VAR will hold the partition number found. CODE is the
442 code fragment executed for every node found. */
443
444 #define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, CODE) \
445 do { \
446 unsigned x_; \
447 int y_; \
448 for (x_ = 0; x_ < (GRAPH)->edge_list.length (); x_ += 2) \
449 { \
450 y_ = (GRAPH)->edge_list[x_]; \
451 if (y_ != (NODE)) \
452 continue; \
453 (void) ((VAR) = (GRAPH)->edge_list[x_ + 1]); \
454 (void) ((LOCUS) = (GRAPH)->edge_locus[x_ / 2]); \
455 CODE; \
456 } \
457 } while (0)
458
459
460 /* Find all the nodes which are predecessors of NODE in the edge list for
461 GRAPH. VAR will hold the partition number found. CODE is the
462 code fragment executed for every node found. */
463
464 #define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, CODE) \
465 do { \
466 unsigned x_; \
467 int y_; \
468 for (x_ = 0; x_ < (GRAPH)->edge_list.length (); x_ += 2) \
469 { \
470 y_ = (GRAPH)->edge_list[x_ + 1]; \
471 if (y_ != (NODE)) \
472 continue; \
473 (void) ((VAR) = (GRAPH)->edge_list[x_]); \
474 (void) ((LOCUS) = (GRAPH)->edge_locus[x_ / 2]); \
475 CODE; \
476 } \
477 } while (0)
478
479
480 /* Add T to elimination graph G. */
481
482 static inline void
483 eliminate_name (elim_graph g, int T)
484 {
485 elim_graph_add_node (g, T);
486 }
487
488
489 /* Build elimination graph G for basic block BB on incoming PHI edge
490 G->e. */
491
492 static void
493 eliminate_build (elim_graph g)
494 {
495 tree Ti;
496 int p0, pi;
497 gimple_stmt_iterator gsi;
498
499 clear_elim_graph (g);
500
501 for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
502 {
503 gimple phi = gsi_stmt (gsi);
504 source_location locus;
505
506 p0 = var_to_partition (g->map, gimple_phi_result (phi));
507 /* Ignore results which are not in partitions. */
508 if (p0 == NO_PARTITION)
509 continue;
510
511 Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
512 locus = gimple_phi_arg_location_from_edge (phi, g->e);
513
514 /* If this argument is a constant, or a SSA_NAME which is being
515 left in SSA form, just queue a copy to be emitted on this
516 edge. */
517 if (!phi_ssa_name_p (Ti)
518 || (TREE_CODE (Ti) == SSA_NAME
519 && var_to_partition (g->map, Ti) == NO_PARTITION))
520 {
521 /* Save constant copies until all other copies have been emitted
522 on this edge. */
523 g->const_dests.safe_push (p0);
524 g->const_copies.safe_push (Ti);
525 g->copy_locus.safe_push (locus);
526 }
527 else
528 {
529 pi = var_to_partition (g->map, Ti);
530 if (p0 != pi)
531 {
532 eliminate_name (g, p0);
533 eliminate_name (g, pi);
534 elim_graph_add_edge (g, p0, pi, locus);
535 }
536 }
537 }
538 }
539
540
541 /* Push successors of T onto the elimination stack for G. */
542
543 static void
544 elim_forward (elim_graph g, int T)
545 {
546 int S;
547 source_location locus;
548
549 bitmap_set_bit (g->visited, T);
550 FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus,
551 {
552 if (!bitmap_bit_p (g->visited, S))
553 elim_forward (g, S);
554 });
555 g->stack.safe_push (T);
556 }
557
558
559 /* Return 1 if there unvisited predecessors of T in graph G. */
560
561 static int
562 elim_unvisited_predecessor (elim_graph g, int T)
563 {
564 int P;
565 source_location locus;
566
567 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
568 {
569 if (!bitmap_bit_p (g->visited, P))
570 return 1;
571 });
572 return 0;
573 }
574
575 /* Process predecessors first, and insert a copy. */
576
577 static void
578 elim_backward (elim_graph g, int T)
579 {
580 int P;
581 source_location locus;
582
583 bitmap_set_bit (g->visited, T);
584 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
585 {
586 if (!bitmap_bit_p (g->visited, P))
587 {
588 elim_backward (g, P);
589 insert_partition_copy_on_edge (g->e, P, T, locus);
590 }
591 });
592 }
593
594 /* Allocate a new pseudo register usable for storing values sitting
595 in NAME (a decl or SSA name), i.e. with matching mode and attributes. */
596
597 static rtx
598 get_temp_reg (tree name)
599 {
600 tree var = TREE_CODE (name) == SSA_NAME ? SSA_NAME_VAR (name) : name;
601 tree type = TREE_TYPE (var);
602 int unsignedp;
603 enum machine_mode reg_mode = promote_decl_mode (var, &unsignedp);
604 rtx x = gen_reg_rtx (reg_mode);
605 if (POINTER_TYPE_P (type))
606 mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (var))));
607 return x;
608 }
609
610 /* Insert required copies for T in graph G. Check for a strongly connected
611 region, and create a temporary to break the cycle if one is found. */
612
613 static void
614 elim_create (elim_graph g, int T)
615 {
616 int P, S;
617 source_location locus;
618
619 if (elim_unvisited_predecessor (g, T))
620 {
621 tree var = partition_to_var (g->map, T);
622 rtx U = get_temp_reg (var);
623 int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var));
624
625 insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION);
626 FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
627 {
628 if (!bitmap_bit_p (g->visited, P))
629 {
630 elim_backward (g, P);
631 insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus);
632 }
633 });
634 }
635 else
636 {
637 S = elim_graph_remove_succ_edge (g, T, &locus);
638 if (S != -1)
639 {
640 bitmap_set_bit (g->visited, T);
641 insert_partition_copy_on_edge (g->e, T, S, locus);
642 }
643 }
644 }
645
646
647 /* Eliminate all the phi nodes on edge E in graph G. */
648
649 static void
650 eliminate_phi (edge e, elim_graph g)
651 {
652 int x;
653
654 gcc_assert (g->const_copies.length () == 0);
655 gcc_assert (g->copy_locus.length () == 0);
656
657 /* Abnormal edges already have everything coalesced. */
658 if (e->flags & EDGE_ABNORMAL)
659 return;
660
661 g->e = e;
662
663 eliminate_build (g);
664
665 if (elim_graph_size (g) != 0)
666 {
667 int part;
668
669 bitmap_clear (g->visited);
670 g->stack.truncate (0);
671
672 FOR_EACH_VEC_ELT (g->nodes, x, part)
673 {
674 if (!bitmap_bit_p (g->visited, part))
675 elim_forward (g, part);
676 }
677
678 bitmap_clear (g->visited);
679 while (g->stack.length () > 0)
680 {
681 x = g->stack.pop ();
682 if (!bitmap_bit_p (g->visited, x))
683 elim_create (g, x);
684 }
685 }
686
687 /* If there are any pending constant copies, issue them now. */
688 while (g->const_copies.length () > 0)
689 {
690 int dest;
691 tree src;
692 source_location locus;
693
694 src = g->const_copies.pop ();
695 dest = g->const_dests.pop ();
696 locus = g->copy_locus.pop ();
697 insert_value_copy_on_edge (e, dest, src, locus);
698 }
699 }
700
701
702 /* Remove each argument from PHI. If an arg was the last use of an SSA_NAME,
703 check to see if this allows another PHI node to be removed. */
704
705 static void
706 remove_gimple_phi_args (gimple phi)
707 {
708 use_operand_p arg_p;
709 ssa_op_iter iter;
710
711 if (dump_file && (dump_flags & TDF_DETAILS))
712 {
713 fprintf (dump_file, "Removing Dead PHI definition: ");
714 print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
715 }
716
717 FOR_EACH_PHI_ARG (arg_p, phi, iter, SSA_OP_USE)
718 {
719 tree arg = USE_FROM_PTR (arg_p);
720 if (TREE_CODE (arg) == SSA_NAME)
721 {
722 /* Remove the reference to the existing argument. */
723 SET_USE (arg_p, NULL_TREE);
724 if (has_zero_uses (arg))
725 {
726 gimple stmt;
727 gimple_stmt_iterator gsi;
728
729 stmt = SSA_NAME_DEF_STMT (arg);
730
731 /* Also remove the def if it is a PHI node. */
732 if (gimple_code (stmt) == GIMPLE_PHI)
733 {
734 remove_gimple_phi_args (stmt);
735 gsi = gsi_for_stmt (stmt);
736 remove_phi_node (&gsi, true);
737 }
738
739 }
740 }
741 }
742 }
743
744 /* Remove any PHI node which is a virtual PHI, or a PHI with no uses. */
745
746 static void
747 eliminate_useless_phis (void)
748 {
749 basic_block bb;
750 gimple_stmt_iterator gsi;
751 tree result;
752
753 FOR_EACH_BB (bb)
754 {
755 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
756 {
757 gimple phi = gsi_stmt (gsi);
758 result = gimple_phi_result (phi);
759 if (virtual_operand_p (result))
760 {
761 #ifdef ENABLE_CHECKING
762 size_t i;
763 /* There should be no arguments which are not virtual, or the
764 results will be incorrect. */
765 for (i = 0; i < gimple_phi_num_args (phi); i++)
766 {
767 tree arg = PHI_ARG_DEF (phi, i);
768 if (TREE_CODE (arg) == SSA_NAME
769 && !virtual_operand_p (arg))
770 {
771 fprintf (stderr, "Argument of PHI is not virtual (");
772 print_generic_expr (stderr, arg, TDF_SLIM);
773 fprintf (stderr, "), but the result is :");
774 print_gimple_stmt (stderr, phi, 0, TDF_SLIM);
775 internal_error ("SSA corruption");
776 }
777 }
778 #endif
779 remove_phi_node (&gsi, true);
780 }
781 else
782 {
783 /* Also remove real PHIs with no uses. */
784 if (has_zero_uses (result))
785 {
786 remove_gimple_phi_args (phi);
787 remove_phi_node (&gsi, true);
788 }
789 else
790 gsi_next (&gsi);
791 }
792 }
793 }
794 }
795
796
797 /* This function will rewrite the current program using the variable mapping
798 found in MAP. If the replacement vector VALUES is provided, any
799 occurrences of partitions with non-null entries in the vector will be
800 replaced with the expression in the vector instead of its mapped
801 variable. */
802
803 static void
804 rewrite_trees (var_map map ATTRIBUTE_UNUSED)
805 {
806 #ifdef ENABLE_CHECKING
807 basic_block bb;
808 /* Search for PHIs where the destination has no partition, but one
809 or more arguments has a partition. This should not happen and can
810 create incorrect code. */
811 FOR_EACH_BB (bb)
812 {
813 gimple_stmt_iterator gsi;
814 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
815 {
816 gimple phi = gsi_stmt (gsi);
817 tree T0 = var_to_partition_to_var (map, gimple_phi_result (phi));
818 if (T0 == NULL_TREE)
819 {
820 size_t i;
821 for (i = 0; i < gimple_phi_num_args (phi); i++)
822 {
823 tree arg = PHI_ARG_DEF (phi, i);
824
825 if (TREE_CODE (arg) == SSA_NAME
826 && var_to_partition (map, arg) != NO_PARTITION)
827 {
828 fprintf (stderr, "Argument of PHI is in a partition :(");
829 print_generic_expr (stderr, arg, TDF_SLIM);
830 fprintf (stderr, "), but the result is not :");
831 print_gimple_stmt (stderr, phi, 0, TDF_SLIM);
832 internal_error ("SSA corruption");
833 }
834 }
835 }
836 }
837 }
838 #endif
839 }
840
841 /* Given the out-of-ssa info object SA (with prepared partitions)
842 eliminate all phi nodes in all basic blocks. Afterwards no
843 basic block will have phi nodes anymore and there are possibly
844 some RTL instructions inserted on edges. */
845
846 void
847 expand_phi_nodes (struct ssaexpand *sa)
848 {
849 basic_block bb;
850 elim_graph g = new_elim_graph (sa->map->num_partitions);
851 g->map = sa->map;
852
853 FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR, next_bb)
854 if (!gimple_seq_empty_p (phi_nodes (bb)))
855 {
856 edge e;
857 edge_iterator ei;
858 FOR_EACH_EDGE (e, ei, bb->preds)
859 eliminate_phi (e, g);
860 set_phi_nodes (bb, NULL);
861 /* We can't redirect EH edges in RTL land, so we need to do this
862 here. Redirection happens only when splitting is necessary,
863 which it is only for critical edges, normally. For EH edges
864 it might also be necessary when the successor has more than
865 one predecessor. In that case the edge is either required to
866 be fallthru (which EH edges aren't), or the predecessor needs
867 to end with a jump (which again, isn't the case with EH edges).
868 Hence, split all EH edges on which we inserted instructions
869 and whose successor has multiple predecessors. */
870 for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
871 {
872 if (e->insns.r && (e->flags & EDGE_EH)
873 && !single_pred_p (e->dest))
874 {
875 rtx insns = e->insns.r;
876 basic_block bb;
877 e->insns.r = NULL_RTX;
878 bb = split_edge (e);
879 single_pred_edge (bb)->insns.r = insns;
880 }
881 else
882 ei_next (&ei);
883 }
884 }
885
886 delete_elim_graph (g);
887 }
888
889
890 /* Remove the ssa-names in the current function and translate them into normal
891 compiler variables. PERFORM_TER is true if Temporary Expression Replacement
892 should also be used. */
893
894 static void
895 remove_ssa_form (bool perform_ter, struct ssaexpand *sa)
896 {
897 bitmap values = NULL;
898 var_map map;
899 unsigned i;
900
901 map = coalesce_ssa_name ();
902
903 /* Return to viewing the variable list as just all reference variables after
904 coalescing has been performed. */
905 partition_view_normal (map, false);
906
907 if (dump_file && (dump_flags & TDF_DETAILS))
908 {
909 fprintf (dump_file, "After Coalescing:\n");
910 dump_var_map (dump_file, map);
911 }
912
913 if (perform_ter)
914 {
915 values = find_replaceable_exprs (map);
916 if (values && dump_file && (dump_flags & TDF_DETAILS))
917 dump_replaceable_exprs (dump_file, values);
918 }
919
920 rewrite_trees (map);
921
922 sa->map = map;
923 sa->values = values;
924 sa->partition_has_default_def = BITMAP_ALLOC (NULL);
925 for (i = 1; i < num_ssa_names; i++)
926 {
927 tree t = ssa_name (i);
928 if (t && SSA_NAME_IS_DEFAULT_DEF (t))
929 {
930 int p = var_to_partition (map, t);
931 if (p != NO_PARTITION)
932 bitmap_set_bit (sa->partition_has_default_def, p);
933 }
934 }
935 }
936
937
938 /* If not already done so for basic block BB, assign increasing uids
939 to each of its instructions. */
940
941 static void
942 maybe_renumber_stmts_bb (basic_block bb)
943 {
944 unsigned i = 0;
945 gimple_stmt_iterator gsi;
946
947 if (!bb->aux)
948 return;
949 bb->aux = NULL;
950 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
951 {
952 gimple stmt = gsi_stmt (gsi);
953 gimple_set_uid (stmt, i);
954 i++;
955 }
956 }
957
958
959 /* Return true if we can determine that the SSA_NAMEs RESULT (a result
960 of a PHI node) and ARG (one of its arguments) conflict. Return false
961 otherwise, also when we simply aren't sure. */
962
963 static bool
964 trivially_conflicts_p (basic_block bb, tree result, tree arg)
965 {
966 use_operand_p use;
967 imm_use_iterator imm_iter;
968 gimple defa = SSA_NAME_DEF_STMT (arg);
969
970 /* If ARG isn't defined in the same block it's too complicated for
971 our little mind. */
972 if (gimple_bb (defa) != bb)
973 return false;
974
975 FOR_EACH_IMM_USE_FAST (use, imm_iter, result)
976 {
977 gimple use_stmt = USE_STMT (use);
978 if (is_gimple_debug (use_stmt))
979 continue;
980 /* Now, if there's a use of RESULT that lies outside this basic block,
981 then there surely is a conflict with ARG. */
982 if (gimple_bb (use_stmt) != bb)
983 return true;
984 if (gimple_code (use_stmt) == GIMPLE_PHI)
985 continue;
986 /* The use now is in a real stmt of BB, so if ARG was defined
987 in a PHI node (like RESULT) both conflict. */
988 if (gimple_code (defa) == GIMPLE_PHI)
989 return true;
990 maybe_renumber_stmts_bb (bb);
991 /* If the use of RESULT occurs after the definition of ARG,
992 the two conflict too. */
993 if (gimple_uid (defa) < gimple_uid (use_stmt))
994 return true;
995 }
996
997 return false;
998 }
999
1000
1001 /* Search every PHI node for arguments associated with backedges which
1002 we can trivially determine will need a copy (the argument is either
1003 not an SSA_NAME or the argument has a different underlying variable
1004 than the PHI result).
1005
1006 Insert a copy from the PHI argument to a new destination at the
1007 end of the block with the backedge to the top of the loop. Update
1008 the PHI argument to reference this new destination. */
1009
1010 static void
1011 insert_backedge_copies (void)
1012 {
1013 basic_block bb;
1014 gimple_stmt_iterator gsi;
1015
1016 mark_dfs_back_edges ();
1017
1018 FOR_EACH_BB (bb)
1019 {
1020 /* Mark block as possibly needing calculation of UIDs. */
1021 bb->aux = &bb->aux;
1022
1023 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1024 {
1025 gimple phi = gsi_stmt (gsi);
1026 tree result = gimple_phi_result (phi);
1027 size_t i;
1028
1029 if (virtual_operand_p (result))
1030 continue;
1031
1032 for (i = 0; i < gimple_phi_num_args (phi); i++)
1033 {
1034 tree arg = gimple_phi_arg_def (phi, i);
1035 edge e = gimple_phi_arg_edge (phi, i);
1036
1037 /* If the argument is not an SSA_NAME, then we will need a
1038 constant initialization. If the argument is an SSA_NAME with
1039 a different underlying variable then a copy statement will be
1040 needed. */
1041 if ((e->flags & EDGE_DFS_BACK)
1042 && (TREE_CODE (arg) != SSA_NAME
1043 || SSA_NAME_VAR (arg) != SSA_NAME_VAR (result)
1044 || trivially_conflicts_p (bb, result, arg)))
1045 {
1046 tree name;
1047 gimple stmt, last = NULL;
1048 gimple_stmt_iterator gsi2;
1049
1050 gsi2 = gsi_last_bb (gimple_phi_arg_edge (phi, i)->src);
1051 if (!gsi_end_p (gsi2))
1052 last = gsi_stmt (gsi2);
1053
1054 /* In theory the only way we ought to get back to the
1055 start of a loop should be with a COND_EXPR or GOTO_EXPR.
1056 However, better safe than sorry.
1057 If the block ends with a control statement or
1058 something that might throw, then we have to
1059 insert this assignment before the last
1060 statement. Else insert it after the last statement. */
1061 if (last && stmt_ends_bb_p (last))
1062 {
1063 /* If the last statement in the block is the definition
1064 site of the PHI argument, then we can't insert
1065 anything after it. */
1066 if (TREE_CODE (arg) == SSA_NAME
1067 && SSA_NAME_DEF_STMT (arg) == last)
1068 continue;
1069 }
1070
1071 /* Create a new instance of the underlying variable of the
1072 PHI result. */
1073 name = copy_ssa_name (result, NULL);
1074 stmt = gimple_build_assign (name,
1075 gimple_phi_arg_def (phi, i));
1076
1077 /* copy location if present. */
1078 if (gimple_phi_arg_has_location (phi, i))
1079 gimple_set_location (stmt,
1080 gimple_phi_arg_location (phi, i));
1081
1082 /* Insert the new statement into the block and update
1083 the PHI node. */
1084 if (last && stmt_ends_bb_p (last))
1085 gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
1086 else
1087 gsi_insert_after (&gsi2, stmt, GSI_NEW_STMT);
1088 SET_PHI_ARG_DEF (phi, i, name);
1089 }
1090 }
1091 }
1092
1093 /* Unmark this block again. */
1094 bb->aux = NULL;
1095 }
1096 }
1097
1098 /* Free all memory associated with going out of SSA form. SA is
1099 the outof-SSA info object. */
1100
1101 void
1102 finish_out_of_ssa (struct ssaexpand *sa)
1103 {
1104 free (sa->partition_to_pseudo);
1105 if (sa->values)
1106 BITMAP_FREE (sa->values);
1107 delete_var_map (sa->map);
1108 BITMAP_FREE (sa->partition_has_default_def);
1109 memset (sa, 0, sizeof *sa);
1110 }
1111
1112 /* Take the current function out of SSA form, translating PHIs as described in
1113 R. Morgan, ``Building an Optimizing Compiler'',
1114 Butterworth-Heinemann, Boston, MA, 1998. pp 176-186. */
1115
1116 unsigned int
1117 rewrite_out_of_ssa (struct ssaexpand *sa)
1118 {
1119 /* If elimination of a PHI requires inserting a copy on a backedge,
1120 then we will have to split the backedge which has numerous
1121 undesirable performance effects.
1122
1123 A significant number of such cases can be handled here by inserting
1124 copies into the loop itself. */
1125 insert_backedge_copies ();
1126
1127
1128 /* Eliminate PHIs which are of no use, such as virtual or dead phis. */
1129 eliminate_useless_phis ();
1130
1131 if (dump_file && (dump_flags & TDF_DETAILS))
1132 gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);
1133
1134 remove_ssa_form (flag_tree_ter, sa);
1135
1136 if (dump_file && (dump_flags & TDF_DETAILS))
1137 gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);
1138
1139 return 0;
1140 }