OSDN Git Service

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