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