OSDN Git Service

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