xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-ssa-uninit.c (revision 7330f729ccf0bd976a06f95fad452fe774fc7fd1)
1 /* Predicate aware uninitialized variable warning.
2    Copyright (C) 2001-2017 Free Software Foundation, Inc.
3    Contributed by Xinliang David Li <davidxl@google.com>
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "tree.h"
26 #include "gimple.h"
27 #include "tree-pass.h"
28 #include "ssa.h"
29 #include "gimple-pretty-print.h"
30 #include "diagnostic-core.h"
31 #include "fold-const.h"
32 #include "gimple-iterator.h"
33 #include "tree-ssa.h"
34 #include "params.h"
35 #include "tree-cfg.h"
36 
37 /* This implements the pass that does predicate aware warning on uses of
38    possibly uninitialized variables.  The pass first collects the set of
39    possibly uninitialized SSA names.  For each such name, it walks through
40    all its immediate uses.  For each immediate use, it rebuilds the condition
41    expression (the predicate) that guards the use.  The predicate is then
42    examined to see if the variable is always defined under that same condition.
43    This is done either by pruning the unrealizable paths that lead to the
44    default definitions or by checking if the predicate set that guards the
45    defining paths is a superset of the use predicate.  */
46 
47 /* Max PHI args we can handle in pass.  */
48 const unsigned max_phi_args = 32;
49 
50 /* Pointer set of potentially undefined ssa names, i.e.,
51    ssa names that are defined by phi with operands that
52    are not defined or potentially undefined.  */
53 static hash_set<tree> *possibly_undefined_names = 0;
54 
55 /* Bit mask handling macros.  */
56 #define MASK_SET_BIT(mask, pos) mask |= (1 << pos)
57 #define MASK_TEST_BIT(mask, pos) (mask & (1 << pos))
58 #define MASK_EMPTY(mask) (mask == 0)
59 
60 /* Returns the first bit position (starting from LSB)
61    in mask that is non zero.  Returns -1 if the mask is empty.  */
62 static int
63 get_mask_first_set_bit (unsigned mask)
64 {
65   int pos = 0;
66   if (mask == 0)
67     return -1;
68 
69   while ((mask & (1 << pos)) == 0)
70     pos++;
71 
72   return pos;
73 }
74 #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
75 
76 /* Return true if T, an SSA_NAME, has an undefined value.  */
77 static bool
78 has_undefined_value_p (tree t)
79 {
80   return (ssa_undefined_value_p (t)
81 	  || (possibly_undefined_names
82 	      && possibly_undefined_names->contains (t)));
83 }
84 
85 /* Like has_undefined_value_p, but don't return true if TREE_NO_WARNING
86    is set on SSA_NAME_VAR.  */
87 
88 static inline bool
89 uninit_undefined_value_p (tree t)
90 {
91   if (!has_undefined_value_p (t))
92     return false;
93   if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t)))
94     return false;
95   return true;
96 }
97 
98 /* Emit warnings for uninitialized variables.  This is done in two passes.
99 
100    The first pass notices real uses of SSA names with undefined values.
101    Such uses are unconditionally uninitialized, and we can be certain that
102    such a use is a mistake.  This pass is run before most optimizations,
103    so that we catch as many as we can.
104 
105    The second pass follows PHI nodes to find uses that are potentially
106    uninitialized.  In this case we can't necessarily prove that the use
107    is really uninitialized.  This pass is run after most optimizations,
108    so that we thread as many jumps and possible, and delete as much dead
109    code as possible, in order to reduce false positives.  We also look
110    again for plain uninitialized variables, since optimization may have
111    changed conditionally uninitialized to unconditionally uninitialized.  */
112 
113 /* Emit a warning for EXPR based on variable VAR at the point in the
114    program T, an SSA_NAME, is used being uninitialized.  The exact
115    warning text is in MSGID and DATA is the gimple stmt with info about
116    the location in source code.  When DATA is a GIMPLE_PHI, PHIARG_IDX
117    gives which argument of the phi node to take the location from.  WC
118    is the warning code.  */
119 
120 static void
121 warn_uninit (enum opt_code wc, tree t, tree expr, tree var,
122 	     const char *gmsgid, void *data, location_t phiarg_loc)
123 {
124   gimple *context = (gimple *) data;
125   location_t location, cfun_loc;
126   expanded_location xloc, floc;
127 
128   /* Ignore COMPLEX_EXPR as initializing only a part of a complex
129      turns in a COMPLEX_EXPR with the not initialized part being
130      set to its previous (undefined) value.  */
131   if (is_gimple_assign (context)
132       && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
133     return;
134   if (!has_undefined_value_p (t))
135     return;
136 
137   /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
138      can return true if the def stmt of anonymous SSA_NAME is COMPLEX_EXPR
139      created for conversion from scalar to complex.  Use the underlying var of
140      the COMPLEX_EXPRs real part in that case.  See PR71581.  */
141   if (expr == NULL_TREE
142       && var == NULL_TREE
143       && SSA_NAME_VAR (t) == NULL_TREE
144       && is_gimple_assign (SSA_NAME_DEF_STMT (t))
145       && gimple_assign_rhs_code (SSA_NAME_DEF_STMT (t)) == COMPLEX_EXPR)
146     {
147       tree v = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (t));
148       if (TREE_CODE (v) == SSA_NAME
149 	  && has_undefined_value_p (v)
150 	  && zerop (gimple_assign_rhs2 (SSA_NAME_DEF_STMT (t))))
151 	{
152 	  expr = SSA_NAME_VAR (v);
153 	  var = expr;
154 	}
155     }
156 
157   if (expr == NULL_TREE)
158     return;
159 
160   /* TREE_NO_WARNING either means we already warned, or the front end
161      wishes to suppress the warning.  */
162   if ((context
163        && (gimple_no_warning_p (context)
164 	   || (gimple_assign_single_p (context)
165 	       && TREE_NO_WARNING (gimple_assign_rhs1 (context)))))
166       || TREE_NO_WARNING (expr))
167     return;
168 
169   if (context != NULL && gimple_has_location (context))
170     location = gimple_location (context);
171   else if (phiarg_loc != UNKNOWN_LOCATION)
172     location = phiarg_loc;
173   else
174     location = DECL_SOURCE_LOCATION (var);
175   location = linemap_resolve_location (line_table, location,
176 				       LRK_SPELLING_LOCATION, NULL);
177   cfun_loc = DECL_SOURCE_LOCATION (cfun->decl);
178   xloc = expand_location (location);
179   floc = expand_location (cfun_loc);
180   if (warning_at (location, wc, gmsgid, expr))
181     {
182       TREE_NO_WARNING (expr) = 1;
183 
184       if (location == DECL_SOURCE_LOCATION (var))
185 	return;
186       if (xloc.file != floc.file
187 	  || linemap_location_before_p (line_table, location, cfun_loc)
188 	  || linemap_location_before_p (line_table, cfun->function_end_locus,
189 					location))
190 	inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var);
191     }
192 }
193 
194 struct check_defs_data
195 {
196   /* If we found any may-defs besides must-def clobbers.  */
197   bool found_may_defs;
198 };
199 
200 /* Callback for walk_aliased_vdefs.  */
201 
202 static bool
203 check_defs (ao_ref *ref, tree vdef, void *data_)
204 {
205   check_defs_data *data = (check_defs_data *)data_;
206   gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
207   /* If this is a clobber then if it is not a kill walk past it.  */
208   if (gimple_clobber_p (def_stmt))
209     {
210       if (stmt_kills_ref_p (def_stmt, ref))
211 	return true;
212       return false;
213     }
214   /* Found a may-def on this path.  */
215   data->found_may_defs = true;
216   return true;
217 }
218 
219 static unsigned int
220 warn_uninitialized_vars (bool warn_possibly_uninitialized)
221 {
222   gimple_stmt_iterator gsi;
223   basic_block bb;
224   unsigned int vdef_cnt = 0;
225   unsigned int oracle_cnt = 0;
226   unsigned limit = 0;
227 
228   FOR_EACH_BB_FN (bb, cfun)
229     {
230       basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
231       bool always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb);
232       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
233 	{
234 	  gimple *stmt = gsi_stmt (gsi);
235 	  use_operand_p use_p;
236 	  ssa_op_iter op_iter;
237 	  tree use;
238 
239 	  if (is_gimple_debug (stmt))
240 	    continue;
241 
242 	  /* We only do data flow with SSA_NAMEs, so that's all we
243 	     can warn about.  */
244 	  FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
245 	    {
246 	      /* BIT_INSERT_EXPR first operand should not be considered
247 	         a use for the purpose of uninit warnings.  */
248 	      if (gassign *ass = dyn_cast <gassign *> (stmt))
249 		{
250 		  if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
251 		      && use_p->use == gimple_assign_rhs1_ptr (ass))
252 		    continue;
253 		}
254 	      use = USE_FROM_PTR (use_p);
255 	      if (always_executed)
256 		warn_uninit (OPT_Wuninitialized, use, SSA_NAME_VAR (use),
257 			     SSA_NAME_VAR (use),
258 			     "%qD is used uninitialized in this function", stmt,
259 			     UNKNOWN_LOCATION);
260 	      else if (warn_possibly_uninitialized)
261 		warn_uninit (OPT_Wmaybe_uninitialized, use, SSA_NAME_VAR (use),
262 			     SSA_NAME_VAR (use),
263 			     "%qD may be used uninitialized in this function",
264 			     stmt, UNKNOWN_LOCATION);
265 	    }
266 
267 	  /* For limiting the alias walk below we count all
268 	     vdefs in the function.  */
269 	  if (gimple_vdef (stmt))
270 	    vdef_cnt++;
271 
272 	  if (gimple_assign_load_p (stmt)
273 	      && gimple_has_location (stmt))
274 	    {
275 	      tree rhs = gimple_assign_rhs1 (stmt);
276 	      if (TREE_NO_WARNING (rhs))
277 		continue;
278 
279 	      ao_ref ref;
280 	      ao_ref_init (&ref, rhs);
281 
282 	      /* Do not warn if it can be initialized outside this function.  */
283 	      tree base = ao_ref_base (&ref);
284 	      if (!VAR_P (base)
285 		  || DECL_HARD_REGISTER (base)
286 		  || is_global_var (base)
287 		  || TREE_NO_WARNING (base))
288 		continue;
289 
290 	      /* Do not warn if the access is fully outside of the
291 	         variable.  */
292 	      if (ref.size != -1
293 		  && ((ref.max_size == ref.size
294 		       && ref.offset + ref.size <= 0)
295 		      || (ref.offset >= 0
296 			  && TREE_CODE (DECL_SIZE (base)) == INTEGER_CST
297 			  && compare_tree_int (DECL_SIZE (base),
298 					       ref.offset) <= 0)))
299 		continue;
300 
301 	      /* Limit the walking to a constant number of stmts after
302 	         we overcommit quadratic behavior for small functions
303 		 and O(n) behavior.  */
304 	      if (oracle_cnt > 128 * 128
305 		  && oracle_cnt > vdef_cnt * 2)
306 		limit = 32;
307 	      check_defs_data data;
308 	      data.found_may_defs = false;
309 	      use = gimple_vuse (stmt);
310 	      int res = walk_aliased_vdefs (&ref, use,
311 					    check_defs, &data, NULL,
312 					    NULL, limit);
313 	      if (res == -1)
314 		{
315 		  oracle_cnt += limit;
316 		  continue;
317 		}
318 	      oracle_cnt += res;
319 	      if (data.found_may_defs)
320 		continue;
321 
322 	      /* We didn't find any may-defs so on all paths either
323 	         reached function entry or a killing clobber.  */
324 	      location_t location
325 		= linemap_resolve_location (line_table, gimple_location (stmt),
326 					    LRK_SPELLING_LOCATION, NULL);
327 	      if (always_executed)
328 		{
329 		  if (warning_at (location, OPT_Wuninitialized,
330 				  "%qE is used uninitialized in this function",
331 				  rhs))
332 		    /* ???  This is only effective for decls as in
333 		       gcc.dg/uninit-B-O0.c.  Avoid doing this for
334 		       maybe-uninit uses as it may hide important
335 		       locations.  */
336 		    TREE_NO_WARNING (rhs) = 1;
337 		}
338 	      else if (warn_possibly_uninitialized)
339 		warning_at (location, OPT_Wmaybe_uninitialized,
340 			    "%qE may be used uninitialized in this function",
341 			    rhs);
342 	    }
343 	}
344     }
345 
346   return 0;
347 }
348 
349 /* Checks if the operand OPND of PHI is defined by
350    another phi with one operand defined by this PHI,
351    but the rest operands are all defined.  If yes,
352    returns true to skip this operand as being
353    redundant.  Can be enhanced to be more general.  */
354 
355 static bool
356 can_skip_redundant_opnd (tree opnd, gimple *phi)
357 {
358   gimple *op_def;
359   tree phi_def;
360   int i, n;
361 
362   phi_def = gimple_phi_result (phi);
363   op_def = SSA_NAME_DEF_STMT (opnd);
364   if (gimple_code (op_def) != GIMPLE_PHI)
365     return false;
366   n = gimple_phi_num_args (op_def);
367   for (i = 0; i < n; ++i)
368     {
369       tree op = gimple_phi_arg_def (op_def, i);
370       if (TREE_CODE (op) != SSA_NAME)
371 	continue;
372       if (op != phi_def && uninit_undefined_value_p (op))
373 	return false;
374     }
375 
376   return true;
377 }
378 
379 /* Returns a bit mask holding the positions of arguments in PHI
380    that have empty (or possibly empty) definitions.  */
381 
382 static unsigned
383 compute_uninit_opnds_pos (gphi *phi)
384 {
385   size_t i, n;
386   unsigned uninit_opnds = 0;
387 
388   n = gimple_phi_num_args (phi);
389   /* Bail out for phi with too many args.  */
390   if (n > max_phi_args)
391     return 0;
392 
393   for (i = 0; i < n; ++i)
394     {
395       tree op = gimple_phi_arg_def (phi, i);
396       if (TREE_CODE (op) == SSA_NAME
397 	  && uninit_undefined_value_p (op)
398 	  && !can_skip_redundant_opnd (op, phi))
399 	{
400 	  if (cfun->has_nonlocal_label || cfun->calls_setjmp)
401 	    {
402 	      /* Ignore SSA_NAMEs that appear on abnormal edges
403 		 somewhere.  */
404 	      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
405 		continue;
406 	    }
407 	  MASK_SET_BIT (uninit_opnds, i);
408 	}
409     }
410   return uninit_opnds;
411 }
412 
413 /* Find the immediate postdominator PDOM of the specified
414    basic block BLOCK.  */
415 
416 static inline basic_block
417 find_pdom (basic_block block)
418 {
419   if (block == EXIT_BLOCK_PTR_FOR_FN (cfun))
420     return EXIT_BLOCK_PTR_FOR_FN (cfun);
421   else
422     {
423       basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block);
424       if (!bb)
425 	return EXIT_BLOCK_PTR_FOR_FN (cfun);
426       return bb;
427     }
428 }
429 
430 /* Find the immediate DOM of the specified basic block BLOCK.  */
431 
432 static inline basic_block
433 find_dom (basic_block block)
434 {
435   if (block == ENTRY_BLOCK_PTR_FOR_FN (cfun))
436     return ENTRY_BLOCK_PTR_FOR_FN (cfun);
437   else
438     {
439       basic_block bb = get_immediate_dominator (CDI_DOMINATORS, block);
440       if (!bb)
441 	return ENTRY_BLOCK_PTR_FOR_FN (cfun);
442       return bb;
443     }
444 }
445 
446 /* Returns true if BB1 is postdominating BB2 and BB1 is
447    not a loop exit bb.  The loop exit bb check is simple and does
448    not cover all cases.  */
449 
450 static bool
451 is_non_loop_exit_postdominating (basic_block bb1, basic_block bb2)
452 {
453   if (!dominated_by_p (CDI_POST_DOMINATORS, bb2, bb1))
454     return false;
455 
456   if (single_pred_p (bb1) && !single_succ_p (bb2))
457     return false;
458 
459   return true;
460 }
461 
462 /* Find the closest postdominator of a specified BB, which is control
463    equivalent to BB.  */
464 
465 static inline basic_block
466 find_control_equiv_block (basic_block bb)
467 {
468   basic_block pdom;
469 
470   pdom = find_pdom (bb);
471 
472   /* Skip the postdominating bb that is also loop exit.  */
473   if (!is_non_loop_exit_postdominating (pdom, bb))
474     return NULL;
475 
476   if (dominated_by_p (CDI_DOMINATORS, pdom, bb))
477     return pdom;
478 
479   return NULL;
480 }
481 
482 #define MAX_NUM_CHAINS 8
483 #define MAX_CHAIN_LEN 5
484 #define MAX_POSTDOM_CHECK 8
485 #define MAX_SWITCH_CASES 40
486 
487 /* Computes the control dependence chains (paths of edges)
488    for DEP_BB up to the dominating basic block BB (the head node of a
489    chain should be dominated by it).  CD_CHAINS is pointer to an
490    array holding the result chains.  CUR_CD_CHAIN is the current
491    chain being computed.  *NUM_CHAINS is total number of chains.  The
492    function returns true if the information is successfully computed,
493    return false if there is no control dependence or not computed.  */
494 
495 static bool
496 compute_control_dep_chain (basic_block bb, basic_block dep_bb,
497 			   vec<edge> *cd_chains,
498 			   size_t *num_chains,
499 			   vec<edge> *cur_cd_chain,
500 			   int *num_calls)
501 {
502   edge_iterator ei;
503   edge e;
504   size_t i;
505   bool found_cd_chain = false;
506   size_t cur_chain_len = 0;
507 
508   if (EDGE_COUNT (bb->succs) < 2)
509     return false;
510 
511   if (*num_calls > PARAM_VALUE (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS))
512     return false;
513   ++*num_calls;
514 
515   /* Could use a set instead.  */
516   cur_chain_len = cur_cd_chain->length ();
517   if (cur_chain_len > MAX_CHAIN_LEN)
518     return false;
519 
520   for (i = 0; i < cur_chain_len; i++)
521     {
522       edge e = (*cur_cd_chain)[i];
523       /* Cycle detected.  */
524       if (e->src == bb)
525 	return false;
526     }
527 
528   FOR_EACH_EDGE (e, ei, bb->succs)
529     {
530       basic_block cd_bb;
531       int post_dom_check = 0;
532       if (e->flags & (EDGE_FAKE | EDGE_ABNORMAL))
533 	continue;
534 
535       cd_bb = e->dest;
536       cur_cd_chain->safe_push (e);
537       while (!is_non_loop_exit_postdominating (cd_bb, bb))
538 	{
539 	  if (cd_bb == dep_bb)
540 	    {
541 	      /* Found a direct control dependence.  */
542 	      if (*num_chains < MAX_NUM_CHAINS)
543 		{
544 		  cd_chains[*num_chains] = cur_cd_chain->copy ();
545 		  (*num_chains)++;
546 		}
547 	      found_cd_chain = true;
548 	      /* Check path from next edge.  */
549 	      break;
550 	    }
551 
552 	  /* Now check if DEP_BB is indirectly control dependent on BB.  */
553 	  if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains, num_chains,
554 					 cur_cd_chain, num_calls))
555 	    {
556 	      found_cd_chain = true;
557 	      break;
558 	    }
559 
560 	  cd_bb = find_pdom (cd_bb);
561 	  post_dom_check++;
562 	  if (cd_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
563 	      || post_dom_check > MAX_POSTDOM_CHECK)
564 	    break;
565 	}
566       cur_cd_chain->pop ();
567       gcc_assert (cur_cd_chain->length () == cur_chain_len);
568     }
569   gcc_assert (cur_cd_chain->length () == cur_chain_len);
570 
571   return found_cd_chain;
572 }
573 
574 /* The type to represent a simple predicate.  */
575 
576 struct pred_info
577 {
578   tree pred_lhs;
579   tree pred_rhs;
580   enum tree_code cond_code;
581   bool invert;
582 };
583 
584 /* The type to represent a sequence of predicates grouped
585   with .AND. operation.  */
586 
587 typedef vec<pred_info, va_heap, vl_ptr> pred_chain;
588 
589 /* The type to represent a sequence of pred_chains grouped
590   with .OR. operation.  */
591 
592 typedef vec<pred_chain, va_heap, vl_ptr> pred_chain_union;
593 
594 /* Converts the chains of control dependence edges into a set of
595    predicates.  A control dependence chain is represented by a vector
596    edges.  DEP_CHAINS points to an array of dependence chains.
597    NUM_CHAINS is the size of the chain array.  One edge in a dependence
598    chain is mapped to predicate expression represented by pred_info
599    type.  One dependence chain is converted to a composite predicate that
600    is the result of AND operation of pred_info mapped to each edge.
601    A composite predicate is presented by a vector of pred_info.  On
602    return, *PREDS points to the resulting array of composite predicates.
603    *NUM_PREDS is the number of composite predictes.  */
604 
605 static bool
606 convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
607 				      size_t num_chains,
608 				      pred_chain_union *preds)
609 {
610   bool has_valid_pred = false;
611   size_t i, j;
612   if (num_chains == 0 || num_chains >= MAX_NUM_CHAINS)
613     return false;
614 
615   /* Now convert the control dep chain into a set
616      of predicates.  */
617   preds->reserve (num_chains);
618 
619   for (i = 0; i < num_chains; i++)
620     {
621       vec<edge> one_cd_chain = dep_chains[i];
622 
623       has_valid_pred = false;
624       pred_chain t_chain = vNULL;
625       for (j = 0; j < one_cd_chain.length (); j++)
626 	{
627 	  gimple *cond_stmt;
628 	  gimple_stmt_iterator gsi;
629 	  basic_block guard_bb;
630 	  pred_info one_pred;
631 	  edge e;
632 
633 	  e = one_cd_chain[j];
634 	  guard_bb = e->src;
635 	  gsi = gsi_last_bb (guard_bb);
636 	  if (gsi_end_p (gsi))
637 	    {
638 	      has_valid_pred = false;
639 	      break;
640 	    }
641 	  cond_stmt = gsi_stmt (gsi);
642 	  if (is_gimple_call (cond_stmt) && EDGE_COUNT (e->src->succs) >= 2)
643 	    /* Ignore EH edge.  Can add assertion on the other edge's flag.  */
644 	    continue;
645 	  /* Skip if there is essentially one succesor.  */
646 	  if (EDGE_COUNT (e->src->succs) == 2)
647 	    {
648 	      edge e1;
649 	      edge_iterator ei1;
650 	      bool skip = false;
651 
652 	      FOR_EACH_EDGE (e1, ei1, e->src->succs)
653 		{
654 		  if (EDGE_COUNT (e1->dest->succs) == 0)
655 		    {
656 		      skip = true;
657 		      break;
658 		    }
659 		}
660 	      if (skip)
661 		continue;
662 	    }
663 	  if (gimple_code (cond_stmt) == GIMPLE_COND)
664 	    {
665 	      one_pred.pred_lhs = gimple_cond_lhs (cond_stmt);
666 	      one_pred.pred_rhs = gimple_cond_rhs (cond_stmt);
667 	      one_pred.cond_code = gimple_cond_code (cond_stmt);
668 	      one_pred.invert = !!(e->flags & EDGE_FALSE_VALUE);
669 	      t_chain.safe_push (one_pred);
670 	      has_valid_pred = true;
671 	    }
672 	  else if (gswitch *gs = dyn_cast<gswitch *> (cond_stmt))
673 	    {
674 	      /* Avoid quadratic behavior.  */
675 	      if (gimple_switch_num_labels (gs) > MAX_SWITCH_CASES)
676 		{
677 		  has_valid_pred = false;
678 		  break;
679 		}
680 	      /* Find the case label.  */
681 	      tree l = NULL_TREE;
682 	      unsigned idx;
683 	      for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx)
684 		{
685 		  tree tl = gimple_switch_label (gs, idx);
686 		  if (e->dest == label_to_block (CASE_LABEL (tl)))
687 		    {
688 		      if (!l)
689 			l = tl;
690 		      else
691 			{
692 			  l = NULL_TREE;
693 			  break;
694 			}
695 		    }
696 		}
697 	      /* If more than one label reaches this block or the case
698 		 label doesn't have a single value (like the default one)
699 		 fail.  */
700 	      if (!l
701 		  || !CASE_LOW (l)
702 		  || (CASE_HIGH (l)
703 		      && !operand_equal_p (CASE_LOW (l), CASE_HIGH (l), 0)))
704 		{
705 		  has_valid_pred = false;
706 		  break;
707 		}
708 	      one_pred.pred_lhs = gimple_switch_index (gs);
709 	      one_pred.pred_rhs = CASE_LOW (l);
710 	      one_pred.cond_code = EQ_EXPR;
711 	      one_pred.invert = false;
712 	      t_chain.safe_push (one_pred);
713 	      has_valid_pred = true;
714 	    }
715 	  else
716 	    {
717 	      has_valid_pred = false;
718 	      break;
719 	    }
720 	}
721 
722       if (!has_valid_pred)
723 	break;
724       else
725 	preds->safe_push (t_chain);
726     }
727   return has_valid_pred;
728 }
729 
730 /* Computes all control dependence chains for USE_BB.  The control
731    dependence chains are then converted to an array of composite
732    predicates pointed to by PREDS.  PHI_BB is the basic block of
733    the phi whose result is used in USE_BB.  */
734 
735 static bool
736 find_predicates (pred_chain_union *preds,
737 		 basic_block phi_bb,
738 		 basic_block use_bb)
739 {
740   size_t num_chains = 0, i;
741   int num_calls = 0;
742   vec<edge> dep_chains[MAX_NUM_CHAINS];
743   auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
744   bool has_valid_pred = false;
745   basic_block cd_root = 0;
746 
747   /* First find the closest bb that is control equivalent to PHI_BB
748      that also dominates USE_BB.  */
749   cd_root = phi_bb;
750   while (dominated_by_p (CDI_DOMINATORS, use_bb, cd_root))
751     {
752       basic_block ctrl_eq_bb = find_control_equiv_block (cd_root);
753       if (ctrl_eq_bb && dominated_by_p (CDI_DOMINATORS, use_bb, ctrl_eq_bb))
754 	cd_root = ctrl_eq_bb;
755       else
756 	break;
757     }
758 
759   compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains,
760 			     &cur_chain, &num_calls);
761 
762   has_valid_pred
763     = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds);
764   for (i = 0; i < num_chains; i++)
765     dep_chains[i].release ();
766   return has_valid_pred;
767 }
768 
769 /* Computes the set of incoming edges of PHI that have non empty
770    definitions of a phi chain.  The collection will be done
771    recursively on operands that are defined by phis.  CD_ROOT
772    is the control dependence root.  *EDGES holds the result, and
773    VISITED_PHIS is a pointer set for detecting cycles.  */
774 
775 static void
776 collect_phi_def_edges (gphi *phi, basic_block cd_root,
777 		       auto_vec<edge> *edges,
778 		       hash_set<gimple *> *visited_phis)
779 {
780   size_t i, n;
781   edge opnd_edge;
782   tree opnd;
783 
784   if (visited_phis->add (phi))
785     return;
786 
787   n = gimple_phi_num_args (phi);
788   for (i = 0; i < n; i++)
789     {
790       opnd_edge = gimple_phi_arg_edge (phi, i);
791       opnd = gimple_phi_arg_def (phi, i);
792 
793       if (TREE_CODE (opnd) != SSA_NAME)
794 	{
795 	  if (dump_file && (dump_flags & TDF_DETAILS))
796 	    {
797 	      fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int) i);
798 	      print_gimple_stmt (dump_file, phi, 0, 0);
799 	    }
800 	  edges->safe_push (opnd_edge);
801 	}
802       else
803 	{
804 	  gimple *def = SSA_NAME_DEF_STMT (opnd);
805 
806 	  if (gimple_code (def) == GIMPLE_PHI
807 	      && dominated_by_p (CDI_DOMINATORS, gimple_bb (def), cd_root))
808 	    collect_phi_def_edges (as_a<gphi *> (def), cd_root, edges,
809 				   visited_phis);
810 	  else if (!uninit_undefined_value_p (opnd))
811 	    {
812 	      if (dump_file && (dump_flags & TDF_DETAILS))
813 		{
814 		  fprintf (dump_file, "\n[CHECK] Found def edge %d in ",
815 			   (int) i);
816 		  print_gimple_stmt (dump_file, phi, 0, 0);
817 		}
818 	      edges->safe_push (opnd_edge);
819 	    }
820 	}
821     }
822 }
823 
824 /* For each use edge of PHI, computes all control dependence chains.
825    The control dependence chains are then converted to an array of
826    composite predicates pointed to by PREDS.  */
827 
828 static bool
829 find_def_preds (pred_chain_union *preds, gphi *phi)
830 {
831   size_t num_chains = 0, i, n;
832   vec<edge> dep_chains[MAX_NUM_CHAINS];
833   auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
834   auto_vec<edge> def_edges;
835   bool has_valid_pred = false;
836   basic_block phi_bb, cd_root = 0;
837 
838   phi_bb = gimple_bb (phi);
839   /* First find the closest dominating bb to be
840      the control dependence root.  */
841   cd_root = find_dom (phi_bb);
842   if (!cd_root)
843     return false;
844 
845   hash_set<gimple *> visited_phis;
846   collect_phi_def_edges (phi, cd_root, &def_edges, &visited_phis);
847 
848   n = def_edges.length ();
849   if (n == 0)
850     return false;
851 
852   for (i = 0; i < n; i++)
853     {
854       size_t prev_nc, j;
855       int num_calls = 0;
856       edge opnd_edge;
857 
858       opnd_edge = def_edges[i];
859       prev_nc = num_chains;
860       compute_control_dep_chain (cd_root, opnd_edge->src, dep_chains,
861 				 &num_chains, &cur_chain, &num_calls);
862 
863       /* Now update the newly added chains with
864 	 the phi operand edge:  */
865       if (EDGE_COUNT (opnd_edge->src->succs) > 1)
866 	{
867 	  if (prev_nc == num_chains && num_chains < MAX_NUM_CHAINS)
868 	    dep_chains[num_chains++] = vNULL;
869 	  for (j = prev_nc; j < num_chains; j++)
870 	    dep_chains[j].safe_push (opnd_edge);
871 	}
872     }
873 
874   has_valid_pred
875     = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds);
876   for (i = 0; i < num_chains; i++)
877     dep_chains[i].release ();
878   return has_valid_pred;
879 }
880 
881 /* Dumps the predicates (PREDS) for USESTMT.  */
882 
883 static void
884 dump_predicates (gimple *usestmt, pred_chain_union preds, const char *msg)
885 {
886   size_t i, j;
887   pred_chain one_pred_chain = vNULL;
888   fprintf (dump_file, "%s", msg);
889   print_gimple_stmt (dump_file, usestmt, 0, 0);
890   fprintf (dump_file, "is guarded by :\n\n");
891   size_t num_preds = preds.length ();
892   /* Do some dumping here:  */
893   for (i = 0; i < num_preds; i++)
894     {
895       size_t np;
896 
897       one_pred_chain = preds[i];
898       np = one_pred_chain.length ();
899 
900       for (j = 0; j < np; j++)
901 	{
902 	  pred_info one_pred = one_pred_chain[j];
903 	  if (one_pred.invert)
904 	    fprintf (dump_file, " (.NOT.) ");
905 	  print_generic_expr (dump_file, one_pred.pred_lhs, 0);
906 	  fprintf (dump_file, " %s ", op_symbol_code (one_pred.cond_code));
907 	  print_generic_expr (dump_file, one_pred.pred_rhs, 0);
908 	  if (j < np - 1)
909 	    fprintf (dump_file, " (.AND.) ");
910 	  else
911 	    fprintf (dump_file, "\n");
912 	}
913       if (i < num_preds - 1)
914 	fprintf (dump_file, "(.OR.)\n");
915       else
916 	fprintf (dump_file, "\n\n");
917     }
918 }
919 
920 /* Destroys the predicate set *PREDS.  */
921 
922 static void
923 destroy_predicate_vecs (pred_chain_union *preds)
924 {
925   size_t i;
926 
927   size_t n = preds->length ();
928   for (i = 0; i < n; i++)
929     (*preds)[i].release ();
930   preds->release ();
931 }
932 
933 /* Computes the 'normalized' conditional code with operand
934    swapping and condition inversion.  */
935 
936 static enum tree_code
937 get_cmp_code (enum tree_code orig_cmp_code, bool swap_cond, bool invert)
938 {
939   enum tree_code tc = orig_cmp_code;
940 
941   if (swap_cond)
942     tc = swap_tree_comparison (orig_cmp_code);
943   if (invert)
944     tc = invert_tree_comparison (tc, false);
945 
946   switch (tc)
947     {
948     case LT_EXPR:
949     case LE_EXPR:
950     case GT_EXPR:
951     case GE_EXPR:
952     case EQ_EXPR:
953     case NE_EXPR:
954       break;
955     default:
956       return ERROR_MARK;
957     }
958   return tc;
959 }
960 
961 /* Returns true if VAL falls in the range defined by BOUNDARY and CMPC, i.e.
962    all values in the range satisfies (x CMPC BOUNDARY) == true.  */
963 
964 static bool
965 is_value_included_in (tree val, tree boundary, enum tree_code cmpc)
966 {
967   bool inverted = false;
968   bool is_unsigned;
969   bool result;
970 
971   /* Only handle integer constant here.  */
972   if (TREE_CODE (val) != INTEGER_CST || TREE_CODE (boundary) != INTEGER_CST)
973     return true;
974 
975   is_unsigned = TYPE_UNSIGNED (TREE_TYPE (val));
976 
977   if (cmpc == GE_EXPR || cmpc == GT_EXPR || cmpc == NE_EXPR)
978     {
979       cmpc = invert_tree_comparison (cmpc, false);
980       inverted = true;
981     }
982 
983   if (is_unsigned)
984     {
985       if (cmpc == EQ_EXPR)
986 	result = tree_int_cst_equal (val, boundary);
987       else if (cmpc == LT_EXPR)
988 	result = tree_int_cst_lt (val, boundary);
989       else
990 	{
991 	  gcc_assert (cmpc == LE_EXPR);
992 	  result = tree_int_cst_le (val, boundary);
993 	}
994     }
995   else
996     {
997       if (cmpc == EQ_EXPR)
998 	result = tree_int_cst_equal (val, boundary);
999       else if (cmpc == LT_EXPR)
1000 	result = tree_int_cst_lt (val, boundary);
1001       else
1002 	{
1003 	  gcc_assert (cmpc == LE_EXPR);
1004 	  result = (tree_int_cst_equal (val, boundary)
1005 		    || tree_int_cst_lt (val, boundary));
1006 	}
1007     }
1008 
1009   if (inverted)
1010     result ^= 1;
1011 
1012   return result;
1013 }
1014 
1015 /* Returns true if PRED is common among all the predicate
1016    chains (PREDS) (and therefore can be factored out).
1017    NUM_PRED_CHAIN is the size of array PREDS.  */
1018 
1019 static bool
1020 find_matching_predicate_in_rest_chains (pred_info pred,
1021 					pred_chain_union preds,
1022 					size_t num_pred_chains)
1023 {
1024   size_t i, j, n;
1025 
1026   /* Trival case.  */
1027   if (num_pred_chains == 1)
1028     return true;
1029 
1030   for (i = 1; i < num_pred_chains; i++)
1031     {
1032       bool found = false;
1033       pred_chain one_chain = preds[i];
1034       n = one_chain.length ();
1035       for (j = 0; j < n; j++)
1036 	{
1037 	  pred_info pred2 = one_chain[j];
1038 	  /* Can relax the condition comparison to not
1039 	     use address comparison.  However, the most common
1040 	     case is that multiple control dependent paths share
1041 	     a common path prefix, so address comparison should
1042 	     be ok.  */
1043 
1044 	  if (operand_equal_p (pred2.pred_lhs, pred.pred_lhs, 0)
1045 	      && operand_equal_p (pred2.pred_rhs, pred.pred_rhs, 0)
1046 	      && pred2.invert == pred.invert)
1047 	    {
1048 	      found = true;
1049 	      break;
1050 	    }
1051 	}
1052       if (!found)
1053 	return false;
1054     }
1055   return true;
1056 }
1057 
1058 /* Forward declaration.  */
1059 static bool is_use_properly_guarded (gimple *use_stmt,
1060 				     basic_block use_bb,
1061 				     gphi *phi,
1062 				     unsigned uninit_opnds,
1063 				     pred_chain_union *def_preds,
1064 				     hash_set<gphi *> *visited_phis);
1065 
1066 /* Returns true if all uninitialized opnds are pruned.  Returns false
1067    otherwise.  PHI is the phi node with uninitialized operands,
1068    UNINIT_OPNDS is the bitmap of the uninitialize operand positions,
1069    FLAG_DEF is the statement defining the flag guarding the use of the
1070    PHI output, BOUNDARY_CST is the const value used in the predicate
1071    associated with the flag, CMP_CODE is the comparison code used in
1072    the predicate, VISITED_PHIS is the pointer set of phis visited, and
1073    VISITED_FLAG_PHIS is the pointer to the pointer set of flag definitions
1074    that are also phis.
1075 
1076    Example scenario:
1077 
1078    BB1:
1079    flag_1 = phi <0, 1>			// (1)
1080    var_1  = phi <undef, some_val>
1081 
1082 
1083    BB2:
1084    flag_2 = phi <0,   flag_1, flag_1>   // (2)
1085    var_2  = phi <undef, var_1, var_1>
1086    if (flag_2 == 1)
1087       goto BB3;
1088 
1089    BB3:
1090    use of var_2				// (3)
1091 
1092    Because some flag arg in (1) is not constant, if we do not look into the
1093    flag phis recursively, it is conservatively treated as unknown and var_1
1094    is thought to be flowed into use at (3).  Since var_1 is potentially
1095    uninitialized a false warning will be emitted.
1096    Checking recursively into (1), the compiler can find out that only some_val
1097    (which is defined) can flow into (3) which is OK.  */
1098 
1099 static bool
1100 prune_uninit_phi_opnds (gphi *phi, unsigned uninit_opnds, gphi *flag_def,
1101 			tree boundary_cst, enum tree_code cmp_code,
1102 			hash_set<gphi *> *visited_phis,
1103 			bitmap *visited_flag_phis)
1104 {
1105   unsigned i;
1106 
1107   for (i = 0; i < MIN (max_phi_args, gimple_phi_num_args (flag_def)); i++)
1108     {
1109       tree flag_arg;
1110 
1111       if (!MASK_TEST_BIT (uninit_opnds, i))
1112 	continue;
1113 
1114       flag_arg = gimple_phi_arg_def (flag_def, i);
1115       if (!is_gimple_constant (flag_arg))
1116 	{
1117 	  gphi *flag_arg_def, *phi_arg_def;
1118 	  tree phi_arg;
1119 	  unsigned uninit_opnds_arg_phi;
1120 
1121 	  if (TREE_CODE (flag_arg) != SSA_NAME)
1122 	    return false;
1123 	  flag_arg_def = dyn_cast<gphi *> (SSA_NAME_DEF_STMT (flag_arg));
1124 	  if (!flag_arg_def)
1125 	    return false;
1126 
1127 	  phi_arg = gimple_phi_arg_def (phi, i);
1128 	  if (TREE_CODE (phi_arg) != SSA_NAME)
1129 	    return false;
1130 
1131 	  phi_arg_def = dyn_cast<gphi *> (SSA_NAME_DEF_STMT (phi_arg));
1132 	  if (!phi_arg_def)
1133 	    return false;
1134 
1135 	  if (gimple_bb (phi_arg_def) != gimple_bb (flag_arg_def))
1136 	    return false;
1137 
1138 	  if (!*visited_flag_phis)
1139 	    *visited_flag_phis = BITMAP_ALLOC (NULL);
1140 
1141 	  tree phi_result = gimple_phi_result (flag_arg_def);
1142 	  if (bitmap_bit_p (*visited_flag_phis, SSA_NAME_VERSION (phi_result)))
1143 	    return false;
1144 
1145 	  bitmap_set_bit (*visited_flag_phis,
1146 			  SSA_NAME_VERSION (gimple_phi_result (flag_arg_def)));
1147 
1148 	  /* Now recursively prune the uninitialized phi args.  */
1149 	  uninit_opnds_arg_phi = compute_uninit_opnds_pos (phi_arg_def);
1150 	  if (!prune_uninit_phi_opnds
1151 	      (phi_arg_def, uninit_opnds_arg_phi, flag_arg_def, boundary_cst,
1152 	       cmp_code, visited_phis, visited_flag_phis))
1153 	    return false;
1154 
1155 	  phi_result = gimple_phi_result (flag_arg_def);
1156 	  bitmap_clear_bit (*visited_flag_phis, SSA_NAME_VERSION (phi_result));
1157 	  continue;
1158 	}
1159 
1160       /* Now check if the constant is in the guarded range.  */
1161       if (is_value_included_in (flag_arg, boundary_cst, cmp_code))
1162 	{
1163 	  tree opnd;
1164 	  gimple *opnd_def;
1165 
1166 	  /* Now that we know that this undefined edge is not
1167 	     pruned.  If the operand is defined by another phi,
1168 	     we can further prune the incoming edges of that
1169 	     phi by checking the predicates of this operands.  */
1170 
1171 	  opnd = gimple_phi_arg_def (phi, i);
1172 	  opnd_def = SSA_NAME_DEF_STMT (opnd);
1173 	  if (gphi *opnd_def_phi = dyn_cast <gphi *> (opnd_def))
1174 	    {
1175 	      edge opnd_edge;
1176 	      unsigned uninit_opnds2 = compute_uninit_opnds_pos (opnd_def_phi);
1177 	      if (!MASK_EMPTY (uninit_opnds2))
1178 		{
1179 		  pred_chain_union def_preds = vNULL;
1180 		  bool ok;
1181 		  opnd_edge = gimple_phi_arg_edge (phi, i);
1182 		  ok = is_use_properly_guarded (phi,
1183 						opnd_edge->src,
1184 						opnd_def_phi,
1185 						uninit_opnds2,
1186 						&def_preds,
1187 						visited_phis);
1188 		  destroy_predicate_vecs (&def_preds);
1189 		  if (!ok)
1190 		    return false;
1191 		}
1192 	    }
1193 	  else
1194 	    return false;
1195 	}
1196     }
1197 
1198   return true;
1199 }
1200 
1201 /* A helper function that determines if the predicate set
1202    of the use is not overlapping with that of the uninit paths.
1203    The most common senario of guarded use is in Example 1:
1204      Example 1:
1205 	   if (some_cond)
1206 	   {
1207 	      x = ...;
1208 	      flag = true;
1209 	   }
1210 
1211 	    ... some code ...
1212 
1213 	   if (flag)
1214 	      use (x);
1215 
1216      The real world examples are usually more complicated, but similar
1217      and usually result from inlining:
1218 
1219 	 bool init_func (int * x)
1220 	 {
1221 	     if (some_cond)
1222 		return false;
1223 	     *x  =  ..
1224 	     return true;
1225 	 }
1226 
1227 	 void foo (..)
1228 	 {
1229 	     int x;
1230 
1231 	     if (!init_func (&x))
1232 		return;
1233 
1234 	     .. some_code ...
1235 	     use (x);
1236 	 }
1237 
1238      Another possible use scenario is in the following trivial example:
1239 
1240      Example 2:
1241 	  if (n > 0)
1242 	     x = 1;
1243 	  ...
1244 	  if (n > 0)
1245 	    {
1246 	      if (m < 2)
1247 		 .. = x;
1248 	    }
1249 
1250      Predicate analysis needs to compute the composite predicate:
1251 
1252        1) 'x' use predicate: (n > 0) .AND. (m < 2)
1253        2) 'x' default value  (non-def) predicate: .NOT. (n > 0)
1254        (the predicate chain for phi operand defs can be computed
1255        starting from a bb that is control equivalent to the phi's
1256        bb and is dominating the operand def.)
1257 
1258        and check overlapping:
1259 	  (n > 0) .AND. (m < 2) .AND. (.NOT. (n > 0))
1260 	<==> false
1261 
1262      This implementation provides framework that can handle
1263      scenarios.  (Note that many simple cases are handled properly
1264      without the predicate analysis -- this is due to jump threading
1265      transformation which eliminates the merge point thus makes
1266      path sensitive analysis unnecessary.)
1267 
1268      PHI is the phi node whose incoming (undefined) paths need to be
1269      pruned, and UNINIT_OPNDS is the bitmap holding uninit operand
1270      positions.  VISITED_PHIS is the pointer set of phi stmts being
1271      checked.  */
1272 
1273 static bool
1274 use_pred_not_overlap_with_undef_path_pred (pred_chain_union preds,
1275 					   gphi *phi, unsigned uninit_opnds,
1276 					   hash_set<gphi *> *visited_phis)
1277 {
1278   unsigned int i, n;
1279   gimple *flag_def = 0;
1280   tree boundary_cst = 0;
1281   enum tree_code cmp_code;
1282   bool swap_cond = false;
1283   bool invert = false;
1284   pred_chain the_pred_chain = vNULL;
1285   bitmap visited_flag_phis = NULL;
1286   bool all_pruned = false;
1287   size_t num_preds = preds.length ();
1288 
1289   gcc_assert (num_preds > 0);
1290   /* Find within the common prefix of multiple predicate chains
1291      a predicate that is a comparison of a flag variable against
1292      a constant.  */
1293   the_pred_chain = preds[0];
1294   n = the_pred_chain.length ();
1295   for (i = 0; i < n; i++)
1296     {
1297       tree cond_lhs, cond_rhs, flag = 0;
1298 
1299       pred_info the_pred = the_pred_chain[i];
1300 
1301       invert = the_pred.invert;
1302       cond_lhs = the_pred.pred_lhs;
1303       cond_rhs = the_pred.pred_rhs;
1304       cmp_code = the_pred.cond_code;
1305 
1306       if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME
1307 	  && cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs))
1308 	{
1309 	  boundary_cst = cond_rhs;
1310 	  flag = cond_lhs;
1311 	}
1312       else if (cond_rhs != NULL_TREE && TREE_CODE (cond_rhs) == SSA_NAME
1313 	       && cond_lhs != NULL_TREE && is_gimple_constant (cond_lhs))
1314 	{
1315 	  boundary_cst = cond_lhs;
1316 	  flag = cond_rhs;
1317 	  swap_cond = true;
1318 	}
1319 
1320       if (!flag)
1321 	continue;
1322 
1323       flag_def = SSA_NAME_DEF_STMT (flag);
1324 
1325       if (!flag_def)
1326 	continue;
1327 
1328       if ((gimple_code (flag_def) == GIMPLE_PHI)
1329 	  && (gimple_bb (flag_def) == gimple_bb (phi))
1330 	  && find_matching_predicate_in_rest_chains (the_pred, preds,
1331 						     num_preds))
1332 	break;
1333 
1334       flag_def = 0;
1335     }
1336 
1337   if (!flag_def)
1338     return false;
1339 
1340   /* Now check all the uninit incoming edge has a constant flag value
1341      that is in conflict with the use guard/predicate.  */
1342   cmp_code = get_cmp_code (cmp_code, swap_cond, invert);
1343 
1344   if (cmp_code == ERROR_MARK)
1345     return false;
1346 
1347   all_pruned = prune_uninit_phi_opnds
1348     (phi, uninit_opnds, as_a<gphi *> (flag_def), boundary_cst, cmp_code,
1349      visited_phis, &visited_flag_phis);
1350 
1351   if (visited_flag_phis)
1352     BITMAP_FREE (visited_flag_phis);
1353 
1354   return all_pruned;
1355 }
1356 
1357 /* The helper function returns true if two predicates X1 and X2
1358    are equivalent.  It assumes the expressions have already
1359    properly re-associated.  */
1360 
1361 static inline bool
1362 pred_equal_p (pred_info x1, pred_info x2)
1363 {
1364   enum tree_code c1, c2;
1365   if (!operand_equal_p (x1.pred_lhs, x2.pred_lhs, 0)
1366       || !operand_equal_p (x1.pred_rhs, x2.pred_rhs, 0))
1367     return false;
1368 
1369   c1 = x1.cond_code;
1370   if (x1.invert != x2.invert
1371       && TREE_CODE_CLASS (x2.cond_code) == tcc_comparison)
1372     c2 = invert_tree_comparison (x2.cond_code, false);
1373   else
1374     c2 = x2.cond_code;
1375 
1376   return c1 == c2;
1377 }
1378 
1379 /* Returns true if the predication is testing !=.  */
1380 
1381 static inline bool
1382 is_neq_relop_p (pred_info pred)
1383 {
1384 
1385   return ((pred.cond_code == NE_EXPR && !pred.invert)
1386 	  || (pred.cond_code == EQ_EXPR && pred.invert));
1387 }
1388 
1389 /* Returns true if pred is of the form X != 0.  */
1390 
1391 static inline bool
1392 is_neq_zero_form_p (pred_info pred)
1393 {
1394   if (!is_neq_relop_p (pred) || !integer_zerop (pred.pred_rhs)
1395       || TREE_CODE (pred.pred_lhs) != SSA_NAME)
1396     return false;
1397   return true;
1398 }
1399 
1400 /* The helper function returns true if two predicates X1
1401    is equivalent to X2 != 0.  */
1402 
1403 static inline bool
1404 pred_expr_equal_p (pred_info x1, tree x2)
1405 {
1406   if (!is_neq_zero_form_p (x1))
1407     return false;
1408 
1409   return operand_equal_p (x1.pred_lhs, x2, 0);
1410 }
1411 
1412 /* Returns true of the domain of single predicate expression
1413    EXPR1 is a subset of that of EXPR2.  Returns false if it
1414    can not be proved.  */
1415 
1416 static bool
1417 is_pred_expr_subset_of (pred_info expr1, pred_info expr2)
1418 {
1419   enum tree_code code1, code2;
1420 
1421   if (pred_equal_p (expr1, expr2))
1422     return true;
1423 
1424   if ((TREE_CODE (expr1.pred_rhs) != INTEGER_CST)
1425       || (TREE_CODE (expr2.pred_rhs) != INTEGER_CST))
1426     return false;
1427 
1428   if (!operand_equal_p (expr1.pred_lhs, expr2.pred_lhs, 0))
1429     return false;
1430 
1431   code1 = expr1.cond_code;
1432   if (expr1.invert)
1433     code1 = invert_tree_comparison (code1, false);
1434   code2 = expr2.cond_code;
1435   if (expr2.invert)
1436     code2 = invert_tree_comparison (code2, false);
1437 
1438   if ((code1 == EQ_EXPR || code1 == BIT_AND_EXPR) && code2 == BIT_AND_EXPR)
1439     return wi::eq_p (expr1.pred_rhs,
1440 		     wi::bit_and (expr1.pred_rhs, expr2.pred_rhs));
1441 
1442   if (code1 != code2 && code2 != NE_EXPR)
1443     return false;
1444 
1445   if (is_value_included_in (expr1.pred_rhs, expr2.pred_rhs, code2))
1446     return true;
1447 
1448   return false;
1449 }
1450 
1451 /* Returns true if the domain of PRED1 is a subset
1452    of that of PRED2.  Returns false if it can not be proved so.  */
1453 
1454 static bool
1455 is_pred_chain_subset_of (pred_chain pred1, pred_chain pred2)
1456 {
1457   size_t np1, np2, i1, i2;
1458 
1459   np1 = pred1.length ();
1460   np2 = pred2.length ();
1461 
1462   for (i2 = 0; i2 < np2; i2++)
1463     {
1464       bool found = false;
1465       pred_info info2 = pred2[i2];
1466       for (i1 = 0; i1 < np1; i1++)
1467 	{
1468 	  pred_info info1 = pred1[i1];
1469 	  if (is_pred_expr_subset_of (info1, info2))
1470 	    {
1471 	      found = true;
1472 	      break;
1473 	    }
1474 	}
1475       if (!found)
1476 	return false;
1477     }
1478   return true;
1479 }
1480 
1481 /* Returns true if the domain defined by
1482    one pred chain ONE_PRED is a subset of the domain
1483    of *PREDS.  It returns false if ONE_PRED's domain is
1484    not a subset of any of the sub-domains of PREDS
1485    (corresponding to each individual chains in it), even
1486    though it may be still be a subset of whole domain
1487    of PREDS which is the union (ORed) of all its subdomains.
1488    In other words, the result is conservative.  */
1489 
1490 static bool
1491 is_included_in (pred_chain one_pred, pred_chain_union preds)
1492 {
1493   size_t i;
1494   size_t n = preds.length ();
1495 
1496   for (i = 0; i < n; i++)
1497     {
1498       if (is_pred_chain_subset_of (one_pred, preds[i]))
1499 	return true;
1500     }
1501 
1502   return false;
1503 }
1504 
1505 /* Compares two predicate sets PREDS1 and PREDS2 and returns
1506    true if the domain defined by PREDS1 is a superset
1507    of PREDS2's domain.  N1 and N2 are array sizes of PREDS1 and
1508    PREDS2 respectively.  The implementation chooses not to build
1509    generic trees (and relying on the folding capability of the
1510    compiler), but instead performs brute force comparison of
1511    individual predicate chains (won't be a compile time problem
1512    as the chains are pretty short).  When the function returns
1513    false, it does not necessarily mean *PREDS1 is not a superset
1514    of *PREDS2, but mean it may not be so since the analysis can
1515    not prove it.  In such cases, false warnings may still be
1516    emitted.  */
1517 
1518 static bool
1519 is_superset_of (pred_chain_union preds1, pred_chain_union preds2)
1520 {
1521   size_t i, n2;
1522   pred_chain one_pred_chain = vNULL;
1523 
1524   n2 = preds2.length ();
1525 
1526   for (i = 0; i < n2; i++)
1527     {
1528       one_pred_chain = preds2[i];
1529       if (!is_included_in (one_pred_chain, preds1))
1530 	return false;
1531     }
1532 
1533   return true;
1534 }
1535 
1536 /* Returns true if TC is AND or OR.  */
1537 
1538 static inline bool
1539 is_and_or_or_p (enum tree_code tc, tree type)
1540 {
1541   return (tc == BIT_IOR_EXPR
1542 	  || (tc == BIT_AND_EXPR
1543 	      && (type == 0 || TREE_CODE (type) == BOOLEAN_TYPE)));
1544 }
1545 
1546 /* Returns true if X1 is the negate of X2.  */
1547 
1548 static inline bool
1549 pred_neg_p (pred_info x1, pred_info x2)
1550 {
1551   enum tree_code c1, c2;
1552   if (!operand_equal_p (x1.pred_lhs, x2.pred_lhs, 0)
1553       || !operand_equal_p (x1.pred_rhs, x2.pred_rhs, 0))
1554     return false;
1555 
1556   c1 = x1.cond_code;
1557   if (x1.invert == x2.invert)
1558     c2 = invert_tree_comparison (x2.cond_code, false);
1559   else
1560     c2 = x2.cond_code;
1561 
1562   return c1 == c2;
1563 }
1564 
1565 /* 1) ((x IOR y) != 0) AND (x != 0) is equivalent to (x != 0);
1566    2) (X AND Y) OR (!X AND Y) is equivalent to Y;
1567    3) X OR (!X AND Y) is equivalent to (X OR Y);
1568    4) ((x IAND y) != 0) || (x != 0 AND y != 0)) is equivalent to
1569       (x != 0 AND y != 0)
1570    5) (X AND Y) OR (!X AND Z) OR (!Y AND Z) is equivalent to
1571       (X AND Y) OR Z
1572 
1573    PREDS is the predicate chains, and N is the number of chains.  */
1574 
1575 /* Helper function to implement rule 1 above.  ONE_CHAIN is
1576    the AND predication to be simplified.  */
1577 
1578 static void
1579 simplify_pred (pred_chain *one_chain)
1580 {
1581   size_t i, j, n;
1582   bool simplified = false;
1583   pred_chain s_chain = vNULL;
1584 
1585   n = one_chain->length ();
1586 
1587   for (i = 0; i < n; i++)
1588     {
1589       pred_info *a_pred = &(*one_chain)[i];
1590 
1591       if (!a_pred->pred_lhs)
1592 	continue;
1593       if (!is_neq_zero_form_p (*a_pred))
1594 	continue;
1595 
1596       gimple *def_stmt = SSA_NAME_DEF_STMT (a_pred->pred_lhs);
1597       if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
1598 	continue;
1599       if (gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
1600 	{
1601 	  for (j = 0; j < n; j++)
1602 	    {
1603 	      pred_info *b_pred = &(*one_chain)[j];
1604 
1605 	      if (!b_pred->pred_lhs)
1606 		continue;
1607 	      if (!is_neq_zero_form_p (*b_pred))
1608 		continue;
1609 
1610 	      if (pred_expr_equal_p (*b_pred, gimple_assign_rhs1 (def_stmt))
1611 		  || pred_expr_equal_p (*b_pred, gimple_assign_rhs2 (def_stmt)))
1612 		{
1613 		  /* Mark a_pred for removal.  */
1614 		  a_pred->pred_lhs = NULL;
1615 		  a_pred->pred_rhs = NULL;
1616 		  simplified = true;
1617 		  break;
1618 		}
1619 	    }
1620 	}
1621     }
1622 
1623   if (!simplified)
1624     return;
1625 
1626   for (i = 0; i < n; i++)
1627     {
1628       pred_info *a_pred = &(*one_chain)[i];
1629       if (!a_pred->pred_lhs)
1630 	continue;
1631       s_chain.safe_push (*a_pred);
1632     }
1633 
1634   one_chain->release ();
1635   *one_chain = s_chain;
1636 }
1637 
1638 /* The helper function implements the rule 2 for the
1639    OR predicate PREDS.
1640 
1641    2) (X AND Y) OR (!X AND Y) is equivalent to Y.  */
1642 
1643 static bool
1644 simplify_preds_2 (pred_chain_union *preds)
1645 {
1646   size_t i, j, n;
1647   bool simplified = false;
1648   pred_chain_union s_preds = vNULL;
1649 
1650   /* (X AND Y) OR (!X AND Y) is equivalent to Y.
1651      (X AND Y) OR (X AND !Y) is equivalent to X.  */
1652 
1653   n = preds->length ();
1654   for (i = 0; i < n; i++)
1655     {
1656       pred_info x, y;
1657       pred_chain *a_chain = &(*preds)[i];
1658 
1659       if (a_chain->length () != 2)
1660 	continue;
1661 
1662       x = (*a_chain)[0];
1663       y = (*a_chain)[1];
1664 
1665       for (j = 0; j < n; j++)
1666 	{
1667 	  pred_chain *b_chain;
1668 	  pred_info x2, y2;
1669 
1670 	  if (j == i)
1671 	    continue;
1672 
1673 	  b_chain = &(*preds)[j];
1674 	  if (b_chain->length () != 2)
1675 	    continue;
1676 
1677 	  x2 = (*b_chain)[0];
1678 	  y2 = (*b_chain)[1];
1679 
1680 	  if (pred_equal_p (x, x2) && pred_neg_p (y, y2))
1681 	    {
1682 	      /* Kill a_chain.  */
1683 	      a_chain->release ();
1684 	      b_chain->release ();
1685 	      b_chain->safe_push (x);
1686 	      simplified = true;
1687 	      break;
1688 	    }
1689 	  if (pred_neg_p (x, x2) && pred_equal_p (y, y2))
1690 	    {
1691 	      /* Kill a_chain.  */
1692 	      a_chain->release ();
1693 	      b_chain->release ();
1694 	      b_chain->safe_push (y);
1695 	      simplified = true;
1696 	      break;
1697 	    }
1698 	}
1699     }
1700   /* Now clean up the chain.  */
1701   if (simplified)
1702     {
1703       for (i = 0; i < n; i++)
1704 	{
1705 	  if ((*preds)[i].is_empty ())
1706 	    continue;
1707 	  s_preds.safe_push ((*preds)[i]);
1708 	}
1709       preds->release ();
1710       (*preds) = s_preds;
1711       s_preds = vNULL;
1712     }
1713 
1714   return simplified;
1715 }
1716 
1717 /* The helper function implements the rule 2 for the
1718    OR predicate PREDS.
1719 
1720    3) x OR (!x AND y) is equivalent to x OR y.  */
1721 
1722 static bool
1723 simplify_preds_3 (pred_chain_union *preds)
1724 {
1725   size_t i, j, n;
1726   bool simplified = false;
1727 
1728   /* Now iteratively simplify X OR (!X AND Z ..)
1729        into X OR (Z ...).  */
1730 
1731   n = preds->length ();
1732   if (n < 2)
1733     return false;
1734 
1735   for (i = 0; i < n; i++)
1736     {
1737       pred_info x;
1738       pred_chain *a_chain = &(*preds)[i];
1739 
1740       if (a_chain->length () != 1)
1741 	continue;
1742 
1743       x = (*a_chain)[0];
1744 
1745       for (j = 0; j < n; j++)
1746 	{
1747 	  pred_chain *b_chain;
1748 	  pred_info x2;
1749 	  size_t k;
1750 
1751 	  if (j == i)
1752 	    continue;
1753 
1754 	  b_chain = &(*preds)[j];
1755 	  if (b_chain->length () < 2)
1756 	    continue;
1757 
1758 	  for (k = 0; k < b_chain->length (); k++)
1759 	    {
1760 	      x2 = (*b_chain)[k];
1761 	      if (pred_neg_p (x, x2))
1762 		{
1763 		  b_chain->unordered_remove (k);
1764 		  simplified = true;
1765 		  break;
1766 		}
1767 	    }
1768 	}
1769     }
1770   return simplified;
1771 }
1772 
1773 /* The helper function implements the rule 4 for the
1774    OR predicate PREDS.
1775 
1776    2) ((x AND y) != 0) OR (x != 0 AND y != 0) is equivalent to
1777        (x != 0 ANd y != 0).   */
1778 
1779 static bool
1780 simplify_preds_4 (pred_chain_union *preds)
1781 {
1782   size_t i, j, n;
1783   bool simplified = false;
1784   pred_chain_union s_preds = vNULL;
1785   gimple *def_stmt;
1786 
1787   n = preds->length ();
1788   for (i = 0; i < n; i++)
1789     {
1790       pred_info z;
1791       pred_chain *a_chain = &(*preds)[i];
1792 
1793       if (a_chain->length () != 1)
1794 	continue;
1795 
1796       z = (*a_chain)[0];
1797 
1798       if (!is_neq_zero_form_p (z))
1799 	continue;
1800 
1801       def_stmt = SSA_NAME_DEF_STMT (z.pred_lhs);
1802       if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
1803 	continue;
1804 
1805       if (gimple_assign_rhs_code (def_stmt) != BIT_AND_EXPR)
1806 	continue;
1807 
1808       for (j = 0; j < n; j++)
1809 	{
1810 	  pred_chain *b_chain;
1811 	  pred_info x2, y2;
1812 
1813 	  if (j == i)
1814 	    continue;
1815 
1816 	  b_chain = &(*preds)[j];
1817 	  if (b_chain->length () != 2)
1818 	    continue;
1819 
1820 	  x2 = (*b_chain)[0];
1821 	  y2 = (*b_chain)[1];
1822 	  if (!is_neq_zero_form_p (x2) || !is_neq_zero_form_p (y2))
1823 	    continue;
1824 
1825 	  if ((pred_expr_equal_p (x2, gimple_assign_rhs1 (def_stmt))
1826 	       && pred_expr_equal_p (y2, gimple_assign_rhs2 (def_stmt)))
1827 	      || (pred_expr_equal_p (x2, gimple_assign_rhs2 (def_stmt))
1828 		  && pred_expr_equal_p (y2, gimple_assign_rhs1 (def_stmt))))
1829 	    {
1830 	      /* Kill a_chain.  */
1831 	      a_chain->release ();
1832 	      simplified = true;
1833 	      break;
1834 	    }
1835 	}
1836     }
1837   /* Now clean up the chain.  */
1838   if (simplified)
1839     {
1840       for (i = 0; i < n; i++)
1841 	{
1842 	  if ((*preds)[i].is_empty ())
1843 	    continue;
1844 	  s_preds.safe_push ((*preds)[i]);
1845 	}
1846 
1847       preds->release ();
1848       (*preds) = s_preds;
1849       s_preds = vNULL;
1850     }
1851 
1852   return simplified;
1853 }
1854 
1855 /* This function simplifies predicates in PREDS.  */
1856 
1857 static void
1858 simplify_preds (pred_chain_union *preds, gimple *use_or_def, bool is_use)
1859 {
1860   size_t i, n;
1861   bool changed = false;
1862 
1863   if (dump_file && dump_flags & TDF_DETAILS)
1864     {
1865       fprintf (dump_file, "[BEFORE SIMPLICATION -- ");
1866       dump_predicates (use_or_def, *preds, is_use ? "[USE]:\n" : "[DEF]:\n");
1867     }
1868 
1869   for (i = 0; i < preds->length (); i++)
1870     simplify_pred (&(*preds)[i]);
1871 
1872   n = preds->length ();
1873   if (n < 2)
1874     return;
1875 
1876   do
1877     {
1878       changed = false;
1879       if (simplify_preds_2 (preds))
1880 	changed = true;
1881 
1882       /* Now iteratively simplify X OR (!X AND Z ..)
1883        into X OR (Z ...).  */
1884       if (simplify_preds_3 (preds))
1885 	changed = true;
1886 
1887       if (simplify_preds_4 (preds))
1888 	changed = true;
1889     }
1890   while (changed);
1891 
1892   return;
1893 }
1894 
1895 /* This is a helper function which attempts to normalize predicate chains
1896   by following UD chains.  It basically builds up a big tree of either IOR
1897   operations or AND operations, and convert the IOR tree into a
1898   pred_chain_union or BIT_AND tree into a pred_chain.
1899   Example:
1900 
1901   _3 = _2 RELOP1 _1;
1902   _6 = _5 RELOP2 _4;
1903   _9 = _8 RELOP3 _7;
1904   _10 = _3 | _6;
1905   _12 = _9 | _0;
1906   _t = _10 | _12;
1907 
1908  then _t != 0 will be normalized into a pred_chain_union
1909 
1910    (_2 RELOP1 _1) OR (_5 RELOP2 _4) OR (_8 RELOP3 _7) OR (_0 != 0)
1911 
1912  Similarly given,
1913 
1914   _3 = _2 RELOP1 _1;
1915   _6 = _5 RELOP2 _4;
1916   _9 = _8 RELOP3 _7;
1917   _10 = _3 & _6;
1918   _12 = _9 & _0;
1919 
1920  then _t != 0 will be normalized into a pred_chain:
1921    (_2 RELOP1 _1) AND (_5 RELOP2 _4) AND (_8 RELOP3 _7) AND (_0 != 0)
1922 
1923   */
1924 
1925 /* This is a helper function that stores a PRED into NORM_PREDS.  */
1926 
1927 inline static void
1928 push_pred (pred_chain_union *norm_preds, pred_info pred)
1929 {
1930   pred_chain pred_chain = vNULL;
1931   pred_chain.safe_push (pred);
1932   norm_preds->safe_push (pred_chain);
1933 }
1934 
1935 /* A helper function that creates a predicate of the form
1936    OP != 0 and push it WORK_LIST.  */
1937 
1938 inline static void
1939 push_to_worklist (tree op, vec<pred_info, va_heap, vl_ptr> *work_list,
1940 		  hash_set<tree> *mark_set)
1941 {
1942   if (mark_set->contains (op))
1943     return;
1944   mark_set->add (op);
1945 
1946   pred_info arg_pred;
1947   arg_pred.pred_lhs = op;
1948   arg_pred.pred_rhs = integer_zero_node;
1949   arg_pred.cond_code = NE_EXPR;
1950   arg_pred.invert = false;
1951   work_list->safe_push (arg_pred);
1952 }
1953 
1954 /* A helper that generates a pred_info from a gimple assignment
1955    CMP_ASSIGN with comparison rhs.  */
1956 
1957 static pred_info
1958 get_pred_info_from_cmp (gimple *cmp_assign)
1959 {
1960   pred_info n_pred;
1961   n_pred.pred_lhs = gimple_assign_rhs1 (cmp_assign);
1962   n_pred.pred_rhs = gimple_assign_rhs2 (cmp_assign);
1963   n_pred.cond_code = gimple_assign_rhs_code (cmp_assign);
1964   n_pred.invert = false;
1965   return n_pred;
1966 }
1967 
1968 /* Returns true if the PHI is a degenerated phi with
1969    all args with the same value (relop).  In that case, *PRED
1970    will be updated to that value.  */
1971 
1972 static bool
1973 is_degenerated_phi (gimple *phi, pred_info *pred_p)
1974 {
1975   int i, n;
1976   tree op0;
1977   gimple *def0;
1978   pred_info pred0;
1979 
1980   n = gimple_phi_num_args (phi);
1981   op0 = gimple_phi_arg_def (phi, 0);
1982 
1983   if (TREE_CODE (op0) != SSA_NAME)
1984     return false;
1985 
1986   def0 = SSA_NAME_DEF_STMT (op0);
1987   if (gimple_code (def0) != GIMPLE_ASSIGN)
1988     return false;
1989   if (TREE_CODE_CLASS (gimple_assign_rhs_code (def0)) != tcc_comparison)
1990     return false;
1991   pred0 = get_pred_info_from_cmp (def0);
1992 
1993   for (i = 1; i < n; ++i)
1994     {
1995       gimple *def;
1996       pred_info pred;
1997       tree op = gimple_phi_arg_def (phi, i);
1998 
1999       if (TREE_CODE (op) != SSA_NAME)
2000 	return false;
2001 
2002       def = SSA_NAME_DEF_STMT (op);
2003       if (gimple_code (def) != GIMPLE_ASSIGN)
2004 	return false;
2005       if (TREE_CODE_CLASS (gimple_assign_rhs_code (def)) != tcc_comparison)
2006 	return false;
2007       pred = get_pred_info_from_cmp (def);
2008       if (!pred_equal_p (pred, pred0))
2009 	return false;
2010     }
2011 
2012   *pred_p = pred0;
2013   return true;
2014 }
2015 
2016 /* Normalize one predicate PRED
2017    1) if PRED can no longer be normlized, put it into NORM_PREDS.
2018    2) otherwise if PRED is of the form x != 0, follow x's definition
2019       and put normalized predicates into WORK_LIST.  */
2020 
2021 static void
2022 normalize_one_pred_1 (pred_chain_union *norm_preds,
2023 		      pred_chain *norm_chain,
2024 		      pred_info pred,
2025 		      enum tree_code and_or_code,
2026 		      vec<pred_info, va_heap, vl_ptr> *work_list,
2027 		      hash_set<tree> *mark_set)
2028 {
2029   if (!is_neq_zero_form_p (pred))
2030     {
2031       if (and_or_code == BIT_IOR_EXPR)
2032 	push_pred (norm_preds, pred);
2033       else
2034 	norm_chain->safe_push (pred);
2035       return;
2036     }
2037 
2038   gimple *def_stmt = SSA_NAME_DEF_STMT (pred.pred_lhs);
2039 
2040   if (gimple_code (def_stmt) == GIMPLE_PHI
2041       && is_degenerated_phi (def_stmt, &pred))
2042     work_list->safe_push (pred);
2043   else if (gimple_code (def_stmt) == GIMPLE_PHI && and_or_code == BIT_IOR_EXPR)
2044     {
2045       int i, n;
2046       n = gimple_phi_num_args (def_stmt);
2047 
2048       /* If we see non zero constant, we should punt.  The predicate
2049        * should be one guarding the phi edge.  */
2050       for (i = 0; i < n; ++i)
2051 	{
2052 	  tree op = gimple_phi_arg_def (def_stmt, i);
2053 	  if (TREE_CODE (op) == INTEGER_CST && !integer_zerop (op))
2054 	    {
2055 	      push_pred (norm_preds, pred);
2056 	      return;
2057 	    }
2058 	}
2059 
2060       for (i = 0; i < n; ++i)
2061 	{
2062 	  tree op = gimple_phi_arg_def (def_stmt, i);
2063 	  if (integer_zerop (op))
2064 	    continue;
2065 
2066 	  push_to_worklist (op, work_list, mark_set);
2067 	}
2068     }
2069   else if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
2070     {
2071       if (and_or_code == BIT_IOR_EXPR)
2072 	push_pred (norm_preds, pred);
2073       else
2074 	norm_chain->safe_push (pred);
2075     }
2076   else if (gimple_assign_rhs_code (def_stmt) == and_or_code)
2077     {
2078       /* Avoid splitting up bit manipulations like x & 3 or y | 1.  */
2079       if (is_gimple_min_invariant (gimple_assign_rhs2 (def_stmt)))
2080 	{
2081 	  /* But treat x & 3 as condition.  */
2082 	  if (and_or_code == BIT_AND_EXPR)
2083 	    {
2084 	      pred_info n_pred;
2085 	      n_pred.pred_lhs = gimple_assign_rhs1 (def_stmt);
2086 	      n_pred.pred_rhs = gimple_assign_rhs2 (def_stmt);
2087 	      n_pred.cond_code = and_or_code;
2088 	      n_pred.invert = false;
2089 	      norm_chain->safe_push (n_pred);
2090 	    }
2091 	}
2092       else
2093 	{
2094 	  push_to_worklist (gimple_assign_rhs1 (def_stmt), work_list, mark_set);
2095 	  push_to_worklist (gimple_assign_rhs2 (def_stmt), work_list, mark_set);
2096 	}
2097     }
2098   else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
2099 	   == tcc_comparison)
2100     {
2101       pred_info n_pred = get_pred_info_from_cmp (def_stmt);
2102       if (and_or_code == BIT_IOR_EXPR)
2103 	push_pred (norm_preds, n_pred);
2104       else
2105 	norm_chain->safe_push (n_pred);
2106     }
2107   else
2108     {
2109       if (and_or_code == BIT_IOR_EXPR)
2110 	push_pred (norm_preds, pred);
2111       else
2112 	norm_chain->safe_push (pred);
2113     }
2114 }
2115 
2116 /* Normalize PRED and store the normalized predicates into NORM_PREDS.  */
2117 
2118 static void
2119 normalize_one_pred (pred_chain_union *norm_preds, pred_info pred)
2120 {
2121   vec<pred_info, va_heap, vl_ptr> work_list = vNULL;
2122   enum tree_code and_or_code = ERROR_MARK;
2123   pred_chain norm_chain = vNULL;
2124 
2125   if (!is_neq_zero_form_p (pred))
2126     {
2127       push_pred (norm_preds, pred);
2128       return;
2129     }
2130 
2131   gimple *def_stmt = SSA_NAME_DEF_STMT (pred.pred_lhs);
2132   if (gimple_code (def_stmt) == GIMPLE_ASSIGN)
2133     and_or_code = gimple_assign_rhs_code (def_stmt);
2134   if (and_or_code != BIT_IOR_EXPR && and_or_code != BIT_AND_EXPR)
2135     {
2136       if (TREE_CODE_CLASS (and_or_code) == tcc_comparison)
2137 	{
2138 	  pred_info n_pred = get_pred_info_from_cmp (def_stmt);
2139 	  push_pred (norm_preds, n_pred);
2140 	}
2141       else
2142 	push_pred (norm_preds, pred);
2143       return;
2144     }
2145 
2146   work_list.safe_push (pred);
2147   hash_set<tree> mark_set;
2148 
2149   while (!work_list.is_empty ())
2150     {
2151       pred_info a_pred = work_list.pop ();
2152       normalize_one_pred_1 (norm_preds, &norm_chain, a_pred, and_or_code,
2153 			    &work_list, &mark_set);
2154     }
2155   if (and_or_code == BIT_AND_EXPR)
2156     norm_preds->safe_push (norm_chain);
2157 
2158   work_list.release ();
2159 }
2160 
2161 static void
2162 normalize_one_pred_chain (pred_chain_union *norm_preds, pred_chain one_chain)
2163 {
2164   vec<pred_info, va_heap, vl_ptr> work_list = vNULL;
2165   hash_set<tree> mark_set;
2166   pred_chain norm_chain = vNULL;
2167   size_t i;
2168 
2169   for (i = 0; i < one_chain.length (); i++)
2170     {
2171       work_list.safe_push (one_chain[i]);
2172       mark_set.add (one_chain[i].pred_lhs);
2173     }
2174 
2175   while (!work_list.is_empty ())
2176     {
2177       pred_info a_pred = work_list.pop ();
2178       normalize_one_pred_1 (0, &norm_chain, a_pred, BIT_AND_EXPR, &work_list,
2179 			    &mark_set);
2180     }
2181 
2182   norm_preds->safe_push (norm_chain);
2183   work_list.release ();
2184 }
2185 
2186 /* Normalize predicate chains PREDS and returns the normalized one.  */
2187 
2188 static pred_chain_union
2189 normalize_preds (pred_chain_union preds, gimple *use_or_def, bool is_use)
2190 {
2191   pred_chain_union norm_preds = vNULL;
2192   size_t n = preds.length ();
2193   size_t i;
2194 
2195   if (dump_file && dump_flags & TDF_DETAILS)
2196     {
2197       fprintf (dump_file, "[BEFORE NORMALIZATION --");
2198       dump_predicates (use_or_def, preds, is_use ? "[USE]:\n" : "[DEF]:\n");
2199     }
2200 
2201   for (i = 0; i < n; i++)
2202     {
2203       if (preds[i].length () != 1)
2204 	normalize_one_pred_chain (&norm_preds, preds[i]);
2205       else
2206 	{
2207 	  normalize_one_pred (&norm_preds, preds[i][0]);
2208 	  preds[i].release ();
2209 	}
2210     }
2211 
2212   if (dump_file)
2213     {
2214       fprintf (dump_file, "[AFTER NORMALIZATION -- ");
2215       dump_predicates (use_or_def, norm_preds,
2216 		       is_use ? "[USE]:\n" : "[DEF]:\n");
2217     }
2218 
2219   destroy_predicate_vecs (&preds);
2220   return norm_preds;
2221 }
2222 
2223 /* Return TRUE if PREDICATE can be invalidated by any individual
2224    predicate in WORKLIST.  */
2225 
2226 static bool
2227 can_one_predicate_be_invalidated_p (pred_info predicate,
2228 				    pred_chain use_guard)
2229 {
2230   for (size_t i = 0; i < use_guard.length (); ++i)
2231     {
2232       /* NOTE: This is a very simple check, and only understands an
2233 	 exact opposite.  So, [i == 0] is currently only invalidated
2234 	 by [.NOT. i == 0] or [i != 0].  Ideally we should also
2235 	 invalidate with say [i > 5] or [i == 8].  There is certainly
2236 	 room for improvement here.  */
2237       if (pred_neg_p (predicate, use_guard[i]))
2238 	return true;
2239     }
2240   return false;
2241 }
2242 
2243 /* Return TRUE if all predicates in UNINIT_PRED are invalidated by
2244    USE_GUARD being true.  */
2245 
2246 static bool
2247 can_chain_union_be_invalidated_p (pred_chain_union uninit_pred,
2248 				  pred_chain use_guard)
2249 {
2250   if (uninit_pred.is_empty ())
2251     return false;
2252   for (size_t i = 0; i < uninit_pred.length (); ++i)
2253     {
2254       pred_chain c = uninit_pred[i];
2255       for (size_t j = 0; j < c.length (); ++j)
2256 	if (!can_one_predicate_be_invalidated_p (c[j], use_guard))
2257 	  return false;
2258     }
2259   return true;
2260 }
2261 
2262 /* Return TRUE if none of the uninitialized operands in UNINT_OPNDS
2263    can actually happen if we arrived at a use for PHI.
2264 
2265    PHI_USE_GUARDS are the guard conditions for the use of the PHI.  */
2266 
2267 static bool
2268 uninit_uses_cannot_happen (gphi *phi, unsigned uninit_opnds,
2269 			   pred_chain_union phi_use_guards)
2270 {
2271   unsigned phi_args = gimple_phi_num_args (phi);
2272   if (phi_args > max_phi_args)
2273     return false;
2274 
2275   /* PHI_USE_GUARDS are OR'ed together.  If we have more than one
2276      possible guard, there's no way of knowing which guard was true.
2277      Since we need to be absolutely sure that the uninitialized
2278      operands will be invalidated, bail.  */
2279   if (phi_use_guards.length () != 1)
2280     return false;
2281 
2282   /* Look for the control dependencies of all the uninitialized
2283      operands and build guard predicates describing them.  */
2284   pred_chain_union uninit_preds;
2285   bool ret = true;
2286   for (unsigned i = 0; i < phi_args; ++i)
2287     {
2288       if (!MASK_TEST_BIT (uninit_opnds, i))
2289 	continue;
2290 
2291       edge e = gimple_phi_arg_edge (phi, i);
2292       vec<edge> dep_chains[MAX_NUM_CHAINS];
2293       auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
2294       size_t num_chains = 0;
2295       int num_calls = 0;
2296 
2297       /* Build the control dependency chain for uninit operand `i'...  */
2298       uninit_preds = vNULL;
2299       if (!compute_control_dep_chain (find_dom (e->src),
2300 				      e->src, dep_chains, &num_chains,
2301 				      &cur_chain, &num_calls))
2302 	{
2303 	  ret = false;
2304 	  break;
2305 	}
2306       /* ...and convert it into a set of predicates.  */
2307       convert_control_dep_chain_into_preds (dep_chains, num_chains,
2308 					    &uninit_preds);
2309       for (size_t j = 0; j < num_chains; ++j)
2310 	dep_chains[j].release ();
2311       simplify_preds (&uninit_preds, NULL, false);
2312       uninit_preds = normalize_preds (uninit_preds, NULL, false);
2313 
2314       /* Can the guard for this uninitialized operand be invalidated
2315 	 by the PHI use?  */
2316       if (!can_chain_union_be_invalidated_p (uninit_preds, phi_use_guards[0]))
2317 	{
2318 	  ret = false;
2319 	  break;
2320 	}
2321     }
2322   destroy_predicate_vecs (&uninit_preds);
2323   return ret;
2324 }
2325 
2326 /* Computes the predicates that guard the use and checks
2327    if the incoming paths that have empty (or possibly
2328    empty) definition can be pruned/filtered.  The function returns
2329    true if it can be determined that the use of PHI's def in
2330    USE_STMT is guarded with a predicate set not overlapping with
2331    predicate sets of all runtime paths that do not have a definition.
2332 
2333    Returns false if it is not or it can not be determined.  USE_BB is
2334    the bb of the use (for phi operand use, the bb is not the bb of
2335    the phi stmt, but the src bb of the operand edge).
2336 
2337    UNINIT_OPNDS is a bit vector.  If an operand of PHI is uninitialized, the
2338    corresponding bit in the vector is 1.  VISITED_PHIS is a pointer
2339    set of phis being visited.
2340 
2341    *DEF_PREDS contains the (memoized) defining predicate chains of PHI.
2342    If *DEF_PREDS is the empty vector, the defining predicate chains of
2343    PHI will be computed and stored into *DEF_PREDS as needed.
2344 
2345    VISITED_PHIS is a pointer set of phis being visited.  */
2346 
2347 static bool
2348 is_use_properly_guarded (gimple *use_stmt,
2349 			 basic_block use_bb,
2350 			 gphi *phi,
2351 			 unsigned uninit_opnds,
2352 			 pred_chain_union *def_preds,
2353 			 hash_set<gphi *> *visited_phis)
2354 {
2355   basic_block phi_bb;
2356   pred_chain_union preds = vNULL;
2357   bool has_valid_preds = false;
2358   bool is_properly_guarded = false;
2359 
2360   if (visited_phis->add (phi))
2361     return false;
2362 
2363   phi_bb = gimple_bb (phi);
2364 
2365   if (is_non_loop_exit_postdominating (use_bb, phi_bb))
2366     return false;
2367 
2368   has_valid_preds = find_predicates (&preds, phi_bb, use_bb);
2369 
2370   if (!has_valid_preds)
2371     {
2372       destroy_predicate_vecs (&preds);
2373       return false;
2374     }
2375 
2376   /* Try to prune the dead incoming phi edges.  */
2377   is_properly_guarded
2378     = use_pred_not_overlap_with_undef_path_pred (preds, phi, uninit_opnds,
2379 						 visited_phis);
2380 
2381   /* We might be able to prove that if the control dependencies
2382      for UNINIT_OPNDS are true, that the control dependencies for
2383      USE_STMT can never be true.  */
2384   if (!is_properly_guarded)
2385     is_properly_guarded |= uninit_uses_cannot_happen (phi, uninit_opnds,
2386 						      preds);
2387 
2388   if (is_properly_guarded)
2389     {
2390       destroy_predicate_vecs (&preds);
2391       return true;
2392     }
2393 
2394   if (def_preds->is_empty ())
2395     {
2396       has_valid_preds = find_def_preds (def_preds, phi);
2397 
2398       if (!has_valid_preds)
2399 	{
2400 	  destroy_predicate_vecs (&preds);
2401 	  return false;
2402 	}
2403 
2404       simplify_preds (def_preds, phi, false);
2405       *def_preds = normalize_preds (*def_preds, phi, false);
2406     }
2407 
2408   simplify_preds (&preds, use_stmt, true);
2409   preds = normalize_preds (preds, use_stmt, true);
2410 
2411   is_properly_guarded = is_superset_of (*def_preds, preds);
2412 
2413   destroy_predicate_vecs (&preds);
2414   return is_properly_guarded;
2415 }
2416 
2417 /* Searches through all uses of a potentially
2418    uninitialized variable defined by PHI and returns a use
2419    statement if the use is not properly guarded.  It returns
2420    NULL if all uses are guarded.  UNINIT_OPNDS is a bitvector
2421    holding the position(s) of uninit PHI operands.  WORKLIST
2422    is the vector of candidate phis that may be updated by this
2423    function.  ADDED_TO_WORKLIST is the pointer set tracking
2424    if the new phi is already in the worklist.  */
2425 
2426 static gimple *
2427 find_uninit_use (gphi *phi, unsigned uninit_opnds,
2428 		 vec<gphi *> *worklist,
2429 		 hash_set<gphi *> *added_to_worklist)
2430 {
2431   tree phi_result;
2432   use_operand_p use_p;
2433   gimple *use_stmt;
2434   imm_use_iterator iter;
2435   pred_chain_union def_preds = vNULL;
2436   gimple *ret = NULL;
2437 
2438   phi_result = gimple_phi_result (phi);
2439 
2440   FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
2441     {
2442       basic_block use_bb;
2443 
2444       use_stmt = USE_STMT (use_p);
2445       if (is_gimple_debug (use_stmt))
2446 	continue;
2447 
2448       if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
2449 	use_bb = gimple_phi_arg_edge (use_phi,
2450 				      PHI_ARG_INDEX_FROM_USE (use_p))->src;
2451       else
2452 	use_bb = gimple_bb (use_stmt);
2453 
2454       hash_set<gphi *> visited_phis;
2455       if (is_use_properly_guarded (use_stmt, use_bb, phi, uninit_opnds,
2456 				   &def_preds, &visited_phis))
2457 	continue;
2458 
2459       if (dump_file && (dump_flags & TDF_DETAILS))
2460 	{
2461 	  fprintf (dump_file, "[CHECK]: Found unguarded use: ");
2462 	  print_gimple_stmt (dump_file, use_stmt, 0, 0);
2463 	}
2464       /* Found one real use, return.  */
2465       if (gimple_code (use_stmt) != GIMPLE_PHI)
2466 	{
2467 	  ret = use_stmt;
2468 	  break;
2469 	}
2470 
2471       /* Found a phi use that is not guarded,
2472 	 add the phi to the worklist.  */
2473       if (!added_to_worklist->add (as_a<gphi *> (use_stmt)))
2474 	{
2475 	  if (dump_file && (dump_flags & TDF_DETAILS))
2476 	    {
2477 	      fprintf (dump_file, "[WORKLIST]: Update worklist with phi: ");
2478 	      print_gimple_stmt (dump_file, use_stmt, 0, 0);
2479 	    }
2480 
2481 	  worklist->safe_push (as_a<gphi *> (use_stmt));
2482 	  possibly_undefined_names->add (phi_result);
2483 	}
2484     }
2485 
2486   destroy_predicate_vecs (&def_preds);
2487   return ret;
2488 }
2489 
2490 /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
2491    and gives warning if there exists a runtime path from the entry to a
2492    use of the PHI def that does not contain a definition.  In other words,
2493    the warning is on the real use.  The more dead paths that can be pruned
2494    by the compiler, the fewer false positives the warning is.  WORKLIST
2495    is a vector of candidate phis to be examined.  ADDED_TO_WORKLIST is
2496    a pointer set tracking if the new phi is added to the worklist or not.  */
2497 
2498 static void
2499 warn_uninitialized_phi (gphi *phi, vec<gphi *> *worklist,
2500 			hash_set<gphi *> *added_to_worklist)
2501 {
2502   unsigned uninit_opnds;
2503   gimple *uninit_use_stmt = 0;
2504   tree uninit_op;
2505   int phiarg_index;
2506   location_t loc;
2507 
2508   /* Don't look at virtual operands.  */
2509   if (virtual_operand_p (gimple_phi_result (phi)))
2510     return;
2511 
2512   uninit_opnds = compute_uninit_opnds_pos (phi);
2513 
2514   if (MASK_EMPTY (uninit_opnds))
2515     return;
2516 
2517   if (dump_file && (dump_flags & TDF_DETAILS))
2518     {
2519       fprintf (dump_file, "[CHECK]: examining phi: ");
2520       print_gimple_stmt (dump_file, phi, 0, 0);
2521     }
2522 
2523   /* Now check if we have any use of the value without proper guard.  */
2524   uninit_use_stmt = find_uninit_use (phi, uninit_opnds,
2525 				     worklist, added_to_worklist);
2526 
2527   /* All uses are properly guarded.  */
2528   if (!uninit_use_stmt)
2529     return;
2530 
2531   phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
2532   uninit_op = gimple_phi_arg_def (phi, phiarg_index);
2533   if (SSA_NAME_VAR (uninit_op) == NULL_TREE)
2534     return;
2535   if (gimple_phi_arg_has_location (phi, phiarg_index))
2536     loc = gimple_phi_arg_location (phi, phiarg_index);
2537   else
2538     loc = UNKNOWN_LOCATION;
2539   warn_uninit (OPT_Wmaybe_uninitialized, uninit_op, SSA_NAME_VAR (uninit_op),
2540 	       SSA_NAME_VAR (uninit_op),
2541 	       "%qD may be used uninitialized in this function",
2542 	       uninit_use_stmt, loc);
2543 }
2544 
2545 static bool
2546 gate_warn_uninitialized (void)
2547 {
2548   return warn_uninitialized || warn_maybe_uninitialized;
2549 }
2550 
2551 namespace {
2552 
2553 const pass_data pass_data_late_warn_uninitialized =
2554 {
2555   GIMPLE_PASS, /* type */
2556   "uninit", /* name */
2557   OPTGROUP_NONE, /* optinfo_flags */
2558   TV_NONE, /* tv_id */
2559   PROP_ssa, /* properties_required */
2560   0, /* properties_provided */
2561   0, /* properties_destroyed */
2562   0, /* todo_flags_start */
2563   0, /* todo_flags_finish */
2564 };
2565 
2566 class pass_late_warn_uninitialized : public gimple_opt_pass
2567 {
2568 public:
2569   pass_late_warn_uninitialized (gcc::context *ctxt)
2570     : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
2571   {}
2572 
2573   /* opt_pass methods: */
2574   opt_pass *clone () { return new pass_late_warn_uninitialized (m_ctxt); }
2575   virtual bool gate (function *) { return gate_warn_uninitialized (); }
2576   virtual unsigned int execute (function *);
2577 
2578 }; // class pass_late_warn_uninitialized
2579 
2580 unsigned int
2581 pass_late_warn_uninitialized::execute (function *fun)
2582 {
2583   basic_block bb;
2584   gphi_iterator gsi;
2585   vec<gphi *> worklist = vNULL;
2586 
2587   calculate_dominance_info (CDI_DOMINATORS);
2588   calculate_dominance_info (CDI_POST_DOMINATORS);
2589   /* Re-do the plain uninitialized variable check, as optimization may have
2590      straightened control flow.  Do this first so that we don't accidentally
2591      get a "may be" warning when we'd have seen an "is" warning later.  */
2592   warn_uninitialized_vars (/*warn_possibly_uninitialized=*/1);
2593 
2594   timevar_push (TV_TREE_UNINIT);
2595 
2596   possibly_undefined_names = new hash_set<tree>;
2597   hash_set<gphi *> added_to_worklist;
2598 
2599   /* Initialize worklist  */
2600   FOR_EACH_BB_FN (bb, fun)
2601     for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2602       {
2603 	gphi *phi = gsi.phi ();
2604 	size_t n, i;
2605 
2606 	n = gimple_phi_num_args (phi);
2607 
2608 	/* Don't look at virtual operands.  */
2609 	if (virtual_operand_p (gimple_phi_result (phi)))
2610 	  continue;
2611 
2612 	for (i = 0; i < n; ++i)
2613 	  {
2614 	    tree op = gimple_phi_arg_def (phi, i);
2615 	    if (TREE_CODE (op) == SSA_NAME && uninit_undefined_value_p (op))
2616 	      {
2617 		worklist.safe_push (phi);
2618 		added_to_worklist.add (phi);
2619 		if (dump_file && (dump_flags & TDF_DETAILS))
2620 		  {
2621 		    fprintf (dump_file, "[WORKLIST]: add to initial list: ");
2622 		    print_gimple_stmt (dump_file, phi, 0, 0);
2623 		  }
2624 		break;
2625 	      }
2626 	  }
2627       }
2628 
2629   while (worklist.length () != 0)
2630     {
2631       gphi *cur_phi = 0;
2632       cur_phi = worklist.pop ();
2633       warn_uninitialized_phi (cur_phi, &worklist, &added_to_worklist);
2634     }
2635 
2636   worklist.release ();
2637   delete possibly_undefined_names;
2638   possibly_undefined_names = NULL;
2639   free_dominance_info (CDI_POST_DOMINATORS);
2640   timevar_pop (TV_TREE_UNINIT);
2641   return 0;
2642 }
2643 
2644 } // anon namespace
2645 
2646 gimple_opt_pass *
2647 make_pass_late_warn_uninitialized (gcc::context *ctxt)
2648 {
2649   return new pass_late_warn_uninitialized (ctxt);
2650 }
2651 
2652 static unsigned int
2653 execute_early_warn_uninitialized (void)
2654 {
2655   /* Currently, this pass runs always but
2656      execute_late_warn_uninitialized only runs with optimization.  With
2657      optimization we want to warn about possible uninitialized as late
2658      as possible, thus don't do it here.  However, without
2659      optimization we need to warn here about "may be uninitialized".  */
2660   calculate_dominance_info (CDI_POST_DOMINATORS);
2661 
2662   warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize);
2663 
2664   /* Post-dominator information can not be reliably updated.  Free it
2665      after the use.  */
2666 
2667   free_dominance_info (CDI_POST_DOMINATORS);
2668   return 0;
2669 }
2670 
2671 namespace {
2672 
2673 const pass_data pass_data_early_warn_uninitialized =
2674 {
2675   GIMPLE_PASS, /* type */
2676   "*early_warn_uninitialized", /* name */
2677   OPTGROUP_NONE, /* optinfo_flags */
2678   TV_TREE_UNINIT, /* tv_id */
2679   PROP_ssa, /* properties_required */
2680   0, /* properties_provided */
2681   0, /* properties_destroyed */
2682   0, /* todo_flags_start */
2683   0, /* todo_flags_finish */
2684 };
2685 
2686 class pass_early_warn_uninitialized : public gimple_opt_pass
2687 {
2688 public:
2689   pass_early_warn_uninitialized (gcc::context *ctxt)
2690     : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
2691   {}
2692 
2693   /* opt_pass methods: */
2694   virtual bool gate (function *) { return gate_warn_uninitialized (); }
2695   virtual unsigned int execute (function *)
2696   {
2697     return execute_early_warn_uninitialized ();
2698   }
2699 
2700 }; // class pass_early_warn_uninitialized
2701 
2702 } // anon namespace
2703 
2704 gimple_opt_pass *
2705 make_pass_early_warn_uninitialized (gcc::context *ctxt)
2706 {
2707   return new pass_early_warn_uninitialized (ctxt);
2708 }
2709