OSDN Git Service

2004-12-02 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa.c
1 /* Miscellaneous SSA utility functions.
2    Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "rtl.h"
28 #include "tm_p.h"
29 #include "ggc.h"
30 #include "langhooks.h"
31 #include "hard-reg-set.h"
32 #include "basic-block.h"
33 #include "output.h"
34 #include "errors.h"
35 #include "expr.h"
36 #include "function.h"
37 #include "diagnostic.h"
38 #include "bitmap.h"
39 #include "pointer-set.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 "hashtab.h"
46 #include "tree-dump.h"
47 #include "tree-pass.h"
48
49 /* Remove the corresponding arguments from the PHI nodes in E's
50    destination block and redirect it to DEST.  Return redirected edge.
51    The list of removed arguments is stored in PENDING_STMT (e).  */
52
53 edge
54 ssa_redirect_edge (edge e, basic_block dest)
55 {
56   tree phi, next;
57   tree list = NULL, *last = &list;
58   tree src, dst, node;
59   int i;
60
61   /* Remove the appropriate PHI arguments in E's destination block.  */
62   for (phi = phi_nodes (e->dest); phi; phi = next)
63     {
64       next = PHI_CHAIN (phi);
65
66       i = phi_arg_from_edge (phi, e);
67       if (PHI_ARG_DEF (phi, i) == NULL_TREE)
68         continue;
69
70       src = PHI_ARG_DEF (phi, i);
71       dst = PHI_RESULT (phi);
72       node = build_tree_list (dst, src);
73       *last = node;
74       last = &TREE_CHAIN (node);
75     }
76
77   e = redirect_edge_succ_nodup (e, dest);
78   PENDING_STMT (e) = list;
79
80   return e;
81 }
82
83 /* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
84    E->dest.  */
85
86 void
87 flush_pending_stmts (edge e)
88 {
89   tree phi, arg;
90
91   if (!PENDING_STMT (e))
92     return;
93
94   for (phi = phi_nodes (e->dest), arg = PENDING_STMT (e);
95        phi;
96        phi = PHI_CHAIN (phi), arg = TREE_CHAIN (arg))
97     {
98       tree def = TREE_VALUE (arg);
99       add_phi_arg (phi, def, e);
100     }
101
102   PENDING_STMT (e) = NULL;
103 }
104
105 /* Return true if SSA_NAME is malformed and mark it visited.
106
107    IS_VIRTUAL is true if this SSA_NAME was found inside a virtual
108       operand.  */
109
110 static bool
111 verify_ssa_name (tree ssa_name, bool is_virtual)
112 {
113   TREE_VISITED (ssa_name) = 1;
114
115   if (TREE_CODE (ssa_name) != SSA_NAME)
116     {
117       error ("Expected an SSA_NAME object");
118       return true;
119     }
120
121   if (TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name)))
122     {
123       error ("Type mismatch between an SSA_NAME and its symbol.");
124       return true;
125     }
126
127   if (SSA_NAME_IN_FREE_LIST (ssa_name))
128     {
129       error ("Found an SSA_NAME that had been released into the free pool");
130       return true;
131     }
132
133   if (is_virtual && is_gimple_reg (ssa_name))
134     {
135       error ("Found a virtual definition for a GIMPLE register");
136       return true;
137     }
138
139   if (!is_virtual && !is_gimple_reg (ssa_name))
140     {
141       error ("Found a real definition for a non-register");
142       return true;
143     }
144
145   return false;
146 }
147
148
149 /* Return true if the definition of SSA_NAME at block BB is malformed.
150
151    STMT is the statement where SSA_NAME is created.
152
153    DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
154       version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
155       it means that the block in that array slot contains the
156       definition of SSA_NAME.
157
158    IS_VIRTUAL is true if SSA_NAME is created by a V_MAY_DEF or a
159       V_MUST_DEF.  */
160
161 static bool
162 verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
163             tree stmt, bool is_virtual)
164 {
165   if (verify_ssa_name (ssa_name, is_virtual))
166     goto err;
167
168   if (definition_block[SSA_NAME_VERSION (ssa_name)])
169     {
170       error ("SSA_NAME created in two different blocks %i and %i",
171              definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
172       goto err;
173     }
174
175   definition_block[SSA_NAME_VERSION (ssa_name)] = bb;
176
177   if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
178     {
179       error ("SSA_NAME_DEF_STMT is wrong");
180       fprintf (stderr, "Expected definition statement:\n");
181       print_generic_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), TDF_VOPS);
182       fprintf (stderr, "\nActual definition statement:\n");
183       print_generic_stmt (stderr, stmt, TDF_VOPS);
184       goto err;
185     }
186
187   return false;
188
189 err:
190   fprintf (stderr, "while verifying SSA_NAME ");
191   print_generic_expr (stderr, ssa_name, 0);
192   fprintf (stderr, " in statement\n");
193   print_generic_stmt (stderr, stmt, TDF_VOPS);
194
195   return true;
196 }
197
198
199 /* Return true if the use of SSA_NAME at statement STMT in block BB is
200    malformed.
201
202    DEF_BB is the block where SSA_NAME was found to be created.
203
204    IDOM contains immediate dominator information for the flowgraph.
205
206    CHECK_ABNORMAL is true if the caller wants to check whether this use
207       is flowing through an abnormal edge (only used when checking PHI
208       arguments).
209
210    IS_VIRTUAL is true if SSA_NAME is created by a V_MAY_DEF or a
211       V_MUST_DEF.
212    
213    If NAMES_DEFINED_IN_BB is not NULL, it contains a bitmap of ssa names
214      that are defined before STMT in basic block BB.  */
215
216 static bool
217 verify_use (basic_block bb, basic_block def_bb, tree ssa_name,
218             tree stmt, bool check_abnormal, bool is_virtual,
219             bitmap names_defined_in_bb)
220 {
221   bool err = false;
222
223   err = verify_ssa_name (ssa_name, is_virtual);
224
225   if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name))
226       && var_ann (SSA_NAME_VAR (ssa_name))->default_def == ssa_name)
227     ; /* Default definitions have empty statements.  Nothing to do.  */
228   else if (!def_bb)
229     {
230       error ("Missing definition");
231       err = true;
232     }
233   else if (bb != def_bb
234            && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
235     {
236       error ("Definition in block %i does not dominate use in block %i",
237              def_bb->index, bb->index);
238       err = true;
239     }
240   else if (bb == def_bb
241            && names_defined_in_bb != NULL
242            && !bitmap_bit_p (names_defined_in_bb, SSA_NAME_VERSION (ssa_name)))
243     {
244       error ("Definition in block %i follows the use", def_bb->index);
245       err = true;
246     }
247
248   if (check_abnormal
249       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
250     {
251       error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI should be set");
252       err = true;
253     }
254
255   if (err)
256     {
257       fprintf (stderr, "for SSA_NAME: ");
258       print_generic_expr (stderr, ssa_name, TDF_VOPS);
259       fprintf (stderr, "in statement:\n");
260       print_generic_stmt (stderr, stmt, TDF_VOPS);
261     }
262
263   return err;
264 }
265
266
267 /* Return true if any of the arguments for PHI node PHI at block BB is
268    malformed.
269
270    DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME version
271       numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set, it means that the
272       block in that array slot contains the definition of SSA_NAME.  */
273
274 static bool
275 verify_phi_args (tree phi, basic_block bb, basic_block *definition_block)
276 {
277   edge e;
278   bool err = false;
279   unsigned i, phi_num_args = PHI_NUM_ARGS (phi);
280
281   if (EDGE_COUNT (bb->preds) != phi_num_args)
282     {
283       error ("Incoming edge count does not match number of PHI arguments\n");
284       err = true;
285       goto error;
286     }
287
288   for (i = 0; i < phi_num_args; i++)
289     {
290       tree op = PHI_ARG_DEF (phi, i);
291
292       e = EDGE_PRED (bb, i);
293
294       if (op == NULL_TREE)
295         {
296           error ("PHI argument is missing for edge %d->%d\n",
297                  e->src->index,
298                  e->dest->index);
299           err = true;
300           goto error;
301         }
302
303       if (TREE_CODE (op) != SSA_NAME && !is_gimple_min_invariant (op))
304         {
305           error ("PHI argument is not SSA_NAME, or invariant");
306           err = true;
307         }
308
309       if (TREE_CODE (op) == SSA_NAME)
310         err = verify_use (e->src, definition_block[SSA_NAME_VERSION (op)], op,
311                           phi, e->flags & EDGE_ABNORMAL,
312                           !is_gimple_reg (PHI_RESULT (phi)),
313                           NULL);
314
315       if (e->dest != bb)
316         {
317           error ("Wrong edge %d->%d for PHI argument\n",
318                  e->src->index, e->dest->index, bb->index);
319           err = true;
320         }
321
322       if (err)
323         {
324           fprintf (stderr, "PHI argument\n");
325           print_generic_stmt (stderr, op, TDF_VOPS);
326           goto error;
327         }
328     }
329
330 error:
331   if (err)
332     {
333       fprintf (stderr, "for PHI node\n");
334       print_generic_stmt (stderr, phi, TDF_VOPS);
335     }
336
337
338   return err;
339 }
340
341
342 static void
343 verify_flow_insensitive_alias_info (void)
344 {
345   size_t i;
346   tree var;
347   bitmap visited = BITMAP_XMALLOC ();
348
349   for (i = 0; i < num_referenced_vars; i++)
350     {
351       size_t j;
352       var_ann_t ann;
353       varray_type may_aliases;
354
355       var = referenced_var (i);
356       ann = var_ann (var);
357       may_aliases = ann->may_aliases;
358
359       for (j = 0; may_aliases && j < VARRAY_ACTIVE_SIZE (may_aliases); j++)
360         {
361           tree alias = VARRAY_TREE (may_aliases, j);
362
363           bitmap_set_bit (visited, var_ann (alias)->uid);
364
365           if (!may_be_aliased (alias))
366             {
367               error ("Non-addressable variable inside an alias set.");
368               debug_variable (alias);
369               goto err;
370             }
371         }
372     }
373
374   for (i = 0; i < num_referenced_vars; i++)
375     {
376       var_ann_t ann;
377
378       var = referenced_var (i);
379       ann = var_ann (var);
380
381       if (ann->mem_tag_kind == NOT_A_TAG
382           && ann->is_alias_tag
383           && !bitmap_bit_p (visited, ann->uid))
384         {
385           error ("Addressable variable that is an alias tag but is not in any alias set.");
386           goto err;
387         }
388     }
389
390   BITMAP_XFREE (visited);
391   return;
392
393 err:
394   debug_variable (var);
395   internal_error ("verify_flow_insensitive_alias_info failed.");
396 }
397
398
399 static void
400 verify_flow_sensitive_alias_info (void)
401 {
402   size_t i;
403   tree ptr;
404
405   for (i = 1; i < num_ssa_names; i++)
406     {
407       tree var;
408       var_ann_t ann;
409       struct ptr_info_def *pi;
410  
411
412       ptr = ssa_name (i);
413       if (!ptr)
414         continue;
415
416       /* We only care for pointers that are actually referenced in the
417          program.  */
418       if (!POINTER_TYPE_P (TREE_TYPE (ptr)) || !TREE_VISITED (ptr))
419         continue;
420
421       /* RESULT_DECL is special.  If it's a GIMPLE register, then it
422          is only written-to only once in the return statement.
423          Otherwise, aggregate RESULT_DECLs may be written-to more than
424          once in virtual operands.  */
425       var = SSA_NAME_VAR (ptr);
426       if (TREE_CODE (var) == RESULT_DECL
427           && is_gimple_reg (ptr))
428         continue;
429
430       pi = SSA_NAME_PTR_INFO (ptr);
431       if (pi == NULL)
432         continue;
433
434       ann = var_ann (var);
435       if (pi->is_dereferenced && !pi->name_mem_tag && !ann->type_mem_tag)
436         {
437           error ("Dereferenced pointers should have a name or a type tag");
438           goto err;
439         }
440
441       if (pi->name_mem_tag
442           && !pi->pt_malloc
443           && (pi->pt_vars == NULL || bitmap_empty_p (pi->pt_vars)))
444         {
445           error ("Pointers with a memory tag, should have points-to sets or point to malloc");
446           goto err;
447         }
448
449       if (pi->value_escapes_p
450           && pi->name_mem_tag
451           && !is_call_clobbered (pi->name_mem_tag))
452         {
453           error ("Pointer escapes but its name tag is not call-clobbered.");
454           goto err;
455         }
456     }
457
458   return;
459
460 err:
461   debug_variable (ptr);
462   internal_error ("verify_flow_sensitive_alias_info failed.");
463 }
464
465 DEF_VEC_MALLOC_P (bitmap);
466
467 /* Verify that all name tags have different points to sets.
468    This algorithm takes advantage of the fact that every variable with the
469    same name tag must have the same points-to set. 
470    So we check a single variable for each name tag, and verify that its
471    points-to set is different from every other points-to set for other name
472    tags.  */
473
474 static void
475 verify_name_tags (void)
476 {
477   size_t i;  
478   size_t j;
479   bitmap first, second;  
480   VEC (tree) *name_tag_reps = NULL;
481   VEC (bitmap) *pt_vars_for_reps = NULL;
482
483   /* First we compute the name tag representatives and their points-to sets.  */
484   for (i = 0; i < num_ssa_names; i++)
485     {
486       if (ssa_name (i))
487         {
488           tree ptr = ssa_name (i);
489           struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
490           if (!TREE_VISITED (ptr) 
491               || !POINTER_TYPE_P (TREE_TYPE (ptr)) 
492               || !pi
493               || !pi->name_mem_tag 
494               || TREE_VISITED (pi->name_mem_tag))
495             continue;
496           TREE_VISITED (pi->name_mem_tag) = 1;
497           if (pi->pt_vars != NULL)
498             {    
499               VEC_safe_push (tree, name_tag_reps, ptr);
500               VEC_safe_push (bitmap, pt_vars_for_reps, pi->pt_vars);
501             }
502         }
503     }
504   
505   /* Now compare all the representative bitmaps with all other representative
506      bitmaps, to verify that they are all different.  */
507   for (i = 0; VEC_iterate (bitmap, pt_vars_for_reps, i, first); i++)
508     {
509        for (j = i + 1; VEC_iterate (bitmap, pt_vars_for_reps, j, second); j++)
510          { 
511            if (bitmap_equal_p (first, second))
512              {
513                error ("Two different pointers with identical points-to sets but different name tags");
514                debug_variable (VEC_index (tree, name_tag_reps, j));
515                goto err;
516              }
517          }
518     }
519
520   /* Lastly, clear out the visited flags.  */
521   for (i = 0; i < num_ssa_names; i++)
522     {
523       if (ssa_name (i))
524         {
525           tree ptr = ssa_name (i);
526           struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
527           if (!TREE_VISITED (ptr) 
528               || !POINTER_TYPE_P (TREE_TYPE (ptr)) 
529               || !pi
530               || !pi->name_mem_tag)
531             continue;
532           TREE_VISITED (pi->name_mem_tag) = 0;
533         }
534     } 
535   VEC_free (bitmap, pt_vars_for_reps);
536   return;
537   
538 err:
539   debug_variable (VEC_index (tree, name_tag_reps, i));
540   internal_error ("verify_name_tags failed");
541 }
542 /* Verify the consistency of aliasing information.  */
543
544 static void
545 verify_alias_info (void)
546 {
547   verify_flow_sensitive_alias_info ();
548   verify_name_tags ();
549   verify_flow_insensitive_alias_info ();
550 }
551
552
553 /* Verify common invariants in the SSA web.
554    TODO: verify the variable annotations.  */
555
556 void
557 verify_ssa (void)
558 {
559   size_t i;
560   basic_block bb;
561   basic_block *definition_block = xcalloc (num_ssa_names, sizeof (basic_block));
562   ssa_op_iter iter;
563   tree op;
564   enum dom_state orig_dom_state = dom_computed[CDI_DOMINATORS];
565   bitmap names_defined_in_bb = BITMAP_XMALLOC ();
566
567   timevar_push (TV_TREE_SSA_VERIFY);
568
569   /* Keep track of SSA names present in the IL.  */
570   for (i = 1; i < num_ssa_names; i++)
571     {
572       tree name = ssa_name (i);
573       if (name)
574         {
575           tree stmt;
576           TREE_VISITED (name) = 0;
577
578           stmt = SSA_NAME_DEF_STMT (name);
579           if (!IS_EMPTY_STMT (stmt))
580             {
581               basic_block bb = bb_for_stmt (stmt);
582               verify_def (bb, definition_block,
583                           name, stmt, !is_gimple_reg (name));
584
585             }
586         }
587     }
588
589   calculate_dominance_info (CDI_DOMINATORS);
590
591   /* Now verify all the uses and make sure they agree with the definitions
592      found in the previous pass.  */
593   FOR_EACH_BB (bb)
594     {
595       edge e;
596       tree phi;
597       edge_iterator ei;
598       block_stmt_iterator bsi;
599
600       /* Make sure that all edges have a clear 'aux' field.  */
601       FOR_EACH_EDGE (e, ei, bb->preds)
602         {
603           if (e->aux)
604             {
605               error ("AUX pointer initialized for edge %d->%d\n", e->src->index,
606                       e->dest->index);
607               goto err;
608             }
609         }
610
611       /* Verify the arguments for every PHI node in the block.  */
612       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
613         {
614           if (verify_phi_args (phi, bb, definition_block))
615             goto err;
616           bitmap_set_bit (names_defined_in_bb,
617                           SSA_NAME_VERSION (PHI_RESULT (phi)));
618         }
619
620       /* Now verify all the uses and vuses in every statement of the block.  */
621       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
622         {
623           tree stmt = bsi_stmt (bsi);
624
625               get_stmt_operands (stmt);
626
627               if (stmt_ann (stmt)->makes_aliased_stores 
628                   && NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0)
629                 {
630                   error ("Statement makes aliased stores, but has no V_MAY_DEFS");
631                   print_generic_stmt (stderr, stmt, TDF_VOPS);
632                   goto err;
633                 }
634
635           FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
636             {
637               if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
638                               op, stmt, false, !is_gimple_reg (op),
639                               names_defined_in_bb))
640                 goto err;
641             }
642
643           FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
644             {
645               bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
646             }
647         }
648
649       bitmap_clear (names_defined_in_bb);
650     }
651
652   /* Finally, verify alias information.  */
653   verify_alias_info ();
654
655   free (definition_block);
656   /* Restore the dominance information to its prior known state, so
657      that we do not perturb the compiler's subsequent behavior.  */
658   if (orig_dom_state == DOM_NONE)
659     free_dominance_info (CDI_DOMINATORS);
660   else
661     dom_computed[CDI_DOMINATORS] = orig_dom_state;
662   
663   BITMAP_XFREE (names_defined_in_bb);
664   timevar_pop (TV_TREE_SSA_VERIFY);
665   return;
666
667 err:
668   internal_error ("verify_ssa failed.");
669 }
670
671
672 /* Initialize global DFA and SSA structures.  */
673
674 void
675 init_tree_ssa (void)
676 {
677   VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
678   call_clobbered_vars = BITMAP_XMALLOC ();
679   addressable_vars = BITMAP_XMALLOC ();
680   init_ssa_operands ();
681   init_ssanames ();
682   init_phinodes ();
683   global_var = NULL_TREE;
684 }
685
686
687 /* Deallocate memory associated with SSA data structures for FNDECL.  */
688
689 void
690 delete_tree_ssa (void)
691 {
692   size_t i;
693   basic_block bb;
694   block_stmt_iterator bsi;
695
696   /* Remove annotations from every tree in the function.  */
697   FOR_EACH_BB (bb)
698     for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
699       {
700         tree stmt = bsi_stmt (bsi);
701         release_defs (stmt);
702         ggc_free (stmt->common.ann);
703         stmt->common.ann = NULL;
704       }
705
706   /* Remove annotations from every referenced variable.  */
707   if (referenced_vars)
708     {
709       for (i = 0; i < num_referenced_vars; i++)
710         {
711           tree var = referenced_var (i);
712           ggc_free (var->common.ann);
713           var->common.ann = NULL;
714         }
715       referenced_vars = NULL;
716     }
717
718   fini_ssanames ();
719   fini_phinodes ();
720   fini_ssa_operands ();
721
722   global_var = NULL_TREE;
723   BITMAP_XFREE (call_clobbered_vars);
724   call_clobbered_vars = NULL;
725   BITMAP_XFREE (addressable_vars);
726   addressable_vars = NULL;
727 }
728
729
730 /* Return true if EXPR is a useless type conversion, otherwise return
731    false.  */
732
733 bool
734 tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
735 {
736   /* If the inner and outer types are effectively the same, then
737      strip the type conversion and enter the equivalence into
738      the table.  */
739   if (inner_type == outer_type
740      || (lang_hooks.types_compatible_p (inner_type, outer_type)))
741     return true;
742
743   /* If both types are pointers and the outer type is a (void *), then
744      the conversion is not necessary.  The opposite is not true since
745      that conversion would result in a loss of information if the
746      equivalence was used.  Consider an indirect function call where
747      we need to know the exact type of the function to correctly
748      implement the ABI.  */
749   else if (POINTER_TYPE_P (inner_type)
750            && POINTER_TYPE_P (outer_type)
751            && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
752            && TYPE_REF_CAN_ALIAS_ALL (inner_type)
753               == TYPE_REF_CAN_ALIAS_ALL (outer_type)
754            && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
755     return true;
756
757   /* Pointers and references are equivalent once we get to GENERIC,
758      so strip conversions that just switch between them.  */
759   else if (POINTER_TYPE_P (inner_type)
760            && POINTER_TYPE_P (outer_type)
761            && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
762            && TYPE_REF_CAN_ALIAS_ALL (inner_type)
763               == TYPE_REF_CAN_ALIAS_ALL (outer_type)
764            && lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
765                                              TREE_TYPE (outer_type)))
766     return true;
767
768   /* If both the inner and outer types are integral types, then the
769      conversion is not necessary if they have the same mode and
770      signedness and precision, and both or neither are boolean.  Some
771      code assumes an invariant that boolean types stay boolean and do
772      not become 1-bit bit-field types.  Note that types with precision
773      not using all bits of the mode (such as bit-field types in C)
774      mean that testing of precision is necessary.  */
775   else if (INTEGRAL_TYPE_P (inner_type)
776            && INTEGRAL_TYPE_P (outer_type)
777            && TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
778            && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
779            && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
780     {
781       bool first_boolean = (TREE_CODE (inner_type) == BOOLEAN_TYPE);
782       bool second_boolean = (TREE_CODE (outer_type) == BOOLEAN_TYPE);
783       if (first_boolean == second_boolean)
784         return true;
785     }
786
787   /* Recurse for complex types.  */
788   else if (TREE_CODE (inner_type) == COMPLEX_TYPE
789            && TREE_CODE (outer_type) == COMPLEX_TYPE
790            && tree_ssa_useless_type_conversion_1 (TREE_TYPE (outer_type),
791                                                   TREE_TYPE (inner_type)))
792     return true;
793
794   return false;
795 }
796
797 /* Return true if EXPR is a useless type conversion, otherwise return
798    false.  */
799
800 bool
801 tree_ssa_useless_type_conversion (tree expr)
802 {
803   /* If we have an assignment that merely uses a NOP_EXPR to change
804      the top of the RHS to the type of the LHS and the type conversion
805      is "safe", then strip away the type conversion so that we can
806      enter LHS = RHS into the const_and_copies table.  */
807   if (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR
808       || TREE_CODE (expr) == VIEW_CONVERT_EXPR
809       || TREE_CODE (expr) == NON_LVALUE_EXPR)
810     return tree_ssa_useless_type_conversion_1 (TREE_TYPE (expr),
811                                                TREE_TYPE (TREE_OPERAND (expr,
812                                                                         0)));
813
814
815   return false;
816 }
817
818 /* Returns true if statement STMT may read memory.  */
819
820 bool
821 stmt_references_memory_p (tree stmt)
822 {
823   stmt_ann_t ann;
824
825   get_stmt_operands (stmt);
826   ann = stmt_ann (stmt);
827
828   if (ann->has_volatile_ops)
829     return true;
830
831   return (NUM_VUSES (VUSE_OPS (ann)) > 0
832           || NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
833           || NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0);
834 }
835
836 /* Internal helper for walk_use_def_chains.  VAR, FN and DATA are as
837    described in walk_use_def_chains.
838    
839    VISITED is a pointer set used to mark visited SSA_NAMEs to avoid
840       infinite loops.  We used to have a bitmap for this to just mark
841       SSA versions we had visited.  But non-sparse bitmaps are way too
842       expensive, while sparse bitmaps may cause quadratic behavior.
843
844    IS_DFS is true if the caller wants to perform a depth-first search
845       when visiting PHI nodes.  A DFS will visit each PHI argument and
846       call FN after each one.  Otherwise, all the arguments are
847       visited first and then FN is called with each of the visited
848       arguments in a separate pass.  */
849
850 static bool
851 walk_use_def_chains_1 (tree var, walk_use_def_chains_fn fn, void *data,
852                        struct pointer_set_t *visited, bool is_dfs)
853 {
854   tree def_stmt;
855
856   if (pointer_set_insert (visited, var))
857     return false;
858
859   def_stmt = SSA_NAME_DEF_STMT (var);
860
861   if (TREE_CODE (def_stmt) != PHI_NODE)
862     {
863       /* If we reached the end of the use-def chain, call FN.  */
864       return fn (var, def_stmt, data);
865     }
866   else
867     {
868       int i;
869
870       /* When doing a breadth-first search, call FN before following the
871          use-def links for each argument.  */
872       if (!is_dfs)
873         for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
874           if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
875             return true;
876
877       /* Follow use-def links out of each PHI argument.  */
878       for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
879         {
880           tree arg = PHI_ARG_DEF (def_stmt, i);
881           if (TREE_CODE (arg) == SSA_NAME
882               && walk_use_def_chains_1 (arg, fn, data, visited, is_dfs))
883             return true;
884         }
885
886       /* When doing a depth-first search, call FN after following the
887          use-def links for each argument.  */
888       if (is_dfs)
889         for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
890           if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
891             return true;
892     }
893   
894   return false;
895 }
896   
897
898
899 /* Walk use-def chains starting at the SSA variable VAR.  Call
900    function FN at each reaching definition found.  FN takes three
901    arguments: VAR, its defining statement (DEF_STMT) and a generic
902    pointer to whatever state information that FN may want to maintain
903    (DATA).  FN is able to stop the walk by returning true, otherwise
904    in order to continue the walk, FN should return false.  
905
906    Note, that if DEF_STMT is a PHI node, the semantics are slightly
907    different.  The first argument to FN is no longer the original
908    variable VAR, but the PHI argument currently being examined.  If FN
909    wants to get at VAR, it should call PHI_RESULT (PHI).
910
911    If IS_DFS is true, this function will:
912
913         1- walk the use-def chains for all the PHI arguments, and,
914         2- call (*FN) (ARG, PHI, DATA) on all the PHI arguments.
915
916    If IS_DFS is false, the two steps above are done in reverse order
917    (i.e., a breadth-first search).  */
918
919
920 void
921 walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
922                      bool is_dfs)
923 {
924   tree def_stmt;
925
926   gcc_assert (TREE_CODE (var) == SSA_NAME);
927
928   def_stmt = SSA_NAME_DEF_STMT (var);
929
930   /* We only need to recurse if the reaching definition comes from a PHI
931      node.  */
932   if (TREE_CODE (def_stmt) != PHI_NODE)
933     (*fn) (var, def_stmt, data);
934   else
935     {
936       struct pointer_set_t *visited = pointer_set_create ();
937       walk_use_def_chains_1 (var, fn, data, visited, is_dfs);
938       pointer_set_destroy (visited);
939     }
940 }
941
942
943 /* Replaces VAR with REPL in memory reference expression *X in
944    statement STMT.  */
945
946 static void
947 propagate_into_addr (tree stmt, tree var, tree *x, tree repl)
948 {
949   tree new_var, ass_stmt, addr_var;
950   basic_block bb;
951   block_stmt_iterator bsi;
952
953   /* There is nothing special to handle in the other cases.  */
954   if (TREE_CODE (repl) != ADDR_EXPR)
955     return;
956   addr_var = TREE_OPERAND (repl, 0);
957
958   while (handled_component_p (*x)
959          || TREE_CODE (*x) == REALPART_EXPR
960          || TREE_CODE (*x) == IMAGPART_EXPR)
961     x = &TREE_OPERAND (*x, 0);
962
963   if (TREE_CODE (*x) != INDIRECT_REF
964       || TREE_OPERAND (*x, 0) != var)
965     return;
966
967   if (TREE_TYPE (*x) == TREE_TYPE (addr_var))
968     {
969       *x = addr_var;
970       mark_new_vars_to_rename (stmt, vars_to_rename);
971       return;
972     }
973
974
975   /* Frontends sometimes produce expressions like *&a instead of a[0].
976      Create a temporary variable to handle this case.  */
977   ass_stmt = build2 (MODIFY_EXPR, void_type_node, NULL_TREE, repl);
978   new_var = duplicate_ssa_name (var, ass_stmt);
979   TREE_OPERAND (*x, 0) = new_var;
980   TREE_OPERAND (ass_stmt, 0) = new_var;
981
982   bb = bb_for_stmt (stmt);
983   tree_block_label (bb);
984   bsi = bsi_after_labels (bb);
985   bsi_insert_after (&bsi, ass_stmt, BSI_NEW_STMT);
986
987   mark_new_vars_to_rename (stmt, vars_to_rename);
988 }
989
990 /* Replaces immediate uses of VAR by REPL.  */
991
992 static void
993 replace_immediate_uses (tree var, tree repl)
994 {
995   int i, j, n;
996   dataflow_t df;
997   tree stmt;
998   bool mark_new_vars;
999   ssa_op_iter iter;
1000   use_operand_p use_p;
1001
1002   df = get_immediate_uses (SSA_NAME_DEF_STMT (var));
1003   n = num_immediate_uses (df);
1004
1005   for (i = 0; i < n; i++)
1006     {
1007       stmt = immediate_use (df, i);
1008
1009       if (TREE_CODE (stmt) == PHI_NODE)
1010         {
1011           for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
1012             if (PHI_ARG_DEF (stmt, j) == var)
1013               {
1014                 SET_PHI_ARG_DEF (stmt, j, repl);
1015                 if (TREE_CODE (repl) == SSA_NAME
1016                     && PHI_ARG_EDGE (stmt, j)->flags & EDGE_ABNORMAL)
1017                   SSA_NAME_OCCURS_IN_ABNORMAL_PHI (repl) = 1;
1018               }
1019
1020           continue;
1021         }
1022
1023       get_stmt_operands (stmt);
1024       mark_new_vars = false;
1025       if (is_gimple_reg (SSA_NAME_VAR (var)))
1026         {
1027           if (TREE_CODE (stmt) == MODIFY_EXPR)
1028             {
1029               propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 0), repl);
1030               propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 1), repl);
1031             }
1032
1033           FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
1034             if (USE_FROM_PTR (use_p) == var)
1035               {
1036                 propagate_value (use_p, repl);
1037                 mark_new_vars = POINTER_TYPE_P (TREE_TYPE (repl));
1038               }
1039         }
1040       else
1041         {
1042           FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, 
1043                                     SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
1044             if (USE_FROM_PTR (use_p) == var)
1045               propagate_value (use_p, repl);
1046         }
1047
1048       /* FIXME.  If REPL is a constant, we need to fold STMT.
1049          However, fold_stmt wants a pointer to the statement, because
1050          it may happen that it needs to replace the whole statement
1051          with a new expression.  Since the current def-use machinery
1052          does not return pointers to statements, we call fold_stmt
1053          with the address of a local temporary, if that call changes
1054          the temporary then we fallback on looking for a proper
1055          pointer to STMT by scanning STMT's basic block.
1056
1057          Note that all this will become unnecessary soon.  This
1058          pass is being replaced with a proper copy propagation pass
1059          for 4.1 (dnovillo, 2004-09-17).  */
1060       if (TREE_CODE (repl) != SSA_NAME)
1061         {
1062           tree tmp = stmt;
1063           fold_stmt (&tmp);
1064           mark_new_vars = true;
1065           if (tmp != stmt)
1066             {
1067               block_stmt_iterator si = bsi_for_stmt (stmt);
1068               bsi_replace (&si, tmp, true);
1069               stmt = bsi_stmt (si);
1070             }
1071         }
1072
1073       /* If REPL is a pointer, it may have different memory tags associated
1074          with it.  For instance, VAR may have had a name tag while REPL
1075          only had a type tag.  In these cases, the virtual operands (if
1076          any) in the statement will refer to different symbols which need
1077          to be renamed.  */
1078       if (mark_new_vars)
1079         mark_new_vars_to_rename (stmt, vars_to_rename);
1080       else
1081         modify_stmt (stmt);
1082     }
1083 }
1084
1085 /* Gets the value VAR is equivalent to according to EQ_TO.  */
1086
1087 static tree
1088 get_eq_name (tree *eq_to, tree var)
1089 {
1090   unsigned ver;
1091   tree val = var;
1092
1093   while (TREE_CODE (val) == SSA_NAME)
1094     {
1095       ver = SSA_NAME_VERSION (val);
1096       if (!eq_to[ver])
1097         break;
1098
1099       val = eq_to[ver];
1100     }
1101
1102   while (TREE_CODE (var) == SSA_NAME)
1103     {
1104       ver = SSA_NAME_VERSION (var);
1105       if (!eq_to[ver])
1106         break;
1107
1108       var = eq_to[ver];
1109       eq_to[ver] = val;
1110     }
1111
1112   return val;
1113 }
1114
1115 /* Checks whether phi node PHI is redundant and if it is, records the ssa name
1116    its result is redundant to to EQ_TO array.  */
1117
1118 static void
1119 check_phi_redundancy (tree phi, tree *eq_to)
1120 {
1121   tree val = NULL_TREE, def, res = PHI_RESULT (phi), stmt;
1122   unsigned i, ver = SSA_NAME_VERSION (res), n;
1123   dataflow_t df;
1124
1125   /* It is unlikely that such large phi node would be redundant.  */
1126   if (PHI_NUM_ARGS (phi) > 16)
1127     return;
1128
1129   for (i = 0; i < (unsigned) PHI_NUM_ARGS (phi); i++)
1130     {
1131       def = PHI_ARG_DEF (phi, i);
1132
1133       if (TREE_CODE (def) == SSA_NAME)
1134         {
1135           def = get_eq_name (eq_to, def);
1136           if (def == res)
1137             continue;
1138         }
1139
1140       if (val
1141           && !operand_equal_for_phi_arg_p (val, def))
1142         return;
1143
1144       val = def;
1145     }
1146
1147   /* At least one of the arguments should not be equal to the result, or
1148      something strange is happening.  */
1149   gcc_assert (val);
1150
1151   if (get_eq_name (eq_to, res) == val)
1152     return;
1153
1154   if (!may_propagate_copy (res, val))
1155     return;
1156
1157   eq_to[ver] = val;
1158
1159   df = get_immediate_uses (SSA_NAME_DEF_STMT (res));
1160   n = num_immediate_uses (df);
1161
1162   for (i = 0; i < n; i++)
1163     {
1164       stmt = immediate_use (df, i);
1165
1166       if (TREE_CODE (stmt) == PHI_NODE)
1167         check_phi_redundancy (stmt, eq_to);
1168     }
1169 }
1170
1171 /* Removes redundant phi nodes.
1172
1173    A redundant PHI node is a PHI node where all of its PHI arguments
1174    are the same value, excluding any PHI arguments which are the same
1175    as the PHI result.
1176
1177    A redundant PHI node is effectively a copy, so we forward copy propagate
1178    which removes all uses of the destination of the PHI node then
1179    finally we delete the redundant PHI node.
1180
1181    Note that if we can not copy propagate the PHI node, then the PHI
1182    will not be removed.  Thus we do not have to worry about dependencies
1183    between PHIs and the problems serializing PHIs into copies creates. 
1184    
1185    The most important effect of this pass is to remove degenerate PHI
1186    nodes created by removing unreachable code.  */
1187
1188 void
1189 kill_redundant_phi_nodes (void)
1190 {
1191   tree *eq_to;
1192   unsigned i, old_num_ssa_names;
1193   basic_block bb;
1194   tree phi, var, repl, stmt;
1195
1196   /* The EQ_TO[VER] holds the value by that the ssa name VER should be
1197      replaced.  If EQ_TO[VER] is ssa name and it is decided to replace it by
1198      other value, it may be necessary to follow the chain till the final value.
1199      We perform path shortening (replacing the entries of the EQ_TO array with
1200      heads of these chains) whenever we access the field to prevent quadratic
1201      complexity (probably would not occur in practice anyway, but let us play
1202      it safe).  */
1203   eq_to = xcalloc (num_ssa_names, sizeof (tree));
1204
1205   /* We have had cases where computing immediate uses takes a
1206      significant amount of compile time.  If we run into such
1207      problems here, we may want to only compute immediate uses for
1208      a subset of all the SSA_NAMEs instead of computing it for
1209      all of the SSA_NAMEs.  */
1210   compute_immediate_uses (TDFA_USE_OPS | TDFA_USE_VOPS, NULL);
1211   old_num_ssa_names = num_ssa_names;
1212
1213   FOR_EACH_BB (bb)
1214     {
1215       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
1216         {
1217           var = PHI_RESULT (phi);
1218           check_phi_redundancy (phi, eq_to);
1219         }
1220     }
1221
1222   /* Now propagate the values.  */
1223   for (i = 0; i < old_num_ssa_names; i++)
1224     {
1225       if (!ssa_name (i))
1226         continue;
1227
1228       repl = get_eq_name (eq_to, ssa_name (i));
1229       if (repl != ssa_name (i))
1230         replace_immediate_uses (ssa_name (i), repl);
1231     }
1232
1233   /* And remove the dead phis.  */
1234   for (i = 0; i < old_num_ssa_names; i++)
1235     {
1236       if (!ssa_name (i))
1237         continue;
1238
1239       repl = get_eq_name (eq_to, ssa_name (i));
1240       if (repl != ssa_name (i))
1241         {
1242           stmt = SSA_NAME_DEF_STMT (ssa_name (i));
1243           remove_phi_node (stmt, NULL_TREE, bb_for_stmt (stmt));
1244         }
1245     }
1246
1247   free_df ();
1248   free (eq_to);
1249 }
1250
1251 struct tree_opt_pass pass_redundant_phi =
1252 {
1253   "redphi",                             /* name */
1254   NULL,                                 /* gate */
1255   kill_redundant_phi_nodes,             /* execute */
1256   NULL,                                 /* sub */
1257   NULL,                                 /* next */
1258   0,                                    /* static_pass_number */
1259   TV_TREE_REDPHI,                       /* tv_id */
1260   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
1261   0,                                    /* properties_provided */
1262   0,                                    /* properties_destroyed */
1263   0,                                    /* todo_flags_start */
1264   TODO_dump_func | TODO_rename_vars 
1265     | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */
1266   0                                     /* letter */
1267 };
1268 \f
1269 /* Emit warnings for uninitialized variables.  This is done in two passes.
1270
1271    The first pass notices real uses of SSA names with default definitions.
1272    Such uses are unconditionally uninitialized, and we can be certain that
1273    such a use is a mistake.  This pass is run before most optimizations,
1274    so that we catch as many as we can.
1275
1276    The second pass follows PHI nodes to find uses that are potentially
1277    uninitialized.  In this case we can't necessarily prove that the use
1278    is really uninitialized.  This pass is run after most optimizations,
1279    so that we thread as many jumps and possible, and delete as much dead
1280    code as possible, in order to reduce false positives.  We also look
1281    again for plain uninitialized variables, since optimization may have
1282    changed conditionally uninitialized to unconditionally uninitialized.  */
1283
1284 /* Emit a warning for T, an SSA_NAME, being uninitialized.  The exact
1285    warning text is in MSGID and LOCUS may contain a location or be null.  */
1286
1287 static void
1288 warn_uninit (tree t, const char *msgid, location_t *locus)
1289 {
1290   tree var = SSA_NAME_VAR (t);
1291   tree def = SSA_NAME_DEF_STMT (t);
1292
1293   /* Default uses (indicated by an empty definition statement),
1294      are uninitialized.  */
1295   if (!IS_EMPTY_STMT (def))
1296     return;
1297
1298   /* Except for PARMs of course, which are always initialized.  */
1299   if (TREE_CODE (var) == PARM_DECL)
1300     return;
1301
1302   /* Hard register variables get their initial value from the ether.  */
1303   if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
1304     return;
1305
1306   /* TREE_NO_WARNING either means we already warned, or the front end
1307      wishes to suppress the warning.  */
1308   if (TREE_NO_WARNING (var))
1309     return;
1310
1311   if (!locus)
1312     locus = &DECL_SOURCE_LOCATION (var);
1313   warning (msgid, locus, var);
1314   TREE_NO_WARNING (var) = 1;
1315 }
1316    
1317 /* Called via walk_tree, look for SSA_NAMEs that have empty definitions
1318    and warn about them.  */
1319
1320 static tree
1321 warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data)
1322 {
1323   location_t *locus = data;
1324   tree t = *tp;
1325
1326   /* We only do data flow with SSA_NAMEs, so that's all we can warn about.  */
1327   if (TREE_CODE (t) == SSA_NAME)
1328     {
1329       warn_uninit (t, "%H%qD is used uninitialized in this function", locus);
1330       *walk_subtrees = 0;
1331     }
1332   else if (IS_TYPE_OR_DECL_P (t))
1333     *walk_subtrees = 0;
1334
1335   return NULL_TREE;
1336 }
1337
1338 /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1339    and warn about them.  */
1340
1341 static void
1342 warn_uninitialized_phi (tree phi)
1343 {
1344   int i, n = PHI_NUM_ARGS (phi);
1345
1346   /* Don't look at memory tags.  */
1347   if (!is_gimple_reg (PHI_RESULT (phi)))
1348     return;
1349
1350   for (i = 0; i < n; ++i)
1351     {
1352       tree op = PHI_ARG_DEF (phi, i);
1353       if (TREE_CODE (op) == SSA_NAME)
1354         warn_uninit (op, "%H%qD may be used uninitialized in this function",
1355                      NULL);
1356     }
1357 }
1358
1359 static void
1360 execute_early_warn_uninitialized (void)
1361 {
1362   block_stmt_iterator bsi;
1363   basic_block bb;
1364
1365   FOR_EACH_BB (bb)
1366     for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1367       walk_tree (bsi_stmt_ptr (bsi), warn_uninitialized_var,
1368                  EXPR_LOCUS (bsi_stmt (bsi)), NULL);
1369 }
1370
1371 static void
1372 execute_late_warn_uninitialized (void)
1373 {
1374   basic_block bb;
1375   tree phi;
1376
1377   /* Re-do the plain uninitialized variable check, as optimization may have
1378      straightened control flow.  Do this first so that we don't accidentally
1379      get a "may be" warning when we'd have seen an "is" warning later.  */
1380   execute_early_warn_uninitialized ();
1381
1382   FOR_EACH_BB (bb)
1383     for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
1384       warn_uninitialized_phi (phi);
1385 }
1386
1387 static bool
1388 gate_warn_uninitialized (void)
1389 {
1390   return warn_uninitialized != 0;
1391 }
1392
1393 struct tree_opt_pass pass_early_warn_uninitialized =
1394 {
1395   NULL,                                 /* name */
1396   gate_warn_uninitialized,              /* gate */
1397   execute_early_warn_uninitialized,     /* execute */
1398   NULL,                                 /* sub */
1399   NULL,                                 /* next */
1400   0,                                    /* static_pass_number */
1401   0,                                    /* tv_id */
1402   PROP_ssa,                             /* properties_required */
1403   0,                                    /* properties_provided */
1404   0,                                    /* properties_destroyed */
1405   0,                                    /* todo_flags_start */
1406   0,                                    /* todo_flags_finish */
1407   0                                     /* letter */
1408 };
1409
1410 struct tree_opt_pass pass_late_warn_uninitialized =
1411 {
1412   NULL,                                 /* name */
1413   gate_warn_uninitialized,              /* gate */
1414   execute_late_warn_uninitialized,      /* execute */
1415   NULL,                                 /* sub */
1416   NULL,                                 /* next */
1417   0,                                    /* static_pass_number */
1418   0,                                    /* tv_id */
1419   PROP_ssa,                             /* properties_required */
1420   0,                                    /* properties_provided */
1421   0,                                    /* properties_destroyed */
1422   0,                                    /* todo_flags_start */
1423   0,                                    /* todo_flags_finish */
1424   0                                     /* letter */
1425 };
1426