OSDN Git Service

* Makefile.in (tree-ssanames.o): Depend on TREE_FLOW_H.
[pf3gnuchains/gcc-fork.git] / gcc / tree-outof-ssa.c
1 /* Convert a program in SSA form into Normal form.
2    Copyright (C) 2004 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 2, 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 COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "flags.h"
28 #include "rtl.h"
29 #include "tm_p.h"
30 #include "ggc.h"
31 #include "langhooks.h"
32 #include "hard-reg-set.h"
33 #include "basic-block.h"
34 #include "output.h"
35 #include "errors.h"
36 #include "expr.h"
37 #include "function.h"
38 #include "diagnostic.h"
39 #include "bitmap.h"
40 #include "tree-flow.h"
41 #include "tree-gimple.h"
42 #include "tree-inline.h"
43 #include "varray.h"
44 #include "timevar.h"
45 #include "tree-alias-common.h"
46 #include "hashtab.h"
47 #include "tree-dump.h"
48 #include "tree-ssa-live.h"
49 #include "tree-pass.h"
50
51 /* Used to hold all the components required to do SSA PHI elimination.
52    The node and pred/succ list is a simple linear list of nodes and
53    edges represented as pairs of nodes.
54
55    The predecessor and successor list:  Nodes are entered in pairs, where
56    [0] ->PRED, [1]->SUCC.  All the even indexes in the array represent 
57    predecessors, all the odd elements are successors. 
58    
59    Rationale:
60    When implemented as bitmaps, very large programs SSA->Normal times were 
61    being dominated by clearing the interference graph.
62
63    Typically this list of edges is extremely small since it only includes 
64    PHI results and uses from a single edge which have not coalesced with 
65    each other.  This means that no virtual PHI nodes are included, and
66    empirical evidence suggests that the number of edges rarely exceed
67    3, and in a bootstrap of GCC, the maximum size encountered was 7.
68    This also limits the number of possible nodes that are involved to
69    rarely more than 6, and in the bootstrap of gcc, the maximum number
70    of nodes encountered was 12.  */
71  
72 typedef struct _elim_graph {
73   /* Size of the elimination vectors.  */
74   int size;
75
76   /* List of nodes in the elimination graph.  */
77   varray_type nodes;
78
79   /*  The predecessor and successor edge list.  */
80   varray_type edge_list;
81
82   /* Visited vector.  */
83   sbitmap visited;
84
85   /* Stack for visited nodes.  */
86   varray_type stack;
87   
88   /* The variable partition map.  */
89   var_map map;
90
91   /* Edge being eliminated by this graph.  */
92   edge e;
93
94   /* List of constant copies to emit.  These are pushed on in pairs.  */
95   varray_type  const_copies;
96 } *elim_graph;
97
98
99 /* Local functions.  */
100 static tree create_temp (tree);
101 static void insert_copy_on_edge (edge, tree, tree);
102 static elim_graph new_elim_graph (int);
103 static inline void delete_elim_graph (elim_graph);
104 static inline void clear_elim_graph (elim_graph);
105 static inline int elim_graph_size (elim_graph);
106 static inline void elim_graph_add_node (elim_graph, tree);
107 static inline void elim_graph_add_edge (elim_graph, int, int);
108 static inline int elim_graph_remove_succ_edge (elim_graph, int);
109
110 static inline void eliminate_name (elim_graph, tree);
111 static void eliminate_build (elim_graph, basic_block, int);
112 static void elim_forward (elim_graph, int);
113 static int elim_unvisited_predecessor (elim_graph, int);
114 static void elim_backward (elim_graph, int);
115 static void elim_create (elim_graph, int);
116 static void eliminate_phi (edge, int, elim_graph);
117 static tree_live_info_p coalesce_ssa_name (var_map, int);
118 static void assign_vars (var_map);
119 static bool replace_variable (var_map, tree *, tree *);
120 static void eliminate_virtual_phis (void);
121 static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p);
122 static void print_exprs (FILE *, const char *, tree, const char *, tree,
123                          const char *);
124 static void print_exprs_edge (FILE *, edge, const char *, tree, const char *,
125                               tree);
126
127
128 /* Create a temporary variable based on the type of variable T.  Use T's name
129    as the prefix.  */
130
131 static tree
132 create_temp (tree t)
133 {
134   tree tmp;
135   const char *name = NULL;
136   tree type;
137
138   if (TREE_CODE (t) == SSA_NAME)
139     t = SSA_NAME_VAR (t);
140  
141   if (TREE_CODE (t) != VAR_DECL 
142       && TREE_CODE (t) != PARM_DECL)
143     abort ();
144
145   type = TREE_TYPE (t);
146   tmp = DECL_NAME (t);
147   if (tmp)
148     name = IDENTIFIER_POINTER (tmp);
149
150   if (name == NULL)
151     name = "temp";
152   tmp = create_tmp_var (type, name);
153   DECL_ARTIFICIAL (tmp) = DECL_ARTIFICIAL (t);
154   add_referenced_tmp_var (tmp);
155
156   /* add_referenced_tmp_var will create the annotation and set up some
157      of the flags in the annotation.  However, some flags we need to
158      inherit from our original variable.  */
159   var_ann (tmp)->type_mem_tag = var_ann (t)->type_mem_tag;
160   if (is_call_clobbered (t))
161     mark_call_clobbered (tmp);
162
163   return tmp;
164 }
165
166
167 /* This helper function fill insert a copy from a constant or variable SRC to 
168    variable DEST on edge E.  */
169
170 static void
171 insert_copy_on_edge (edge e, tree dest, tree src)
172 {
173   tree copy;
174
175   copy = build (MODIFY_EXPR, TREE_TYPE (dest), dest, src);
176   set_is_used (dest);
177
178   if (TREE_CODE (src) == ADDR_EXPR)
179     src = TREE_OPERAND (src, 0);
180   if (TREE_CODE (src) == VAR_DECL || TREE_CODE (src) == PARM_DECL)
181     set_is_used (src);
182
183   if (dump_file && (dump_flags & TDF_DETAILS))
184     {
185       fprintf (dump_file,
186                "Inserting a copy on edge BB%d->BB%d :",
187                e->src->index,
188                e->dest->index);
189       print_generic_expr (dump_file, copy, dump_flags);
190       fprintf (dump_file, "\n");
191     }
192
193   bsi_insert_on_edge (e, copy);
194 }
195
196
197 /* Create an elimination graph with SIZE nodes and associated data
198    structures.  */
199
200 static elim_graph
201 new_elim_graph (int size)
202 {
203   elim_graph g = (elim_graph) xmalloc (sizeof (struct _elim_graph));
204
205   VARRAY_TREE_INIT (g->nodes, 30, "Elimination Node List");
206   VARRAY_TREE_INIT (g->const_copies, 20, "Elimination Constant Copies");
207   VARRAY_INT_INIT (g->edge_list, 20, "Elimination Edge List");
208   VARRAY_INT_INIT (g->stack, 30, " Elimination Stack");
209   
210   g->visited = sbitmap_alloc (size);
211
212   return g;
213 }
214
215
216 /* Empty elimination graph G.  */
217
218 static inline void
219 clear_elim_graph (elim_graph g)
220 {
221   VARRAY_POP_ALL (g->nodes);
222   VARRAY_POP_ALL (g->edge_list);
223 }
224
225
226 /* Delete elimination graph G.  */
227
228 static inline void
229 delete_elim_graph (elim_graph g)
230 {
231   sbitmap_free (g->visited);
232   free (g);
233 }
234
235
236 /* Return the number of nodes in graph G.  */
237
238 static inline int
239 elim_graph_size (elim_graph g)
240 {
241   return VARRAY_ACTIVE_SIZE (g->nodes);
242 }
243
244
245 /* Add NODE to graph G, if it doesn't exist already.  */
246
247 static inline void 
248 elim_graph_add_node (elim_graph g, tree node)
249 {
250   int x;
251   for (x = 0; x < elim_graph_size (g); x++)
252     if (VARRAY_TREE (g->nodes, x) == node)
253       return;
254   VARRAY_PUSH_TREE (g->nodes, node);
255 }
256
257
258 /* Add the edge PRED->SUCC to graph G.  */
259
260 static inline void
261 elim_graph_add_edge (elim_graph g, int pred, int succ)
262 {
263   VARRAY_PUSH_INT (g->edge_list, pred);
264   VARRAY_PUSH_INT (g->edge_list, succ);
265 }
266
267
268 /* Remove an edge from graph G for which NODE is the predecessor, and
269    return the successor node.  -1 is returned if there is no such edge.  */
270
271 static inline int
272 elim_graph_remove_succ_edge (elim_graph g, int node)
273 {
274   int y;
275   unsigned x;
276   for (x = 0; x < VARRAY_ACTIVE_SIZE (g->edge_list); x += 2)
277     if (VARRAY_INT (g->edge_list, x) == node)
278       {
279         VARRAY_INT (g->edge_list, x) = -1;
280         y = VARRAY_INT (g->edge_list, x + 1);
281         VARRAY_INT (g->edge_list, x + 1) = -1;
282         return y;
283       }
284   return -1;
285 }
286
287
288 /* Find all the nodes in GRAPH which are successors to NODE in the
289    edge list.  VAR will hold the partition number found.  CODE is the
290    code fragment executed for every node found.  */
291
292 #define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE)                \
293 do {                                                                    \
294   unsigned x_;                                                          \
295   int y_;                                                               \
296   for (x_ = 0; x_ < VARRAY_ACTIVE_SIZE ((GRAPH)->edge_list); x_ += 2)   \
297     {                                                                   \
298       y_ = VARRAY_INT ((GRAPH)->edge_list, x_);                         \
299       if (y_ != (NODE))                                                 \
300         continue;                                                       \
301       (VAR) = VARRAY_INT ((GRAPH)->edge_list, x_ + 1);                  \
302       CODE;                                                             \
303     }                                                                   \
304 } while (0)
305
306
307 /* Find all the nodes which are predecessors of NODE in the edge list for
308    GRAPH.  VAR will hold the partition number found.  CODE is the
309    code fragment executed for every node found.  */
310
311 #define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE)                \
312 do {                                                                    \
313   unsigned x_;                                                          \
314   int y_;                                                               \
315   for (x_ = 0; x_ < VARRAY_ACTIVE_SIZE ((GRAPH)->edge_list); x_ += 2)   \
316     {                                                                   \
317       y_ = VARRAY_INT ((GRAPH)->edge_list, x_ + 1);                     \
318       if (y_ != (NODE))                                                 \
319         continue;                                                       \
320       (VAR) = VARRAY_INT ((GRAPH)->edge_list, x_);                      \
321       CODE;                                                             \
322     }                                                                   \
323 } while (0)
324
325
326 /* Add T to elimination graph G.  */
327
328 static inline void
329 eliminate_name (elim_graph g, tree T)
330 {
331   elim_graph_add_node (g, T);
332 }
333
334
335 /* Build elimination graph G for basic block BB on incoming PHI edge I.  */
336
337 static void
338 eliminate_build (elim_graph g, basic_block B, int i)
339 {
340   tree phi;
341   tree T0, Ti;
342   int p0, pi;
343
344   clear_elim_graph (g);
345   
346   for (phi = phi_nodes (B); phi; phi = TREE_CHAIN (phi))
347     {
348       T0 = var_to_partition_to_var (g->map, PHI_RESULT (phi));
349       
350       /* Ignore results which are not in partitions.  */
351       if (T0 == NULL_TREE)
352         continue;
353
354       if (PHI_ARG_EDGE (phi, i) == g->e)
355         Ti = PHI_ARG_DEF (phi, i);
356       else
357         {
358           /* On rare occasions, a PHI node may not have the arguments
359              in the same order as all of the other PHI nodes. If they don't 
360              match, find the appropriate index here.  */
361           pi = phi_arg_from_edge (phi, g->e);
362           if (pi == -1)
363             abort();
364           Ti = PHI_ARG_DEF (phi, pi);
365         }
366
367       /* If this argument is a constant, or a SSA_NAME which is being
368          left in SSA form, just queue a copy to be emitted on this
369          edge.  */
370       if (!phi_ssa_name_p (Ti)
371           || (TREE_CODE (Ti) == SSA_NAME
372               && var_to_partition (g->map, Ti) == NO_PARTITION))
373         {
374           /* Save constant copies until all other copies have been emitted
375              on this edge.  */
376           VARRAY_PUSH_TREE (g->const_copies, T0);
377           VARRAY_PUSH_TREE (g->const_copies, Ti);
378         }
379       else
380         {
381           Ti = var_to_partition_to_var (g->map, Ti);
382           if (T0 != Ti)
383             {
384               eliminate_name (g, T0);
385               eliminate_name (g, Ti);
386               p0 = var_to_partition (g->map, T0);
387               pi = var_to_partition (g->map, Ti);
388               elim_graph_add_edge (g, p0, pi);
389             }
390         }
391     }
392 }
393
394
395 /* Push successors of T onto the elimination stack for G.  */
396
397 static void 
398 elim_forward (elim_graph g, int T)
399 {
400   int S;
401   SET_BIT (g->visited, T);
402   FOR_EACH_ELIM_GRAPH_SUCC (g, T, S,
403     {
404       if (!TEST_BIT (g->visited, S))
405         elim_forward (g, S);
406     });
407   VARRAY_PUSH_INT (g->stack, T);
408 }
409
410
411 /* Return 1 if there unvisited predecessors of T in graph G.  */
412
413 static int
414 elim_unvisited_predecessor (elim_graph g, int T)
415 {
416   int P;
417   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
418     {
419       if (!TEST_BIT (g->visited, P))
420         return 1;
421     });
422   return 0;
423 }
424
425 /* Process predecessors first, and insert a copy.  */
426
427 static void
428 elim_backward (elim_graph g, int T)
429 {
430   int P;
431   SET_BIT (g->visited, T);
432   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
433     {
434       if (!TEST_BIT (g->visited, P))
435         {
436           elim_backward (g, P);
437           insert_copy_on_edge (g->e, 
438                                partition_to_var (g->map, P), 
439                                partition_to_var (g->map, T));
440         }
441     });
442 }
443
444 /* Insert required copies for T in graph G.  Check for a strongly connected 
445    region, and create a temporary to break the cycle if one is found.  */
446
447 static void 
448 elim_create (elim_graph g, int T)
449 {
450   tree U;
451   int P, S;
452
453   if (elim_unvisited_predecessor (g, T))
454     {
455       U = create_temp (partition_to_var (g->map, T));
456       insert_copy_on_edge (g->e, U, partition_to_var (g->map, T));
457       FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
458         {
459           if (!TEST_BIT (g->visited, P))
460             {
461               elim_backward (g, P);
462               insert_copy_on_edge (g->e, partition_to_var (g->map, P), U);
463             }
464         });
465     }
466   else
467     {
468       S = elim_graph_remove_succ_edge (g, T);
469       if (S != -1)
470         {
471           SET_BIT (g->visited, T);
472           insert_copy_on_edge (g->e, 
473                                partition_to_var (g->map, T), 
474                                partition_to_var (g->map, S));
475         }
476     }
477   
478 }
479
480 /* Eliminate all the phi nodes on edge E in graph G. I is the usual PHI
481    index that edge E's values are found on.  */
482
483 static void
484 eliminate_phi (edge e, int i, elim_graph g)
485 {
486   int num_nodes = 0;
487   int x;
488   basic_block B = e->dest;
489
490 #if defined ENABLE_CHECKING
491   if (i == -1)
492     abort ();
493   if (VARRAY_ACTIVE_SIZE (g->const_copies) != 0)
494     abort ();
495 #endif
496
497   /* Abnormal edges already have everything coalesced, or the coalescer
498      would have aborted.  */
499   if (e->flags & EDGE_ABNORMAL)
500     return;
501
502   num_nodes = num_var_partitions (g->map);
503   g->e = e;
504
505   eliminate_build (g, B, i);
506
507   if (elim_graph_size (g) != 0)
508     {
509       sbitmap_zero (g->visited);
510       VARRAY_POP_ALL (g->stack);
511
512       for (x = 0; x < elim_graph_size (g); x++)
513         {
514           tree var = VARRAY_TREE (g->nodes, x);
515           int p = var_to_partition (g->map, var);
516           if (!TEST_BIT (g->visited, p))
517             elim_forward (g, p);
518         }
519        
520       sbitmap_zero (g->visited);
521       while (VARRAY_ACTIVE_SIZE (g->stack) > 0)
522         {
523           x = VARRAY_TOP_INT (g->stack);
524           VARRAY_POP (g->stack);
525           if (!TEST_BIT (g->visited, x))
526             elim_create (g, x);
527         }
528     }
529
530   /* If there are any pending constant copies, issue them now.  */
531   while (VARRAY_ACTIVE_SIZE (g->const_copies) > 0)
532     {
533       tree src, dest;
534       src = VARRAY_TOP_TREE (g->const_copies);
535       VARRAY_POP (g->const_copies);
536       dest = VARRAY_TOP_TREE (g->const_copies);
537       VARRAY_POP (g->const_copies);
538       insert_copy_on_edge (e, dest, src);
539     }
540 }
541
542
543 /* Shortcut routine to print messages to file F of the form:
544    "STR1 EXPR1 STR2 EXPR2 STR3."  */
545
546 static void
547 print_exprs (FILE *f, const char *str1, tree expr1, const char *str2,
548              tree expr2, const char *str3)
549 {
550   fprintf (f, "%s", str1);
551   print_generic_expr (f, expr1, TDF_SLIM);
552   fprintf (f, "%s", str2);
553   print_generic_expr (f, expr2, TDF_SLIM);
554   fprintf (f, "%s", str3);
555 }
556
557
558 /* Shortcut routine to print abnormal edge messages to file F of the form:
559    "STR1 EXPR1 STR2 EXPR2 across edge E.  */
560
561 static void
562 print_exprs_edge (FILE *f, edge e, const char *str1, tree expr1, 
563                   const char *str2, tree expr2)
564 {
565   print_exprs (f, str1, expr1, str2, expr2, " across an abnormal edge");
566   fprintf (f, " from BB%d->BB%d\n", e->src->index,
567                e->dest->index);
568 }
569
570
571 /* Coalesce partitions in MAP which are live across abnormal edges in GRAPH.
572    RV is the root variable groupings of the partitions in MAP.  Since code 
573    cannot be inserted on these edges, failure to coalesce something across
574    an abnormal edge is an error.  */
575
576 static void
577 coalesce_abnormal_edges (var_map map, conflict_graph graph, root_var_p rv)
578 {
579   basic_block bb;
580   edge e;
581   tree phi, var, tmp;
582   int x, y;
583
584   /* Code cannot be inserted on abnormal edges. Look for all abnormal 
585      edges, and coalesce any PHI results with their arguments across 
586      that edge.  */
587
588   FOR_EACH_BB (bb)
589     for (e = bb->succ; e; e = e->succ_next)
590       if (e->dest != EXIT_BLOCK_PTR && e->flags & EDGE_ABNORMAL)
591         for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
592           {
593             /* Visit each PHI on the destination side of this abnormal
594                edge, and attempt to coalesce the argument with the result.  */
595             var = PHI_RESULT (phi);
596             x = var_to_partition (map, var);
597
598             /* Ignore results which are not relevant.  */
599             if (x == NO_PARTITION)
600               continue;
601
602             y = phi_arg_from_edge (phi, e);
603             if (y == -1)
604               abort ();
605
606             tmp = PHI_ARG_DEF (phi, y);
607             if (!phi_ssa_name_p (tmp))
608               {
609                 print_exprs_edge (stderr, e,
610                                   "\nConstant argument in PHI. Can't insert :",
611                                   var, " = ", tmp);
612                 abort ();
613               }
614             y = var_to_partition (map, tmp);
615             if (x == NO_PARTITION || y == NO_PARTITION)
616               abort ();
617             if (root_var_find (rv, x) != root_var_find (rv, y))
618               {
619                 print_exprs_edge (stderr, e, "\nDifferent root vars: ",
620                                   root_var (rv, root_var_find (rv, x)), 
621                                   " and ", 
622                                   root_var (rv, root_var_find (rv, y)));
623                 abort ();
624               }
625
626             if (x != y)
627               {
628                 if (!conflict_graph_conflict_p (graph, x, y))
629                   {
630                     /* Now map the partitions back to their real variables.  */
631                     var = partition_to_var (map, x);
632                     tmp = partition_to_var (map, y);
633                     if (dump_file 
634                         && (dump_flags & TDF_DETAILS))
635                       {
636                         print_exprs_edge (dump_file, e, 
637                                           "ABNORMAL: Coalescing ",
638                                           var, " and ", tmp);
639                       }
640                     if (var_union (map, var, tmp) == NO_PARTITION)
641                       {
642                         print_exprs_edge (stderr, e, "\nUnable to coalesce", 
643                                           partition_to_var (map, x), " and ", 
644                                           partition_to_var (map, y));
645                         abort ();
646                       }
647                     conflict_graph_merge_regs (graph, x, y);
648                   }
649                 else
650                   {
651                     print_exprs_edge (stderr, e, "\n Conflict ", 
652                                       partition_to_var (map, x),
653                                       " and ", partition_to_var (map, y));
654                     abort ();
655                   }
656               }
657           }
658 }
659
660
661 /* Reduce the number of live ranges in MAP.  Live range information is 
662    returned if FLAGS indicates that we are combining temporaries, otherwise 
663    NULL is returned.  The only partitions which are associated with actual 
664    variables at this point are those which are forced to be coalesced for 
665    various reason. (live on entry, live across abnormal edges, etc.).  */
666
667 static tree_live_info_p
668 coalesce_ssa_name (var_map map, int flags)
669 {
670   int num, x, i;
671   sbitmap live;
672   tree var, phi;
673   root_var_p rv;
674   tree_live_info_p liveinfo;
675   var_ann_t ann;
676   conflict_graph graph;
677   basic_block bb;
678   coalesce_list_p cl = NULL;
679
680   if (num_var_partitions (map) <= 1)
681     return NULL;
682
683   /* If no preference given, use cheap coalescing of all partitions.  */
684   if ((flags & (SSANORM_COALESCE_PARTITIONS | SSANORM_USE_COALESCE_LIST)) == 0)
685     flags |= SSANORM_COALESCE_PARTITIONS;
686   
687   liveinfo = calculate_live_on_entry (map);
688   calculate_live_on_exit (liveinfo);
689   rv = root_var_init (map);
690
691   /* Remove single element variable from the list.  */
692   root_var_compact (rv);
693
694   if (flags & SSANORM_USE_COALESCE_LIST)
695     {
696       cl = create_coalesce_list (map);
697       
698       /* Add all potential copies via PHI arguments to the list.  */
699       FOR_EACH_BB (bb)
700         {
701           for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
702             {
703               tree res = PHI_RESULT (phi);
704               int p = var_to_partition (map, res);
705               if (p == NO_PARTITION)
706                 continue;
707               for (x = 0; x < PHI_NUM_ARGS (phi); x++)
708                 {
709                   tree arg = PHI_ARG_DEF (phi, x);
710                   int p2;
711
712                   if (TREE_CODE (arg) != SSA_NAME)
713                     continue;
714                   if (SSA_NAME_VAR (res) != SSA_NAME_VAR (arg))
715                     continue;
716                   p2 = var_to_partition (map, PHI_ARG_DEF (phi, x));
717                   if (p2 != NO_PARTITION)
718                     add_coalesce (cl, p, p2, 1);
719                 }
720             }
721         }
722
723       /* Coalesce all the result decls together.  */
724       var = NULL_TREE;
725       i = 0;
726       for (x = 0; x < num_var_partitions (map); x++)
727         {
728           tree p = partition_to_var (map, x);
729           if (TREE_CODE (SSA_NAME_VAR(p)) == RESULT_DECL)
730             {
731               if (var == NULL_TREE)
732                 {
733                   var = p;
734                   i = x;
735                 }
736               else
737                 add_coalesce (cl, i, x, 1);
738             }
739         }
740     }
741
742   /* Build a conflict graph.  */
743   graph = build_tree_conflict_graph (liveinfo, rv, cl);
744
745   if (cl)
746     {
747       if (dump_file && (dump_flags & TDF_DETAILS))
748         {
749           fprintf (dump_file, "Before sorting:\n");
750           dump_coalesce_list (dump_file, cl);
751         }
752
753       sort_coalesce_list (cl);
754
755       if (dump_file && (dump_flags & TDF_DETAILS))
756         {
757           fprintf (dump_file, "\nAfter sorting:\n");
758           dump_coalesce_list (dump_file, cl);
759         }
760     }
761
762   /* Put the single element variables back in.  */
763   root_var_decompact (rv);
764
765   /* First, coalesce all live on entry variables to their root variable. 
766      This will ensure the first use is coming from the correct location.  */
767
768   live = sbitmap_alloc (num_var_partitions (map));
769   sbitmap_zero (live);
770
771   /* Set 'live' vector to indicate live on entry partitions.  */
772   num = num_var_partitions (map);
773   for (x = 0 ; x < num; x++)
774     {
775       var = partition_to_var (map, x);
776       if (default_def (SSA_NAME_VAR (var)) == var)
777         SET_BIT (live, x);
778     }
779
780   if ((flags & SSANORM_COMBINE_TEMPS) == 0)
781     {
782       delete_tree_live_info (liveinfo);
783       liveinfo = NULL;
784     }
785
786   /* Assign root variable as partition representative for each live on entry
787      partition.  */
788   EXECUTE_IF_SET_IN_SBITMAP (live, 0, x, 
789     {
790       var = root_var (rv, root_var_find (rv, x));
791       ann = var_ann (var);
792       /* If these aren't already coalesced...  */
793       if (partition_to_var (map, x) != var)
794         {
795           if (ann->out_of_ssa_tag)
796             {
797               /* This root variable has already been assigned to another
798                  partition which is not coalesced with this one.  */
799               abort ();
800             }
801
802           if (dump_file && (dump_flags & TDF_DETAILS))
803             {
804               print_exprs (dump_file, "Must coalesce ", 
805                            partition_to_var (map, x),
806                            " with the root variable ", var, ".\n");
807             }
808
809           change_partition_var (map, var, x);
810         }
811     });
812
813   sbitmap_free (live);
814
815   /* Coalesce partitions live across abnormal edges.  */
816   coalesce_abnormal_edges (map, graph, rv);
817
818   if (dump_file && (dump_flags & TDF_DETAILS))
819     dump_var_map (dump_file, map);
820
821   /* Coalesce partitions.  */
822   if (flags & SSANORM_USE_COALESCE_LIST)
823     coalesce_tpa_members (rv, graph, map, cl, 
824                           ((dump_flags & TDF_DETAILS) ? dump_file 
825                                                            : NULL));
826
827   
828   if (flags & SSANORM_COALESCE_PARTITIONS)
829     coalesce_tpa_members (rv, graph, map, NULL, 
830                           ((dump_flags & TDF_DETAILS) ? dump_file 
831                                                            : NULL));
832   if (cl)
833     delete_coalesce_list (cl);
834   root_var_delete (rv);
835   conflict_graph_delete (graph);
836
837   return liveinfo;
838 }
839
840
841 /* Take the ssa-name var_map MAP, and assign real variables to each 
842    partition.  */
843
844 static void
845 assign_vars (var_map map)
846 {
847   int x, i, num, rep;
848   tree t, var;
849   var_ann_t ann;
850   root_var_p rv;
851
852   rv = root_var_init (map);
853   if (!rv) 
854     return;
855
856   /* Coalescing may already have forced some partitions to their root 
857      variable. Find these and tag them.  */
858
859   num = num_var_partitions (map);
860   for (x = 0; x < num; x++)
861     {
862       var = partition_to_var (map, x);
863       if (TREE_CODE (var) != SSA_NAME)
864         {
865           /* Coalescing will already have verified that more than one
866              partition doesn't have the same root variable. Simply marked
867              the variable as assigned.  */
868           ann = var_ann (var);
869           ann->out_of_ssa_tag = 1;
870           if (dump_file && (dump_flags & TDF_DETAILS))
871             {
872               fprintf (dump_file, "partition %d has variable ", x);
873               print_generic_expr (dump_file, var, TDF_SLIM);
874               fprintf (dump_file, " assigned to it.\n");
875             }
876
877         }
878     }
879
880   num = root_var_num (rv);
881   for (x = 0; x < num; x++)
882     {
883       var = root_var (rv, x);
884       ann = var_ann (var);
885       for (i = root_var_first_partition (rv, x);
886            i != ROOT_VAR_NONE;
887            i = root_var_next_partition (rv, i))
888         {
889           t = partition_to_var (map, i);
890
891           if (t == var || TREE_CODE (t) != SSA_NAME)
892             continue;
893
894           rep = var_to_partition (map, t);
895           
896           if (!ann->out_of_ssa_tag)
897             {
898               if (dump_file && (dump_flags & TDF_DETAILS))
899                 print_exprs (dump_file, "", t, "  --> ", var, "\n");
900               change_partition_var (map, var, rep);
901               continue;
902             }
903
904           if (dump_file && (dump_flags & TDF_DETAILS))
905             print_exprs (dump_file, "", t, " not coalesced with ", var, 
906                          "");
907
908           var = create_temp (t);
909           change_partition_var (map, var, rep);
910           ann = var_ann (var);
911
912           if (dump_file && (dump_flags & TDF_DETAILS))
913             {
914               fprintf (dump_file, " -->  New temp:  '");
915               print_generic_expr (dump_file, var, TDF_SLIM);
916               fprintf (dump_file, "'\n");
917             }
918         }
919     }
920
921   root_var_delete (rv);
922 }
923
924
925 /* Replace *P with whatever variable it has been rewritten to based on the 
926    partitions in MAP.  EXPR is an optional expression vector over SSA versions
927    which is used to replace *P with an expression instead of a variable.  
928    If the stmt is changed, return true.  */ 
929
930 static inline bool
931 replace_variable (var_map map, tree *p, tree *expr)
932 {
933   tree new_var;
934   tree var = *p;
935
936   /* Check if we are replacing this variable with an expression.  */
937   if (expr)
938     {
939       int version = SSA_NAME_VERSION (*p);
940       if (expr[version])
941         {
942           tree new_expr = TREE_OPERAND (expr[version], 1);
943           *p = new_expr;
944           /* Clear the stmt's RHS, or GC might bite us.  */
945           TREE_OPERAND (expr[version], 1) = NULL_TREE;
946           return true;
947         }
948     }
949
950   new_var = var_to_partition_to_var (map, var);
951   if (new_var)
952     {
953       *p = new_var;
954       set_is_used (new_var);
955       return true;
956     }
957   return false;
958 }
959
960
961 /* Remove any PHI node which is a virtual PHI.  */
962
963 static void
964 eliminate_virtual_phis (void)
965 {
966   basic_block bb;
967   tree phi, next;
968
969   FOR_EACH_BB (bb)
970     {
971       for (phi = phi_nodes (bb); phi; phi = next)
972         {
973           next = TREE_CHAIN (phi);
974           if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
975             {
976 #ifdef ENABLE_CHECKING
977               int i;
978               /* There should be no arguments of this PHI which are in
979                  the partition list, or we get incorrect results.  */
980               for (i = 0; i < PHI_NUM_ARGS (phi); i++)
981                 {
982                   tree arg = PHI_ARG_DEF (phi, i);
983                   if (TREE_CODE (arg) == SSA_NAME 
984                       && is_gimple_reg (SSA_NAME_VAR (arg)))
985                     {
986                       fprintf (stderr, "Argument of PHI is not virtual (");
987                       print_generic_expr (stderr, arg, TDF_SLIM);
988                       fprintf (stderr, "), but the result is :");
989                       print_generic_stmt (stderr, phi, TDF_SLIM);
990                       abort();
991                     }
992                 }
993 #endif
994               remove_phi_node (phi, NULL_TREE, bb);
995             }
996         }
997     }
998 }
999
1000
1001 /* This routine will coalesce variables in MAP of the same type which do not 
1002    interfere with each other. LIVEINFO is the live range info for variables
1003    of interest.  This will both reduce the memory footprint of the stack, and 
1004    allow us to coalesce together local copies of globals and scalarized 
1005    component refs.  */
1006
1007 static void
1008 coalesce_vars (var_map map, tree_live_info_p liveinfo)
1009 {
1010   basic_block bb;
1011   type_var_p tv;
1012   tree var;
1013   int x, p, p2;
1014   coalesce_list_p cl;
1015   conflict_graph graph;
1016
1017   cl = create_coalesce_list (map);
1018
1019   /* Merge all the live on entry vectors for coalesced partitions.  */
1020   for (x = 0; x < num_var_partitions (map); x++)
1021     {
1022       var = partition_to_var (map, x);
1023       p = var_to_partition (map, var);
1024       if (p != x)
1025         live_merge_and_clear (liveinfo, p, x);
1026     }
1027
1028   /* When PHI nodes are turned into copies, the result of each PHI node
1029      becomes live on entry to the block. Mark these now.  */
1030   FOR_EACH_BB (bb)
1031     {
1032       tree phi, arg;
1033       int p;
1034       for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
1035         {
1036           p = var_to_partition (map, PHI_RESULT (phi));
1037
1038           /* Skip virtual PHI nodes.  */
1039           if (p == NO_PARTITION)
1040             continue;
1041
1042           make_live_on_entry (liveinfo, bb, p);
1043
1044           /* Each argument is a potential copy operation. Add any arguments 
1045              which are not coalesced to the result to the coalesce list.  */
1046           for (x = 0; x < PHI_NUM_ARGS (phi); x++)
1047             {
1048               arg = PHI_ARG_DEF (phi, x);
1049               if (!phi_ssa_name_p (arg))
1050                 continue;
1051               p2 = var_to_partition (map, arg);
1052               if (p2 == NO_PARTITION)
1053                 continue;
1054               if (p != p2)
1055                 add_coalesce (cl, p, p2, 1);
1056             }
1057         }
1058    }
1059
1060   
1061   /* Re-calculate live on exit info.  */
1062   calculate_live_on_exit (liveinfo);
1063
1064   if (dump_file && (dump_flags & TDF_DETAILS))
1065     {
1066       fprintf (dump_file, "Live range info for variable memory coalescing.\n");
1067       dump_live_info (dump_file, liveinfo, LIVEDUMP_ALL);
1068
1069       fprintf (dump_file, "Coalesce list from phi nodes:\n");
1070       dump_coalesce_list (dump_file, cl);
1071     }
1072
1073
1074   tv = type_var_init (map);
1075   if (dump_file)
1076     type_var_dump (dump_file, tv);
1077   type_var_compact (tv);
1078   if (dump_file)
1079     type_var_dump (dump_file, tv);
1080
1081   graph = build_tree_conflict_graph (liveinfo, tv, cl);
1082
1083   type_var_decompact (tv);
1084   if (dump_file && (dump_flags & TDF_DETAILS))
1085     {
1086       fprintf (dump_file, "type var list now looks like:n");
1087       type_var_dump (dump_file, tv);
1088
1089       fprintf (dump_file, "Coalesce list after conflict graph build:\n");
1090       dump_coalesce_list (dump_file, cl);
1091     }
1092
1093   sort_coalesce_list (cl);
1094   if (dump_file && (dump_flags & TDF_DETAILS))
1095     {
1096       fprintf (dump_file, "Coalesce list after sorting:\n");
1097       dump_coalesce_list (dump_file, cl);
1098     }
1099
1100   coalesce_tpa_members (tv, graph, map, cl, 
1101                         ((dump_flags & TDF_DETAILS) ? dump_file : NULL));
1102
1103   type_var_delete (tv);
1104   delete_coalesce_list (cl);
1105 }
1106
1107
1108 /* Temporary Expression Replacement (TER)
1109
1110    Replace SSA version variables during out-of-ssa with their defining
1111    expression if there is only one use of the variable.
1112
1113    A pass is made through the function, one block at a time.  No cross block
1114    information is tracked.
1115
1116    Variables which only have one use, and whose defining stmt is considered
1117    a replaceable expression (see check_replaceable) are entered into 
1118    consideration by adding a list of dependent partitions to the version_info
1119    vector for that ssa_name_version.  This information comes from the partition
1120    mapping for each USE.  At the same time, the partition_dep_list vector for 
1121    these partitions have this version number entered into their lists.
1122
1123    When the use of a replaceable ssa_variable is encountered, the dependence
1124    list in version_info[] is moved to the "pending_dependence" list in case
1125    the current expression is also replaceable. (To be determined later in 
1126    processing this stmt.) version_info[] for the version is then updated to 
1127    point to the defining stmt and the 'replaceable' bit is set.
1128
1129    Any partition which is defined by a statement 'kills' any expression which
1130    is dependent on this partition.  Every ssa version in the partitions' 
1131    dependence list is removed from future consideration.
1132
1133    All virtual references are lumped together.  Any expression which is
1134    dependent on any virtual variable (via a VUSE) has a dependence added
1135    to the special partition defined by VIRTUAL_PARTITION.
1136
1137    Whenever a V_MAY_DEF is seen, all expressions dependent this 
1138    VIRTUAL_PARTITION are removed from consideration.
1139
1140    At the end of a basic block, all expression are removed from consideration
1141    in preparation for the next block.  
1142    
1143    The end result is a vector over SSA_NAME_VERSION which is passed back to
1144    rewrite_out_of_ssa.  As the SSA variables are being rewritten, instead of
1145    replacing the SSA_NAME tree element with the partition it was assigned, 
1146    it is replaced with the RHS of the defining expression.  */
1147
1148
1149 /* Dependancy list element.  This can contain either a partition index or a
1150    version number, depending on which list it is in.  */
1151
1152 typedef struct value_expr_d 
1153 {
1154   int value;
1155   struct value_expr_d *next;
1156 } *value_expr_p;
1157
1158
1159 /* Temporary Expression Replacement (TER) table information.  */
1160
1161 typedef struct temp_expr_table_d 
1162 {
1163   var_map map;
1164   void **version_info;          
1165   value_expr_p *partition_dep_list;
1166   bitmap replaceable;
1167   bool saw_replaceable;
1168   int virtual_partition;
1169   bitmap partition_in_use;
1170   value_expr_p free_list;
1171   value_expr_p pending_dependence;
1172 } *temp_expr_table_p;
1173
1174 /* Used to indicate a dependancy on V_MAY_DEFs.  */
1175 #define VIRTUAL_PARTITION(table)        (table->virtual_partition)
1176
1177 static temp_expr_table_p new_temp_expr_table (var_map);
1178 static tree *free_temp_expr_table (temp_expr_table_p);
1179 static inline value_expr_p new_value_expr (temp_expr_table_p);
1180 static inline void free_value_expr (temp_expr_table_p, value_expr_p);
1181 static inline value_expr_p find_value_in_list (value_expr_p, int, 
1182                                                value_expr_p *);
1183 static inline void add_value_to_list (temp_expr_table_p, value_expr_p *, int);
1184 static inline void add_info_to_list (temp_expr_table_p, value_expr_p *, 
1185                                      value_expr_p);
1186 static value_expr_p remove_value_from_list (value_expr_p *, int);
1187 static void add_dependance (temp_expr_table_p, int, tree);
1188 static bool check_replaceable (temp_expr_table_p, tree);
1189 static void finish_expr (temp_expr_table_p, int, bool);
1190 static void mark_replaceable (temp_expr_table_p, tree);
1191 static inline void kill_expr (temp_expr_table_p, int, bool);
1192 static inline void kill_virtual_exprs (temp_expr_table_p, bool);
1193 static void find_replaceable_in_bb (temp_expr_table_p, basic_block);
1194 static tree *find_replaceable_exprs (var_map);
1195 static void dump_replaceable_exprs (FILE *, tree *);
1196
1197
1198 /* Create a new TER table for MAP.  */
1199
1200 static temp_expr_table_p
1201 new_temp_expr_table (var_map map)
1202 {
1203   temp_expr_table_p t;
1204
1205   t = (temp_expr_table_p) xmalloc (sizeof (struct temp_expr_table_d));
1206   t->map = map;
1207
1208   t->version_info = xcalloc (num_ssa_names + 1, sizeof (void *));
1209   t->partition_dep_list = xcalloc (num_var_partitions (map) + 1, 
1210                                    sizeof (value_expr_p));
1211
1212   t->replaceable = BITMAP_XMALLOC ();
1213   t->partition_in_use = BITMAP_XMALLOC ();
1214
1215   t->saw_replaceable = false;
1216   t->virtual_partition = num_var_partitions (map);
1217   t->free_list = NULL;
1218   t->pending_dependence = NULL;
1219
1220   return t;
1221 }
1222
1223
1224 /* Free TER table T.  If there are valid replacements, return the expression 
1225    vector.  */
1226
1227 static tree *
1228 free_temp_expr_table (temp_expr_table_p t)
1229 {
1230   value_expr_p p;
1231   tree *ret = NULL;
1232
1233 #ifdef ENABLE_CHECKING
1234   int x;
1235   for (x = 0; x <= num_var_partitions (t->map); x++)
1236     if (t->partition_dep_list[x] != NULL)
1237       abort();
1238 #endif
1239
1240   while ((p = t->free_list))
1241     {
1242       t->free_list = p->next;
1243       free (p);
1244     }
1245
1246   BITMAP_XFREE (t->partition_in_use);
1247   BITMAP_XFREE (t->replaceable);
1248
1249   free (t->partition_dep_list);
1250   if (t->saw_replaceable)
1251     ret = (tree *)t->version_info;
1252   else
1253     free (t->version_info);
1254   
1255   free (t);
1256   return ret;
1257 }
1258
1259
1260 /* Allocate a new value list node. Take it from the free list in TABLE if 
1261    possible.  */
1262
1263 static inline value_expr_p
1264 new_value_expr (temp_expr_table_p table)
1265 {
1266   value_expr_p p;
1267   if (table->free_list)
1268     {
1269       p = table->free_list;
1270       table->free_list = p->next;
1271     }
1272   else
1273     p = (value_expr_p) xmalloc (sizeof (struct value_expr_d));
1274
1275   return p;
1276 }
1277
1278
1279 /* Add value list node P to the free list in TABLE.  */
1280
1281 static inline void
1282 free_value_expr (temp_expr_table_p table, value_expr_p p)
1283 {
1284   p->next = table->free_list;
1285   table->free_list = p;
1286 }
1287
1288
1289 /* Find VALUE if its in LIST.  Return a pointer to the list object if found,  
1290    else return NULL.  If LAST_PTR is provided, it will point to the previous 
1291    item upon return, or NULL if this is the first item in the list.  */
1292
1293 static inline value_expr_p
1294 find_value_in_list (value_expr_p list, int value, value_expr_p *last_ptr)
1295 {
1296   value_expr_p curr;
1297   value_expr_p last = NULL;
1298
1299   for (curr = list; curr; last = curr, curr = curr->next)
1300     {
1301       if (curr->value == value)
1302         break;
1303     }
1304   if (last_ptr)
1305     *last_ptr = last;
1306   return curr;
1307 }
1308
1309
1310 /* Add VALUE to LIST, if it isn't already present.  TAB is the expression 
1311    table */
1312
1313 static inline void
1314 add_value_to_list (temp_expr_table_p tab, value_expr_p *list, int value)
1315 {
1316   value_expr_p info;
1317
1318   if (!find_value_in_list (*list, value, NULL))
1319     {
1320       info = new_value_expr (tab);
1321       info->value = value;
1322       info->next = *list;
1323       *list = info;
1324     }
1325 }
1326
1327
1328 /* Add value node INFO if it's value isn't already in LIST.  Free INFO if
1329    it is already in the list. TAB is the expression table.  */
1330
1331 static inline void
1332 add_info_to_list (temp_expr_table_p tab, value_expr_p *list, value_expr_p info)
1333 {
1334   if (find_value_in_list (*list, info->value, NULL))
1335     free_value_expr (tab, info);
1336   else
1337     {
1338       info->next = *list;
1339       *list = info;
1340     }
1341 }
1342
1343
1344 /* Look for VALUE in LIST.  If found, remove it from the list and return it's 
1345    pointer.  */
1346
1347 static value_expr_p
1348 remove_value_from_list (value_expr_p *list, int value)
1349 {
1350   value_expr_p info, last;
1351
1352   info = find_value_in_list (*list, value, &last);
1353   if (!info)
1354     return NULL;
1355   if (!last)
1356     *list = info->next;
1357   else
1358     last->next = info->next;
1359  
1360   return info;
1361 }
1362
1363
1364 /* Add a dependancy between the def of ssa VERSION and VAR.  if VAR is 
1365    replaceable by an expression, add a dependance each of the elements of the 
1366    expression.  These are contained in the pending list.  TAB is the
1367    expression table.  */
1368
1369 static void
1370 add_dependance (temp_expr_table_p tab, int version, tree var)
1371 {
1372   int i, x;
1373   value_expr_p info;
1374
1375   i = SSA_NAME_VERSION (var);
1376   if (bitmap_bit_p (tab->replaceable, i))
1377     {
1378       /* This variable is being substituted, so use whatever dependences
1379          were queued up when we marked this as replaceable earlier.  */
1380       while ((info = tab->pending_dependence))
1381         {
1382           tab->pending_dependence = info->next;
1383           /* Get the partition this variable was dependent on. Reuse this
1384              object to represent the current  expression instead.  */
1385           x = info->value;
1386           info->value = version;
1387           add_info_to_list (tab, &(tab->partition_dep_list[x]), info);
1388           add_value_to_list (tab, 
1389                              (value_expr_p *)&(tab->version_info[version]), x);
1390           bitmap_set_bit (tab->partition_in_use, x);
1391         }
1392     }
1393   else
1394     {
1395       i = var_to_partition (tab->map, var);
1396 #ifdef ENABLE_CHECKING
1397       if (i== NO_PARTITION)
1398         abort ();
1399 #endif
1400       add_value_to_list (tab, &(tab->partition_dep_list[i]), version);
1401       add_value_to_list (tab, 
1402                          (value_expr_p *)&(tab->version_info[version]), i);
1403       bitmap_set_bit (tab->partition_in_use, i);
1404     }
1405 }
1406
1407
1408 /* Check if expression STMT is suitable for replacement in table TAB.  If so, 
1409    create an expression entry.  Return true if this stmt is replaceable.  */
1410
1411 static bool
1412 check_replaceable (temp_expr_table_p tab, tree stmt)
1413 {
1414   stmt_ann_t ann;
1415   vuse_optype vuseops;
1416   def_optype defs;
1417   use_optype uses;
1418   tree var, def;
1419   int num_use_ops, version, i;
1420   var_map map = tab->map;
1421
1422   if (TREE_CODE (stmt) != MODIFY_EXPR)
1423     return false;
1424   
1425   ann = stmt_ann (stmt);
1426   defs = DEF_OPS (ann);
1427
1428   /* Punt if there is more than 1 def, or more than 1 use.  */
1429   if (NUM_DEFS (defs) != 1)
1430     return false;
1431   def = DEF_OP (defs, 0);
1432   if (version_ref_count (map, def) != 1)
1433     return false;
1434
1435   /* Assignments to variables assigned to hard registers are not
1436      replaceable.  */
1437   if (DECL_HARD_REGISTER (SSA_NAME_VAR (def)))
1438     return false;
1439
1440   /* There must be no V_MAY_DEFS.  */
1441   if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) != 0)
1442     return false;
1443
1444   /* There must be no V_MUST_DEFS.  */
1445   if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) != 0)
1446     return false;
1447
1448   /* Float expressions must go through memory if float-store is on.  */
1449   if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 1))))
1450     return false;
1451
1452   uses = USE_OPS (ann);
1453   num_use_ops = NUM_USES (uses);
1454   vuseops = VUSE_OPS (ann);
1455
1456   /* Any expression which has no virtual operands and no real operands
1457      should have been propagated if it's possible to do anything with them. 
1458      If this happens here, it probably exists that way for a reason, so we 
1459      won't touch it.   An example is:
1460          b_4 = &tab
1461      There are no virtual uses nor any real uses, so we just leave this 
1462      alone to be safe.  */
1463
1464   if (num_use_ops == 0 && NUM_VUSES (vuseops) == 0)
1465     return false;
1466
1467   version = SSA_NAME_VERSION (def);
1468
1469   /* Add this expression to the dependancy list for each use partition.  */
1470   for (i = 0; i < num_use_ops; i++)
1471     {
1472       var = USE_OP (uses, i);
1473       add_dependance (tab, version, var);
1474     }
1475
1476   /* If there are VUSES, add a dependence on virtual defs.  */
1477   if (NUM_VUSES (vuseops) != 0)
1478     {
1479       add_value_to_list (tab, (value_expr_p *)&(tab->version_info[version]), 
1480                          VIRTUAL_PARTITION (tab));
1481       add_value_to_list (tab, 
1482                          &(tab->partition_dep_list[VIRTUAL_PARTITION (tab)]), 
1483                          version);
1484       bitmap_set_bit (tab->partition_in_use, VIRTUAL_PARTITION (tab));
1485     }
1486
1487   return true;
1488 }
1489
1490
1491 /* This function will remove the expression for VERSION from replacement 
1492    consideration.n table TAB  If 'replace' is true, it is marked as 
1493    replaceable, otherwise not.  */
1494
1495 static void
1496 finish_expr (temp_expr_table_p tab, int version, bool replace)
1497 {
1498   value_expr_p info, tmp;
1499   int partition;
1500
1501   /* Remove this expression from its dependent lists.  The partition dependance
1502      list is retained and transfered later to whomever uses this version.  */
1503   for (info = (value_expr_p) tab->version_info[version]; info; info = tmp)
1504     {
1505       partition = info->value;
1506 #ifdef ENABLE_CHECKING
1507       if (tab->partition_dep_list[partition] == NULL)
1508         abort ();
1509 #endif
1510       tmp = remove_value_from_list (&(tab->partition_dep_list[partition]), 
1511                                     version);
1512 #ifdef ENABLE_CHECKING
1513       if (!tmp)
1514         abort ();
1515 #endif
1516       free_value_expr (tab, tmp);
1517       /* Only clear the bit when the dependancy list is emptied via 
1518          a replacement. Otherwise kill_expr will take care of it.  */
1519       if (!(tab->partition_dep_list[partition]) && replace)
1520         bitmap_clear_bit (tab->partition_in_use, partition);
1521       tmp = info->next;
1522       if (!replace)
1523         free_value_expr (tab, info);
1524     }
1525
1526   if (replace)
1527     {
1528       tab->saw_replaceable = true;
1529       bitmap_set_bit (tab->replaceable, version);
1530     }
1531   else
1532     {
1533 #ifdef ENABLE_CHECKING
1534       if (bitmap_bit_p (tab->replaceable, version))
1535         abort ();
1536 #endif
1537       tab->version_info[version] = NULL;
1538     }
1539 }
1540
1541
1542 /* Mark the expression associated with VAR as replaceable, and enter
1543    the defining stmt into the version_info table TAB.  */
1544
1545 static void
1546 mark_replaceable (temp_expr_table_p tab, tree var)
1547 {
1548   value_expr_p info;
1549   int version = SSA_NAME_VERSION (var);
1550   finish_expr (tab, version, true);
1551
1552   /* Move the dependence list to the pending list.  */
1553   if (tab->version_info[version])
1554     {
1555       info = (value_expr_p) tab->version_info[version]; 
1556       for ( ; info->next; info = info->next)
1557         continue;
1558       info->next = tab->pending_dependence;
1559       tab->pending_dependence = (value_expr_p)tab->version_info[version];
1560     }
1561
1562   tab->version_info[version] = SSA_NAME_DEF_STMT (var);
1563 }
1564
1565
1566 /* This function marks any expression in TAB which is dependent on PARTITION
1567    as NOT replaceable.  CLEAR_BIT is used to determine whether partition_in_use
1568    should have its bit cleared.  Since this routine can be called within an
1569    EXECUTE_IF_SET_IN_BITMAP, the bit can't always be cleared.  */
1570
1571 static inline void
1572 kill_expr (temp_expr_table_p tab, int partition, bool clear_bit)
1573 {
1574   value_expr_p ptr;
1575
1576   /* Mark every active expr dependant on this var as not replaceable.  */
1577   while ((ptr = tab->partition_dep_list[partition]) != NULL)
1578     finish_expr (tab, ptr->value, false);
1579
1580   if (clear_bit)
1581     bitmap_clear_bit (tab->partition_in_use, partition);
1582 }
1583
1584
1585 /* This function kills all expressions in TAB which are dependant on virtual 
1586    DEFs.  CLEAR_BIT determines whether partition_in_use gets cleared.  */
1587
1588 static inline void
1589 kill_virtual_exprs (temp_expr_table_p tab, bool clear_bit)
1590 {
1591   kill_expr (tab, VIRTUAL_PARTITION (tab), clear_bit);
1592 }
1593
1594
1595 /* This function processes basic block BB, and looks for variables which can
1596    be replaced by their expressions.  Results are stored in TAB.  */
1597
1598 static void
1599 find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
1600 {
1601   block_stmt_iterator bsi;
1602   tree stmt, def;
1603   stmt_ann_t ann;
1604   int partition, num, i;
1605   use_optype uses;
1606   def_optype defs;
1607   var_map map = tab->map;
1608   value_expr_p p;
1609
1610   for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1611     {
1612       stmt = bsi_stmt (bsi);
1613       ann = stmt_ann (stmt);
1614
1615       /* Determine if this stmt finishes an existing expression.  */
1616       uses = USE_OPS (ann);
1617       num = NUM_USES (uses);
1618       for (i = 0; i < num; i++)
1619         {
1620           def = USE_OP (uses, i);
1621           if (tab->version_info[SSA_NAME_VERSION (def)])
1622             {
1623               /* Mark expression as replaceable unless stmt is volatile.  */
1624               if (!ann->has_volatile_ops)
1625                 mark_replaceable (tab, def);
1626               else
1627                 finish_expr (tab, SSA_NAME_VERSION (def), false);
1628             }
1629         }
1630       
1631       /* Next, see if this stmt kills off an active expression.  */
1632       defs = DEF_OPS (ann);
1633       num = NUM_DEFS (defs);
1634       for (i = 0; i < num; i++)
1635         {
1636           def = DEF_OP (defs, i);
1637           partition = var_to_partition (map, def);
1638           if (partition != NO_PARTITION && tab->partition_dep_list[partition])
1639             kill_expr (tab, partition, true);
1640         }
1641
1642       /* Now see if we are creating a new expression or not.  */
1643       if (!ann->has_volatile_ops)
1644         check_replaceable (tab, stmt);
1645
1646       /* Free any unused dependancy lists.  */
1647       while ((p = tab->pending_dependence))
1648         {
1649           tab->pending_dependence = p->next;
1650           free_value_expr (tab, p);
1651         }
1652
1653       /* A V_MAY_DEF kills any expression using a virtual operand.  */
1654       if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0)
1655         kill_virtual_exprs (tab, true);
1656         
1657       /* A V_MUST_DEF kills any expression using a virtual operand.  */
1658       if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0)
1659         kill_virtual_exprs (tab, true);
1660     }
1661 }
1662
1663
1664 /* This function is the driver routine for replacement of temporary expressions
1665    in the SSA->normal phase, operating on MAP.  If there are replaceable 
1666    expressions, a table is returned which maps SSA versions to the 
1667    expressions they should be replaced with.  A NULL_TREE indicates no 
1668    replacement should take place.  If there are no replacements at all, 
1669    NULL is returned by the function, otherwise an expression vector indexed
1670    by SSA_NAME version numbers.  */
1671
1672 static tree *
1673 find_replaceable_exprs (var_map map)
1674 {
1675   basic_block bb;
1676   int i;
1677   temp_expr_table_p table;
1678   tree *ret;
1679
1680   table = new_temp_expr_table (map);
1681   FOR_EACH_BB (bb)
1682     {
1683       find_replaceable_in_bb (table, bb);
1684       EXECUTE_IF_SET_IN_BITMAP ((table->partition_in_use), 0, i,
1685         {
1686           kill_expr (table, i, false);
1687         });
1688     }
1689
1690   ret = free_temp_expr_table (table);
1691   return ret;
1692 }
1693
1694
1695 /* Dump TER expression table EXPR to file F.  */
1696
1697 static void
1698 dump_replaceable_exprs (FILE *f, tree *expr)
1699 {
1700   tree stmt, var;
1701   int x;
1702   fprintf (f, "\nReplacing Expressions\n");
1703   for (x = 0; x < (int)num_ssa_names + 1; x++)
1704     if (expr[x])
1705       {
1706         stmt = expr[x];
1707         var = DEF_OP (STMT_DEF_OPS (stmt), 0);
1708         print_generic_expr (f, var, TDF_SLIM);
1709         fprintf (f, " replace with --> ");
1710         print_generic_expr (f, TREE_OPERAND (stmt, 1), TDF_SLIM);
1711         fprintf (f, "\n");
1712       }
1713   fprintf (f, "\n");
1714 }
1715
1716
1717 /* Helper function for discover_nonconstant_array_refs. 
1718    Look for ARRAY_REF nodes with non-constant indexes and mark them
1719    addressable.  */
1720
1721 static tree
1722 discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
1723                                    void *data ATTRIBUTE_UNUSED)
1724 {
1725   tree t = *tp;
1726
1727   if (TYPE_P (t) || DECL_P (t))
1728     *walk_subtrees = 0;
1729   else if (TREE_CODE (t) == ARRAY_REF)
1730     {
1731       while ((TREE_CODE (t) == ARRAY_REF
1732               && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
1733              || (TREE_CODE (t) == COMPONENT_REF
1734                  || TREE_CODE (t) == BIT_FIELD_REF
1735                  || TREE_CODE (t) == REALPART_EXPR
1736                  || TREE_CODE (t) == IMAGPART_EXPR))
1737         t = TREE_OPERAND (t, 0);
1738
1739       if (TREE_CODE (t) == ARRAY_REF)
1740         {
1741           t = get_base_address (t);
1742           if (t && DECL_P (t))
1743             TREE_ADDRESSABLE (t) = 1;
1744         }
1745
1746       *walk_subtrees = 0;
1747     }
1748
1749   return NULL_TREE;
1750 }
1751
1752
1753 /* RTL expansion is not able to compile array references with variable
1754    offsets for arrays stored in single register.  Discover such
1755    expressions and mark variables as addressable to avoid this
1756    scenario.  */
1757
1758 static void
1759 discover_nonconstant_array_refs (void)
1760 {
1761   basic_block bb;
1762   block_stmt_iterator bsi;
1763
1764   FOR_EACH_BB (bb)
1765     {
1766       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1767         walk_tree (bsi_stmt_ptr (bsi), discover_nonconstant_array_refs_r,
1768                    NULL , NULL);
1769     }
1770 }
1771
1772
1773 /* This function will rewrite the current program using the variable mapping
1774    found in MAP.  If the replacement vector VALUES is provided, any 
1775    occurrences of partitions with non-null entries in the vector will be 
1776    replaced with the expression in the vector instead of its mapped 
1777    variable.  */
1778
1779 static void
1780 rewrite_trees (var_map map, tree *values)
1781 {
1782   elim_graph g;
1783   basic_block bb;
1784   block_stmt_iterator si;
1785   edge e;
1786   tree phi;
1787   bool changed;
1788  
1789 #ifdef ENABLE_CHECKING
1790   /* Search for PHIs where the destination has no partition, but one
1791      or more arguments has a partition.  This should not happen and can
1792      create incorrect code.  */
1793   FOR_EACH_BB (bb)
1794     {
1795       tree phi;
1796
1797       for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
1798         {
1799           tree T0 = var_to_partition_to_var (map, PHI_RESULT (phi));
1800       
1801           if (T0 == NULL_TREE)
1802             {
1803               int i;
1804
1805               for (i = 0; i < PHI_NUM_ARGS (phi); i++)
1806                 {
1807                   tree arg = PHI_ARG_DEF (phi, i);
1808
1809                   if (TREE_CODE (arg) == SSA_NAME
1810                       && var_to_partition (map, arg) != NO_PARTITION)
1811                     {
1812                       fprintf (stderr, "Argument of PHI is in a partition :(");
1813                       print_generic_expr (stderr, arg, TDF_SLIM);
1814                       fprintf (stderr, "), but the result is not :");
1815                       print_generic_stmt (stderr, phi, TDF_SLIM);
1816                       abort();
1817                     }
1818                 }
1819             }
1820         }
1821     }
1822 #endif
1823
1824   /* Replace PHI nodes with any required copies.  */
1825   g = new_elim_graph (map->num_partitions);
1826   g->map = map;
1827   FOR_EACH_BB (bb)
1828     {
1829       for (si = bsi_start (bb); !bsi_end_p (si); )
1830         {
1831           size_t i, num_uses, num_defs;
1832           use_optype uses;
1833           def_optype defs;
1834           tree stmt = bsi_stmt (si);
1835           tree *use_p = NULL;
1836           int remove = 0, is_copy = 0;
1837           stmt_ann_t ann;
1838
1839           get_stmt_operands (stmt);
1840           ann = stmt_ann (stmt);
1841           changed = false;
1842
1843           if (TREE_CODE (stmt) == MODIFY_EXPR 
1844               && (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME))
1845             is_copy = 1;
1846
1847           uses = USE_OPS (ann);
1848           num_uses = NUM_USES (uses);
1849
1850           for (i = 0; i < num_uses; i++)
1851             {
1852               use_p = USE_OP_PTR (uses, i);
1853               if (replace_variable (map, use_p, values))
1854                 changed = true;
1855             }
1856
1857           defs = DEF_OPS (ann);
1858           num_defs = NUM_DEFS (defs);
1859
1860           /* Mark this stmt for removal if it is the list of replaceable 
1861              expressions.  */
1862           if (values && num_defs == 1)
1863             {
1864               tree def = DEF_OP (defs, 0);
1865               tree val;
1866               val = values[SSA_NAME_VERSION (def)];
1867               if (val)
1868                 remove = 1;
1869             }
1870           if (!remove)
1871             {
1872               for (i = 0; i < num_defs; i++)
1873                 {
1874                   tree *def_p = DEF_OP_PTR (defs, i);
1875
1876                   if (replace_variable (map, def_p, NULL))
1877                     changed = true;
1878
1879                   /* If both SSA_NAMEs coalesce to the same variable,
1880                      mark the now redundant copy for removal.  */
1881                   if (is_copy
1882                       && num_uses == 1
1883                       && use_p
1884                       && def_p
1885                       && (*def_p == *use_p))
1886                     remove = 1;
1887                 }
1888               if (changed)
1889                 modify_stmt (stmt);
1890             }
1891
1892           /* Remove any stmts marked for removal.  */
1893           if (remove)
1894             bsi_remove (&si);
1895           else
1896             bsi_next (&si);
1897         }
1898
1899       phi = phi_nodes (bb);
1900       if (phi)
1901         {
1902           for (e = bb->pred; e; e = e->pred_next)
1903             eliminate_phi (e, phi_arg_from_edge (phi, e), g);
1904         }
1905     }
1906
1907   delete_elim_graph (g);
1908
1909   /* If any copies were inserted on edges, actually insert them now.  */
1910   bsi_commit_edge_inserts (NULL);
1911 }
1912
1913
1914 /* Remove the variables specified in MAP from SSA form.  Any debug information
1915    is sent to DUMP.  FLAGS indicate what options should be used.  */
1916
1917 void
1918 remove_ssa_form (FILE *dump, var_map map, int flags)
1919 {
1920   tree_live_info_p liveinfo;
1921   basic_block bb;
1922   tree phi, next;
1923   FILE *save;
1924   tree *values = NULL;
1925
1926   save = dump_file;
1927   dump_file = dump;
1928
1929   /* If we are not combining temps, don't calculate live ranges for variables
1930      with only one SSA version.  */
1931   if ((flags & SSANORM_COMBINE_TEMPS) == 0)
1932     compact_var_map (map, VARMAP_NO_SINGLE_DEFS);
1933   else
1934     compact_var_map (map, VARMAP_NORMAL);
1935
1936   if (dump_file && (dump_flags & TDF_DETAILS))
1937     dump_var_map (dump_file, map);
1938
1939   liveinfo = coalesce_ssa_name (map, flags);
1940
1941   /* Make sure even single occurrence variables are in the list now.  */
1942   if ((flags & SSANORM_COMBINE_TEMPS) == 0)
1943     compact_var_map (map, VARMAP_NORMAL);
1944
1945   if (dump_file && (dump_flags & TDF_DETAILS))
1946     {
1947       fprintf (dump_file, "After Coalescing:\n");
1948       dump_var_map (dump_file, map);
1949     }
1950
1951   if (flags & SSANORM_PERFORM_TER)
1952     {
1953       values = find_replaceable_exprs (map);
1954       if (values && dump_file && (dump_flags & TDF_DETAILS))
1955         dump_replaceable_exprs (dump_file, values);
1956     }
1957
1958   /* Assign real variables to the partitions now.  */
1959   assign_vars (map);
1960
1961   if (dump_file && (dump_flags & TDF_DETAILS))
1962     {
1963       fprintf (dump_file, "After Root variable replacement:\n");
1964       dump_var_map (dump_file, map);
1965     }
1966
1967   if ((flags & SSANORM_COMBINE_TEMPS) && liveinfo)
1968     {
1969       coalesce_vars (map, liveinfo);
1970       if (dump_file && (dump_flags & TDF_DETAILS))
1971         {
1972           fprintf (dump_file, "After variable memory coalescing:\n");
1973           dump_var_map (dump_file, map);
1974         }
1975     }
1976   
1977   if (liveinfo)
1978     delete_tree_live_info (liveinfo);
1979
1980   rewrite_trees (map, values);
1981
1982   if (values)
1983     free (values);
1984
1985   /* Remove phi nodes which have been translated back to real variables.  */
1986   FOR_EACH_BB (bb)
1987     {
1988       for (phi = phi_nodes (bb); phi; phi = next)
1989         {
1990           next = TREE_CHAIN (phi);
1991           if ((flags & SSANORM_REMOVE_ALL_PHIS) 
1992               || var_to_partition (map, PHI_RESULT (phi)) != NO_PARTITION)
1993             remove_phi_node (phi, NULL_TREE, bb);
1994         }
1995     }
1996
1997   dump_file = save;
1998 }
1999
2000
2001 /* Take a subset of the variables VARS in the current function out of SSA
2002    form.  */
2003
2004 void
2005 rewrite_vars_out_of_ssa (bitmap vars)
2006 {
2007   if (bitmap_first_set_bit (vars) >= 0)
2008     {
2009       var_map map;
2010       basic_block bb;
2011       tree phi;
2012       int i;
2013       int ssa_flags;
2014
2015       /* Search for PHIs in which one of the PHI arguments is marked for
2016          translation out of SSA form, but for which the PHI result is not
2017          marked for translation out of SSA form.
2018
2019          Our per-variable out of SSA translation can not handle that case;
2020          however we can easily handle it here by creating a new instance
2021          of the PHI result's underlying variable and initializing it to
2022          the offending PHI argument on the edge associated with the
2023          PHI argument.  We then change the PHI argument to use our new
2024          instead of the PHI's underlying variable.
2025
2026          You might think we could register partitions for the out-of-ssa
2027          translation here and avoid a second walk of the PHI nodes.  No
2028          such luck since the size of the var map will change if we have
2029          to manually take variables out of SSA form here.  */
2030       FOR_EACH_BB (bb)
2031         {
2032           for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
2033             {
2034               tree result = SSA_NAME_VAR (PHI_RESULT (phi));
2035
2036               /* If the definition is marked for renaming, then we need
2037                  to do nothing more for this PHI node.  */
2038               if (bitmap_bit_p (vars, var_ann (result)->uid))
2039                 continue;
2040
2041               /* Look at all the arguments and see if any of them are
2042                  marked for renaming.  If so, we need to handle them
2043                  specially.  */
2044               for (i = 0; i < PHI_NUM_ARGS (phi); i++)
2045                 {
2046                   tree arg = PHI_ARG_DEF (phi, i);
2047
2048                   /* If the argument is not an SSA_NAME, then we can ignore
2049                      this argument.  */
2050                   if (TREE_CODE (arg) != SSA_NAME)
2051                     continue;
2052
2053                   /* If this argument is marked for renaming, then we need
2054                      to undo the copy propagation so that we can take
2055                      the argument out of SSA form without taking the
2056                      result out of SSA form.  */
2057                   arg = SSA_NAME_VAR (arg);
2058                   if (bitmap_bit_p (vars, var_ann (arg)->uid))
2059                     {
2060                       tree new_name, copy;
2061
2062                       /* Get a new SSA_NAME for the copy, it is based on
2063                          the result, not the argument!   We use the PHI
2064                          as the definition since we haven't created the
2065                          definition statement yet.  */
2066                       new_name = make_ssa_name (result, phi);
2067
2068                       /* Now create the copy statement.  */
2069                       copy = build (MODIFY_EXPR, TREE_TYPE (arg),
2070                                     new_name, PHI_ARG_DEF (phi, i));
2071
2072                       /* Now update SSA_NAME_DEF_STMT to point to the
2073                          newly created statement.  */
2074                       SSA_NAME_DEF_STMT (new_name) = copy;
2075
2076                       /* Now make the argument reference our new SSA_NAME.  */
2077                       PHI_ARG_DEF (phi, i) = new_name;
2078
2079                       /* Queue the statement for insertion.  */
2080                       bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), copy);
2081                       modify_stmt (copy);
2082                     }
2083                 }
2084             }
2085         }
2086
2087       /* If any copies were inserted on edges, actually insert them now.  */
2088       bsi_commit_edge_inserts (NULL);
2089                                                                                 
2090       /* Now register partitions for all instances of the variables we
2091          are taking out of SSA form.  */
2092       map = init_var_map (num_ssa_names + 1);
2093       register_ssa_partitions_for_vars (vars, map);
2094
2095       /* Now that we have all the partitions registered, translate the
2096          appropriate variables out of SSA form.  */
2097       ssa_flags = SSANORM_COALESCE_PARTITIONS;
2098       if (flag_tree_combine_temps)
2099         ssa_flags |= SSANORM_COMBINE_TEMPS;
2100       remove_ssa_form (dump_file, map, ssa_flags);
2101
2102       /* And finally, reset the out_of_ssa flag for each of the vars
2103          we just took out of SSA form.  */
2104       EXECUTE_IF_SET_IN_BITMAP (vars, 0, i,
2105         {
2106           var_ann (referenced_var (i))->out_of_ssa_tag = 0;
2107         });
2108
2109      /* Free the map as we are done with it.  */
2110      delete_var_map (map);
2111
2112     }
2113 }
2114
2115
2116 /* Take the current function out of SSA form, as described in
2117    R. Morgan, ``Building an Optimizing Compiler'',
2118    Butterworth-Heinemann, Boston, MA, 1998. pp 176-186.  */
2119
2120 static void
2121 rewrite_out_of_ssa (void)
2122 {
2123   var_map map;
2124   int var_flags = 0;
2125   int ssa_flags = (SSANORM_REMOVE_ALL_PHIS | SSANORM_USE_COALESCE_LIST);
2126
2127   if (!flag_tree_live_range_split)
2128     ssa_flags |= SSANORM_COALESCE_PARTITIONS;
2129     
2130   eliminate_virtual_phis ();
2131
2132   if (dump_file && (dump_flags & TDF_DETAILS))
2133     dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
2134
2135   /* We cannot allow unssa to un-gimplify trees before we instrument them.  */
2136   if (flag_tree_ter && !flag_mudflap)
2137     var_flags = SSA_VAR_MAP_REF_COUNT;
2138
2139   map = create_ssa_var_map (var_flags);
2140
2141   if (flag_tree_combine_temps)
2142     ssa_flags |= SSANORM_COMBINE_TEMPS;
2143   if (flag_tree_ter && !flag_mudflap)
2144     ssa_flags |= SSANORM_PERFORM_TER;
2145
2146   remove_ssa_form (dump_file, map, ssa_flags);
2147
2148   if (dump_file && (dump_flags & TDF_DETAILS))
2149     dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
2150
2151   /* Do some cleanups which reduce the amount of data the
2152      tree->rtl expanders deal with.  */
2153   cfg_remove_useless_stmts ();
2154
2155   /* Flush out flow graph and SSA data.  */
2156   delete_var_map (map);
2157
2158   /* Mark arrays indexed with non-constant indices with TREE_ADDRESSABLE.  */
2159   discover_nonconstant_array_refs ();
2160 }
2161
2162
2163 /* Define the parameters of the out of SSA pass.  */
2164
2165 struct tree_opt_pass pass_del_ssa = 
2166 {
2167   "optimized",                          /* name */
2168   NULL,                                 /* gate */
2169   rewrite_out_of_ssa,                   /* execute */
2170   NULL,                                 /* sub */
2171   NULL,                                 /* next */
2172   0,                                    /* static_pass_number */
2173   TV_TREE_SSA_TO_NORMAL,                /* tv_id */
2174   PROP_cfg | PROP_ssa,                  /* properties_required */
2175   0,                                    /* properties_provided */
2176   /* ??? If TER is enabled, we also kill gimple.  */
2177   PROP_ssa,                             /* properties_destroyed */
2178   TODO_verify_ssa | TODO_verify_flow
2179     | TODO_verify_stmts,                /* todo_flags_start */
2180   TODO_dump_func | TODO_ggc_collect     /* todo_flags_finish */
2181 };