OSDN Git Service

2011-05-27 Alexander Monakov <amonakov@ispras.ru>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-uninit.c
1 /* Predicate aware uninitialized variable warning.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2010 Free Software
3    Foundation, Inc.
4    Contributed by Xinliang David Li <davidxl@google.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
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 "tm_p.h"
29 #include "langhooks.h"
30 #include "basic-block.h"
31 #include "output.h"
32 #include "function.h"
33 #include "gimple-pretty-print.h"
34 #include "bitmap.h"
35 #include "pointer-set.h"
36 #include "tree-flow.h"
37 #include "gimple.h"
38 #include "tree-inline.h"
39 #include "timevar.h"
40 #include "hashtab.h"
41 #include "tree-dump.h"
42 #include "tree-pass.h"
43 #include "diagnostic-core.h"
44 #include "timevar.h"
45
46 /* This implements the pass that does predicate aware warning on uses of
47    possibly uninitialized variables. The pass first collects the set of
48    possibly uninitialized SSA names. For each such name, it walks through
49    all its immediate uses. For each immediate use, it rebuilds the condition
50    expression (the predicate) that guards the use. The predicate is then
51    examined to see if the variable is always defined under that same condition.
52    This is done either by pruning the unrealizable paths that lead to the
53    default definitions or by checking if the predicate set that guards the
54    defining paths is a superset of the use predicate.  */
55
56
57 /* Pointer set of potentially undefined ssa names, i.e.,
58    ssa names that are defined by phi with operands that
59    are not defined or potentially undefined.  */
60 static struct pointer_set_t *possibly_undefined_names = 0;
61
62 /* Bit mask handling macros.  */
63 #define MASK_SET_BIT(mask, pos) mask |= (1 << pos)
64 #define MASK_TEST_BIT(mask, pos) (mask & (1 << pos))
65 #define MASK_EMPTY(mask) (mask == 0)
66
67 /* Returns the first bit position (starting from LSB)
68    in mask that is non zero. Returns -1 if the mask is empty.  */
69 static int
70 get_mask_first_set_bit (unsigned mask)
71 {
72   int pos = 0;
73   if (mask == 0)
74     return -1;
75
76   while ((mask & (1 << pos)) == 0)
77     pos++;
78
79   return pos;
80 }
81 #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
82
83
84 /* Return true if T, an SSA_NAME, has an undefined value.  */
85
86 bool
87 ssa_undefined_value_p (tree t)
88 {
89   tree var = SSA_NAME_VAR (t);
90
91   /* Parameters get their initial value from the function entry.  */
92   if (TREE_CODE (var) == PARM_DECL)
93     return false;
94
95   /* When returning by reference the return address is actually a hidden
96      parameter.  */
97   if (TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL
98       && DECL_BY_REFERENCE (SSA_NAME_VAR (t)))
99     return false;
100
101   /* Hard register variables get their initial value from the ether.  */
102   if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
103     return false;
104
105   /* The value is undefined iff its definition statement is empty.  */
106   return (gimple_nop_p (SSA_NAME_DEF_STMT (t))
107           || (possibly_undefined_names
108               && pointer_set_contains (possibly_undefined_names, t)));
109 }
110
111 /* Checks if the operand OPND of PHI is defined by 
112    another phi with one operand defined by this PHI, 
113    but the rest operands are all defined. If yes, 
114    returns true to skip this this operand as being
115    redundant. Can be enhanced to be more general.  */
116
117 static bool
118 can_skip_redundant_opnd (tree opnd, gimple phi)
119 {
120   gimple op_def;
121   tree phi_def;
122   int i, n;
123
124   phi_def = gimple_phi_result (phi);
125   op_def = SSA_NAME_DEF_STMT (opnd);
126   if (gimple_code (op_def) != GIMPLE_PHI)
127     return false;
128   n = gimple_phi_num_args (op_def);
129   for (i = 0; i < n; ++i)
130     {
131       tree op = gimple_phi_arg_def (op_def, i);
132       if (TREE_CODE (op) != SSA_NAME)
133         continue;
134       if (op != phi_def && ssa_undefined_value_p (op))
135         return false;
136     }
137
138   return true;
139 }
140
141 /* Returns a bit mask holding the positions of arguments in PHI
142    that have empty (or possibly empty) definitions.  */
143
144 static unsigned
145 compute_uninit_opnds_pos (gimple phi)
146 {
147   size_t i, n;
148   unsigned uninit_opnds = 0;
149
150   n = gimple_phi_num_args (phi);
151   /* Bail out for phi with too many args.  */
152   if (n > 32)
153     return 0;
154
155   for (i = 0; i < n; ++i)
156     {
157       tree op = gimple_phi_arg_def (phi, i);
158       if (TREE_CODE (op) == SSA_NAME
159           && ssa_undefined_value_p (op)
160           && !can_skip_redundant_opnd (op, phi))
161         MASK_SET_BIT (uninit_opnds, i);
162     }
163   return uninit_opnds;
164 }
165
166 /* Find the immediate postdominator PDOM of the specified
167    basic block BLOCK.  */
168
169 static inline basic_block
170 find_pdom (basic_block block)
171 {
172    if (block == EXIT_BLOCK_PTR)
173      return EXIT_BLOCK_PTR;
174    else
175      {
176        basic_block bb
177            = get_immediate_dominator (CDI_POST_DOMINATORS, block);
178        if (! bb)
179          return EXIT_BLOCK_PTR;
180        return bb;
181      }
182 }
183
184 /* Find the immediate DOM of the specified
185    basic block BLOCK.  */
186
187 static inline basic_block
188 find_dom (basic_block block)
189 {
190    if (block == ENTRY_BLOCK_PTR)
191      return ENTRY_BLOCK_PTR;
192    else
193      {
194        basic_block bb = get_immediate_dominator (CDI_DOMINATORS, block);
195        if (! bb)
196          return ENTRY_BLOCK_PTR;
197        return bb;
198      }
199 }
200
201 /* Returns true if BB1 is postdominating BB2 and BB1 is
202    not a loop exit bb. The loop exit bb check is simple and does
203    not cover all cases.  */
204
205 static bool
206 is_non_loop_exit_postdominating (basic_block bb1, basic_block bb2)
207 {
208   if (!dominated_by_p (CDI_POST_DOMINATORS, bb2, bb1))
209     return false;
210
211   if (single_pred_p (bb1) && !single_succ_p (bb2))
212     return false;
213
214   return true;
215 }
216
217 /* Find the closest postdominator of a specified BB, which is control
218    equivalent to BB.  */
219
220 static inline  basic_block
221 find_control_equiv_block (basic_block bb)
222 {
223   basic_block pdom;
224
225   pdom = find_pdom (bb);
226
227   /* Skip the postdominating bb that is also loop exit.  */
228   if (!is_non_loop_exit_postdominating (pdom, bb))
229     return NULL;
230
231   if (dominated_by_p (CDI_DOMINATORS, pdom, bb))
232     return pdom;
233
234   return NULL;
235 }
236
237 #define MAX_NUM_CHAINS 8
238 #define MAX_CHAIN_LEN 5
239
240 /* Computes the control dependence chains (paths of edges)
241    for DEP_BB up to the dominating basic block BB (the head node of a
242    chain should be dominated by it).  CD_CHAINS is pointer to a
243    dynamic array holding the result chains. CUR_CD_CHAIN is the current
244    chain being computed.  *NUM_CHAINS is total number of chains.  The
245    function returns true if the information is successfully computed,
246    return false if there is no control dependence or not computed.  */
247
248 static bool
249 compute_control_dep_chain (basic_block bb, basic_block dep_bb,
250                            VEC(edge, heap) **cd_chains,
251                            size_t *num_chains,
252                            VEC(edge, heap) **cur_cd_chain)
253 {
254   edge_iterator ei;
255   edge e;
256   size_t i;
257   bool found_cd_chain = false;
258   size_t cur_chain_len = 0;
259
260   if (EDGE_COUNT (bb->succs) < 2)
261     return false;
262
263   /* Could  use a set instead.  */
264   cur_chain_len = VEC_length (edge, *cur_cd_chain);
265   if (cur_chain_len > MAX_CHAIN_LEN)
266     return false;
267
268   for (i = 0; i < cur_chain_len; i++)
269     {
270       edge e = VEC_index (edge, *cur_cd_chain, i);
271       /* cycle detected. */
272       if (e->src == bb)
273         return false;
274     }
275
276   FOR_EACH_EDGE (e, ei, bb->succs)
277     {
278       basic_block cd_bb;
279       if (e->flags & (EDGE_FAKE | EDGE_ABNORMAL))
280         continue;
281
282       cd_bb = e->dest;
283       VEC_safe_push (edge, heap, *cur_cd_chain, e);
284       while (!is_non_loop_exit_postdominating (cd_bb, bb))
285         {
286           if (cd_bb == dep_bb)
287             {
288               /* Found a direct control dependence.  */
289               if (*num_chains < MAX_NUM_CHAINS)
290                 {
291                   cd_chains[*num_chains]
292                       = VEC_copy (edge, heap, *cur_cd_chain);
293                   (*num_chains)++;
294                 }
295               found_cd_chain = true;
296               /* check path from next edge.  */
297               break;
298             }
299
300           /* Now check if DEP_BB is indirectly control dependent on BB.  */
301           if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains,
302                                          num_chains, cur_cd_chain))
303             {
304               found_cd_chain = true;
305               break;
306             }
307
308           cd_bb = find_pdom (cd_bb);
309           if (cd_bb == EXIT_BLOCK_PTR)
310             break;
311         }
312       VEC_pop (edge, *cur_cd_chain);
313       gcc_assert (VEC_length (edge, *cur_cd_chain) == cur_chain_len);
314     }
315   gcc_assert (VEC_length (edge, *cur_cd_chain) == cur_chain_len);
316
317   return found_cd_chain;
318 }
319
320 typedef struct use_pred_info
321 {
322   gimple cond;
323   bool invert;
324 } *use_pred_info_t;
325
326 DEF_VEC_P(use_pred_info_t);
327 DEF_VEC_ALLOC_P(use_pred_info_t, heap);
328
329
330 /* Converts the chains of control dependence edges into a set of
331    predicates. A control dependence chain is represented by a vector
332    edges. DEP_CHAINS points to an array of dependence chains.
333    NUM_CHAINS is the size of the chain array. One edge in a dependence
334    chain is mapped to predicate expression represented by use_pred_info_t
335    type. One dependence chain is converted to a composite predicate that
336    is the result of AND operation of use_pred_info_t mapped to each edge.
337    A composite predicate is presented by a vector of use_pred_info_t. On
338    return, *PREDS points to the resulting array of composite predicates.
339    *NUM_PREDS is the number of composite predictes.  */
340
341 static bool
342 convert_control_dep_chain_into_preds (VEC(edge, heap) **dep_chains,
343                                       size_t num_chains,
344                                       VEC(use_pred_info_t, heap) ***preds,
345                                       size_t *num_preds)
346 {
347   bool has_valid_pred = false;
348   size_t i, j;
349   if (num_chains == 0 || num_chains >= MAX_NUM_CHAINS)
350     return false;
351
352   /* Now convert the control dep chain into a set
353      of predicates.  */
354   *preds = XCNEWVEC (VEC(use_pred_info_t, heap) *,
355                      num_chains);
356   *num_preds = num_chains;
357
358   for (i = 0; i < num_chains; i++)
359     {
360       VEC(edge, heap) *one_cd_chain = dep_chains[i];
361
362       has_valid_pred = false;
363       for (j = 0; j < VEC_length (edge, one_cd_chain); j++)
364         {
365           gimple cond_stmt;
366           gimple_stmt_iterator gsi;
367           basic_block guard_bb;
368           use_pred_info_t one_pred;
369           edge e;
370
371           e = VEC_index (edge, one_cd_chain, j);
372           guard_bb = e->src;
373           gsi = gsi_last_bb (guard_bb);
374           if (gsi_end_p (gsi))
375             {
376               has_valid_pred = false;
377               break;
378             }
379           cond_stmt = gsi_stmt (gsi);
380           if (gimple_code (cond_stmt) == GIMPLE_CALL
381               && EDGE_COUNT (e->src->succs) >= 2)
382             {
383               /* Ignore EH edge. Can add assertion
384                  on the other edge's flag.  */
385               continue;
386             }
387           /* Skip if there is essentially one succesor.  */
388           if (EDGE_COUNT (e->src->succs) == 2)
389             {
390               edge e1;
391               edge_iterator ei1;
392               bool skip = false;
393
394               FOR_EACH_EDGE (e1, ei1, e->src->succs)
395                 {
396                   if (EDGE_COUNT (e1->dest->succs) == 0)
397                     {
398                       skip = true;
399                       break;
400                     }
401                 }
402               if (skip)
403                 continue;
404             }
405           if (gimple_code (cond_stmt) != GIMPLE_COND)
406             {
407               has_valid_pred = false;
408               break;
409             }
410           one_pred = XNEW (struct use_pred_info);
411           one_pred->cond = cond_stmt;
412           one_pred->invert = !!(e->flags & EDGE_FALSE_VALUE);
413           VEC_safe_push (use_pred_info_t, heap, (*preds)[i], one_pred);
414           has_valid_pred = true;
415         }
416
417       if (!has_valid_pred)
418         break;
419     }
420   return has_valid_pred;
421 }
422
423 /* Computes all control dependence chains for USE_BB. The control
424    dependence chains are then converted to an array of composite
425    predicates pointed to by PREDS.  PHI_BB is the basic block of
426    the phi whose result is used in USE_BB.  */
427
428 static bool
429 find_predicates (VEC(use_pred_info_t, heap) ***preds,
430                  size_t *num_preds,
431                  basic_block phi_bb,
432                  basic_block use_bb)
433 {
434   size_t num_chains = 0, i;
435   VEC(edge, heap) **dep_chains = 0;
436   VEC(edge, heap) *cur_chain = 0;
437   bool has_valid_pred = false;
438   basic_block cd_root = 0;
439
440   dep_chains = XCNEWVEC (VEC(edge, heap) *, MAX_NUM_CHAINS);
441
442   /* First find the closest bb that is control equivalent to PHI_BB
443      that also dominates USE_BB.  */
444   cd_root = phi_bb;
445   while (dominated_by_p (CDI_DOMINATORS, use_bb, cd_root))
446     {
447       basic_block ctrl_eq_bb = find_control_equiv_block (cd_root);
448       if (ctrl_eq_bb && dominated_by_p (CDI_DOMINATORS, use_bb, ctrl_eq_bb))
449         cd_root = ctrl_eq_bb;
450       else
451         break;
452     }
453
454   compute_control_dep_chain (cd_root, use_bb,
455                              dep_chains, &num_chains,
456                              &cur_chain);
457
458   has_valid_pred
459       = convert_control_dep_chain_into_preds (dep_chains,
460                                               num_chains,
461                                               preds,
462                                               num_preds);
463   /* Free individual chain  */
464   VEC_free (edge, heap, cur_chain);
465   for (i = 0; i < num_chains; i++)
466       VEC_free (edge, heap, dep_chains[i]);
467   free (dep_chains);
468   return has_valid_pred;
469 }
470
471 /* Computes the set of incoming edges of PHI that have non empty
472    definitions of a phi chain.  The collection will be done
473    recursively on operands that are defined by phis. CD_ROOT
474    is the control dependence root. *EDGES holds the result, and
475    VISITED_PHIS is a pointer set for detecting cycles.  */
476
477 static void
478 collect_phi_def_edges (gimple phi, basic_block cd_root,
479                        VEC(edge, heap) **edges,
480                        struct pointer_set_t *visited_phis)
481 {
482   size_t i, n;
483   edge opnd_edge;
484   tree opnd;
485
486   if (pointer_set_insert (visited_phis, phi))
487     return;
488
489   n = gimple_phi_num_args (phi);
490   for (i = 0; i < n; i++)
491     {
492       opnd_edge = gimple_phi_arg_edge (phi, i);
493       opnd = gimple_phi_arg_def (phi, i);
494
495       if (TREE_CODE (opnd) != SSA_NAME)
496         {
497           if (dump_file && (dump_flags & TDF_DETAILS))
498             {
499               fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int)i);
500               print_gimple_stmt (dump_file, phi, 0, 0);
501             }
502           VEC_safe_push (edge, heap, *edges, opnd_edge);
503         }
504       else
505         {
506           gimple def = SSA_NAME_DEF_STMT (opnd);
507
508           if (gimple_code (def) == GIMPLE_PHI
509               && dominated_by_p (CDI_DOMINATORS,
510                                  gimple_bb (def), cd_root))
511             collect_phi_def_edges (def, cd_root, edges,
512                                    visited_phis);
513           else if (!ssa_undefined_value_p (opnd))
514             {
515               if (dump_file && (dump_flags & TDF_DETAILS))
516                 {
517                   fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int)i);
518                   print_gimple_stmt (dump_file, phi, 0, 0);
519                 }
520               VEC_safe_push (edge, heap, *edges, opnd_edge);
521             }
522         }
523     }
524 }
525
526 /* For each use edge of PHI, computes all control dependence chains.
527    The control dependence chains are then converted to an array of
528    composite predicates pointed to by PREDS.  */
529
530 static bool
531 find_def_preds (VEC(use_pred_info_t, heap) ***preds,
532                 size_t *num_preds, gimple phi)
533 {
534   size_t num_chains = 0, i, n;
535   VEC(edge, heap) **dep_chains = 0;
536   VEC(edge, heap) *cur_chain = 0;
537   VEC(edge, heap) *def_edges = 0;
538   bool has_valid_pred = false;
539   basic_block phi_bb, cd_root = 0;
540   struct pointer_set_t *visited_phis;
541
542   dep_chains = XCNEWVEC (VEC(edge, heap) *, MAX_NUM_CHAINS);
543
544   phi_bb = gimple_bb (phi);
545   /* First find the closest dominating bb to be
546      the control dependence root  */
547   cd_root = find_dom (phi_bb);
548   if (!cd_root)
549     return false;
550
551   visited_phis = pointer_set_create ();
552   collect_phi_def_edges (phi, cd_root, &def_edges, visited_phis);
553   pointer_set_destroy (visited_phis);
554
555   n = VEC_length (edge, def_edges);
556   if (n == 0)
557     return false;
558
559   for (i = 0; i < n; i++)
560     {
561       size_t prev_nc, j;
562       edge opnd_edge;
563
564       opnd_edge = VEC_index (edge, def_edges, i);
565       prev_nc = num_chains;
566       compute_control_dep_chain (cd_root, opnd_edge->src,
567                                  dep_chains, &num_chains,
568                                  &cur_chain);
569       /* Free individual chain  */
570       VEC_free (edge, heap, cur_chain);
571       cur_chain = 0;
572
573       /* Now update the newly added chains with
574          the phi operand edge:  */
575       if (EDGE_COUNT (opnd_edge->src->succs) > 1)
576         {
577           if (prev_nc == num_chains
578               && num_chains < MAX_NUM_CHAINS)
579             num_chains++;
580           for (j = prev_nc; j < num_chains; j++)
581             {
582               VEC_safe_push (edge, heap, dep_chains[j], opnd_edge);
583             }
584         }
585     }
586
587   has_valid_pred
588       = convert_control_dep_chain_into_preds (dep_chains,
589                                               num_chains,
590                                               preds,
591                                               num_preds);
592   for (i = 0; i < num_chains; i++)
593       VEC_free (edge, heap, dep_chains[i]);
594   free (dep_chains);
595   return has_valid_pred;
596 }
597
598 /* Dumps the predicates (PREDS) for USESTMT.  */
599
600 static void
601 dump_predicates (gimple usestmt, size_t num_preds,
602                  VEC(use_pred_info_t, heap) **preds,
603                  const char* msg)
604 {
605   size_t i, j;
606   VEC(use_pred_info_t, heap) *one_pred_chain;
607   fprintf (dump_file, msg);
608   print_gimple_stmt (dump_file, usestmt, 0, 0);
609   fprintf (dump_file, "is guarded by :\n");
610   /* do some dumping here:  */
611   for (i = 0; i < num_preds; i++)
612     {
613       size_t np;
614
615       one_pred_chain = preds[i];
616       np = VEC_length (use_pred_info_t, one_pred_chain);
617
618       for (j = 0; j < np; j++)
619         {
620           use_pred_info_t one_pred
621               = VEC_index (use_pred_info_t, one_pred_chain, j);
622           if (one_pred->invert)
623             fprintf (dump_file, " (.NOT.) ");
624           print_gimple_stmt (dump_file, one_pred->cond, 0, 0);
625           if (j < np - 1)
626             fprintf (dump_file, "(.AND.)\n");
627         }
628       if (i < num_preds - 1)
629         fprintf (dump_file, "(.OR.)\n");
630     }
631 }
632
633 /* Destroys the predicate set *PREDS.  */
634
635 static void
636 destroy_predicate_vecs (size_t n,
637                         VEC(use_pred_info_t, heap) ** preds)
638 {
639   size_t i, j;
640   for (i = 0; i < n; i++)
641     {
642       for (j = 0; j < VEC_length (use_pred_info_t, preds[i]); j++)
643         free (VEC_index (use_pred_info_t, preds[i], j));
644       VEC_free (use_pred_info_t, heap, preds[i]);
645     }
646   free (preds);
647 }
648
649
650 /* Computes the 'normalized' conditional code with operand 
651    swapping and condition inversion.  */
652
653 static enum tree_code
654 get_cmp_code (enum tree_code orig_cmp_code,
655               bool swap_cond, bool invert)
656 {
657   enum tree_code tc = orig_cmp_code;
658
659   if (swap_cond)
660     tc = swap_tree_comparison (orig_cmp_code);
661   if (invert)
662     tc = invert_tree_comparison (tc, false);
663
664   switch (tc)
665     {
666     case LT_EXPR:
667     case LE_EXPR:
668     case GT_EXPR:
669     case GE_EXPR:
670     case EQ_EXPR:
671     case NE_EXPR:
672       break;
673     default:
674       return ERROR_MARK;
675     }
676   return tc;
677 }
678
679 /* Returns true if VAL falls in the range defined by BOUNDARY and CMPC, i.e.
680    all values in the range satisfies (x CMPC BOUNDARY) == true.  */
681
682 static bool
683 is_value_included_in (tree val, tree boundary, enum tree_code cmpc)
684 {
685   bool inverted = false;
686   bool is_unsigned;
687   bool result;
688
689   /* Only handle integer constant here.  */
690   if (TREE_CODE (val) != INTEGER_CST
691       || TREE_CODE (boundary) != INTEGER_CST)
692     return true;
693
694   is_unsigned = TYPE_UNSIGNED (TREE_TYPE (val));
695
696   if (cmpc == GE_EXPR || cmpc == GT_EXPR
697       || cmpc == NE_EXPR)
698     {
699       cmpc = invert_tree_comparison (cmpc, false);
700       inverted = true;
701     }
702
703   if (is_unsigned)
704     {
705       if (cmpc == EQ_EXPR)
706         result = tree_int_cst_equal (val, boundary);
707       else if (cmpc == LT_EXPR)
708         result = INT_CST_LT_UNSIGNED (val, boundary);
709       else
710         {
711           gcc_assert (cmpc == LE_EXPR);
712           result = (tree_int_cst_equal (val, boundary)
713                     || INT_CST_LT_UNSIGNED (val, boundary));
714         }
715     }
716   else
717     {
718       if (cmpc == EQ_EXPR)
719         result = tree_int_cst_equal (val, boundary);
720       else if (cmpc == LT_EXPR)
721         result = INT_CST_LT (val, boundary);
722       else
723         {
724           gcc_assert (cmpc == LE_EXPR);
725           result = (tree_int_cst_equal (val, boundary)
726                     || INT_CST_LT (val, boundary));
727         }
728     }
729
730   if (inverted)
731     result ^= 1;
732
733   return result;
734 }
735
736 /* Returns true if PRED is common among all the predicate
737    chains (PREDS) (and therefore can be factored out).
738    NUM_PRED_CHAIN is the size of array PREDS.  */
739
740 static bool
741 find_matching_predicate_in_rest_chains (use_pred_info_t pred,
742                                         VEC(use_pred_info_t, heap) **preds,
743                                         size_t num_pred_chains)
744 {
745   size_t i, j, n;
746
747   /* trival case  */
748   if (num_pred_chains == 1)
749     return true;
750
751   for (i = 1; i < num_pred_chains; i++)
752     {
753       bool found = false;
754       VEC(use_pred_info_t, heap) *one_chain = preds[i];
755       n = VEC_length (use_pred_info_t, one_chain);
756       for (j = 0; j < n; j++)
757         {
758           use_pred_info_t pred2
759               = VEC_index (use_pred_info_t, one_chain, j);
760           /* can relax the condition comparison to not
761              use address comparison. However, the most common
762              case is that multiple control dependent paths share
763              a common path prefix, so address comparison should
764              be ok.  */
765
766           if (pred2->cond == pred->cond
767               && pred2->invert == pred->invert)
768             {
769               found = true;
770               break;
771             }
772         }
773       if (!found)
774         return false;
775     }
776   return true;
777 }
778
779 /* Forward declaration.  */
780 static bool
781 is_use_properly_guarded (gimple use_stmt,
782                          basic_block use_bb,
783                          gimple phi,
784                          unsigned uninit_opnds,
785                          struct pointer_set_t *visited_phis);
786
787 /* Returns true if all uninitialized opnds are pruned. Returns false
788    otherwise. PHI is the phi node with uninitialized operands,
789    UNINIT_OPNDS is the bitmap of the uninitialize operand positions,
790    FLAG_DEF is the statement defining the flag guarding the use of the
791    PHI output, BOUNDARY_CST is the const value used in the predicate
792    associated with the flag, CMP_CODE is the comparison code used in
793    the predicate, VISITED_PHIS is the pointer set of phis visited, and
794    VISITED_FLAG_PHIS is the pointer to the pointer set of flag definitions
795    that are also phis.
796
797    Example scenario:
798
799    BB1:
800    flag_1 = phi <0, 1>                  // (1)
801    var_1  = phi <undef, some_val>
802
803
804    BB2:
805    flag_2 = phi <0,   flag_1, flag_1>   // (2)
806    var_2  = phi <undef, var_1, var_1>
807    if (flag_2 == 1)
808       goto BB3;
809
810    BB3:
811    use of var_2                         // (3)
812
813    Because some flag arg in (1) is not constant, if we do not look into the
814    flag phis recursively, it is conservatively treated as unknown and var_1
815    is thought to be flowed into use at (3). Since var_1 is potentially uninitialized
816    a false warning will be emitted. Checking recursively into (1), the compiler can
817    find out that only some_val (which is defined) can flow into (3) which is OK.
818
819 */
820
821 static bool
822 prune_uninit_phi_opnds_in_unrealizable_paths (
823     gimple phi, unsigned uninit_opnds,
824     gimple flag_def, tree boundary_cst,
825     enum tree_code cmp_code,
826     struct pointer_set_t *visited_phis,
827     bitmap *visited_flag_phis)
828 {
829   unsigned i;
830
831   for (i = 0; i < MIN (32, gimple_phi_num_args (flag_def)); i++)
832     {
833       tree flag_arg;
834
835       if (!MASK_TEST_BIT (uninit_opnds, i))
836         continue;
837
838       flag_arg = gimple_phi_arg_def (flag_def, i);
839       if (!is_gimple_constant (flag_arg))
840         {
841           gimple flag_arg_def, phi_arg_def;
842           tree phi_arg;
843           unsigned uninit_opnds_arg_phi;
844
845           if (TREE_CODE (flag_arg) != SSA_NAME)
846             return false;
847           flag_arg_def = SSA_NAME_DEF_STMT (flag_arg);
848           if (gimple_code (flag_arg_def) != GIMPLE_PHI)
849             return false;
850
851           phi_arg = gimple_phi_arg_def (phi, i);
852           if (TREE_CODE (phi_arg) != SSA_NAME)
853             return false;
854
855           phi_arg_def = SSA_NAME_DEF_STMT (phi_arg);
856           if (gimple_code (phi_arg_def) != GIMPLE_PHI)
857             return false;
858
859           if (gimple_bb (phi_arg_def) != gimple_bb (flag_arg_def))
860             return false;
861
862           if (!*visited_flag_phis)
863             *visited_flag_phis = BITMAP_ALLOC (NULL);
864
865           if (bitmap_bit_p (*visited_flag_phis,
866                             SSA_NAME_VERSION (gimple_phi_result (flag_arg_def))))
867             return false;
868
869           bitmap_set_bit (*visited_flag_phis,
870                           SSA_NAME_VERSION (gimple_phi_result (flag_arg_def)));
871
872           /* Now recursively prune the uninitialized phi args.  */
873           uninit_opnds_arg_phi = compute_uninit_opnds_pos (phi_arg_def);
874           if (!prune_uninit_phi_opnds_in_unrealizable_paths (
875                   phi_arg_def, uninit_opnds_arg_phi,
876                   flag_arg_def, boundary_cst, cmp_code,
877                   visited_phis, visited_flag_phis))
878             return false;
879
880           bitmap_clear_bit (*visited_flag_phis,
881                             SSA_NAME_VERSION (gimple_phi_result (flag_arg_def)));
882           continue;
883         }
884
885       /* Now check if the constant is in the guarded range.  */
886       if (is_value_included_in (flag_arg, boundary_cst, cmp_code))
887         {
888           tree opnd;
889           gimple opnd_def;
890
891           /* Now that we know that this undefined edge is not
892              pruned. If the operand is defined by another phi,
893              we can further prune the incoming edges of that
894              phi by checking the predicates of this operands.  */
895
896           opnd = gimple_phi_arg_def (phi, i);
897           opnd_def = SSA_NAME_DEF_STMT (opnd);
898           if (gimple_code (opnd_def) == GIMPLE_PHI)
899             {
900               edge opnd_edge;
901               unsigned uninit_opnds2
902                   = compute_uninit_opnds_pos (opnd_def);
903               gcc_assert (!MASK_EMPTY (uninit_opnds2));
904               opnd_edge = gimple_phi_arg_edge (phi, i);
905               if (!is_use_properly_guarded (phi,
906                                             opnd_edge->src,
907                                             opnd_def,
908                                             uninit_opnds2,
909                                             visited_phis))
910                   return false;
911             }
912           else
913             return false;
914         }
915     }
916
917   return true;
918 }
919
920 /* A helper function that determines if the predicate set
921    of the use is not overlapping with that of the uninit paths.
922    The most common senario of guarded use is in Example 1:
923      Example 1:
924            if (some_cond)
925            {
926               x = ...;
927               flag = true;
928            }
929
930             ... some code ...
931
932            if (flag)
933               use (x);
934
935      The real world examples are usually more complicated, but similar
936      and usually result from inlining:
937
938          bool init_func (int * x)
939          {
940              if (some_cond)
941                 return false;
942              *x  =  ..
943              return true;
944          }
945
946          void foo(..)
947          {
948              int x;
949
950              if (!init_func(&x))
951                 return;
952
953              .. some_code ...
954              use (x);
955          }
956
957      Another possible use scenario is in the following trivial example:
958
959      Example 2:
960           if (n > 0)
961              x = 1;
962           ...
963           if (n > 0)
964             {
965               if (m < 2)
966                  .. = x;
967             }
968
969      Predicate analysis needs to compute the composite predicate:
970
971        1) 'x' use predicate: (n > 0) .AND. (m < 2)
972        2) 'x' default value  (non-def) predicate: .NOT. (n > 0)
973        (the predicate chain for phi operand defs can be computed
974        starting from a bb that is control equivalent to the phi's
975        bb and is dominating the operand def.)
976
977        and check overlapping:
978           (n > 0) .AND. (m < 2) .AND. (.NOT. (n > 0))
979         <==> false
980
981      This implementation provides framework that can handle
982      scenarios. (Note that many simple cases are handled properly
983      without the predicate analysis -- this is due to jump threading
984      transformation which eliminates the merge point thus makes
985      path sensitive analysis unnecessary.)
986
987      NUM_PREDS is the number is the number predicate chains, PREDS is
988      the array of chains, PHI is the phi node whose incoming (undefined)
989      paths need to be pruned, and UNINIT_OPNDS is the bitmap holding
990      uninit operand positions. VISITED_PHIS is the pointer set of phi
991      stmts being checked.  */
992
993
994 static bool
995 use_pred_not_overlap_with_undef_path_pred (
996     size_t num_preds,
997     VEC(use_pred_info_t, heap) **preds,
998     gimple phi, unsigned uninit_opnds,
999     struct pointer_set_t *visited_phis)
1000 {
1001   unsigned int i, n;
1002   gimple flag_def = 0;
1003   tree  boundary_cst = 0;
1004   enum tree_code cmp_code;
1005   bool swap_cond = false;
1006   bool invert = false;
1007   VEC(use_pred_info_t, heap) *the_pred_chain;
1008   bitmap visited_flag_phis = NULL;
1009   bool all_pruned = false;
1010
1011   gcc_assert (num_preds > 0);
1012   /* Find within the common prefix of multiple predicate chains
1013      a predicate that is a comparison of a flag variable against
1014      a constant.  */
1015   the_pred_chain = preds[0];
1016   n = VEC_length (use_pred_info_t, the_pred_chain);
1017   for (i = 0; i < n; i++)
1018     {
1019       gimple cond;
1020       tree cond_lhs, cond_rhs, flag = 0;
1021
1022       use_pred_info_t the_pred
1023           = VEC_index (use_pred_info_t, the_pred_chain, i);
1024
1025       cond = the_pred->cond;
1026       invert = the_pred->invert;
1027       cond_lhs = gimple_cond_lhs (cond);
1028       cond_rhs = gimple_cond_rhs (cond);
1029       cmp_code = gimple_cond_code (cond);
1030
1031       if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME
1032           && cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs))
1033         {
1034           boundary_cst = cond_rhs;
1035           flag = cond_lhs;
1036         }
1037       else if (cond_rhs != NULL_TREE && TREE_CODE (cond_rhs) == SSA_NAME
1038                && cond_lhs != NULL_TREE && is_gimple_constant (cond_lhs))
1039         {
1040           boundary_cst = cond_lhs;
1041           flag = cond_rhs;
1042           swap_cond = true;
1043         }
1044
1045       if (!flag)
1046         continue;
1047
1048       flag_def = SSA_NAME_DEF_STMT (flag);
1049
1050       if (!flag_def)
1051         continue;
1052
1053       if ((gimple_code (flag_def) == GIMPLE_PHI)
1054           && (gimple_bb (flag_def) == gimple_bb (phi))
1055           && find_matching_predicate_in_rest_chains (
1056               the_pred, preds, num_preds))
1057         break;
1058
1059       flag_def = 0;
1060     }
1061
1062   if (!flag_def)
1063     return false;
1064
1065   /* Now check all the uninit incoming edge has a constant flag value
1066      that is in conflict with the use guard/predicate.  */
1067   cmp_code = get_cmp_code (cmp_code, swap_cond, invert);
1068
1069   if (cmp_code == ERROR_MARK)
1070     return false;
1071
1072   all_pruned = prune_uninit_phi_opnds_in_unrealizable_paths (phi,
1073                                                              uninit_opnds,
1074                                                              flag_def,
1075                                                              boundary_cst,
1076                                                              cmp_code,
1077                                                              visited_phis,
1078                                                              &visited_flag_phis);
1079
1080   if (visited_flag_phis)
1081     BITMAP_FREE (visited_flag_phis);
1082
1083   return all_pruned;
1084 }
1085
1086 /* Returns true if TC is AND or OR */
1087
1088 static inline bool
1089 is_and_or_or (enum tree_code tc, tree typ)
1090 {
1091   return (tc == TRUTH_AND_EXPR
1092           || tc == TRUTH_OR_EXPR
1093           || tc == BIT_IOR_EXPR
1094           || (tc == BIT_AND_EXPR
1095               && (typ == 0 || TREE_CODE (typ) == BOOLEAN_TYPE)));
1096 }
1097
1098 typedef struct norm_cond
1099 {
1100   VEC(gimple, heap) *conds;
1101   enum tree_code cond_code;
1102   bool invert;
1103 } *norm_cond_t;
1104
1105
1106 /* Normalizes gimple condition COND. The normalization follows
1107    UD chains to form larger condition expression trees. NORM_COND
1108    holds the normalized result. COND_CODE is the logical opcode
1109    (AND or OR) of the normalized tree.  */
1110
1111 static void
1112 normalize_cond_1 (gimple cond,
1113                   norm_cond_t norm_cond,
1114                   enum tree_code cond_code)
1115 {
1116   enum gimple_code gc;
1117   enum tree_code cur_cond_code;
1118   tree rhs1, rhs2;
1119
1120   gc = gimple_code (cond);
1121   if (gc != GIMPLE_ASSIGN)
1122     {
1123       VEC_safe_push (gimple, heap, norm_cond->conds, cond);
1124       return;
1125     }
1126
1127   cur_cond_code = gimple_assign_rhs_code (cond);
1128   rhs1 = gimple_assign_rhs1 (cond);
1129   rhs2 = gimple_assign_rhs2 (cond);
1130   if (cur_cond_code == NE_EXPR)
1131     {
1132       if (integer_zerop (rhs2)
1133           && (TREE_CODE (rhs1) == SSA_NAME))
1134         normalize_cond_1 (
1135             SSA_NAME_DEF_STMT (rhs1),
1136             norm_cond, cond_code);
1137       else if (integer_zerop (rhs1)
1138                && (TREE_CODE (rhs2) == SSA_NAME))
1139         normalize_cond_1 (
1140             SSA_NAME_DEF_STMT (rhs2),
1141             norm_cond, cond_code);
1142       else
1143         VEC_safe_push (gimple, heap, norm_cond->conds, cond);
1144
1145       return;
1146     }
1147
1148   if (is_and_or_or (cur_cond_code, TREE_TYPE (rhs1))
1149       && (cond_code == cur_cond_code || cond_code == ERROR_MARK)
1150       && (TREE_CODE (rhs1) == SSA_NAME && TREE_CODE (rhs2) == SSA_NAME))
1151     {
1152       normalize_cond_1 (SSA_NAME_DEF_STMT (rhs1),
1153                         norm_cond, cur_cond_code);
1154       normalize_cond_1 (SSA_NAME_DEF_STMT (rhs2),
1155                         norm_cond, cur_cond_code);
1156       norm_cond->cond_code = cur_cond_code;
1157     }
1158   else
1159     VEC_safe_push (gimple, heap, norm_cond->conds, cond);
1160 }
1161
1162 /* See normalize_cond_1 for details. INVERT is a flag to indicate
1163    if COND needs to be inverted or not.  */
1164
1165 static void
1166 normalize_cond (gimple cond, norm_cond_t norm_cond, bool invert)
1167 {
1168   enum tree_code cond_code;
1169
1170   norm_cond->cond_code = ERROR_MARK;
1171   norm_cond->invert = false;
1172   norm_cond->conds = NULL;
1173   gcc_assert (gimple_code (cond) == GIMPLE_COND);
1174   cond_code = gimple_cond_code (cond);
1175   if (invert)
1176     cond_code = invert_tree_comparison (cond_code, false);
1177
1178   if (cond_code == NE_EXPR)
1179     {
1180       if (integer_zerop (gimple_cond_rhs (cond))
1181           && (TREE_CODE (gimple_cond_lhs (cond)) == SSA_NAME))
1182         normalize_cond_1 (
1183             SSA_NAME_DEF_STMT (gimple_cond_lhs (cond)),
1184             norm_cond, ERROR_MARK);
1185       else if (integer_zerop (gimple_cond_lhs (cond))
1186                && (TREE_CODE (gimple_cond_rhs (cond)) == SSA_NAME))
1187         normalize_cond_1 (
1188             SSA_NAME_DEF_STMT (gimple_cond_rhs (cond)),
1189             norm_cond, ERROR_MARK);
1190       else
1191         {
1192           VEC_safe_push (gimple, heap, norm_cond->conds, cond);
1193           norm_cond->invert = invert;
1194         }
1195     }
1196   else
1197     {
1198       VEC_safe_push (gimple, heap, norm_cond->conds, cond);
1199       norm_cond->invert = invert;
1200     }
1201
1202   gcc_assert (VEC_length (gimple, norm_cond->conds) == 1
1203               || is_and_or_or (norm_cond->cond_code, NULL));
1204 }
1205
1206 /* Returns true if the domain for condition COND1 is a subset of
1207    COND2. REVERSE is a flag. when it is true the function checks
1208    if COND1 is a superset of COND2. INVERT1 and INVERT2 are flags
1209    to indicate if COND1 and COND2 need to be inverted or not.  */
1210
1211 static bool
1212 is_gcond_subset_of (gimple cond1, bool invert1,
1213                     gimple cond2, bool invert2,
1214                     bool reverse)
1215 {
1216   enum gimple_code gc1, gc2;
1217   enum tree_code cond1_code, cond2_code;
1218   gimple tmp;
1219   tree cond1_lhs, cond1_rhs, cond2_lhs, cond2_rhs;
1220
1221   /* Take the short cut.  */
1222   if (cond1 == cond2)
1223     return true;
1224
1225   if (reverse)
1226     {
1227       tmp = cond1;
1228       cond1 = cond2;
1229       cond2 = tmp;
1230     }
1231
1232   gc1 = gimple_code (cond1);
1233   gc2 = gimple_code (cond2);
1234
1235   if ((gc1 != GIMPLE_ASSIGN && gc1 != GIMPLE_COND)
1236       || (gc2 != GIMPLE_ASSIGN && gc2 != GIMPLE_COND))
1237     return cond1 == cond2;
1238
1239   cond1_code = ((gc1 == GIMPLE_ASSIGN)
1240                 ? gimple_assign_rhs_code (cond1)
1241                 : gimple_cond_code (cond1));
1242
1243   cond2_code = ((gc2 == GIMPLE_ASSIGN)
1244                 ? gimple_assign_rhs_code (cond2)
1245                 : gimple_cond_code (cond2));
1246
1247   if (TREE_CODE_CLASS (cond1_code) != tcc_comparison
1248       || TREE_CODE_CLASS (cond2_code) != tcc_comparison)
1249     return false;
1250
1251   if (invert1)
1252     cond1_code = invert_tree_comparison (cond1_code, false);
1253   if (invert2)
1254     cond2_code = invert_tree_comparison (cond2_code, false);
1255
1256   cond1_lhs = ((gc1 == GIMPLE_ASSIGN)
1257                ? gimple_assign_rhs1 (cond1)
1258                : gimple_cond_lhs (cond1));
1259   cond1_rhs = ((gc1 == GIMPLE_ASSIGN)
1260                ? gimple_assign_rhs2 (cond1)
1261                : gimple_cond_rhs (cond1));
1262   cond2_lhs = ((gc2 == GIMPLE_ASSIGN)
1263                ? gimple_assign_rhs1 (cond2)
1264                : gimple_cond_lhs (cond2));
1265   cond2_rhs = ((gc2 == GIMPLE_ASSIGN)
1266                ? gimple_assign_rhs2 (cond2)
1267                : gimple_cond_rhs (cond2));
1268
1269   /* Assuming const operands have been swapped to the
1270      rhs at this point of the analysis.  */
1271
1272   if (cond1_lhs != cond2_lhs)
1273     return false;
1274
1275   if (!is_gimple_constant (cond1_rhs)
1276       || TREE_CODE (cond1_rhs) != INTEGER_CST)
1277     return (cond1_rhs == cond2_rhs);
1278
1279   if (!is_gimple_constant (cond2_rhs)
1280       || TREE_CODE (cond2_rhs) != INTEGER_CST)
1281     return (cond1_rhs == cond2_rhs);
1282
1283   if (cond1_code == EQ_EXPR)
1284     return is_value_included_in (cond1_rhs,
1285                                  cond2_rhs, cond2_code);
1286   if (cond1_code == NE_EXPR || cond2_code == EQ_EXPR)
1287     return ((cond2_code == cond1_code)
1288             && tree_int_cst_equal (cond1_rhs, cond2_rhs));
1289
1290   if (((cond1_code == GE_EXPR || cond1_code == GT_EXPR)
1291        && (cond2_code == LE_EXPR || cond2_code == LT_EXPR))
1292       || ((cond1_code == LE_EXPR || cond1_code == LT_EXPR)
1293           && (cond2_code == GE_EXPR || cond2_code == GT_EXPR)))
1294     return false;
1295
1296   if (cond1_code != GE_EXPR && cond1_code != GT_EXPR
1297       && cond1_code != LE_EXPR && cond1_code != LT_EXPR)
1298     return false;
1299
1300   if (cond1_code == GT_EXPR)
1301     {
1302       cond1_code = GE_EXPR;
1303       cond1_rhs = fold_binary (PLUS_EXPR, TREE_TYPE (cond1_rhs),
1304                                cond1_rhs,
1305                                fold_convert (TREE_TYPE (cond1_rhs),
1306                                              integer_one_node));
1307     }
1308   else if (cond1_code == LT_EXPR)
1309     {
1310       cond1_code = LE_EXPR;
1311       cond1_rhs = fold_binary (MINUS_EXPR, TREE_TYPE (cond1_rhs),
1312                                cond1_rhs,
1313                                fold_convert (TREE_TYPE (cond1_rhs),
1314                                              integer_one_node));
1315     }
1316
1317   if (!cond1_rhs)
1318     return false;
1319
1320   gcc_assert (cond1_code == GE_EXPR || cond1_code == LE_EXPR);
1321
1322   if (cond2_code == GE_EXPR || cond2_code == GT_EXPR ||
1323       cond2_code == LE_EXPR || cond2_code == LT_EXPR)
1324     return is_value_included_in (cond1_rhs,
1325                                  cond2_rhs, cond2_code);
1326   else if (cond2_code == NE_EXPR)
1327     return
1328         (is_value_included_in (cond1_rhs,
1329                                cond2_rhs, cond2_code)
1330          && !is_value_included_in (cond2_rhs,
1331                                    cond1_rhs, cond1_code));
1332   return false;
1333 }
1334
1335 /* Returns true if the domain of the condition expression 
1336    in COND is a subset of any of the sub-conditions
1337    of the normalized condtion NORM_COND.  INVERT is a flag
1338    to indicate of the COND needs to be inverted.
1339    REVERSE is a flag. When it is true, the check is reversed --
1340    it returns true if COND is a superset of any of the subconditions
1341    of NORM_COND.  */
1342
1343 static bool
1344 is_subset_of_any (gimple cond, bool invert,
1345                   norm_cond_t norm_cond, bool reverse)
1346 {
1347   size_t i;
1348   size_t len = VEC_length (gimple, norm_cond->conds);
1349
1350   for (i = 0; i < len; i++)
1351     {
1352       if (is_gcond_subset_of (cond, invert,
1353                               VEC_index (gimple, norm_cond->conds, i),
1354                               false, reverse))
1355         return true;
1356     }
1357   return false;
1358 }
1359
1360 /* NORM_COND1 and NORM_COND2 are normalized logical/BIT OR
1361    expressions (formed by following UD chains not control
1362    dependence chains). The function returns true of domain
1363    of and expression NORM_COND1 is a subset of NORM_COND2's.
1364    The implementation is conservative, and it returns false if
1365    it the inclusion relationship may not hold.  */
1366
1367 static bool
1368 is_or_set_subset_of (norm_cond_t norm_cond1,
1369                      norm_cond_t norm_cond2)
1370 {
1371   size_t i;
1372   size_t len = VEC_length (gimple, norm_cond1->conds);
1373
1374   for (i = 0; i < len; i++)
1375     {
1376       if (!is_subset_of_any (VEC_index (gimple, norm_cond1->conds, i),
1377                              false, norm_cond2, false))
1378         return false;
1379     }
1380   return true;
1381 }
1382
1383 /* NORM_COND1 and NORM_COND2 are normalized logical AND
1384    expressions (formed by following UD chains not control
1385    dependence chains). The function returns true of domain
1386    of and expression NORM_COND1 is a subset of NORM_COND2's.  */
1387
1388 static bool
1389 is_and_set_subset_of (norm_cond_t norm_cond1,
1390                       norm_cond_t norm_cond2)
1391 {
1392   size_t i;
1393   size_t len = VEC_length (gimple, norm_cond2->conds);
1394
1395   for (i = 0; i < len; i++)
1396     {
1397       if (!is_subset_of_any (VEC_index (gimple, norm_cond2->conds, i),
1398                              false, norm_cond1, true))
1399         return false;
1400     }
1401   return true;
1402 }
1403
1404 /* Returns true of the domain if NORM_COND1 is a subset 
1405    of that of NORM_COND2. Returns false if it can not be 
1406    proved to be so.  */
1407
1408 static bool
1409 is_norm_cond_subset_of (norm_cond_t norm_cond1,
1410                         norm_cond_t norm_cond2)
1411 {
1412   size_t i;
1413   enum tree_code code1, code2;
1414
1415   code1 = norm_cond1->cond_code;
1416   code2 = norm_cond2->cond_code;
1417
1418   if (code1 == TRUTH_AND_EXPR || code1 == BIT_AND_EXPR)
1419     {
1420       /* Both conditions are AND expressions.  */
1421       if (code2 == TRUTH_AND_EXPR || code2 == BIT_AND_EXPR)
1422         return is_and_set_subset_of (norm_cond1, norm_cond2);
1423       /* NORM_COND1 is an AND expression, and NORM_COND2 is an OR
1424          expression. In this case, returns true if any subexpression
1425          of NORM_COND1 is a subset of any subexpression of NORM_COND2.  */
1426       else if (code2 == TRUTH_OR_EXPR || code2 == BIT_IOR_EXPR)
1427         {
1428           size_t len1;
1429           len1 = VEC_length (gimple, norm_cond1->conds);
1430           for (i = 0; i < len1; i++)
1431             {
1432               gimple cond1 = VEC_index (gimple, norm_cond1->conds, i);
1433               if (is_subset_of_any (cond1, false, norm_cond2, false))
1434                 return true;
1435             }
1436           return false;
1437         }
1438       else
1439         {
1440           gcc_assert (code2 == ERROR_MARK);
1441           gcc_assert (VEC_length (gimple, norm_cond2->conds) == 1);
1442           return is_subset_of_any (VEC_index (gimple, norm_cond2->conds, 0),
1443                                    norm_cond2->invert, norm_cond1, true);
1444         }
1445     }
1446   /* NORM_COND1 is an OR expression  */
1447   else if (code1 == TRUTH_OR_EXPR || code1 == BIT_IOR_EXPR)
1448     {
1449       if (code2 != code1)
1450         return false;
1451
1452       return is_or_set_subset_of (norm_cond1, norm_cond2);
1453     }
1454   else
1455     {
1456       gcc_assert (code1 == ERROR_MARK);
1457       gcc_assert (VEC_length (gimple, norm_cond1->conds) == 1);
1458       /* Conservatively returns false if NORM_COND1 is non-decomposible
1459          and NORM_COND2 is an AND expression.  */
1460       if (code2 == TRUTH_AND_EXPR || code2 == BIT_AND_EXPR)
1461         return false;
1462
1463       if (code2 == TRUTH_OR_EXPR || code2 == BIT_IOR_EXPR)
1464         return is_subset_of_any (VEC_index (gimple, norm_cond1->conds, 0),
1465                                  norm_cond1->invert, norm_cond2, false);
1466
1467       gcc_assert (code2 == ERROR_MARK);
1468       gcc_assert (VEC_length (gimple, norm_cond2->conds) == 1);
1469       return is_gcond_subset_of (VEC_index (gimple, norm_cond1->conds, 0),
1470                                  norm_cond1->invert,
1471                                  VEC_index (gimple, norm_cond2->conds, 0),
1472                                  norm_cond2->invert, false);
1473     }
1474 }
1475
1476 /* Returns true of the domain of single predicate expression
1477    EXPR1 is a subset of that of EXPR2. Returns false if it
1478    can not be proved.  */
1479
1480 static bool
1481 is_pred_expr_subset_of (use_pred_info_t expr1,
1482                         use_pred_info_t expr2)
1483 {
1484   gimple cond1, cond2;
1485   enum tree_code code1, code2;
1486   struct norm_cond norm_cond1, norm_cond2;
1487   bool is_subset = false;
1488
1489   cond1 = expr1->cond;
1490   cond2 = expr2->cond;
1491   code1 = gimple_cond_code (cond1);
1492   code2 = gimple_cond_code (cond2);
1493
1494   if (expr1->invert)
1495     code1 = invert_tree_comparison (code1, false);
1496   if (expr2->invert)
1497     code2 = invert_tree_comparison (code2, false);
1498
1499   /* Fast path -- match exactly  */
1500   if ((gimple_cond_lhs (cond1) == gimple_cond_lhs (cond2))
1501       && (gimple_cond_rhs (cond1) == gimple_cond_rhs (cond2))
1502       && (code1 == code2))
1503     return true;
1504
1505   /* Normalize conditions. To keep NE_EXPR, do not invert
1506      with both need inversion.  */
1507   normalize_cond (cond1, &norm_cond1, (expr1->invert));
1508   normalize_cond (cond2, &norm_cond2, (expr2->invert));
1509
1510   is_subset = is_norm_cond_subset_of (&norm_cond1, &norm_cond2);
1511
1512   /* Free memory  */
1513   VEC_free (gimple, heap, norm_cond1.conds);
1514   VEC_free (gimple, heap, norm_cond2.conds);
1515   return is_subset ;
1516 }
1517
1518 /* Returns true if the domain of PRED1 is a subset
1519    of that of PRED2. Returns false if it can not be proved so.  */
1520
1521 static bool
1522 is_pred_chain_subset_of (VEC(use_pred_info_t, heap) *pred1,
1523                          VEC(use_pred_info_t, heap) *pred2)
1524 {
1525   size_t np1, np2, i1, i2;
1526
1527   np1 = VEC_length (use_pred_info_t, pred1);
1528   np2 = VEC_length (use_pred_info_t, pred2);
1529
1530   for (i2 = 0; i2 < np2; i2++)
1531     {
1532       bool found = false;
1533       use_pred_info_t info2
1534           = VEC_index (use_pred_info_t, pred2, i2);
1535       for (i1 = 0; i1 < np1; i1++)
1536         {
1537           use_pred_info_t info1
1538               = VEC_index (use_pred_info_t, pred1, i1);
1539           if (is_pred_expr_subset_of (info1, info2))
1540             {
1541               found = true;
1542               break;
1543             }
1544         }
1545       if (!found)
1546         return false;
1547     }
1548   return true;
1549 }
1550
1551 /* Returns true if the domain defined by
1552    one pred chain ONE_PRED is a subset of the domain
1553    of *PREDS. It returns false if ONE_PRED's domain is
1554    not a subset of any of the sub-domains of PREDS (
1555    corresponding to each individual chains in it), even
1556    though it may be still be a subset of whole domain
1557    of PREDS which is the union (ORed) of all its subdomains.
1558    In other words, the result is conservative.  */
1559
1560 static bool
1561 is_included_in (VEC(use_pred_info_t, heap) *one_pred,
1562                 VEC(use_pred_info_t, heap) **preds,
1563                 size_t n)
1564 {
1565   size_t i;
1566
1567   for (i = 0; i < n; i++)
1568     {
1569       if (is_pred_chain_subset_of (one_pred, preds[i]))
1570         return true;
1571     }
1572
1573   return false;
1574 }
1575
1576 /* compares two predicate sets PREDS1 and PREDS2 and returns
1577    true if the domain defined by PREDS1 is a superset
1578    of PREDS2's domain. N1 and N2 are array sizes of PREDS1 and
1579    PREDS2 respectively. The implementation chooses not to build
1580    generic trees (and relying on the folding capability of the
1581    compiler), but instead performs brute force comparison of
1582    individual predicate chains (won't be a compile time problem
1583    as the chains are pretty short). When the function returns
1584    false, it does not necessarily mean *PREDS1 is not a superset
1585    of *PREDS2, but mean it may not be so since the analysis can
1586    not prove it. In such cases, false warnings may still be
1587    emitted.  */
1588
1589 static bool
1590 is_superset_of (VEC(use_pred_info_t, heap) **preds1,
1591                 size_t n1,
1592                 VEC(use_pred_info_t, heap) **preds2,
1593                 size_t n2)
1594 {
1595   size_t i;
1596   VEC(use_pred_info_t, heap) *one_pred_chain;
1597
1598   for (i = 0; i < n2; i++)
1599     {
1600       one_pred_chain = preds2[i];
1601       if (!is_included_in (one_pred_chain, preds1, n1))
1602         return false;
1603     }
1604
1605   return true;
1606 }
1607
1608 /* Comparison function used by qsort. It is used to
1609    sort predicate chains to allow predicate
1610    simplification.  */
1611
1612 static int
1613 pred_chain_length_cmp (const void *p1, const void *p2)
1614 {
1615   use_pred_info_t i1, i2;
1616   VEC(use_pred_info_t, heap) * const *chain1
1617       = (VEC(use_pred_info_t, heap) * const *)p1;
1618   VEC(use_pred_info_t, heap) * const *chain2
1619       = (VEC(use_pred_info_t, heap) * const *)p2;
1620
1621   if (VEC_length (use_pred_info_t, *chain1)
1622       != VEC_length (use_pred_info_t, *chain2))
1623     return (VEC_length (use_pred_info_t, *chain1)
1624             - VEC_length (use_pred_info_t, *chain2));
1625
1626   i1 = VEC_index (use_pred_info_t, *chain1, 0);
1627   i2 = VEC_index (use_pred_info_t, *chain2, 0);
1628
1629   /* Allow predicates with similar prefix come together.  */
1630   if (!i1->invert && i2->invert)
1631     return -1;
1632   else if (i1->invert && !i2->invert)
1633     return 1;
1634
1635   return gimple_uid (i1->cond) - gimple_uid (i2->cond);
1636 }
1637
1638 /* x OR (!x AND y) is equivalent to x OR y.
1639    This function normalizes x1 OR (!x1 AND x2) OR (!x1 AND !x2 AND x3)
1640    into x1 OR x2 OR x3.  PREDS is the predicate chains, and N is
1641    the number of chains. Returns true if normalization happens.  */
1642
1643 static bool
1644 normalize_preds (VEC(use_pred_info_t, heap) **preds, size_t *n)
1645 {
1646   size_t i, j, ll;
1647   VEC(use_pred_info_t, heap) *pred_chain;
1648   VEC(use_pred_info_t, heap) *x = 0;
1649   use_pred_info_t xj = 0, nxj = 0;
1650
1651   if (*n < 2)
1652     return false;
1653
1654   /* First sort the chains in ascending order of lengths.  */
1655   qsort (preds, *n, sizeof (void *), pred_chain_length_cmp);
1656   pred_chain = preds[0];
1657   ll = VEC_length (use_pred_info_t, pred_chain);
1658   if (ll != 1)
1659    {
1660      if (ll == 2)
1661        {
1662          use_pred_info_t xx, yy, xx2, nyy;
1663          VEC(use_pred_info_t, heap) *pred_chain2 = preds[1];
1664          if (VEC_length (use_pred_info_t, pred_chain2) != 2)
1665            return false;
1666
1667          /* See if simplification x AND y OR x AND !y is possible.  */
1668          xx = VEC_index (use_pred_info_t, pred_chain, 0);
1669          yy = VEC_index (use_pred_info_t, pred_chain, 1);
1670          xx2 = VEC_index (use_pred_info_t, pred_chain2, 0);
1671          nyy = VEC_index (use_pred_info_t, pred_chain2, 1);
1672          if (gimple_cond_lhs (xx->cond) != gimple_cond_lhs (xx2->cond)
1673              || gimple_cond_rhs (xx->cond) != gimple_cond_rhs (xx2->cond)
1674              || gimple_cond_code (xx->cond) != gimple_cond_code (xx2->cond)
1675              || (xx->invert != xx2->invert))
1676            return false;
1677          if (gimple_cond_lhs (yy->cond) != gimple_cond_lhs (nyy->cond)
1678              || gimple_cond_rhs (yy->cond) != gimple_cond_rhs (nyy->cond)
1679              || gimple_cond_code (yy->cond) != gimple_cond_code (nyy->cond)
1680              || (yy->invert == nyy->invert))
1681            return false;
1682
1683          /* Now merge the first two chains.  */
1684          free (yy);
1685          free (nyy);
1686          free (xx2);
1687          VEC_free (use_pred_info_t, heap, pred_chain);
1688          VEC_free (use_pred_info_t, heap, pred_chain2);
1689          pred_chain = 0;
1690          VEC_safe_push (use_pred_info_t, heap, pred_chain, xx);
1691          preds[0] = pred_chain;
1692          for (i = 1; i < *n - 1; i++)
1693            preds[i] = preds[i + 1];
1694
1695          preds[*n - 1] = 0;
1696          *n = *n - 1;
1697        }
1698      else
1699        return false;
1700    }
1701
1702   VEC_safe_push (use_pred_info_t, heap, x,
1703                  VEC_index (use_pred_info_t, pred_chain, 0));
1704
1705   /* The loop extracts x1, x2, x3, etc from chains
1706      x1 OR (!x1 AND x2) OR (!x1 AND !x2 AND x3) OR ...  */
1707   for (i = 1; i < *n; i++)
1708     {
1709       pred_chain = preds[i];
1710       if (VEC_length (use_pred_info_t, pred_chain) != i + 1)
1711         return false;
1712
1713       for (j = 0; j < i; j++)
1714         {
1715           xj = VEC_index (use_pred_info_t, x, j);
1716           nxj = VEC_index (use_pred_info_t, pred_chain, j);
1717
1718           /* Check if nxj is !xj  */
1719           if (gimple_cond_lhs (xj->cond) != gimple_cond_lhs (nxj->cond)
1720               || gimple_cond_rhs (xj->cond) != gimple_cond_rhs (nxj->cond)
1721               || gimple_cond_code (xj->cond) != gimple_cond_code (nxj->cond)
1722               || (xj->invert == nxj->invert))
1723             return false;
1724         }
1725
1726       VEC_safe_push (use_pred_info_t, heap, x,
1727                      VEC_index (use_pred_info_t, pred_chain, i));
1728     }
1729
1730   /* Now normalize the pred chains using the extraced x1, x2, x3 etc.  */
1731   for (j = 0; j < *n; j++)
1732     {
1733       use_pred_info_t t;
1734       xj = VEC_index (use_pred_info_t, x, j);
1735
1736       t = XNEW (struct use_pred_info);
1737       *t = *xj;
1738
1739       VEC_replace (use_pred_info_t, x, j, t);
1740     }
1741
1742   for (i = 0; i < *n; i++)
1743     {
1744       pred_chain = preds[i];
1745       for (j = 0; j < VEC_length (use_pred_info_t, pred_chain); j++)
1746         free (VEC_index (use_pred_info_t, pred_chain, j));
1747       VEC_free (use_pred_info_t, heap, pred_chain);
1748       pred_chain = 0;
1749       /* A new chain.  */
1750       VEC_safe_push (use_pred_info_t, heap, pred_chain,
1751                      VEC_index (use_pred_info_t, x, i));
1752       preds[i] = pred_chain;
1753     }
1754   return true;
1755 }
1756
1757
1758
1759 /* Computes the predicates that guard the use and checks
1760    if the incoming paths that have empty (or possibly
1761    empty) defintion can be pruned/filtered. The function returns
1762    true if it can be determined that the use of PHI's def in
1763    USE_STMT is guarded with a predicate set not overlapping with
1764    predicate sets of all runtime paths that do not have a definition.
1765    Returns false if it is not or it can not be determined. USE_BB is
1766    the bb of the use (for phi operand use, the bb is not the bb of
1767    the phi stmt, but the src bb of the operand edge). UNINIT_OPNDS
1768    is a bit vector. If an operand of PHI is uninitialized, the
1769    correponding bit in the vector is 1.  VISIED_PHIS is a pointer
1770    set of phis being visted.  */
1771
1772 static bool
1773 is_use_properly_guarded (gimple use_stmt,
1774                          basic_block use_bb,
1775                          gimple phi,
1776                          unsigned uninit_opnds,
1777                          struct pointer_set_t *visited_phis)
1778 {
1779   basic_block phi_bb;
1780   VEC(use_pred_info_t, heap) **preds = 0;
1781   VEC(use_pred_info_t, heap) **def_preds = 0;
1782   size_t num_preds = 0, num_def_preds = 0;
1783   bool has_valid_preds = false;
1784   bool is_properly_guarded = false;
1785
1786   if (pointer_set_insert (visited_phis, phi))
1787     return false;
1788
1789   phi_bb = gimple_bb (phi);
1790
1791   if (is_non_loop_exit_postdominating (use_bb, phi_bb))
1792     return false;
1793
1794   has_valid_preds = find_predicates (&preds, &num_preds,
1795                                      phi_bb, use_bb);
1796
1797   if (!has_valid_preds)
1798     {
1799       destroy_predicate_vecs (num_preds, preds);
1800       return false;
1801     }
1802
1803   if (dump_file)
1804     dump_predicates (use_stmt, num_preds, preds,
1805                      "\nUse in stmt ");
1806
1807   has_valid_preds = find_def_preds (&def_preds,
1808                                     &num_def_preds, phi);
1809
1810   if (has_valid_preds)
1811     {
1812       bool normed;
1813       if (dump_file)
1814         dump_predicates (phi, num_def_preds, def_preds,
1815                          "Operand defs of phi ");
1816
1817       normed = normalize_preds (def_preds, &num_def_preds);
1818       if (normed && dump_file)
1819         {
1820           fprintf (dump_file, "\nNormalized to\n");
1821           dump_predicates (phi, num_def_preds, def_preds,
1822                            "Operand defs of phi ");
1823         }
1824       is_properly_guarded =
1825           is_superset_of (def_preds, num_def_preds,
1826                           preds, num_preds);
1827     }
1828
1829   /* further prune the dead incoming phi edges. */
1830   if (!is_properly_guarded)
1831     is_properly_guarded
1832         = use_pred_not_overlap_with_undef_path_pred (
1833             num_preds, preds, phi, uninit_opnds, visited_phis);
1834
1835   destroy_predicate_vecs (num_preds, preds);
1836   destroy_predicate_vecs (num_def_preds, def_preds);
1837   return is_properly_guarded;
1838 }
1839
1840 /* Searches through all uses of a potentially
1841    uninitialized variable defined by PHI and returns a use
1842    statement if the use is not properly guarded. It returns
1843    NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
1844    holding the position(s) of uninit PHI operands. WORKLIST
1845    is the vector of candidate phis that may be updated by this
1846    function. ADDED_TO_WORKLIST is the pointer set tracking
1847    if the new phi is already in the worklist.  */
1848
1849 static gimple
1850 find_uninit_use (gimple phi, unsigned uninit_opnds,
1851                  VEC(gimple, heap) **worklist,
1852                  struct pointer_set_t *added_to_worklist)
1853 {
1854   tree phi_result;
1855   use_operand_p use_p;
1856   gimple use_stmt;
1857   imm_use_iterator iter;
1858
1859   phi_result = gimple_phi_result (phi);
1860
1861   FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
1862     {
1863       struct pointer_set_t *visited_phis;
1864       basic_block use_bb;
1865
1866       use_stmt = USE_STMT (use_p);
1867       if (is_gimple_debug (use_stmt))
1868         continue;
1869
1870       visited_phis = pointer_set_create ();
1871
1872       if (gimple_code (use_stmt) == GIMPLE_PHI)
1873         use_bb = gimple_phi_arg_edge (use_stmt,
1874                                       PHI_ARG_INDEX_FROM_USE (use_p))->src;
1875       else
1876         use_bb = gimple_bb (use_stmt);
1877
1878       if (is_use_properly_guarded (use_stmt,
1879                                    use_bb, 
1880                                    phi,
1881                                    uninit_opnds,
1882                                    visited_phis))
1883         {
1884           pointer_set_destroy (visited_phis);
1885           continue;
1886         }
1887       pointer_set_destroy (visited_phis);
1888
1889       if (dump_file && (dump_flags & TDF_DETAILS))
1890         {
1891           fprintf (dump_file, "[CHECK]: Found unguarded use: ");
1892           print_gimple_stmt (dump_file, use_stmt, 0, 0);
1893         }
1894       /* Found one real use, return.  */
1895       if (gimple_code (use_stmt) != GIMPLE_PHI)
1896         return use_stmt;
1897
1898       /* Found a phi use that is not guarded,
1899          add the phi to the worklist.  */
1900       if (!pointer_set_insert (added_to_worklist,
1901                                use_stmt))
1902         {
1903           if (dump_file && (dump_flags & TDF_DETAILS))
1904             {
1905               fprintf (dump_file, "[WORKLIST]: Update worklist with phi: ");
1906               print_gimple_stmt (dump_file, use_stmt, 0, 0);
1907             }
1908
1909           VEC_safe_push (gimple, heap, *worklist, use_stmt);
1910           pointer_set_insert (possibly_undefined_names,
1911                               phi_result);
1912         }
1913     }
1914
1915   return NULL;
1916 }
1917
1918 /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1919    and gives warning if there exists a runtime path from the entry to a
1920    use of the PHI def that does not contain a definition. In other words,
1921    the warning is on the real use. The more dead paths that can be pruned
1922    by the compiler, the fewer false positives the warning is. WORKLIST
1923    is a vector of candidate phis to be examined. ADDED_TO_WORKLIST is
1924    a pointer set tracking if the new phi is added to the worklist or not.  */
1925
1926 static void
1927 warn_uninitialized_phi (gimple phi, VEC(gimple, heap) **worklist,
1928                         struct pointer_set_t *added_to_worklist)
1929 {
1930   unsigned uninit_opnds;
1931   gimple uninit_use_stmt = 0;
1932   tree uninit_op;
1933
1934   /* Don't look at memory tags.  */
1935   if (!is_gimple_reg (gimple_phi_result (phi)))
1936     return;
1937
1938   uninit_opnds = compute_uninit_opnds_pos (phi);
1939
1940   if  (MASK_EMPTY (uninit_opnds))
1941     return;
1942
1943   if (dump_file && (dump_flags & TDF_DETAILS))
1944     {
1945       fprintf (dump_file, "[CHECK]: examining phi: ");
1946       print_gimple_stmt (dump_file, phi, 0, 0);
1947     }
1948
1949   /* Now check if we have any use of the value without proper guard.  */
1950   uninit_use_stmt = find_uninit_use (phi, uninit_opnds,
1951                                      worklist, added_to_worklist);
1952
1953   /* All uses are properly guarded.  */
1954   if (!uninit_use_stmt)
1955     return;
1956
1957   uninit_op = gimple_phi_arg_def (phi, MASK_FIRST_SET_BIT (uninit_opnds));
1958   warn_uninit (OPT_Wmaybe_uninitialized, uninit_op,
1959                "%qD may be used uninitialized in this function",
1960                uninit_use_stmt);
1961
1962 }
1963
1964
1965 /* Entry point to the late uninitialized warning pass.  */
1966
1967 static unsigned int
1968 execute_late_warn_uninitialized (void)
1969 {
1970   basic_block bb;
1971   gimple_stmt_iterator gsi;
1972   VEC(gimple, heap) *worklist = 0;
1973   struct pointer_set_t *added_to_worklist;
1974
1975   calculate_dominance_info (CDI_DOMINATORS);
1976   calculate_dominance_info (CDI_POST_DOMINATORS);
1977   /* Re-do the plain uninitialized variable check, as optimization may have
1978      straightened control flow.  Do this first so that we don't accidentally
1979      get a "may be" warning when we'd have seen an "is" warning later.  */
1980   warn_uninitialized_vars (/*warn_possibly_uninitialized=*/1);
1981
1982   timevar_push (TV_TREE_UNINIT);
1983
1984   possibly_undefined_names = pointer_set_create ();
1985   added_to_worklist = pointer_set_create ();
1986
1987   /* Initialize worklist  */
1988   FOR_EACH_BB (bb)
1989     for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1990       {
1991         gimple phi = gsi_stmt (gsi);
1992         size_t n, i;
1993
1994         n = gimple_phi_num_args (phi);
1995
1996         /* Don't look at memory tags.  */
1997         if (!is_gimple_reg (gimple_phi_result (phi)))
1998           continue;
1999
2000         for (i = 0; i < n; ++i)
2001           {
2002             tree op = gimple_phi_arg_def (phi, i);
2003             if (TREE_CODE (op) == SSA_NAME
2004                 && ssa_undefined_value_p (op))
2005               {
2006                 VEC_safe_push (gimple, heap, worklist, phi);
2007                 pointer_set_insert (added_to_worklist, phi);
2008                 if (dump_file && (dump_flags & TDF_DETAILS))
2009                   {
2010                     fprintf (dump_file, "[WORKLIST]: add to initial list: ");
2011                     print_gimple_stmt (dump_file, phi, 0, 0);
2012                   }
2013                 break;
2014               }
2015           }
2016       }
2017
2018   while (VEC_length (gimple, worklist) != 0)
2019     {
2020       gimple cur_phi = 0;
2021       cur_phi = VEC_pop (gimple, worklist);
2022       warn_uninitialized_phi (cur_phi, &worklist, added_to_worklist);
2023     }
2024
2025   VEC_free (gimple, heap, worklist);
2026   pointer_set_destroy (added_to_worklist);
2027   pointer_set_destroy (possibly_undefined_names);
2028   possibly_undefined_names = NULL;
2029   free_dominance_info (CDI_POST_DOMINATORS);
2030   timevar_pop (TV_TREE_UNINIT);
2031   return 0;
2032 }
2033
2034 static bool
2035 gate_warn_uninitialized (void)
2036 {
2037   return warn_uninitialized != 0;
2038 }
2039
2040 struct gimple_opt_pass pass_late_warn_uninitialized =
2041 {
2042  {
2043   GIMPLE_PASS,
2044   "uninit",                             /* name */
2045   gate_warn_uninitialized,              /* gate */
2046   execute_late_warn_uninitialized,      /* execute */
2047   NULL,                                 /* sub */
2048   NULL,                                 /* next */
2049   0,                                    /* static_pass_number */
2050   TV_NONE,                              /* tv_id */
2051   PROP_ssa,                             /* properties_required */
2052   0,                                    /* properties_provided */
2053   0,                                    /* properties_destroyed */
2054   0,                                    /* todo_flags_start */
2055   0                                     /* todo_flags_finish */
2056  }
2057 };