OSDN Git Service

* tree-iterator.c (EXPR_LAST_BODY): Remove.
[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-ssa-live.h"
34 #include "tree-pass.h"
35 #include "toplev.h"
36
37
38 /* Used to hold all the components required to do SSA PHI elimination.
39    The node and pred/succ list is a simple linear list of nodes and
40    edges represented as pairs of nodes.
41
42    The predecessor and successor list:  Nodes are entered in pairs, where
43    [0] ->PRED, [1]->SUCC.  All the even indexes in the array represent 
44    predecessors, all the odd elements are successors. 
45    
46    Rationale:
47    When implemented as bitmaps, very large programs SSA->Normal times were 
48    being dominated by clearing the interference graph.
49
50    Typically this list of edges is extremely small since it only includes 
51    PHI results and uses from a single edge which have not coalesced with 
52    each other.  This means that no virtual PHI nodes are included, and
53    empirical evidence suggests that the number of edges rarely exceed
54    3, and in a bootstrap of GCC, the maximum size encountered was 7.
55    This also limits the number of possible nodes that are involved to
56    rarely more than 6, and in the bootstrap of gcc, the maximum number
57    of nodes encountered was 12.  */
58  
59 typedef struct _elim_graph {
60   /* Size of the elimination vectors.  */
61   int size;
62
63   /* List of nodes in the elimination graph.  */
64   VEC(tree,heap) *nodes;
65
66   /*  The predecessor and successor edge list.  */
67   VEC(int,heap) *edge_list;
68
69   /* Visited vector.  */
70   sbitmap visited;
71
72   /* Stack for visited nodes.  */
73   VEC(int,heap) *stack;
74   
75   /* The variable partition map.  */
76   var_map map;
77
78   /* Edge being eliminated by this graph.  */
79   edge e;
80
81   /* List of constant copies to emit.  These are pushed on in pairs.  */
82   VEC(tree,heap) *const_copies;
83 } *elim_graph;
84
85
86 /* Create a temporary variable based on the type of variable T.  Use T's name
87    as the prefix.  */
88
89 static tree
90 create_temp (tree t)
91 {
92   tree tmp;
93   const char *name = NULL;
94   tree type;
95
96   if (TREE_CODE (t) == SSA_NAME)
97     t = SSA_NAME_VAR (t);
98
99   gcc_assert (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL);
100
101   type = TREE_TYPE (t);
102   tmp = DECL_NAME (t);
103   if (tmp)
104     name = IDENTIFIER_POINTER (tmp);
105
106   if (name == NULL)
107     name = "temp";
108   tmp = create_tmp_var (type, name);
109
110   if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
111     {
112       SET_DECL_DEBUG_EXPR (tmp, DECL_DEBUG_EXPR (t));  
113       DECL_DEBUG_EXPR_IS_FROM (tmp) = 1;
114     }
115   else if (!DECL_IGNORED_P (t))
116     {
117       SET_DECL_DEBUG_EXPR (tmp, t);
118       DECL_DEBUG_EXPR_IS_FROM (tmp) = 1;
119     }
120   DECL_ARTIFICIAL (tmp) = DECL_ARTIFICIAL (t);
121   DECL_IGNORED_P (tmp) = DECL_IGNORED_P (t);
122   DECL_GIMPLE_REG_P (tmp) = DECL_GIMPLE_REG_P (t);
123   add_referenced_var (tmp);
124
125   /* We should never have copied variables in non-automatic storage
126      or variables that have their address taken.  So it is pointless
127      to try to copy call-clobber state here.  */
128   gcc_assert (!may_be_aliased (t) && !is_global_var (t));
129
130   return tmp;
131 }
132
133
134 /* This helper function fill insert a copy from a constant or variable SRC to 
135    variable DEST on edge E.  */
136
137 static void
138 insert_copy_on_edge (edge e, tree dest, tree src)
139 {
140   gimple copy;
141
142   copy = gimple_build_assign (dest, src);
143   set_is_used (dest);
144
145   if (TREE_CODE (src) == ADDR_EXPR)
146     src = TREE_OPERAND (src, 0);
147   if (TREE_CODE (src) == VAR_DECL || TREE_CODE (src) == PARM_DECL)
148     set_is_used (src);
149
150   if (dump_file && (dump_flags & TDF_DETAILS))
151     {
152       fprintf (dump_file,
153                "Inserting a copy on edge BB%d->BB%d :",
154                e->src->index,
155                e->dest->index);
156       print_gimple_stmt (dump_file, copy, 0, dump_flags);
157       fprintf (dump_file, "\n");
158     }
159
160   gsi_insert_on_edge (e, copy);
161 }
162
163
164 /* Create an elimination graph with SIZE nodes and associated data
165    structures.  */
166
167 static elim_graph
168 new_elim_graph (int size)
169 {
170   elim_graph g = (elim_graph) xmalloc (sizeof (struct _elim_graph));
171
172   g->nodes = VEC_alloc (tree, heap, 30);
173   g->const_copies = VEC_alloc (tree, heap, 20);
174   g->edge_list = VEC_alloc (int, heap, 20);
175   g->stack = VEC_alloc (int, heap, 30);
176   
177   g->visited = sbitmap_alloc (size);
178
179   return g;
180 }
181
182
183 /* Empty elimination graph G.  */
184
185 static inline void
186 clear_elim_graph (elim_graph g)
187 {
188   VEC_truncate (tree, g->nodes, 0);
189   VEC_truncate (int, g->edge_list, 0);
190 }
191
192
193 /* Delete elimination graph G.  */
194
195 static inline void
196 delete_elim_graph (elim_graph g)
197 {
198   sbitmap_free (g->visited);
199   VEC_free (int, heap, g->stack);
200   VEC_free (int, heap, g->edge_list);
201   VEC_free (tree, heap, g->const_copies);
202   VEC_free (tree, heap, g->nodes);
203   free (g);
204 }
205
206
207 /* Return the number of nodes in graph G.  */
208
209 static inline int
210 elim_graph_size (elim_graph g)
211 {
212   return VEC_length (tree, g->nodes);
213 }
214
215
216 /* Add NODE to graph G, if it doesn't exist already.  */
217
218 static inline void 
219 elim_graph_add_node (elim_graph g, tree node)
220 {
221   int x;
222   tree t;
223
224   for (x = 0; VEC_iterate (tree, g->nodes, x, t); x++)
225     if (t == node)
226       return;
227   VEC_safe_push (tree, heap, g->nodes, node);
228 }
229
230
231 /* Add the edge PRED->SUCC to graph G.  */
232
233 static inline void
234 elim_graph_add_edge (elim_graph g, int pred, int succ)
235 {
236   VEC_safe_push (int, heap, g->edge_list, pred);
237   VEC_safe_push (int, heap, g->edge_list, succ);
238 }
239
240
241 /* Remove an edge from graph G for which NODE is the predecessor, and
242    return the successor node.  -1 is returned if there is no such edge.  */
243
244 static inline int
245 elim_graph_remove_succ_edge (elim_graph g, int node)
246 {
247   int y;
248   unsigned x;
249   for (x = 0; x < VEC_length (int, g->edge_list); x += 2)
250     if (VEC_index (int, g->edge_list, x) == node)
251       {
252         VEC_replace (int, g->edge_list, x, -1);
253         y = VEC_index (int, g->edge_list, x + 1);
254         VEC_replace (int, g->edge_list, x + 1, -1);
255         return y;
256       }
257   return -1;
258 }
259
260
261 /* Find all the nodes in GRAPH which are successors to NODE in the
262    edge list.  VAR will hold the partition number found.  CODE is the
263    code fragment executed for every node found.  */
264
265 #define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE)                \
266 do {                                                                    \
267   unsigned x_;                                                          \
268   int y_;                                                               \
269   for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2)      \
270     {                                                                   \
271       y_ = VEC_index (int, (GRAPH)->edge_list, x_);                     \
272       if (y_ != (NODE))                                                 \
273         continue;                                                       \
274       (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1);              \
275       CODE;                                                             \
276     }                                                                   \
277 } while (0)
278
279
280 /* Find all the nodes which are predecessors of NODE in the edge list for
281    GRAPH.  VAR will hold the partition number found.  CODE is the
282    code fragment executed for every node found.  */
283
284 #define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE)                \
285 do {                                                                    \
286   unsigned x_;                                                          \
287   int y_;                                                               \
288   for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2)      \
289     {                                                                   \
290       y_ = VEC_index (int, (GRAPH)->edge_list, x_ + 1);                 \
291       if (y_ != (NODE))                                                 \
292         continue;                                                       \
293       (VAR) = VEC_index (int, (GRAPH)->edge_list, x_);                  \
294       CODE;                                                             \
295     }                                                                   \
296 } while (0)
297
298
299 /* Add T to elimination graph G.  */
300
301 static inline void
302 eliminate_name (elim_graph g, tree T)
303 {
304   elim_graph_add_node (g, T);
305 }
306
307
308 /* Build elimination graph G for basic block BB on incoming PHI edge
309    G->e.  */
310
311 static void
312 eliminate_build (elim_graph g, basic_block B)
313 {
314   tree T0, Ti;
315   int p0, pi;
316   gimple_stmt_iterator gsi;
317
318   clear_elim_graph (g);
319   
320   for (gsi = gsi_start_phis (B); !gsi_end_p (gsi); gsi_next (&gsi))
321     {
322       gimple phi = gsi_stmt (gsi);
323
324       T0 = var_to_partition_to_var (g->map, gimple_phi_result (phi));
325       
326       /* Ignore results which are not in partitions.  */
327       if (T0 == NULL_TREE)
328         continue;
329
330       Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
331
332       /* If this argument is a constant, or a SSA_NAME which is being
333          left in SSA form, just queue a copy to be emitted on this
334          edge.  */
335       if (!phi_ssa_name_p (Ti)
336           || (TREE_CODE (Ti) == SSA_NAME
337               && var_to_partition (g->map, Ti) == NO_PARTITION))
338         {
339           /* Save constant copies until all other copies have been emitted
340              on this edge.  */
341           VEC_safe_push (tree, heap, g->const_copies, T0);
342           VEC_safe_push (tree, heap, g->const_copies, Ti);
343         }
344       else
345         {
346           Ti = var_to_partition_to_var (g->map, Ti);
347           if (T0 != Ti)
348             {
349               eliminate_name (g, T0);
350               eliminate_name (g, Ti);
351               p0 = var_to_partition (g->map, T0);
352               pi = var_to_partition (g->map, Ti);
353               elim_graph_add_edge (g, p0, pi);
354             }
355         }
356     }
357 }
358
359
360 /* Push successors of T onto the elimination stack for G.  */
361
362 static void 
363 elim_forward (elim_graph g, int T)
364 {
365   int S;
366   SET_BIT (g->visited, T);
367   FOR_EACH_ELIM_GRAPH_SUCC (g, T, S,
368     {
369       if (!TEST_BIT (g->visited, S))
370         elim_forward (g, S);
371     });
372   VEC_safe_push (int, heap, g->stack, T);
373 }
374
375
376 /* Return 1 if there unvisited predecessors of T in graph G.  */
377
378 static int
379 elim_unvisited_predecessor (elim_graph g, int T)
380 {
381   int P;
382   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
383     {
384       if (!TEST_BIT (g->visited, P))
385         return 1;
386     });
387   return 0;
388 }
389
390 /* Process predecessors first, and insert a copy.  */
391
392 static void
393 elim_backward (elim_graph g, int T)
394 {
395   int P;
396   SET_BIT (g->visited, T);
397   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
398     {
399       if (!TEST_BIT (g->visited, P))
400         {
401           elim_backward (g, P);
402           insert_copy_on_edge (g->e, 
403                                partition_to_var (g->map, P), 
404                                partition_to_var (g->map, T));
405         }
406     });
407 }
408
409 /* Insert required copies for T in graph G.  Check for a strongly connected 
410    region, and create a temporary to break the cycle if one is found.  */
411
412 static void 
413 elim_create (elim_graph g, int T)
414 {
415   tree U;
416   int P, S;
417
418   if (elim_unvisited_predecessor (g, T))
419     {
420       U = create_temp (partition_to_var (g->map, T));
421       insert_copy_on_edge (g->e, U, partition_to_var (g->map, T));
422       FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
423         {
424           if (!TEST_BIT (g->visited, P))
425             {
426               elim_backward (g, P);
427               insert_copy_on_edge (g->e, partition_to_var (g->map, P), U);
428             }
429         });
430     }
431   else
432     {
433       S = elim_graph_remove_succ_edge (g, T);
434       if (S != -1)
435         {
436           SET_BIT (g->visited, T);
437           insert_copy_on_edge (g->e, 
438                                partition_to_var (g->map, T), 
439                                partition_to_var (g->map, S));
440         }
441     }
442   
443 }
444
445
446 /* Eliminate all the phi nodes on edge E in graph G.  */
447
448 static void
449 eliminate_phi (edge e, elim_graph g)
450 {
451   int x;
452   basic_block B = e->dest;
453
454   gcc_assert (VEC_length (tree, g->const_copies) == 0);
455
456   /* Abnormal edges already have everything coalesced.  */
457   if (e->flags & EDGE_ABNORMAL)
458     return;
459
460   g->e = e;
461
462   eliminate_build (g, B);
463
464   if (elim_graph_size (g) != 0)
465     {
466       tree var;
467
468       sbitmap_zero (g->visited);
469       VEC_truncate (int, g->stack, 0);
470
471       for (x = 0; VEC_iterate (tree, g->nodes, x, var); x++)
472         {
473           int p = var_to_partition (g->map, var);
474           if (!TEST_BIT (g->visited, p))
475             elim_forward (g, p);
476         }
477        
478       sbitmap_zero (g->visited);
479       while (VEC_length (int, g->stack) > 0)
480         {
481           x = VEC_pop (int, g->stack);
482           if (!TEST_BIT (g->visited, x))
483             elim_create (g, x);
484         }
485     }
486
487   /* If there are any pending constant copies, issue them now.  */
488   while (VEC_length (tree, g->const_copies) > 0)
489     {
490       tree src, dest;
491       src = VEC_pop (tree, g->const_copies);
492       dest = VEC_pop (tree, g->const_copies);
493       insert_copy_on_edge (e, dest, src);
494     }
495 }
496
497
498 /* Take the ssa-name var_map MAP, and assign real variables to each 
499    partition.  */
500
501 static void
502 assign_vars (var_map map)
503 {
504   int x, num;
505   tree var, root;
506   var_ann_t ann;
507
508   num = num_var_partitions (map);
509   for (x = 0; x < num; x++)
510     {
511       var = partition_to_var (map, x);
512       if (TREE_CODE (var) != SSA_NAME)
513         {
514           ann = var_ann (var);
515           /* It must already be coalesced.  */
516           gcc_assert (ann->out_of_ssa_tag == 1);
517           if (dump_file && (dump_flags & TDF_DETAILS))
518             {
519               fprintf (dump_file, "partition %d already has variable ", x);
520               print_generic_expr (dump_file, var, TDF_SLIM);
521               fprintf (dump_file, " assigned to it.\n");
522             }
523         }
524       else
525         {
526           root = SSA_NAME_VAR (var);
527           ann = var_ann (root);
528           /* If ROOT is already associated, create a new one.  */
529           if (ann->out_of_ssa_tag)
530             {
531               root = create_temp (root);
532               ann = var_ann (root);
533             }
534           /* ROOT has not been coalesced yet, so use it.  */
535           if (dump_file && (dump_flags & TDF_DETAILS))
536             {
537               fprintf (dump_file, "Partition %d is assigned to var ", x);
538               print_generic_stmt (dump_file, root, TDF_SLIM);
539             }
540           change_partition_var (map, root, x);
541         }
542     }
543 }
544
545
546 /* Replace use operand P with whatever variable it has been rewritten to based 
547    on the partitions in MAP.  EXPR is an optional expression vector over SSA 
548    versions which is used to replace P with an expression instead of a variable.
549    If the stmt is changed, return true.  */ 
550
551 static inline bool
552 replace_use_variable (var_map map, use_operand_p p, gimple *expr)
553 {
554   tree new_var;
555   tree var = USE_FROM_PTR (p);
556
557   /* Check if we are replacing this variable with an expression.  */
558   if (expr)
559     {
560       int version = SSA_NAME_VERSION (var);
561       if (expr[version])
562         {
563           SET_USE (p, gimple_assign_rhs_to_tree (expr[version]));
564           return true;
565         }
566     }
567
568   new_var = var_to_partition_to_var (map, var);
569   if (new_var)
570     {
571       SET_USE (p, new_var);
572       set_is_used (new_var);
573       return true;
574     }
575   return false;
576 }
577
578
579 /* Replace def operand DEF_P with whatever variable it has been rewritten to 
580    based on the partitions in MAP.  EXPR is an optional expression vector over
581    SSA versions which is used to replace DEF_P with an expression instead of a 
582    variable.  If the stmt is changed, return true.  */ 
583
584 static inline bool
585 replace_def_variable (var_map map, def_operand_p def_p, tree *expr)
586 {
587   tree new_var;
588   tree var = DEF_FROM_PTR (def_p);
589
590   /* Do nothing if we are replacing this variable with an expression.  */
591   if (expr && expr[SSA_NAME_VERSION (var)])
592     return true;
593
594   new_var = var_to_partition_to_var (map, var);
595   if (new_var)
596     {
597       SET_DEF (def_p, new_var);
598       set_is_used (new_var);
599       return true;
600     }
601   return false;
602 }
603
604
605 /* Remove each argument from PHI.  If an arg was the last use of an SSA_NAME, 
606    check to see if this allows another PHI node to be removed.  */
607
608 static void
609 remove_gimple_phi_args (gimple phi)
610 {
611   use_operand_p arg_p;
612   ssa_op_iter iter;
613
614   if (dump_file && (dump_flags & TDF_DETAILS))
615     {
616       fprintf (dump_file, "Removing Dead PHI definition: ");
617       print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
618     }
619
620   FOR_EACH_PHI_ARG (arg_p, phi, iter, SSA_OP_USE)
621     {
622       tree arg = USE_FROM_PTR (arg_p);
623       if (TREE_CODE (arg) == SSA_NAME)
624         {
625           /* Remove the reference to the existing argument.  */
626           SET_USE (arg_p, NULL_TREE);
627           if (has_zero_uses (arg))
628             {
629               gimple stmt;
630               gimple_stmt_iterator gsi;
631
632               stmt = SSA_NAME_DEF_STMT (arg);
633
634               /* Also remove the def if it is a PHI node.  */
635               if (gimple_code (stmt) == GIMPLE_PHI)
636                 {
637                   remove_gimple_phi_args (stmt);
638                   gsi = gsi_for_stmt (stmt);
639                   remove_phi_node (&gsi, true);
640                 }
641
642             }
643         }
644     }
645 }
646
647 /* Remove any PHI node which is a virtual PHI, or a PHI with no uses.  */
648
649 static void
650 eliminate_useless_phis (void)
651 {
652   basic_block bb;
653   gimple_stmt_iterator gsi;
654   tree result;
655
656   FOR_EACH_BB (bb)
657     {
658       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
659         {
660           gimple phi = gsi_stmt (gsi);
661           result = gimple_phi_result (phi);
662           if (!is_gimple_reg (SSA_NAME_VAR (result)))
663             {
664 #ifdef ENABLE_CHECKING
665               size_t i;
666               /* There should be no arguments which are not virtual, or the
667                  results will be incorrect.  */
668               for (i = 0; i < gimple_phi_num_args (phi); i++)
669                 {
670                   tree arg = PHI_ARG_DEF (phi, i);
671                   if (TREE_CODE (arg) == SSA_NAME 
672                       && is_gimple_reg (SSA_NAME_VAR (arg)))
673                     {
674                       fprintf (stderr, "Argument of PHI is not virtual (");
675                       print_generic_expr (stderr, arg, TDF_SLIM);
676                       fprintf (stderr, "), but the result is :");
677                       print_gimple_stmt (stderr, phi, 0, TDF_SLIM);
678                       internal_error ("SSA corruption");
679                     }
680                 }
681 #endif
682               remove_phi_node (&gsi, true);
683             }
684           else
685             {
686               /* Also remove real PHIs with no uses.  */
687               if (has_zero_uses (result))
688                 {
689                   remove_gimple_phi_args (phi);
690                   remove_phi_node (&gsi, true);
691                 }
692               else
693                 gsi_next (&gsi);
694             }
695         }
696     }
697 }
698
699
700 /* This function will rewrite the current program using the variable mapping
701    found in MAP.  If the replacement vector VALUES is provided, any 
702    occurrences of partitions with non-null entries in the vector will be 
703    replaced with the expression in the vector instead of its mapped 
704    variable.  */
705
706 static void
707 rewrite_trees (var_map map, gimple *values)
708 {
709   elim_graph g;
710   basic_block bb;
711   gimple_stmt_iterator gsi;
712   edge e;
713   gimple_seq phi;
714   bool changed;
715  
716 #ifdef ENABLE_CHECKING
717   /* Search for PHIs where the destination has no partition, but one
718      or more arguments has a partition.  This should not happen and can
719      create incorrect code.  */
720   FOR_EACH_BB (bb)
721     {
722       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
723         {
724           gimple phi = gsi_stmt (gsi);
725           tree T0 = var_to_partition_to_var (map, gimple_phi_result (phi));
726           if (T0 == NULL_TREE)
727             {
728               size_t i;
729               for (i = 0; i < gimple_phi_num_args (phi); i++)
730                 {
731                   tree arg = PHI_ARG_DEF (phi, i);
732
733                   if (TREE_CODE (arg) == SSA_NAME
734                       && var_to_partition (map, arg) != NO_PARTITION)
735                     {
736                       fprintf (stderr, "Argument of PHI is in a partition :(");
737                       print_generic_expr (stderr, arg, TDF_SLIM);
738                       fprintf (stderr, "), but the result is not :");
739                       print_gimple_stmt (stderr, phi, 0, TDF_SLIM);
740                       internal_error ("SSA corruption");
741                     }
742                 }
743             }
744         }
745     }
746 #endif
747
748   /* Replace PHI nodes with any required copies.  */
749   g = new_elim_graph (map->num_partitions);
750   g->map = map;
751   FOR_EACH_BB (bb)
752     {
753       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
754         {
755           gimple stmt = gsi_stmt (gsi);
756           use_operand_p use_p, copy_use_p;
757           def_operand_p def_p;
758           bool remove = false, is_copy = false;
759           int num_uses = 0;
760           ssa_op_iter iter;
761
762           changed = false;
763
764           if (gimple_assign_copy_p (stmt))
765             is_copy = true;
766
767           copy_use_p = NULL_USE_OPERAND_P;
768           FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
769             {
770               if (replace_use_variable (map, use_p, values))
771                 changed = true;
772               copy_use_p = use_p;
773               num_uses++;
774             }
775
776           if (num_uses != 1)
777             is_copy = false;
778
779           def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
780
781           if (def_p != NULL)
782             {
783               /* Mark this stmt for removal if it is the list of replaceable 
784                  expressions.  */
785               if (values && values[SSA_NAME_VERSION (DEF_FROM_PTR (def_p))])
786                 remove = true;
787               else
788                 {
789                   if (replace_def_variable (map, def_p, NULL))
790                     changed = true;
791                   /* If both SSA_NAMEs coalesce to the same variable,
792                      mark the now redundant copy for removal.  */
793                   if (is_copy)
794                     {
795                       gcc_assert (copy_use_p != NULL_USE_OPERAND_P);
796                       if (DEF_FROM_PTR (def_p) == USE_FROM_PTR (copy_use_p))
797                         remove = true;
798                     }
799                 }
800             }
801           else
802             FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
803               if (replace_def_variable (map, def_p, NULL))
804                 changed = true;
805
806           /* Remove any stmts marked for removal.  */
807           if (remove)
808             gsi_remove (&gsi, true);
809           else
810             {
811               if (changed)
812                 if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
813                   gimple_purge_dead_eh_edges (bb);
814               gsi_next (&gsi);
815             }
816         }
817
818       phi = phi_nodes (bb);
819       if (phi)
820         {
821           edge_iterator ei;
822           FOR_EACH_EDGE (e, ei, bb->preds)
823             eliminate_phi (e, g);
824         }
825     }
826
827   delete_elim_graph (g);
828 }
829
830 /* These are the local work structures used to determine the best place to 
831    insert the copies that were placed on edges by the SSA->normal pass..  */
832 static VEC(edge,heap) *edge_leader;
833 static VEC(gimple_seq,heap) *stmt_list;
834 static bitmap leader_has_match = NULL;
835 static edge leader_match = NULL;
836
837
838 /* Pass this function to make_forwarder_block so that all the edges with
839    matching PENDING_STMT lists to 'curr_stmt_list' get redirected.  E is the
840    edge to test for a match.  */
841
842 static inline bool 
843 same_stmt_list_p (edge e)
844 {
845   return (e->aux == (PTR) leader_match) ? true : false;
846 }
847
848
849 /* Return TRUE if S1 and S2 are equivalent copies.  */
850
851 static inline bool
852 identical_copies_p (const_gimple s1, const_gimple s2)
853 {
854 #ifdef ENABLE_CHECKING
855   gcc_assert (is_gimple_assign (s1));
856   gcc_assert (is_gimple_assign (s2));
857   gcc_assert (DECL_P (gimple_assign_lhs (s1)));
858   gcc_assert (DECL_P (gimple_assign_lhs (s2)));
859 #endif
860
861   if (gimple_assign_lhs (s1) != gimple_assign_lhs (s2))
862     return false;
863
864   if (gimple_assign_rhs1 (s1) != gimple_assign_rhs1 (s2))
865     return false;
866
867   return true;
868 }
869
870
871 /* Compare the PENDING_STMT list for edges E1 and E2. Return true if the lists
872    contain the same sequence of copies.  */
873
874 static inline bool 
875 identical_stmt_lists_p (const_edge e1, const_edge e2)
876 {
877   gimple_seq t1 = PENDING_STMT (e1);
878   gimple_seq t2 = PENDING_STMT (e2);
879   gimple_stmt_iterator gsi1, gsi2;
880
881   for (gsi1 = gsi_start (t1), gsi2 = gsi_start (t2);
882        !gsi_end_p (gsi1) && !gsi_end_p (gsi2); 
883        gsi_next (&gsi1), gsi_next (&gsi2))
884     {
885       if (!identical_copies_p (gsi_stmt (gsi1), gsi_stmt (gsi2)))
886         break;
887     }
888
889   if (!gsi_end_p (gsi1) || !gsi_end_p (gsi2))
890     return false;
891
892   return true;
893 }
894
895
896 /* Allocate data structures used in analyze_edges_for_bb.   */
897
898 static void
899 init_analyze_edges_for_bb (void)
900 {
901   edge_leader = VEC_alloc (edge, heap, 25);
902   stmt_list = VEC_alloc (gimple_seq, heap, 25);
903   leader_has_match = BITMAP_ALLOC (NULL);
904 }
905
906
907 /* Free data structures used in analyze_edges_for_bb.   */
908
909 static void
910 fini_analyze_edges_for_bb (void)
911 {
912   VEC_free (edge, heap, edge_leader);
913   VEC_free (gimple_seq, heap, stmt_list);
914   BITMAP_FREE (leader_has_match);
915 }
916
917 /* A helper function to be called via walk_tree.  Return DATA if it is
918   contained in subtree TP.  */
919  
920 static tree
921 contains_tree_r (tree * tp, int *walk_subtrees, void *data)
922 {
923   if (*tp == data)
924     {
925       *walk_subtrees = 0;
926       return (tree) data;
927     }
928   else
929     return NULL_TREE;
930 }
931
932 /* A threshold for the number of insns contained in the latch block.
933    It is used to prevent blowing the loop with too many copies from
934    the latch.  */
935 #define MAX_STMTS_IN_LATCH 2
936
937 /* Return TRUE if the stmts on SINGLE-EDGE can be moved to the
938    body of the loop.  This should be permitted only if SINGLE-EDGE is a
939    single-basic-block latch edge and thus cleaning the latch will help
940    to create a single-basic-block loop.  Otherwise return FALSE.  */
941
942 static bool
943 process_single_block_loop_latch (edge single_edge)
944 {
945   gimple_seq stmts;
946   basic_block b_exit, b_pheader, b_loop = single_edge->src;
947   edge_iterator ei;
948   edge e;
949   gimple_stmt_iterator gsi, gsi_exit;
950   gimple_stmt_iterator tsi;
951   tree expr;
952   gimple stmt;
953   unsigned int count = 0;
954
955   if (single_edge == NULL || (single_edge->dest != single_edge->src)
956       || (EDGE_COUNT (b_loop->succs) != 2)
957       || (EDGE_COUNT (b_loop->preds) != 2))
958     return false;
959
960   /* Get the stmts on the latch edge.  */
961   stmts = PENDING_STMT (single_edge);
962
963   /* Find the successor edge which is not the latch edge.  */
964   FOR_EACH_EDGE (e, ei, b_loop->succs) 
965    if (e->dest != b_loop)
966     break;
967
968   b_exit = e->dest;
969
970   /* Check that the exit block has only the loop as a predecessor,
971      and that there are no pending stmts on that edge as well.   */
972   if (EDGE_COUNT (b_exit->preds) != 1 || PENDING_STMT (e))
973     return false;
974
975   /* Find the predecessor edge which is not the latch edge.  */
976   FOR_EACH_EDGE (e, ei, b_loop->preds) 
977    if (e->src != b_loop)
978     break;
979
980   b_pheader = e->src;
981
982   if (b_exit == b_pheader || b_exit == b_loop || b_pheader == b_loop)
983     return false;
984
985   gsi_exit = gsi_after_labels (b_exit);
986
987   /* Get the last stmt in the loop body.  */
988   gsi = gsi_last_bb (single_edge->src);
989   stmt = gsi_stmt (gsi);
990
991   if (gimple_code (stmt) != GIMPLE_COND)
992     return false;
993
994
995   expr = build2 (gimple_cond_code (stmt), boolean_type_node,
996                  gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
997   /* Iterate over the insns on the latch and count them.  */
998   for (tsi = gsi_start (stmts); !gsi_end_p (tsi); gsi_next (&tsi))
999     {
1000       gimple stmt1 = gsi_stmt (tsi);
1001       tree var;
1002
1003       count++;
1004       /* Check that the condition does not contain any new definition
1005          created in the latch as the stmts from the latch intended
1006          to precede it.  */
1007       if (gimple_code (stmt1) != GIMPLE_ASSIGN)
1008         return false;
1009       var = gimple_assign_lhs (stmt1);
1010       if (TREE_THIS_VOLATILE (var)
1011           || TYPE_VOLATILE (TREE_TYPE (var))
1012           || walk_tree (&expr, contains_tree_r, var, NULL))
1013         return false;
1014     }
1015   /* Check that the latch does not contain more than MAX_STMTS_IN_LATCH
1016      insns.  The purpose of this restriction is to prevent blowing the
1017      loop with too many copies from the latch.  */
1018   if (count > MAX_STMTS_IN_LATCH)
1019     return false;
1020
1021   /* Apply the transformation - clean up the latch block:  
1022
1023      var = something; 
1024      L1:
1025      x1 = expr;
1026      if (cond) goto L2 else goto L3;
1027      L2:
1028      var = x1;
1029      goto L1
1030      L3:
1031      ...
1032
1033      ==>
1034
1035      var = something;
1036      L1:
1037      x1 = expr;
1038      tmp_var = var;
1039      var = x1;
1040      if (cond) goto L1 else goto L2;
1041      L2:
1042      var = tmp_var;
1043      ... 
1044    */
1045   for (tsi = gsi_start (stmts); !gsi_end_p (tsi); gsi_next (&tsi))
1046     {
1047       gimple stmt1 = gsi_stmt (tsi);
1048       tree var, tmp_var;
1049       gimple copy;
1050
1051       /* Create a new variable to load back the value of var in case
1052          we exit the loop.  */
1053       var = gimple_assign_lhs (stmt1);
1054       tmp_var = create_temp (var);
1055       copy = gimple_build_assign (tmp_var, var);
1056       set_is_used (tmp_var);
1057       gsi_insert_before (&gsi, copy, GSI_SAME_STMT);
1058       copy = gimple_build_assign (var, tmp_var);
1059       gsi_insert_before (&gsi_exit, copy, GSI_SAME_STMT);
1060     }
1061
1062   PENDING_STMT (single_edge) = 0;
1063   /* Insert the new stmts to the loop body.  */
1064   gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
1065
1066   if (dump_file)
1067     fprintf (dump_file,
1068              "\nCleaned-up latch block of loop with single BB: %d\n\n",
1069              single_edge->dest->index);
1070
1071   return true;
1072 }
1073
1074 /* Look at all the incoming edges to block BB, and decide where the best place
1075    to insert the stmts on each edge are, and perform those insertions.  */
1076
1077 static void
1078 analyze_edges_for_bb (basic_block bb)
1079 {
1080   edge e;
1081   edge_iterator ei;
1082   int count;
1083   unsigned int x;
1084   bool have_opportunity;
1085   gimple_stmt_iterator gsi;
1086   gimple stmt;
1087   edge single_edge = NULL;
1088   bool is_label;
1089   edge leader;
1090
1091   count = 0;
1092
1093   /* Blocks which contain at least one abnormal edge cannot use 
1094      make_forwarder_block.  Look for these blocks, and commit any PENDING_STMTs
1095      found on edges in these block.  */
1096   have_opportunity = true;
1097   FOR_EACH_EDGE (e, ei, bb->preds)
1098     if (e->flags & EDGE_ABNORMAL)
1099       {
1100         have_opportunity = false;
1101         break;
1102       }
1103
1104   if (!have_opportunity)
1105     {
1106       FOR_EACH_EDGE (e, ei, bb->preds)
1107         if (PENDING_STMT (e))
1108           gsi_commit_one_edge_insert (e, NULL);
1109       return;
1110     }
1111
1112   /* Find out how many edges there are with interesting pending stmts on them.  
1113      Commit the stmts on edges we are not interested in.  */
1114   FOR_EACH_EDGE (e, ei, bb->preds)
1115     {
1116       if (PENDING_STMT (e))
1117         {
1118           gcc_assert (!(e->flags & EDGE_ABNORMAL));
1119           if (e->flags & EDGE_FALLTHRU)
1120             {
1121               gsi = gsi_start_bb (e->src);
1122               if (!gsi_end_p (gsi))
1123                 {
1124                   stmt = gsi_stmt (gsi);
1125                   gsi_next (&gsi);
1126                   gcc_assert (stmt != NULL);
1127                   is_label = (gimple_code (stmt) == GIMPLE_LABEL);
1128                   /* Punt if it has non-label stmts, or isn't local.  */
1129                   if (!is_label
1130                       || DECL_NONLOCAL (gimple_label_label (stmt)) 
1131                       || !gsi_end_p (gsi))
1132                     {
1133                       gsi_commit_one_edge_insert (e, NULL);
1134                       continue;
1135                     }
1136                 }
1137             }
1138           single_edge = e;
1139           count++;
1140         }
1141     }
1142
1143   /* If there aren't at least 2 edges, no sharing will happen.  */
1144   if (count < 2)
1145     {
1146       if (single_edge)
1147       {
1148        /* Add stmts to the edge unless processed specially as a
1149           single-block loop latch edge. */
1150        if (!process_single_block_loop_latch (single_edge))
1151          gsi_commit_one_edge_insert (single_edge, NULL);
1152       }
1153       return;
1154     }
1155
1156   /* Ensure that we have empty worklists.  */
1157 #ifdef ENABLE_CHECKING
1158   gcc_assert (VEC_length (edge, edge_leader) == 0);
1159   gcc_assert (VEC_length (gimple_seq, stmt_list) == 0);
1160   gcc_assert (bitmap_empty_p (leader_has_match));
1161 #endif
1162
1163   /* Find the "leader" block for each set of unique stmt lists.  Preference is
1164      given to FALLTHRU blocks since they would need a GOTO to arrive at another
1165      block.  The leader edge destination is the block which all the other edges
1166      with the same stmt list will be redirected to.  */
1167   have_opportunity = false;
1168   FOR_EACH_EDGE (e, ei, bb->preds)
1169     {
1170       if (PENDING_STMT (e))
1171         {
1172           bool found = false;
1173
1174           /* Look for the same stmt list in edge leaders list.  */
1175           for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++)
1176             {
1177               if (identical_stmt_lists_p (leader, e))
1178                 {
1179                   /* Give this edge the same stmt list pointer.  */
1180                   PENDING_STMT (e) = NULL;
1181                   e->aux = leader;
1182                   bitmap_set_bit (leader_has_match, x);
1183                   have_opportunity = found = true;
1184                   break;
1185                 }
1186             }
1187
1188           /* If no similar stmt list, add this edge to the leader list.  */
1189           if (!found)
1190             {
1191               VEC_safe_push (edge, heap, edge_leader, e);
1192               VEC_safe_push (gimple_seq, heap, stmt_list, PENDING_STMT (e));
1193             }
1194         }
1195      }
1196
1197   /* If there are no similar lists, just issue the stmts.  */
1198   if (!have_opportunity)
1199     {
1200       for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++)
1201         gsi_commit_one_edge_insert (leader, NULL);
1202       VEC_truncate (edge, edge_leader, 0);
1203       VEC_truncate (gimple_seq, stmt_list, 0);
1204       bitmap_clear (leader_has_match);
1205       return;
1206     }
1207
1208   if (dump_file)
1209     fprintf (dump_file, "\nOpportunities in BB %d for stmt/block reduction:\n",
1210              bb->index);
1211   
1212   /* For each common list, create a forwarding block and issue the stmt's
1213      in that block.  */
1214   for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++)
1215     if (bitmap_bit_p (leader_has_match, x))
1216       {
1217         edge new_edge;
1218         gimple_stmt_iterator gsi;
1219         gimple_seq curr_stmt_list;
1220
1221         leader_match = leader;
1222
1223         /* The tree_* cfg manipulation routines use the PENDING_EDGE field
1224            for various PHI manipulations, so it gets cleared when calls are 
1225            made to make_forwarder_block(). So make sure the edge is clear, 
1226            and use the saved stmt list.  */
1227         PENDING_STMT (leader) = NULL;
1228         leader->aux = leader;
1229         curr_stmt_list = VEC_index (gimple_seq, stmt_list, x);
1230
1231         new_edge = make_forwarder_block (leader->dest, same_stmt_list_p, 
1232                                          NULL);
1233         bb = new_edge->dest;
1234         if (dump_file)
1235           {
1236             fprintf (dump_file, "Splitting BB %d for Common stmt list.  ", 
1237                      leader->dest->index);
1238             fprintf (dump_file, "Original block is now BB%d.\n", bb->index);
1239             print_gimple_seq (dump_file, curr_stmt_list, 0, TDF_VOPS);
1240           }
1241
1242         FOR_EACH_EDGE (e, ei, new_edge->src->preds)
1243           {
1244             e->aux = NULL;
1245             if (dump_file)
1246               fprintf (dump_file, "  Edge (%d->%d) lands here.\n", 
1247                        e->src->index, e->dest->index);
1248           }
1249
1250         gsi = gsi_last_bb (leader->dest);
1251         gsi_insert_seq_after (&gsi, curr_stmt_list, GSI_NEW_STMT);
1252
1253         leader_match = NULL;
1254         /* We should never get a new block now.  */
1255       }
1256     else
1257       {
1258         PENDING_STMT (leader) = VEC_index (gimple_seq, stmt_list, x);
1259         gsi_commit_one_edge_insert (leader, NULL);
1260       }
1261
1262    
1263   /* Clear the working data structures.  */
1264   VEC_truncate (edge, edge_leader, 0);
1265   VEC_truncate (gimple_seq, stmt_list, 0);
1266   bitmap_clear (leader_has_match);
1267 }
1268
1269
1270 /* This function will analyze the insertions which were performed on edges,
1271    and decide whether they should be left on that edge, or whether it is more
1272    efficient to emit some subset of them in a single block.  All stmts are
1273    inserted somewhere.  */
1274
1275 static void
1276 perform_edge_inserts (void)
1277 {
1278   basic_block bb;
1279
1280   if (dump_file)
1281     fprintf(dump_file, "Analyzing Edge Insertions.\n");
1282
1283   /* analyze_edges_for_bb calls make_forwarder_block, which tries to
1284      incrementally update the dominator information.  Since we don't
1285      need dominator information after this pass, go ahead and free the
1286      dominator information.  */
1287   free_dominance_info (CDI_DOMINATORS);
1288   free_dominance_info (CDI_POST_DOMINATORS);
1289
1290   /* Allocate data structures used in analyze_edges_for_bb.   */
1291   init_analyze_edges_for_bb ();
1292
1293   FOR_EACH_BB (bb)
1294     analyze_edges_for_bb (bb);
1295
1296   analyze_edges_for_bb (EXIT_BLOCK_PTR);
1297
1298   /* Free data structures used in analyze_edges_for_bb.   */
1299   fini_analyze_edges_for_bb ();
1300
1301 #ifdef ENABLE_CHECKING
1302   {
1303     edge_iterator ei;
1304     edge e;
1305     FOR_EACH_BB (bb)
1306       {
1307         FOR_EACH_EDGE (e, ei, bb->preds)
1308           {
1309             if (PENDING_STMT (e))
1310               error (" Pending stmts not issued on PRED edge (%d, %d)\n", 
1311                      e->src->index, e->dest->index);
1312           }
1313         FOR_EACH_EDGE (e, ei, bb->succs)
1314           {
1315             if (PENDING_STMT (e))
1316               error (" Pending stmts not issued on SUCC edge (%d, %d)\n", 
1317                      e->src->index, e->dest->index);
1318           }
1319       }
1320     FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
1321       {
1322         if (PENDING_STMT (e))
1323           error (" Pending stmts not issued on ENTRY edge (%d, %d)\n", 
1324                  e->src->index, e->dest->index);
1325       }
1326     FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
1327       {
1328         if (PENDING_STMT (e))
1329           error (" Pending stmts not issued on EXIT edge (%d, %d)\n", 
1330                  e->src->index, e->dest->index);
1331       }
1332   }
1333 #endif
1334 }
1335
1336
1337 /* Remove the ssa-names in the current function and translate them into normal
1338    compiler variables.  PERFORM_TER is true if Temporary Expression Replacement
1339    should also be used.  */
1340
1341 static void
1342 remove_ssa_form (bool perform_ter)
1343 {
1344   basic_block bb;
1345   gimple *values = NULL;
1346   var_map map;
1347   gimple_stmt_iterator gsi;
1348
1349   map = coalesce_ssa_name ();
1350
1351   /* Return to viewing the variable list as just all reference variables after
1352      coalescing has been performed.  */
1353   partition_view_normal (map, false);
1354
1355   if (dump_file && (dump_flags & TDF_DETAILS))
1356     {
1357       fprintf (dump_file, "After Coalescing:\n");
1358       dump_var_map (dump_file, map);
1359     }
1360
1361   if (perform_ter)
1362     {
1363       values = find_replaceable_exprs (map);
1364       if (values && dump_file && (dump_flags & TDF_DETAILS))
1365         dump_replaceable_exprs (dump_file, values);
1366     }
1367
1368   /* Assign real variables to the partitions now.  */
1369   assign_vars (map);
1370
1371   if (dump_file && (dump_flags & TDF_DETAILS))
1372     {
1373       fprintf (dump_file, "After Base variable replacement:\n");
1374       dump_var_map (dump_file, map);
1375     }
1376
1377   rewrite_trees (map, values);
1378
1379   if (values)
1380     free (values);
1381
1382   /* Remove PHI nodes which have been translated back to real variables.  */
1383   FOR_EACH_BB (bb)
1384     for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);)
1385       remove_phi_node (&gsi, true);
1386
1387   /* If any copies were inserted on edges, analyze and insert them now.  */
1388   perform_edge_inserts ();
1389
1390   delete_var_map (map);
1391 }
1392
1393
1394 /* Search every PHI node for arguments associated with backedges which
1395    we can trivially determine will need a copy (the argument is either
1396    not an SSA_NAME or the argument has a different underlying variable
1397    than the PHI result).
1398
1399    Insert a copy from the PHI argument to a new destination at the
1400    end of the block with the backedge to the top of the loop.  Update
1401    the PHI argument to reference this new destination.  */
1402
1403 static void
1404 insert_backedge_copies (void)
1405 {
1406   basic_block bb;
1407   gimple_stmt_iterator gsi;
1408
1409   FOR_EACH_BB (bb)
1410     {
1411       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1412         {
1413           gimple phi = gsi_stmt (gsi);
1414           tree result = gimple_phi_result (phi);
1415           tree result_var;
1416           size_t i;
1417
1418           if (!is_gimple_reg (result))
1419             continue;
1420
1421           result_var = SSA_NAME_VAR (result);
1422           for (i = 0; i < gimple_phi_num_args (phi); i++)
1423             {
1424               tree arg = gimple_phi_arg_def (phi, i);
1425               edge e = gimple_phi_arg_edge (phi, i);
1426
1427               /* If the argument is not an SSA_NAME, then we will need a 
1428                  constant initialization.  If the argument is an SSA_NAME with
1429                  a different underlying variable then a copy statement will be 
1430                  needed.  */
1431               if ((e->flags & EDGE_DFS_BACK)
1432                   && (TREE_CODE (arg) != SSA_NAME
1433                       || SSA_NAME_VAR (arg) != result_var))
1434                 {
1435                   tree name;
1436                   gimple stmt, last = NULL;
1437                   gimple_stmt_iterator gsi2;
1438
1439                   gsi2 = gsi_last_bb (gimple_phi_arg_edge (phi, i)->src);
1440                   if (!gsi_end_p (gsi2))
1441                     last = gsi_stmt (gsi2);
1442
1443                   /* In theory the only way we ought to get back to the
1444                      start of a loop should be with a COND_EXPR or GOTO_EXPR.
1445                      However, better safe than sorry. 
1446                      If the block ends with a control statement or
1447                      something that might throw, then we have to
1448                      insert this assignment before the last
1449                      statement.  Else insert it after the last statement.  */
1450                   if (last && stmt_ends_bb_p (last))
1451                     {
1452                       /* If the last statement in the block is the definition
1453                          site of the PHI argument, then we can't insert
1454                          anything after it.  */
1455                       if (TREE_CODE (arg) == SSA_NAME
1456                           && SSA_NAME_DEF_STMT (arg) == last)
1457                         continue;
1458                     }
1459
1460                   /* Create a new instance of the underlying variable of the 
1461                      PHI result.  */
1462                   stmt = gimple_build_assign (result_var,
1463                                               gimple_phi_arg_def (phi, i));
1464                   name = make_ssa_name (result_var, stmt);
1465                   gimple_assign_set_lhs (stmt, name);
1466
1467                   /* Insert the new statement into the block and update
1468                      the PHI node.  */
1469                   if (last && stmt_ends_bb_p (last))
1470                     gsi_insert_before (&gsi2, stmt, GSI_NEW_STMT);
1471                   else
1472                     gsi_insert_after (&gsi2, stmt, GSI_NEW_STMT);
1473                   SET_PHI_ARG_DEF (phi, i, name);
1474                 }
1475             }
1476         }
1477     }
1478 }
1479
1480 /* Take the current function out of SSA form, translating PHIs as described in
1481    R. Morgan, ``Building an Optimizing Compiler'',
1482    Butterworth-Heinemann, Boston, MA, 1998. pp 176-186.  */
1483
1484 static unsigned int
1485 rewrite_out_of_ssa (void)
1486 {
1487   /* If elimination of a PHI requires inserting a copy on a backedge,
1488      then we will have to split the backedge which has numerous
1489      undesirable performance effects.
1490
1491      A significant number of such cases can be handled here by inserting
1492      copies into the loop itself.  */
1493   insert_backedge_copies ();
1494
1495
1496   /* Eliminate PHIs which are of no use, such as virtual or dead phis.  */
1497   eliminate_useless_phis ();
1498
1499   if (dump_file && (dump_flags & TDF_DETAILS))
1500     gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);
1501
1502   remove_ssa_form (flag_tree_ter && !flag_mudflap);
1503
1504   if (dump_file && (dump_flags & TDF_DETAILS))
1505     gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS);
1506
1507   cfun->gimple_df->in_ssa_p = false;
1508   return 0;
1509 }
1510
1511
1512 /* Define the parameters of the out of SSA pass.  */
1513
1514 struct gimple_opt_pass pass_del_ssa = 
1515 {
1516  {
1517   GIMPLE_PASS,
1518   "optimized",                          /* name */
1519   NULL,                                 /* gate */
1520   rewrite_out_of_ssa,                   /* execute */
1521   NULL,                                 /* sub */
1522   NULL,                                 /* next */
1523   0,                                    /* static_pass_number */
1524   TV_TREE_SSA_TO_NORMAL,                /* tv_id */
1525   PROP_cfg | PROP_ssa,                  /* properties_required */
1526   0,                                    /* properties_provided */
1527   /* ??? If TER is enabled, we also kill gimple.  */
1528   PROP_ssa,                             /* properties_destroyed */
1529   TODO_verify_ssa | TODO_verify_flow
1530     | TODO_verify_stmts,                /* todo_flags_start */
1531   TODO_dump_func
1532   | TODO_ggc_collect
1533   | TODO_remove_unused_locals           /* todo_flags_finish */
1534  }
1535 };