OSDN Git Service

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