OSDN Git Service

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