testsuite: Correct vec-rlmi-rlnm.c testsuite expected result
[official-gcc.git] / gcc / tree-ssa-uninit.c
blob7ed16866afa60c1b78e38af648db7f7baf4d1c36
1 /* Predicate aware uninitialized variable warning.
2 Copyright (C) 2001-2020 Free Software Foundation, Inc.
3 Contributed by Xinliang David Li <davidxl@google.com>
5 This file is part of GCC.
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.
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.
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/>. */
21 #define INCLUDE_STRING
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "tree-pass.h"
29 #include "ssa.h"
30 #include "gimple-pretty-print.h"
31 #include "diagnostic-core.h"
32 #include "fold-const.h"
33 #include "gimple-iterator.h"
34 #include "tree-ssa.h"
35 #include "tree-cfg.h"
36 #include "cfghooks.h"
37 #include "attribs.h"
38 #include "builtins.h"
39 #include "calls.h"
41 /* This implements the pass that does predicate aware warning on uses of
42 possibly uninitialized variables. The pass first collects the set of
43 possibly uninitialized SSA names. For each such name, it walks through
44 all its immediate uses. For each immediate use, it rebuilds the condition
45 expression (the predicate) that guards the use. The predicate is then
46 examined to see if the variable is always defined under that same condition.
47 This is done either by pruning the unrealizable paths that lead to the
48 default definitions or by checking if the predicate set that guards the
49 defining paths is a superset of the use predicate. */
51 /* Max PHI args we can handle in pass. */
52 const unsigned max_phi_args = 32;
54 /* Pointer set of potentially undefined ssa names, i.e.,
55 ssa names that are defined by phi with operands that
56 are not defined or potentially undefined. */
57 static hash_set<tree> *possibly_undefined_names = 0;
59 /* Bit mask handling macros. */
60 #define MASK_SET_BIT(mask, pos) mask |= (1 << pos)
61 #define MASK_TEST_BIT(mask, pos) (mask & (1 << pos))
62 #define MASK_EMPTY(mask) (mask == 0)
64 /* Returns the first bit position (starting from LSB)
65 in mask that is non zero. Returns -1 if the mask is empty. */
66 static int
67 get_mask_first_set_bit (unsigned mask)
69 int pos = 0;
70 if (mask == 0)
71 return -1;
73 while ((mask & (1 << pos)) == 0)
74 pos++;
76 return pos;
78 #define MASK_FIRST_SET_BIT(mask) get_mask_first_set_bit (mask)
80 /* Return true if T, an SSA_NAME, has an undefined value. */
81 static bool
82 has_undefined_value_p (tree t)
84 return (ssa_undefined_value_p (t)
85 || (possibly_undefined_names
86 && possibly_undefined_names->contains (t)));
89 /* Like has_undefined_value_p, but don't return true if TREE_NO_WARNING
90 is set on SSA_NAME_VAR. */
92 static inline bool
93 uninit_undefined_value_p (tree t)
95 if (!has_undefined_value_p (t))
96 return false;
97 if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t)))
98 return false;
99 return true;
102 /* Emit warnings for uninitialized variables. This is done in two passes.
104 The first pass notices real uses of SSA names with undefined values.
105 Such uses are unconditionally uninitialized, and we can be certain that
106 such a use is a mistake. This pass is run before most optimizations,
107 so that we catch as many as we can.
109 The second pass follows PHI nodes to find uses that are potentially
110 uninitialized. In this case we can't necessarily prove that the use
111 is really uninitialized. This pass is run after most optimizations,
112 so that we thread as many jumps and possible, and delete as much dead
113 code as possible, in order to reduce false positives. We also look
114 again for plain uninitialized variables, since optimization may have
115 changed conditionally uninitialized to unconditionally uninitialized. */
117 /* Emit a warning for EXPR based on variable VAR at the point in the
118 program T, an SSA_NAME, is used being uninitialized. The exact
119 warning text is in MSGID and DATA is the gimple stmt with info about
120 the location in source code. When DATA is a GIMPLE_PHI, PHIARG_IDX
121 gives which argument of the phi node to take the location from. WC
122 is the warning code. */
124 static void
125 warn_uninit (enum opt_code wc, tree t, tree expr, tree var,
126 const char *gmsgid, void *data, location_t phiarg_loc)
128 gimple *context = (gimple *) data;
129 location_t location, cfun_loc;
130 expanded_location xloc, floc;
132 /* Ignore COMPLEX_EXPR as initializing only a part of a complex
133 turns in a COMPLEX_EXPR with the not initialized part being
134 set to its previous (undefined) value. */
135 if (is_gimple_assign (context)
136 && gimple_assign_rhs_code (context) == COMPLEX_EXPR)
137 return;
138 if (!has_undefined_value_p (t))
139 return;
141 /* Anonymous SSA_NAMEs shouldn't be uninitialized, but ssa_undefined_value_p
142 can return true if the def stmt of anonymous SSA_NAME is COMPLEX_EXPR
143 created for conversion from scalar to complex. Use the underlying var of
144 the COMPLEX_EXPRs real part in that case. See PR71581. */
145 if (expr == NULL_TREE
146 && var == NULL_TREE
147 && SSA_NAME_VAR (t) == NULL_TREE
148 && is_gimple_assign (SSA_NAME_DEF_STMT (t))
149 && gimple_assign_rhs_code (SSA_NAME_DEF_STMT (t)) == COMPLEX_EXPR)
151 tree v = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (t));
152 if (TREE_CODE (v) == SSA_NAME
153 && has_undefined_value_p (v)
154 && zerop (gimple_assign_rhs2 (SSA_NAME_DEF_STMT (t))))
156 expr = SSA_NAME_VAR (v);
157 var = expr;
161 if (expr == NULL_TREE)
162 return;
164 /* TREE_NO_WARNING either means we already warned, or the front end
165 wishes to suppress the warning. */
166 if ((context
167 && (gimple_no_warning_p (context)
168 || (gimple_assign_single_p (context)
169 && TREE_NO_WARNING (gimple_assign_rhs1 (context)))))
170 || TREE_NO_WARNING (expr))
171 return;
173 if (context != NULL && gimple_has_location (context))
174 location = gimple_location (context);
175 else if (phiarg_loc != UNKNOWN_LOCATION)
176 location = phiarg_loc;
177 else
178 location = DECL_SOURCE_LOCATION (var);
179 location = linemap_resolve_location (line_table, location,
180 LRK_SPELLING_LOCATION, NULL);
181 cfun_loc = DECL_SOURCE_LOCATION (cfun->decl);
182 xloc = expand_location (location);
183 floc = expand_location (cfun_loc);
184 auto_diagnostic_group d;
185 if (warning_at (location, wc, gmsgid, expr))
187 TREE_NO_WARNING (expr) = 1;
189 if (location == DECL_SOURCE_LOCATION (var))
190 return;
191 if (xloc.file != floc.file
192 || linemap_location_before_p (line_table, location, cfun_loc)
193 || linemap_location_before_p (line_table, cfun->function_end_locus,
194 location))
195 inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var);
199 struct check_defs_data
201 /* If we found any may-defs besides must-def clobbers. */
202 bool found_may_defs;
205 /* Callback for walk_aliased_vdefs. */
207 static bool
208 check_defs (ao_ref *ref, tree vdef, void *data_)
210 check_defs_data *data = (check_defs_data *)data_;
211 gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);
212 /* If this is a clobber then if it is not a kill walk past it. */
213 if (gimple_clobber_p (def_stmt))
215 if (stmt_kills_ref_p (def_stmt, ref))
216 return true;
217 return false;
219 /* Found a may-def on this path. */
220 data->found_may_defs = true;
221 return true;
224 /* Counters and limits controlling the the depth of analysis and
225 strictness of the warning. */
226 struct wlimits
228 /* Number of VDEFs encountered. */
229 unsigned int vdef_cnt;
230 /* Number of statements examined by walk_aliased_vdefs. */
231 unsigned int oracle_cnt;
232 /* Limit on the number of statements visited by walk_aliased_vdefs. */
233 unsigned limit;
234 /* Set when basic block with statement is executed unconditionally. */
235 bool always_executed;
236 /* Set to issue -Wmaybe-uninitialized. */
237 bool wmaybe_uninit;
240 /* Determine if REF references an uninitialized operand and diagnose
241 it if so. */
243 static tree
244 maybe_warn_operand (ao_ref &ref, gimple *stmt, tree lhs, tree rhs,
245 wlimits &wlims)
247 bool has_bit_insert = false;
248 use_operand_p luse_p;
249 imm_use_iterator liter;
251 if (TREE_NO_WARNING (rhs))
252 return NULL_TREE;
254 /* Do not warn if the base was marked so or this is a
255 hard register var. */
256 tree base = ao_ref_base (&ref);
257 if ((VAR_P (base)
258 && DECL_HARD_REGISTER (base))
259 || TREE_NO_WARNING (base))
260 return NULL_TREE;
262 /* Do not warn if the access is fully outside of the variable. */
263 poly_int64 decl_size;
264 if (DECL_P (base)
265 && ((known_size_p (ref.size)
266 && known_eq (ref.max_size, ref.size)
267 && known_le (ref.offset + ref.size, 0))
268 || (known_ge (ref.offset, 0)
269 && DECL_SIZE (base)
270 && poly_int_tree_p (DECL_SIZE (base), &decl_size)
271 && known_le (decl_size, ref.offset))))
272 return NULL_TREE;
274 /* Do not warn if the result of the access is then used for
275 a BIT_INSERT_EXPR. */
276 if (lhs && TREE_CODE (lhs) == SSA_NAME)
277 FOR_EACH_IMM_USE_FAST (luse_p, liter, lhs)
279 gimple *use_stmt = USE_STMT (luse_p);
280 /* BIT_INSERT_EXPR first operand should not be considered
281 a use for the purpose of uninit warnings. */
282 if (gassign *ass = dyn_cast <gassign *> (use_stmt))
284 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
285 && luse_p->use == gimple_assign_rhs1_ptr (ass))
287 has_bit_insert = true;
288 break;
293 if (has_bit_insert)
294 return NULL_TREE;
296 /* Limit the walking to a constant number of stmts after
297 we overcommit quadratic behavior for small functions
298 and O(n) behavior. */
299 if (wlims.oracle_cnt > 128 * 128
300 && wlims.oracle_cnt > wlims.vdef_cnt * 2)
301 wlims.limit = 32;
303 check_defs_data data;
304 bool fentry_reached = false;
305 data.found_may_defs = false;
306 tree use = gimple_vuse (stmt);
307 if (!use)
308 return NULL_TREE;
309 int res = walk_aliased_vdefs (&ref, use,
310 check_defs, &data, NULL,
311 &fentry_reached, wlims.limit);
312 if (res == -1)
314 wlims.oracle_cnt += wlims.limit;
315 return NULL_TREE;
318 wlims.oracle_cnt += res;
319 if (data.found_may_defs)
320 return NULL_TREE;
322 bool found_alloc = false;
324 if (fentry_reached)
326 if (TREE_CODE (base) == MEM_REF)
327 base = TREE_OPERAND (base, 0);
329 /* Follow the chain of SSA_NAME assignments looking for an alloca
330 call (or VLA) or malloc/realloc, or for decls. If any is found
331 (and in the latter case, the operand is a local variable) issue
332 a warning. */
333 while (TREE_CODE (base) == SSA_NAME)
335 gimple *def_stmt = SSA_NAME_DEF_STMT (base);
337 if (is_gimple_call (def_stmt)
338 && gimple_call_builtin_p (def_stmt))
340 /* Detect uses of uninitialized alloca/VLAs. */
341 tree fndecl = gimple_call_fndecl (def_stmt);
342 const built_in_function fncode = DECL_FUNCTION_CODE (fndecl);
343 if (fncode == BUILT_IN_ALLOCA
344 || fncode == BUILT_IN_ALLOCA_WITH_ALIGN
345 || fncode == BUILT_IN_MALLOC)
346 found_alloc = true;
347 break;
350 if (!is_gimple_assign (def_stmt))
351 break;
353 tree_code code = gimple_assign_rhs_code (def_stmt);
354 if (code != ADDR_EXPR && code != POINTER_PLUS_EXPR)
355 break;
357 base = gimple_assign_rhs1 (def_stmt);
358 if (TREE_CODE (base) == ADDR_EXPR)
359 base = TREE_OPERAND (base, 0);
361 if (DECL_P (base)
362 || TREE_CODE (base) == COMPONENT_REF)
363 rhs = base;
365 if (TREE_CODE (base) == MEM_REF)
366 base = TREE_OPERAND (base, 0);
368 if (tree ba = get_base_address (base))
369 base = ba;
372 /* Replace the RHS expression with BASE so that it
373 refers to it in the diagnostic (instead of to
374 '<unknown>'). */
375 if (DECL_P (base)
376 && EXPR_P (rhs)
377 && TREE_CODE (rhs) != COMPONENT_REF)
378 rhs = base;
381 /* Do not warn if it can be initialized outside this function.
382 If we did not reach function entry then we found killing
383 clobbers on all paths to entry. */
384 if (!found_alloc
385 && fentry_reached
386 /* ??? We'd like to use ref_may_alias_global_p but that
387 excludes global readonly memory and thus we get bogus
388 warnings from p = cond ? "a" : "b" for example. */
389 && (!VAR_P (base)
390 || is_global_var (base)))
391 return NULL_TREE;
393 /* Strip the address-of expression from arrays passed to functions. */
394 if (TREE_CODE (rhs) == ADDR_EXPR)
395 rhs = TREE_OPERAND (rhs, 0);
397 /* Check again since RHS may have changed above. */
398 if (TREE_NO_WARNING (rhs))
399 return NULL_TREE;
401 /* Avoid warning about empty types such as structs with no members.
402 The first_field() test is important for C++ where the predicate
403 alone isn't always sufficient. */
404 tree rhstype = TREE_TYPE (rhs);
405 if (POINTER_TYPE_P (rhstype))
406 rhstype = TREE_TYPE (rhstype);
407 if (TYPE_EMPTY_P (rhstype)
408 || (RECORD_OR_UNION_TYPE_P (rhstype)
409 && (!first_field (rhstype)
410 || default_is_empty_record (rhstype))))
411 return NULL_TREE;
413 bool warned = false;
414 /* We didn't find any may-defs so on all paths either
415 reached function entry or a killing clobber. */
416 location_t location
417 = linemap_resolve_location (line_table, gimple_location (stmt),
418 LRK_SPELLING_LOCATION, NULL);
419 if (wlims.always_executed)
421 if (warning_at (location, OPT_Wuninitialized,
422 "%G%qE is used uninitialized", stmt, rhs))
424 /* ??? This is only effective for decls as in
425 gcc.dg/uninit-B-O0.c. Avoid doing this for maybe-uninit
426 uses or accesses by functions as it may hide important
427 locations. */
428 if (lhs)
429 TREE_NO_WARNING (rhs) = 1;
430 warned = true;
433 else if (wlims.wmaybe_uninit)
434 warned = warning_at (location, OPT_Wmaybe_uninitialized,
435 "%G%qE may be used uninitialized", stmt, rhs);
437 return warned ? base : NULL_TREE;
441 /* Diagnose passing addresses of uninitialized objects to either const
442 pointer arguments to functions, or to functions declared with attribute
443 access implying read access to those objects. */
445 static void
446 maybe_warn_pass_by_reference (gimple *stmt, wlimits &wlims)
448 if (!wlims.wmaybe_uninit)
449 return;
451 unsigned nargs = gimple_call_num_args (stmt);
452 if (!nargs)
453 return;
455 tree fndecl = gimple_call_fndecl (stmt);
456 tree fntype = gimple_call_fntype (stmt);
457 if (!fntype)
458 return;
460 const built_in_function fncode
461 = (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
462 ? DECL_FUNCTION_CODE (fndecl) : (built_in_function)BUILT_IN_LAST);
464 if (fncode == BUILT_IN_MEMCPY || fncode == BUILT_IN_MEMMOVE)
465 /* Avoid diagnosing calls to raw memory functions (this is overly
466 permissive; consider tightening it up). */
467 return;
469 /* Save the current warning setting and replace it either a "maybe"
470 when passing addresses of uninitialized variables to const-qualified
471 pointers or arguments declared with attribute read_write, or with
472 a "certain" when passing them to arguments declared with attribute
473 read_only. */
474 const bool save_always_executed = wlims.always_executed;
476 /* Initialize a map of attribute access specifications for arguments
477 to the function function call. */
478 rdwr_map rdwr_idx;
479 init_attr_rdwr_indices (&rdwr_idx, TYPE_ATTRIBUTES (fntype));
481 tree argtype;
482 unsigned argno = 0;
483 function_args_iterator it;
485 FOREACH_FUNCTION_ARGS (fntype, argtype, it)
487 ++argno;
489 if (!POINTER_TYPE_P (argtype))
490 continue;
492 tree access_size = NULL_TREE;
493 const attr_access* access = rdwr_idx.get (argno - 1);
494 if (access)
496 if (access->mode == access_none
497 || access->mode == access_write_only)
498 continue;
500 if (access->mode == access_deferred
501 && !TYPE_READONLY (TREE_TYPE (argtype)))
502 continue;
504 if (save_always_executed && access->mode == access_read_only)
505 /* Attribute read_only arguments imply read access. */
506 wlims.always_executed = true;
507 else
508 /* Attribute read_write arguments are documented as requiring
509 initialized objects but it's expected that aggregates may
510 be only partially initialized regardless. */
511 wlims.always_executed = false;
513 if (access->sizarg < nargs)
514 access_size = gimple_call_arg (stmt, access->sizarg);
516 else if (!TYPE_READONLY (TREE_TYPE (argtype)))
517 continue;
518 else if (save_always_executed && fncode != BUILT_IN_LAST)
519 /* Const-qualified arguments to built-ins imply read access. */
520 wlims.always_executed = true;
521 else
522 /* Const-qualified arguments to ordinary functions imply a likely
523 (but not definitive) read access. */
524 wlims.always_executed = false;
526 tree arg = gimple_call_arg (stmt, argno - 1);
528 ao_ref ref;
529 ao_ref_init_from_ptr_and_size (&ref, arg, access_size);
530 tree argbase = maybe_warn_operand (ref, stmt, NULL_TREE, arg, wlims);
531 if (!argbase)
532 continue;
534 if (access && access->mode != access_deferred)
536 const char* const access_str =
537 TREE_STRING_POINTER (access->to_external_string ());
539 if (fndecl)
541 location_t loc = DECL_SOURCE_LOCATION (fndecl);
542 inform (loc, "in a call to %qD declared with "
543 "attribute %<%s%> here", fndecl, access_str);
545 else
547 /* Handle calls through function pointers. */
548 location_t loc = gimple_location (stmt);
549 inform (loc, "in a call to %qT declared with "
550 "attribute %<%s%>", fntype, access_str);
553 else
555 /* For a declaration with no relevant attribute access create
556 a dummy object and use the formatting function to avoid
557 having to complicate things here. */
558 attr_access ptr_access = { };
559 if (!access)
560 access = &ptr_access;
561 const std::string argtypestr = access->array_as_string (argtype);
562 if (fndecl)
564 location_t loc (DECL_SOURCE_LOCATION (fndecl));
565 inform (loc, "by argument %u of type %s to %qD "
566 "declared here",
567 argno, argtypestr.c_str (), fndecl);
569 else
571 /* Handle calls through function pointers. */
572 location_t loc (gimple_location (stmt));
573 inform (loc, "by argument %u of type %s to %qT",
574 argno, argtypestr.c_str (), fntype);
578 if (DECL_P (argbase))
580 location_t loc = DECL_SOURCE_LOCATION (argbase);
581 inform (loc, "%qD declared here", argbase);
585 wlims.always_executed = save_always_executed;
589 static unsigned int
590 warn_uninitialized_vars (bool wmaybe_uninit)
592 /* Counters and limits controlling the the depth of the warning. */
593 wlimits wlims = { };
594 wlims.wmaybe_uninit = wmaybe_uninit;
596 gimple_stmt_iterator gsi;
597 basic_block bb;
598 FOR_EACH_BB_FN (bb, cfun)
600 basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
601 wlims.always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb);
602 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
604 gimple *stmt = gsi_stmt (gsi);
605 use_operand_p use_p;
606 ssa_op_iter op_iter;
607 tree use;
609 if (is_gimple_debug (stmt))
610 continue;
612 /* We only do data flow with SSA_NAMEs, so that's all we
613 can warn about. */
614 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, op_iter, SSA_OP_USE)
616 /* BIT_INSERT_EXPR first operand should not be considered
617 a use for the purpose of uninit warnings. */
618 if (gassign *ass = dyn_cast <gassign *> (stmt))
620 if (gimple_assign_rhs_code (ass) == BIT_INSERT_EXPR
621 && use_p->use == gimple_assign_rhs1_ptr (ass))
622 continue;
624 use = USE_FROM_PTR (use_p);
625 if (wlims.always_executed)
626 warn_uninit (OPT_Wuninitialized, use, SSA_NAME_VAR (use),
627 SSA_NAME_VAR (use),
628 "%qD is used uninitialized", stmt,
629 UNKNOWN_LOCATION);
630 else if (wmaybe_uninit)
631 warn_uninit (OPT_Wmaybe_uninitialized, use, SSA_NAME_VAR (use),
632 SSA_NAME_VAR (use),
633 "%qD may be used uninitialized",
634 stmt, UNKNOWN_LOCATION);
637 /* For limiting the alias walk below we count all
638 vdefs in the function. */
639 if (gimple_vdef (stmt))
640 wlims.vdef_cnt++;
642 if (is_gimple_call (stmt))
643 maybe_warn_pass_by_reference (stmt, wlims);
644 else if (gimple_assign_load_p (stmt)
645 && gimple_has_location (stmt))
647 tree rhs = gimple_assign_rhs1 (stmt);
648 tree lhs = gimple_assign_lhs (stmt);
650 ao_ref ref;
651 ao_ref_init (&ref, rhs);
652 tree var = maybe_warn_operand (ref, stmt, lhs, rhs, wlims);
653 if (!var)
654 continue;
656 if (DECL_P (var))
658 location_t loc = DECL_SOURCE_LOCATION (var);
659 inform (loc, "%qD declared here", var);
665 return 0;
668 /* Checks if the operand OPND of PHI is defined by
669 another phi with one operand defined by this PHI,
670 but the rest operands are all defined. If yes,
671 returns true to skip this operand as being
672 redundant. Can be enhanced to be more general. */
674 static bool
675 can_skip_redundant_opnd (tree opnd, gimple *phi)
677 gimple *op_def;
678 tree phi_def;
679 int i, n;
681 phi_def = gimple_phi_result (phi);
682 op_def = SSA_NAME_DEF_STMT (opnd);
683 if (gimple_code (op_def) != GIMPLE_PHI)
684 return false;
685 n = gimple_phi_num_args (op_def);
686 for (i = 0; i < n; ++i)
688 tree op = gimple_phi_arg_def (op_def, i);
689 if (TREE_CODE (op) != SSA_NAME)
690 continue;
691 if (op != phi_def && uninit_undefined_value_p (op))
692 return false;
695 return true;
698 /* Returns a bit mask holding the positions of arguments in PHI
699 that have empty (or possibly empty) definitions. */
701 static unsigned
702 compute_uninit_opnds_pos (gphi *phi)
704 size_t i, n;
705 unsigned uninit_opnds = 0;
707 n = gimple_phi_num_args (phi);
708 /* Bail out for phi with too many args. */
709 if (n > max_phi_args)
710 return 0;
712 for (i = 0; i < n; ++i)
714 tree op = gimple_phi_arg_def (phi, i);
715 if (TREE_CODE (op) == SSA_NAME
716 && uninit_undefined_value_p (op)
717 && !can_skip_redundant_opnd (op, phi))
719 if (cfun->has_nonlocal_label || cfun->calls_setjmp)
721 /* Ignore SSA_NAMEs that appear on abnormal edges
722 somewhere. */
723 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
724 continue;
726 MASK_SET_BIT (uninit_opnds, i);
729 return uninit_opnds;
732 /* Find the immediate postdominator PDOM of the specified
733 basic block BLOCK. */
735 static inline basic_block
736 find_pdom (basic_block block)
738 if (block == EXIT_BLOCK_PTR_FOR_FN (cfun))
739 return EXIT_BLOCK_PTR_FOR_FN (cfun);
740 else
742 basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block);
743 if (!bb)
744 return EXIT_BLOCK_PTR_FOR_FN (cfun);
745 return bb;
749 /* Find the immediate DOM of the specified basic block BLOCK. */
751 static inline basic_block
752 find_dom (basic_block block)
754 if (block == ENTRY_BLOCK_PTR_FOR_FN (cfun))
755 return ENTRY_BLOCK_PTR_FOR_FN (cfun);
756 else
758 basic_block bb = get_immediate_dominator (CDI_DOMINATORS, block);
759 if (!bb)
760 return ENTRY_BLOCK_PTR_FOR_FN (cfun);
761 return bb;
765 /* Returns true if BB1 is postdominating BB2 and BB1 is
766 not a loop exit bb. The loop exit bb check is simple and does
767 not cover all cases. */
769 static bool
770 is_non_loop_exit_postdominating (basic_block bb1, basic_block bb2)
772 if (!dominated_by_p (CDI_POST_DOMINATORS, bb2, bb1))
773 return false;
775 if (single_pred_p (bb1) && !single_succ_p (bb2))
776 return false;
778 return true;
781 /* Find the closest postdominator of a specified BB, which is control
782 equivalent to BB. */
784 static inline basic_block
785 find_control_equiv_block (basic_block bb)
787 basic_block pdom;
789 pdom = find_pdom (bb);
791 /* Skip the postdominating bb that is also loop exit. */
792 if (!is_non_loop_exit_postdominating (pdom, bb))
793 return NULL;
795 if (dominated_by_p (CDI_DOMINATORS, pdom, bb))
796 return pdom;
798 return NULL;
801 #define MAX_NUM_CHAINS 8
802 #define MAX_CHAIN_LEN 5
803 #define MAX_POSTDOM_CHECK 8
804 #define MAX_SWITCH_CASES 40
806 /* Computes the control dependence chains (paths of edges)
807 for DEP_BB up to the dominating basic block BB (the head node of a
808 chain should be dominated by it). CD_CHAINS is pointer to an
809 array holding the result chains. CUR_CD_CHAIN is the current
810 chain being computed. *NUM_CHAINS is total number of chains. The
811 function returns true if the information is successfully computed,
812 return false if there is no control dependence or not computed. */
814 static bool
815 compute_control_dep_chain (basic_block bb, basic_block dep_bb,
816 vec<edge> *cd_chains,
817 size_t *num_chains,
818 vec<edge> *cur_cd_chain,
819 int *num_calls)
821 edge_iterator ei;
822 edge e;
823 size_t i;
824 bool found_cd_chain = false;
825 size_t cur_chain_len = 0;
827 if (*num_calls > param_uninit_control_dep_attempts)
828 return false;
829 ++*num_calls;
831 /* Could use a set instead. */
832 cur_chain_len = cur_cd_chain->length ();
833 if (cur_chain_len > MAX_CHAIN_LEN)
834 return false;
836 for (i = 0; i < cur_chain_len; i++)
838 edge e = (*cur_cd_chain)[i];
839 /* Cycle detected. */
840 if (e->src == bb)
841 return false;
844 FOR_EACH_EDGE (e, ei, bb->succs)
846 basic_block cd_bb;
847 int post_dom_check = 0;
848 if (e->flags & (EDGE_FAKE | EDGE_ABNORMAL))
849 continue;
851 cd_bb = e->dest;
852 cur_cd_chain->safe_push (e);
853 while (!is_non_loop_exit_postdominating (cd_bb, bb))
855 if (cd_bb == dep_bb)
857 /* Found a direct control dependence. */
858 if (*num_chains < MAX_NUM_CHAINS)
860 cd_chains[*num_chains] = cur_cd_chain->copy ();
861 (*num_chains)++;
863 found_cd_chain = true;
864 /* Check path from next edge. */
865 break;
868 /* Now check if DEP_BB is indirectly control dependent on BB. */
869 if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains, num_chains,
870 cur_cd_chain, num_calls))
872 found_cd_chain = true;
873 break;
876 cd_bb = find_pdom (cd_bb);
877 post_dom_check++;
878 if (cd_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
879 || post_dom_check > MAX_POSTDOM_CHECK)
880 break;
882 cur_cd_chain->pop ();
883 gcc_assert (cur_cd_chain->length () == cur_chain_len);
885 gcc_assert (cur_cd_chain->length () == cur_chain_len);
887 return found_cd_chain;
890 /* The type to represent a simple predicate. */
892 struct pred_info
894 tree pred_lhs;
895 tree pred_rhs;
896 enum tree_code cond_code;
897 bool invert;
900 /* The type to represent a sequence of predicates grouped
901 with .AND. operation. */
903 typedef vec<pred_info, va_heap, vl_ptr> pred_chain;
905 /* The type to represent a sequence of pred_chains grouped
906 with .OR. operation. */
908 typedef vec<pred_chain, va_heap, vl_ptr> pred_chain_union;
910 /* Converts the chains of control dependence edges into a set of
911 predicates. A control dependence chain is represented by a vector
912 edges. DEP_CHAINS points to an array of dependence chains.
913 NUM_CHAINS is the size of the chain array. One edge in a dependence
914 chain is mapped to predicate expression represented by pred_info
915 type. One dependence chain is converted to a composite predicate that
916 is the result of AND operation of pred_info mapped to each edge.
917 A composite predicate is presented by a vector of pred_info. On
918 return, *PREDS points to the resulting array of composite predicates.
919 *NUM_PREDS is the number of composite predictes. */
921 static bool
922 convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
923 size_t num_chains,
924 pred_chain_union *preds)
926 bool has_valid_pred = false;
927 size_t i, j;
928 if (num_chains == 0 || num_chains >= MAX_NUM_CHAINS)
929 return false;
931 /* Now convert the control dep chain into a set
932 of predicates. */
933 preds->reserve (num_chains);
935 for (i = 0; i < num_chains; i++)
937 vec<edge> one_cd_chain = dep_chains[i];
939 has_valid_pred = false;
940 pred_chain t_chain = vNULL;
941 for (j = 0; j < one_cd_chain.length (); j++)
943 gimple *cond_stmt;
944 gimple_stmt_iterator gsi;
945 basic_block guard_bb;
946 pred_info one_pred;
947 edge e;
949 e = one_cd_chain[j];
950 guard_bb = e->src;
951 gsi = gsi_last_bb (guard_bb);
952 /* Ignore empty forwarder blocks. */
953 if (empty_block_p (guard_bb) && single_succ_p (guard_bb))
954 continue;
955 /* An empty basic block here is likely a PHI, and is not one
956 of the cases we handle below. */
957 if (gsi_end_p (gsi))
959 has_valid_pred = false;
960 break;
962 cond_stmt = gsi_stmt (gsi);
963 if (is_gimple_call (cond_stmt) && EDGE_COUNT (e->src->succs) >= 2)
964 /* Ignore EH edge. Can add assertion on the other edge's flag. */
965 continue;
966 /* Skip if there is essentially one succesor. */
967 if (EDGE_COUNT (e->src->succs) == 2)
969 edge e1;
970 edge_iterator ei1;
971 bool skip = false;
973 FOR_EACH_EDGE (e1, ei1, e->src->succs)
975 if (EDGE_COUNT (e1->dest->succs) == 0)
977 skip = true;
978 break;
981 if (skip)
982 continue;
984 if (gimple_code (cond_stmt) == GIMPLE_COND)
986 one_pred.pred_lhs = gimple_cond_lhs (cond_stmt);
987 one_pred.pred_rhs = gimple_cond_rhs (cond_stmt);
988 one_pred.cond_code = gimple_cond_code (cond_stmt);
989 one_pred.invert = !!(e->flags & EDGE_FALSE_VALUE);
990 t_chain.safe_push (one_pred);
991 has_valid_pred = true;
993 else if (gswitch *gs = dyn_cast<gswitch *> (cond_stmt))
995 /* Avoid quadratic behavior. */
996 if (gimple_switch_num_labels (gs) > MAX_SWITCH_CASES)
998 has_valid_pred = false;
999 break;
1001 /* Find the case label. */
1002 tree l = NULL_TREE;
1003 unsigned idx;
1004 for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx)
1006 tree tl = gimple_switch_label (gs, idx);
1007 if (e->dest == label_to_block (cfun, CASE_LABEL (tl)))
1009 if (!l)
1010 l = tl;
1011 else
1013 l = NULL_TREE;
1014 break;
1018 /* If more than one label reaches this block or the case
1019 label doesn't have a single value (like the default one)
1020 fail. */
1021 if (!l
1022 || !CASE_LOW (l)
1023 || (CASE_HIGH (l)
1024 && !operand_equal_p (CASE_LOW (l), CASE_HIGH (l), 0)))
1026 has_valid_pred = false;
1027 break;
1029 one_pred.pred_lhs = gimple_switch_index (gs);
1030 one_pred.pred_rhs = CASE_LOW (l);
1031 one_pred.cond_code = EQ_EXPR;
1032 one_pred.invert = false;
1033 t_chain.safe_push (one_pred);
1034 has_valid_pred = true;
1036 else
1038 has_valid_pred = false;
1039 break;
1043 if (!has_valid_pred)
1044 break;
1045 else
1046 preds->safe_push (t_chain);
1048 return has_valid_pred;
1051 /* Computes all control dependence chains for USE_BB. The control
1052 dependence chains are then converted to an array of composite
1053 predicates pointed to by PREDS. PHI_BB is the basic block of
1054 the phi whose result is used in USE_BB. */
1056 static bool
1057 find_predicates (pred_chain_union *preds,
1058 basic_block phi_bb,
1059 basic_block use_bb)
1061 size_t num_chains = 0, i;
1062 int num_calls = 0;
1063 vec<edge> dep_chains[MAX_NUM_CHAINS];
1064 auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
1065 bool has_valid_pred = false;
1066 basic_block cd_root = 0;
1068 /* First find the closest bb that is control equivalent to PHI_BB
1069 that also dominates USE_BB. */
1070 cd_root = phi_bb;
1071 while (dominated_by_p (CDI_DOMINATORS, use_bb, cd_root))
1073 basic_block ctrl_eq_bb = find_control_equiv_block (cd_root);
1074 if (ctrl_eq_bb && dominated_by_p (CDI_DOMINATORS, use_bb, ctrl_eq_bb))
1075 cd_root = ctrl_eq_bb;
1076 else
1077 break;
1080 compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains,
1081 &cur_chain, &num_calls);
1083 has_valid_pred
1084 = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds);
1085 for (i = 0; i < num_chains; i++)
1086 dep_chains[i].release ();
1087 return has_valid_pred;
1090 /* Computes the set of incoming edges of PHI that have non empty
1091 definitions of a phi chain. The collection will be done
1092 recursively on operands that are defined by phis. CD_ROOT
1093 is the control dependence root. *EDGES holds the result, and
1094 VISITED_PHIS is a pointer set for detecting cycles. */
1096 static void
1097 collect_phi_def_edges (gphi *phi, basic_block cd_root,
1098 auto_vec<edge> *edges,
1099 hash_set<gimple *> *visited_phis)
1101 size_t i, n;
1102 edge opnd_edge;
1103 tree opnd;
1105 if (visited_phis->add (phi))
1106 return;
1108 n = gimple_phi_num_args (phi);
1109 for (i = 0; i < n; i++)
1111 opnd_edge = gimple_phi_arg_edge (phi, i);
1112 opnd = gimple_phi_arg_def (phi, i);
1114 if (TREE_CODE (opnd) != SSA_NAME)
1116 if (dump_file && (dump_flags & TDF_DETAILS))
1118 fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int) i);
1119 print_gimple_stmt (dump_file, phi, 0);
1121 edges->safe_push (opnd_edge);
1123 else
1125 gimple *def = SSA_NAME_DEF_STMT (opnd);
1127 if (gimple_code (def) == GIMPLE_PHI
1128 && dominated_by_p (CDI_DOMINATORS, gimple_bb (def), cd_root))
1129 collect_phi_def_edges (as_a<gphi *> (def), cd_root, edges,
1130 visited_phis);
1131 else if (!uninit_undefined_value_p (opnd))
1133 if (dump_file && (dump_flags & TDF_DETAILS))
1135 fprintf (dump_file, "\n[CHECK] Found def edge %d in ",
1136 (int) i);
1137 print_gimple_stmt (dump_file, phi, 0);
1139 edges->safe_push (opnd_edge);
1145 /* For each use edge of PHI, computes all control dependence chains.
1146 The control dependence chains are then converted to an array of
1147 composite predicates pointed to by PREDS. */
1149 static bool
1150 find_def_preds (pred_chain_union *preds, gphi *phi)
1152 size_t num_chains = 0, i, n;
1153 vec<edge> dep_chains[MAX_NUM_CHAINS];
1154 auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
1155 auto_vec<edge> def_edges;
1156 bool has_valid_pred = false;
1157 basic_block phi_bb, cd_root = 0;
1159 phi_bb = gimple_bb (phi);
1160 /* First find the closest dominating bb to be
1161 the control dependence root. */
1162 cd_root = find_dom (phi_bb);
1163 if (!cd_root)
1164 return false;
1166 hash_set<gimple *> visited_phis;
1167 collect_phi_def_edges (phi, cd_root, &def_edges, &visited_phis);
1169 n = def_edges.length ();
1170 if (n == 0)
1171 return false;
1173 for (i = 0; i < n; i++)
1175 size_t prev_nc, j;
1176 int num_calls = 0;
1177 edge opnd_edge;
1179 opnd_edge = def_edges[i];
1180 prev_nc = num_chains;
1181 compute_control_dep_chain (cd_root, opnd_edge->src, dep_chains,
1182 &num_chains, &cur_chain, &num_calls);
1184 /* Now update the newly added chains with
1185 the phi operand edge: */
1186 if (EDGE_COUNT (opnd_edge->src->succs) > 1)
1188 if (prev_nc == num_chains && num_chains < MAX_NUM_CHAINS)
1189 dep_chains[num_chains++] = vNULL;
1190 for (j = prev_nc; j < num_chains; j++)
1191 dep_chains[j].safe_push (opnd_edge);
1195 has_valid_pred
1196 = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds);
1197 for (i = 0; i < num_chains; i++)
1198 dep_chains[i].release ();
1199 return has_valid_pred;
1202 /* Dump a pred_info. */
1204 static void
1205 dump_pred_info (pred_info one_pred)
1207 if (one_pred.invert)
1208 fprintf (dump_file, " (.NOT.) ");
1209 print_generic_expr (dump_file, one_pred.pred_lhs);
1210 fprintf (dump_file, " %s ", op_symbol_code (one_pred.cond_code));
1211 print_generic_expr (dump_file, one_pred.pred_rhs);
1214 /* Dump a pred_chain. */
1216 static void
1217 dump_pred_chain (pred_chain one_pred_chain)
1219 size_t np = one_pred_chain.length ();
1220 for (size_t j = 0; j < np; j++)
1222 dump_pred_info (one_pred_chain[j]);
1223 if (j < np - 1)
1224 fprintf (dump_file, " (.AND.) ");
1225 else
1226 fprintf (dump_file, "\n");
1230 /* Dumps the predicates (PREDS) for USESTMT. */
1232 static void
1233 dump_predicates (gimple *usestmt, pred_chain_union preds, const char *msg)
1235 fprintf (dump_file, "%s", msg);
1236 if (usestmt)
1238 print_gimple_stmt (dump_file, usestmt, 0);
1239 fprintf (dump_file, "is guarded by :\n\n");
1241 size_t num_preds = preds.length ();
1242 for (size_t i = 0; i < num_preds; i++)
1244 dump_pred_chain (preds[i]);
1245 if (i < num_preds - 1)
1246 fprintf (dump_file, "(.OR.)\n");
1247 else
1248 fprintf (dump_file, "\n\n");
1252 /* Destroys the predicate set *PREDS. */
1254 static void
1255 destroy_predicate_vecs (pred_chain_union *preds)
1257 size_t i;
1259 size_t n = preds->length ();
1260 for (i = 0; i < n; i++)
1261 (*preds)[i].release ();
1262 preds->release ();
1265 /* Computes the 'normalized' conditional code with operand
1266 swapping and condition inversion. */
1268 static enum tree_code
1269 get_cmp_code (enum tree_code orig_cmp_code, bool swap_cond, bool invert)
1271 enum tree_code tc = orig_cmp_code;
1273 if (swap_cond)
1274 tc = swap_tree_comparison (orig_cmp_code);
1275 if (invert)
1276 tc = invert_tree_comparison (tc, false);
1278 switch (tc)
1280 case LT_EXPR:
1281 case LE_EXPR:
1282 case GT_EXPR:
1283 case GE_EXPR:
1284 case EQ_EXPR:
1285 case NE_EXPR:
1286 break;
1287 default:
1288 return ERROR_MARK;
1290 return tc;
1293 /* Returns whether VAL CMPC BOUNDARY is true. */
1295 static bool
1296 is_value_included_in (tree val, tree boundary, enum tree_code cmpc)
1298 bool inverted = false;
1299 bool result;
1301 /* Only handle integer constant here. */
1302 if (TREE_CODE (val) != INTEGER_CST || TREE_CODE (boundary) != INTEGER_CST)
1303 return true;
1305 if (cmpc == GE_EXPR || cmpc == GT_EXPR || cmpc == NE_EXPR)
1307 cmpc = invert_tree_comparison (cmpc, false);
1308 inverted = true;
1311 if (cmpc == EQ_EXPR)
1312 result = tree_int_cst_equal (val, boundary);
1313 else if (cmpc == LT_EXPR)
1314 result = tree_int_cst_lt (val, boundary);
1315 else
1317 gcc_assert (cmpc == LE_EXPR);
1318 result = tree_int_cst_le (val, boundary);
1321 if (inverted)
1322 result ^= 1;
1324 return result;
1327 /* Returns whether VAL satisfies (x CMPC BOUNDARY) predicate. CMPC can be
1328 either one of the range comparison codes ({GE,LT,EQ,NE}_EXPR and the like),
1329 or BIT_AND_EXPR. EXACT_P is only meaningful for the latter. It modifies the
1330 question from whether VAL & BOUNDARY != 0 to whether VAL & BOUNDARY == VAL.
1331 For other values of CMPC, EXACT_P is ignored. */
1333 static bool
1334 value_sat_pred_p (tree val, tree boundary, enum tree_code cmpc,
1335 bool exact_p = false)
1337 if (cmpc != BIT_AND_EXPR)
1338 return is_value_included_in (val, boundary, cmpc);
1340 wide_int andw = wi::to_wide (val) & wi::to_wide (boundary);
1341 if (exact_p)
1342 return andw == wi::to_wide (val);
1343 else
1344 return andw.to_uhwi ();
1347 /* Returns true if PRED is common among all the predicate
1348 chains (PREDS) (and therefore can be factored out).
1349 NUM_PRED_CHAIN is the size of array PREDS. */
1351 static bool
1352 find_matching_predicate_in_rest_chains (pred_info pred,
1353 pred_chain_union preds,
1354 size_t num_pred_chains)
1356 size_t i, j, n;
1358 /* Trival case. */
1359 if (num_pred_chains == 1)
1360 return true;
1362 for (i = 1; i < num_pred_chains; i++)
1364 bool found = false;
1365 pred_chain one_chain = preds[i];
1366 n = one_chain.length ();
1367 for (j = 0; j < n; j++)
1369 pred_info pred2 = one_chain[j];
1370 /* Can relax the condition comparison to not
1371 use address comparison. However, the most common
1372 case is that multiple control dependent paths share
1373 a common path prefix, so address comparison should
1374 be ok. */
1376 if (operand_equal_p (pred2.pred_lhs, pred.pred_lhs, 0)
1377 && operand_equal_p (pred2.pred_rhs, pred.pred_rhs, 0)
1378 && pred2.invert == pred.invert)
1380 found = true;
1381 break;
1384 if (!found)
1385 return false;
1387 return true;
1390 /* Forward declaration. */
1391 static bool is_use_properly_guarded (gimple *use_stmt,
1392 basic_block use_bb,
1393 gphi *phi,
1394 unsigned uninit_opnds,
1395 pred_chain_union *def_preds,
1396 hash_set<gphi *> *visited_phis);
1398 /* Returns true if all uninitialized opnds are pruned. Returns false
1399 otherwise. PHI is the phi node with uninitialized operands,
1400 UNINIT_OPNDS is the bitmap of the uninitialize operand positions,
1401 FLAG_DEF is the statement defining the flag guarding the use of the
1402 PHI output, BOUNDARY_CST is the const value used in the predicate
1403 associated with the flag, CMP_CODE is the comparison code used in
1404 the predicate, VISITED_PHIS is the pointer set of phis visited, and
1405 VISITED_FLAG_PHIS is the pointer to the pointer set of flag definitions
1406 that are also phis.
1408 Example scenario:
1410 BB1:
1411 flag_1 = phi <0, 1> // (1)
1412 var_1 = phi <undef, some_val>
1415 BB2:
1416 flag_2 = phi <0, flag_1, flag_1> // (2)
1417 var_2 = phi <undef, var_1, var_1>
1418 if (flag_2 == 1)
1419 goto BB3;
1421 BB3:
1422 use of var_2 // (3)
1424 Because some flag arg in (1) is not constant, if we do not look into the
1425 flag phis recursively, it is conservatively treated as unknown and var_1
1426 is thought to be flowed into use at (3). Since var_1 is potentially
1427 uninitialized a false warning will be emitted.
1428 Checking recursively into (1), the compiler can find out that only some_val
1429 (which is defined) can flow into (3) which is OK. */
1431 static bool
1432 prune_uninit_phi_opnds (gphi *phi, unsigned uninit_opnds, gphi *flag_def,
1433 tree boundary_cst, enum tree_code cmp_code,
1434 hash_set<gphi *> *visited_phis,
1435 bitmap *visited_flag_phis)
1437 unsigned i;
1439 for (i = 0; i < MIN (max_phi_args, gimple_phi_num_args (flag_def)); i++)
1441 tree flag_arg;
1443 if (!MASK_TEST_BIT (uninit_opnds, i))
1444 continue;
1446 flag_arg = gimple_phi_arg_def (flag_def, i);
1447 if (!is_gimple_constant (flag_arg))
1449 gphi *flag_arg_def, *phi_arg_def;
1450 tree phi_arg;
1451 unsigned uninit_opnds_arg_phi;
1453 if (TREE_CODE (flag_arg) != SSA_NAME)
1454 return false;
1455 flag_arg_def = dyn_cast<gphi *> (SSA_NAME_DEF_STMT (flag_arg));
1456 if (!flag_arg_def)
1457 return false;
1459 phi_arg = gimple_phi_arg_def (phi, i);
1460 if (TREE_CODE (phi_arg) != SSA_NAME)
1461 return false;
1463 phi_arg_def = dyn_cast<gphi *> (SSA_NAME_DEF_STMT (phi_arg));
1464 if (!phi_arg_def)
1465 return false;
1467 if (gimple_bb (phi_arg_def) != gimple_bb (flag_arg_def))
1468 return false;
1470 if (!*visited_flag_phis)
1471 *visited_flag_phis = BITMAP_ALLOC (NULL);
1473 tree phi_result = gimple_phi_result (flag_arg_def);
1474 if (bitmap_bit_p (*visited_flag_phis, SSA_NAME_VERSION (phi_result)))
1475 return false;
1477 bitmap_set_bit (*visited_flag_phis,
1478 SSA_NAME_VERSION (gimple_phi_result (flag_arg_def)));
1480 /* Now recursively prune the uninitialized phi args. */
1481 uninit_opnds_arg_phi = compute_uninit_opnds_pos (phi_arg_def);
1482 if (!prune_uninit_phi_opnds
1483 (phi_arg_def, uninit_opnds_arg_phi, flag_arg_def, boundary_cst,
1484 cmp_code, visited_phis, visited_flag_phis))
1485 return false;
1487 phi_result = gimple_phi_result (flag_arg_def);
1488 bitmap_clear_bit (*visited_flag_phis, SSA_NAME_VERSION (phi_result));
1489 continue;
1492 /* Now check if the constant is in the guarded range. */
1493 if (is_value_included_in (flag_arg, boundary_cst, cmp_code))
1495 tree opnd;
1496 gimple *opnd_def;
1498 /* Now that we know that this undefined edge is not
1499 pruned. If the operand is defined by another phi,
1500 we can further prune the incoming edges of that
1501 phi by checking the predicates of this operands. */
1503 opnd = gimple_phi_arg_def (phi, i);
1504 opnd_def = SSA_NAME_DEF_STMT (opnd);
1505 if (gphi *opnd_def_phi = dyn_cast <gphi *> (opnd_def))
1507 edge opnd_edge;
1508 unsigned uninit_opnds2 = compute_uninit_opnds_pos (opnd_def_phi);
1509 if (!MASK_EMPTY (uninit_opnds2))
1511 pred_chain_union def_preds = vNULL;
1512 bool ok;
1513 opnd_edge = gimple_phi_arg_edge (phi, i);
1514 ok = is_use_properly_guarded (phi,
1515 opnd_edge->src,
1516 opnd_def_phi,
1517 uninit_opnds2,
1518 &def_preds,
1519 visited_phis);
1520 destroy_predicate_vecs (&def_preds);
1521 if (!ok)
1522 return false;
1525 else
1526 return false;
1530 return true;
1533 /* A helper function that determines if the predicate set
1534 of the use is not overlapping with that of the uninit paths.
1535 The most common senario of guarded use is in Example 1:
1536 Example 1:
1537 if (some_cond)
1539 x = ...;
1540 flag = true;
1543 ... some code ...
1545 if (flag)
1546 use (x);
1548 The real world examples are usually more complicated, but similar
1549 and usually result from inlining:
1551 bool init_func (int * x)
1553 if (some_cond)
1554 return false;
1555 *x = ..
1556 return true;
1559 void foo (..)
1561 int x;
1563 if (!init_func (&x))
1564 return;
1566 .. some_code ...
1567 use (x);
1570 Another possible use scenario is in the following trivial example:
1572 Example 2:
1573 if (n > 0)
1574 x = 1;
1576 if (n > 0)
1578 if (m < 2)
1579 .. = x;
1582 Predicate analysis needs to compute the composite predicate:
1584 1) 'x' use predicate: (n > 0) .AND. (m < 2)
1585 2) 'x' default value (non-def) predicate: .NOT. (n > 0)
1586 (the predicate chain for phi operand defs can be computed
1587 starting from a bb that is control equivalent to the phi's
1588 bb and is dominating the operand def.)
1590 and check overlapping:
1591 (n > 0) .AND. (m < 2) .AND. (.NOT. (n > 0))
1592 <==> false
1594 This implementation provides framework that can handle
1595 scenarios. (Note that many simple cases are handled properly
1596 without the predicate analysis -- this is due to jump threading
1597 transformation which eliminates the merge point thus makes
1598 path sensitive analysis unnecessary.)
1600 PHI is the phi node whose incoming (undefined) paths need to be
1601 pruned, and UNINIT_OPNDS is the bitmap holding uninit operand
1602 positions. VISITED_PHIS is the pointer set of phi stmts being
1603 checked. */
1605 static bool
1606 use_pred_not_overlap_with_undef_path_pred (pred_chain_union preds,
1607 gphi *phi, unsigned uninit_opnds,
1608 hash_set<gphi *> *visited_phis)
1610 unsigned int i, n;
1611 gimple *flag_def = 0;
1612 tree boundary_cst = 0;
1613 enum tree_code cmp_code;
1614 bool swap_cond = false;
1615 bool invert = false;
1616 pred_chain the_pred_chain = vNULL;
1617 bitmap visited_flag_phis = NULL;
1618 bool all_pruned = false;
1619 size_t num_preds = preds.length ();
1621 gcc_assert (num_preds > 0);
1622 /* Find within the common prefix of multiple predicate chains
1623 a predicate that is a comparison of a flag variable against
1624 a constant. */
1625 the_pred_chain = preds[0];
1626 n = the_pred_chain.length ();
1627 for (i = 0; i < n; i++)
1629 tree cond_lhs, cond_rhs, flag = 0;
1631 pred_info the_pred = the_pred_chain[i];
1633 invert = the_pred.invert;
1634 cond_lhs = the_pred.pred_lhs;
1635 cond_rhs = the_pred.pred_rhs;
1636 cmp_code = the_pred.cond_code;
1638 if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME
1639 && cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs))
1641 boundary_cst = cond_rhs;
1642 flag = cond_lhs;
1644 else if (cond_rhs != NULL_TREE && TREE_CODE (cond_rhs) == SSA_NAME
1645 && cond_lhs != NULL_TREE && is_gimple_constant (cond_lhs))
1647 boundary_cst = cond_lhs;
1648 flag = cond_rhs;
1649 swap_cond = true;
1652 if (!flag)
1653 continue;
1655 flag_def = SSA_NAME_DEF_STMT (flag);
1657 if (!flag_def)
1658 continue;
1660 if ((gimple_code (flag_def) == GIMPLE_PHI)
1661 && (gimple_bb (flag_def) == gimple_bb (phi))
1662 && find_matching_predicate_in_rest_chains (the_pred, preds,
1663 num_preds))
1664 break;
1666 flag_def = 0;
1669 if (!flag_def)
1670 return false;
1672 /* Now check all the uninit incoming edge has a constant flag value
1673 that is in conflict with the use guard/predicate. */
1674 cmp_code = get_cmp_code (cmp_code, swap_cond, invert);
1676 if (cmp_code == ERROR_MARK)
1677 return false;
1679 all_pruned = prune_uninit_phi_opnds
1680 (phi, uninit_opnds, as_a<gphi *> (flag_def), boundary_cst, cmp_code,
1681 visited_phis, &visited_flag_phis);
1683 if (visited_flag_phis)
1684 BITMAP_FREE (visited_flag_phis);
1686 return all_pruned;
1689 /* The helper function returns true if two predicates X1 and X2
1690 are equivalent. It assumes the expressions have already
1691 properly re-associated. */
1693 static inline bool
1694 pred_equal_p (pred_info x1, pred_info x2)
1696 enum tree_code c1, c2;
1697 if (!operand_equal_p (x1.pred_lhs, x2.pred_lhs, 0)
1698 || !operand_equal_p (x1.pred_rhs, x2.pred_rhs, 0))
1699 return false;
1701 c1 = x1.cond_code;
1702 if (x1.invert != x2.invert
1703 && TREE_CODE_CLASS (x2.cond_code) == tcc_comparison)
1704 c2 = invert_tree_comparison (x2.cond_code, false);
1705 else
1706 c2 = x2.cond_code;
1708 return c1 == c2;
1711 /* Returns true if the predication is testing !=. */
1713 static inline bool
1714 is_neq_relop_p (pred_info pred)
1717 return ((pred.cond_code == NE_EXPR && !pred.invert)
1718 || (pred.cond_code == EQ_EXPR && pred.invert));
1721 /* Returns true if pred is of the form X != 0. */
1723 static inline bool
1724 is_neq_zero_form_p (pred_info pred)
1726 if (!is_neq_relop_p (pred) || !integer_zerop (pred.pred_rhs)
1727 || TREE_CODE (pred.pred_lhs) != SSA_NAME)
1728 return false;
1729 return true;
1732 /* The helper function returns true if two predicates X1
1733 is equivalent to X2 != 0. */
1735 static inline bool
1736 pred_expr_equal_p (pred_info x1, tree x2)
1738 if (!is_neq_zero_form_p (x1))
1739 return false;
1741 return operand_equal_p (x1.pred_lhs, x2, 0);
1744 /* Returns true of the domain of single predicate expression
1745 EXPR1 is a subset of that of EXPR2. Returns false if it
1746 cannot be proved. */
1748 static bool
1749 is_pred_expr_subset_of (pred_info expr1, pred_info expr2)
1751 enum tree_code code1, code2;
1753 if (pred_equal_p (expr1, expr2))
1754 return true;
1756 if ((TREE_CODE (expr1.pred_rhs) != INTEGER_CST)
1757 || (TREE_CODE (expr2.pred_rhs) != INTEGER_CST))
1758 return false;
1760 if (!operand_equal_p (expr1.pred_lhs, expr2.pred_lhs, 0))
1761 return false;
1763 code1 = expr1.cond_code;
1764 if (expr1.invert)
1765 code1 = invert_tree_comparison (code1, false);
1766 code2 = expr2.cond_code;
1767 if (expr2.invert)
1768 code2 = invert_tree_comparison (code2, false);
1770 if (code2 == NE_EXPR && code1 == NE_EXPR)
1771 return false;
1773 if (code2 == NE_EXPR)
1774 return !value_sat_pred_p (expr2.pred_rhs, expr1.pred_rhs, code1);
1776 if (code1 == EQ_EXPR)
1777 return value_sat_pred_p (expr1.pred_rhs, expr2.pred_rhs, code2);
1779 if (code1 == code2)
1780 return value_sat_pred_p (expr1.pred_rhs, expr2.pred_rhs, code2,
1781 code1 == BIT_AND_EXPR);
1783 return false;
1786 /* Returns true if the domain of PRED1 is a subset
1787 of that of PRED2. Returns false if it cannot be proved so. */
1789 static bool
1790 is_pred_chain_subset_of (pred_chain pred1, pred_chain pred2)
1792 size_t np1, np2, i1, i2;
1794 np1 = pred1.length ();
1795 np2 = pred2.length ();
1797 for (i2 = 0; i2 < np2; i2++)
1799 bool found = false;
1800 pred_info info2 = pred2[i2];
1801 for (i1 = 0; i1 < np1; i1++)
1803 pred_info info1 = pred1[i1];
1804 if (is_pred_expr_subset_of (info1, info2))
1806 found = true;
1807 break;
1810 if (!found)
1811 return false;
1813 return true;
1816 /* Returns true if the domain defined by
1817 one pred chain ONE_PRED is a subset of the domain
1818 of *PREDS. It returns false if ONE_PRED's domain is
1819 not a subset of any of the sub-domains of PREDS
1820 (corresponding to each individual chains in it), even
1821 though it may be still be a subset of whole domain
1822 of PREDS which is the union (ORed) of all its subdomains.
1823 In other words, the result is conservative. */
1825 static bool
1826 is_included_in (pred_chain one_pred, pred_chain_union preds)
1828 size_t i;
1829 size_t n = preds.length ();
1831 for (i = 0; i < n; i++)
1833 if (is_pred_chain_subset_of (one_pred, preds[i]))
1834 return true;
1837 return false;
1840 /* Compares two predicate sets PREDS1 and PREDS2 and returns
1841 true if the domain defined by PREDS1 is a superset
1842 of PREDS2's domain. N1 and N2 are array sizes of PREDS1 and
1843 PREDS2 respectively. The implementation chooses not to build
1844 generic trees (and relying on the folding capability of the
1845 compiler), but instead performs brute force comparison of
1846 individual predicate chains (won't be a compile time problem
1847 as the chains are pretty short). When the function returns
1848 false, it does not necessarily mean *PREDS1 is not a superset
1849 of *PREDS2, but mean it may not be so since the analysis cannot
1850 prove it. In such cases, false warnings may still be
1851 emitted. */
1853 static bool
1854 is_superset_of (pred_chain_union preds1, pred_chain_union preds2)
1856 size_t i, n2;
1857 pred_chain one_pred_chain = vNULL;
1859 n2 = preds2.length ();
1861 for (i = 0; i < n2; i++)
1863 one_pred_chain = preds2[i];
1864 if (!is_included_in (one_pred_chain, preds1))
1865 return false;
1868 return true;
1871 /* Returns true if X1 is the negate of X2. */
1873 static inline bool
1874 pred_neg_p (pred_info x1, pred_info x2)
1876 enum tree_code c1, c2;
1877 if (!operand_equal_p (x1.pred_lhs, x2.pred_lhs, 0)
1878 || !operand_equal_p (x1.pred_rhs, x2.pred_rhs, 0))
1879 return false;
1881 c1 = x1.cond_code;
1882 if (x1.invert == x2.invert)
1883 c2 = invert_tree_comparison (x2.cond_code, false);
1884 else
1885 c2 = x2.cond_code;
1887 return c1 == c2;
1890 /* 1) ((x IOR y) != 0) AND (x != 0) is equivalent to (x != 0);
1891 2) (X AND Y) OR (!X AND Y) is equivalent to Y;
1892 3) X OR (!X AND Y) is equivalent to (X OR Y);
1893 4) ((x IAND y) != 0) || (x != 0 AND y != 0)) is equivalent to
1894 (x != 0 AND y != 0)
1895 5) (X AND Y) OR (!X AND Z) OR (!Y AND Z) is equivalent to
1896 (X AND Y) OR Z
1898 PREDS is the predicate chains, and N is the number of chains. */
1900 /* Helper function to implement rule 1 above. ONE_CHAIN is
1901 the AND predication to be simplified. */
1903 static void
1904 simplify_pred (pred_chain *one_chain)
1906 size_t i, j, n;
1907 bool simplified = false;
1908 pred_chain s_chain = vNULL;
1910 n = one_chain->length ();
1912 for (i = 0; i < n; i++)
1914 pred_info *a_pred = &(*one_chain)[i];
1916 if (!a_pred->pred_lhs)
1917 continue;
1918 if (!is_neq_zero_form_p (*a_pred))
1919 continue;
1921 gimple *def_stmt = SSA_NAME_DEF_STMT (a_pred->pred_lhs);
1922 if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
1923 continue;
1924 if (gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
1926 for (j = 0; j < n; j++)
1928 pred_info *b_pred = &(*one_chain)[j];
1930 if (!b_pred->pred_lhs)
1931 continue;
1932 if (!is_neq_zero_form_p (*b_pred))
1933 continue;
1935 if (pred_expr_equal_p (*b_pred, gimple_assign_rhs1 (def_stmt))
1936 || pred_expr_equal_p (*b_pred, gimple_assign_rhs2 (def_stmt)))
1938 /* Mark a_pred for removal. */
1939 a_pred->pred_lhs = NULL;
1940 a_pred->pred_rhs = NULL;
1941 simplified = true;
1942 break;
1948 if (!simplified)
1949 return;
1951 for (i = 0; i < n; i++)
1953 pred_info *a_pred = &(*one_chain)[i];
1954 if (!a_pred->pred_lhs)
1955 continue;
1956 s_chain.safe_push (*a_pred);
1959 one_chain->release ();
1960 *one_chain = s_chain;
1963 /* The helper function implements the rule 2 for the
1964 OR predicate PREDS.
1966 2) (X AND Y) OR (!X AND Y) is equivalent to Y. */
1968 static bool
1969 simplify_preds_2 (pred_chain_union *preds)
1971 size_t i, j, n;
1972 bool simplified = false;
1973 pred_chain_union s_preds = vNULL;
1975 /* (X AND Y) OR (!X AND Y) is equivalent to Y.
1976 (X AND Y) OR (X AND !Y) is equivalent to X. */
1978 n = preds->length ();
1979 for (i = 0; i < n; i++)
1981 pred_info x, y;
1982 pred_chain *a_chain = &(*preds)[i];
1984 if (a_chain->length () != 2)
1985 continue;
1987 x = (*a_chain)[0];
1988 y = (*a_chain)[1];
1990 for (j = 0; j < n; j++)
1992 pred_chain *b_chain;
1993 pred_info x2, y2;
1995 if (j == i)
1996 continue;
1998 b_chain = &(*preds)[j];
1999 if (b_chain->length () != 2)
2000 continue;
2002 x2 = (*b_chain)[0];
2003 y2 = (*b_chain)[1];
2005 if (pred_equal_p (x, x2) && pred_neg_p (y, y2))
2007 /* Kill a_chain. */
2008 a_chain->release ();
2009 b_chain->release ();
2010 b_chain->safe_push (x);
2011 simplified = true;
2012 break;
2014 if (pred_neg_p (x, x2) && pred_equal_p (y, y2))
2016 /* Kill a_chain. */
2017 a_chain->release ();
2018 b_chain->release ();
2019 b_chain->safe_push (y);
2020 simplified = true;
2021 break;
2025 /* Now clean up the chain. */
2026 if (simplified)
2028 for (i = 0; i < n; i++)
2030 if ((*preds)[i].is_empty ())
2031 continue;
2032 s_preds.safe_push ((*preds)[i]);
2034 preds->release ();
2035 (*preds) = s_preds;
2036 s_preds = vNULL;
2039 return simplified;
2042 /* The helper function implements the rule 2 for the
2043 OR predicate PREDS.
2045 3) x OR (!x AND y) is equivalent to x OR y. */
2047 static bool
2048 simplify_preds_3 (pred_chain_union *preds)
2050 size_t i, j, n;
2051 bool simplified = false;
2053 /* Now iteratively simplify X OR (!X AND Z ..)
2054 into X OR (Z ...). */
2056 n = preds->length ();
2057 if (n < 2)
2058 return false;
2060 for (i = 0; i < n; i++)
2062 pred_info x;
2063 pred_chain *a_chain = &(*preds)[i];
2065 if (a_chain->length () != 1)
2066 continue;
2068 x = (*a_chain)[0];
2070 for (j = 0; j < n; j++)
2072 pred_chain *b_chain;
2073 pred_info x2;
2074 size_t k;
2076 if (j == i)
2077 continue;
2079 b_chain = &(*preds)[j];
2080 if (b_chain->length () < 2)
2081 continue;
2083 for (k = 0; k < b_chain->length (); k++)
2085 x2 = (*b_chain)[k];
2086 if (pred_neg_p (x, x2))
2088 b_chain->unordered_remove (k);
2089 simplified = true;
2090 break;
2095 return simplified;
2098 /* The helper function implements the rule 4 for the
2099 OR predicate PREDS.
2101 2) ((x AND y) != 0) OR (x != 0 AND y != 0) is equivalent to
2102 (x != 0 ANd y != 0). */
2104 static bool
2105 simplify_preds_4 (pred_chain_union *preds)
2107 size_t i, j, n;
2108 bool simplified = false;
2109 pred_chain_union s_preds = vNULL;
2110 gimple *def_stmt;
2112 n = preds->length ();
2113 for (i = 0; i < n; i++)
2115 pred_info z;
2116 pred_chain *a_chain = &(*preds)[i];
2118 if (a_chain->length () != 1)
2119 continue;
2121 z = (*a_chain)[0];
2123 if (!is_neq_zero_form_p (z))
2124 continue;
2126 def_stmt = SSA_NAME_DEF_STMT (z.pred_lhs);
2127 if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
2128 continue;
2130 if (gimple_assign_rhs_code (def_stmt) != BIT_AND_EXPR)
2131 continue;
2133 for (j = 0; j < n; j++)
2135 pred_chain *b_chain;
2136 pred_info x2, y2;
2138 if (j == i)
2139 continue;
2141 b_chain = &(*preds)[j];
2142 if (b_chain->length () != 2)
2143 continue;
2145 x2 = (*b_chain)[0];
2146 y2 = (*b_chain)[1];
2147 if (!is_neq_zero_form_p (x2) || !is_neq_zero_form_p (y2))
2148 continue;
2150 if ((pred_expr_equal_p (x2, gimple_assign_rhs1 (def_stmt))
2151 && pred_expr_equal_p (y2, gimple_assign_rhs2 (def_stmt)))
2152 || (pred_expr_equal_p (x2, gimple_assign_rhs2 (def_stmt))
2153 && pred_expr_equal_p (y2, gimple_assign_rhs1 (def_stmt))))
2155 /* Kill a_chain. */
2156 a_chain->release ();
2157 simplified = true;
2158 break;
2162 /* Now clean up the chain. */
2163 if (simplified)
2165 for (i = 0; i < n; i++)
2167 if ((*preds)[i].is_empty ())
2168 continue;
2169 s_preds.safe_push ((*preds)[i]);
2172 preds->release ();
2173 (*preds) = s_preds;
2174 s_preds = vNULL;
2177 return simplified;
2180 /* This function simplifies predicates in PREDS. */
2182 static void
2183 simplify_preds (pred_chain_union *preds, gimple *use_or_def, bool is_use)
2185 size_t i, n;
2186 bool changed = false;
2188 if (dump_file && dump_flags & TDF_DETAILS)
2190 fprintf (dump_file, "[BEFORE SIMPLICATION -- ");
2191 dump_predicates (use_or_def, *preds, is_use ? "[USE]:\n" : "[DEF]:\n");
2194 for (i = 0; i < preds->length (); i++)
2195 simplify_pred (&(*preds)[i]);
2197 n = preds->length ();
2198 if (n < 2)
2199 return;
2203 changed = false;
2204 if (simplify_preds_2 (preds))
2205 changed = true;
2207 /* Now iteratively simplify X OR (!X AND Z ..)
2208 into X OR (Z ...). */
2209 if (simplify_preds_3 (preds))
2210 changed = true;
2212 if (simplify_preds_4 (preds))
2213 changed = true;
2215 while (changed);
2217 return;
2220 /* This is a helper function which attempts to normalize predicate chains
2221 by following UD chains. It basically builds up a big tree of either IOR
2222 operations or AND operations, and convert the IOR tree into a
2223 pred_chain_union or BIT_AND tree into a pred_chain.
2224 Example:
2226 _3 = _2 RELOP1 _1;
2227 _6 = _5 RELOP2 _4;
2228 _9 = _8 RELOP3 _7;
2229 _10 = _3 | _6;
2230 _12 = _9 | _0;
2231 _t = _10 | _12;
2233 then _t != 0 will be normalized into a pred_chain_union
2235 (_2 RELOP1 _1) OR (_5 RELOP2 _4) OR (_8 RELOP3 _7) OR (_0 != 0)
2237 Similarly given,
2239 _3 = _2 RELOP1 _1;
2240 _6 = _5 RELOP2 _4;
2241 _9 = _8 RELOP3 _7;
2242 _10 = _3 & _6;
2243 _12 = _9 & _0;
2245 then _t != 0 will be normalized into a pred_chain:
2246 (_2 RELOP1 _1) AND (_5 RELOP2 _4) AND (_8 RELOP3 _7) AND (_0 != 0)
2250 /* This is a helper function that stores a PRED into NORM_PREDS. */
2252 inline static void
2253 push_pred (pred_chain_union *norm_preds, pred_info pred)
2255 pred_chain pred_chain = vNULL;
2256 pred_chain.safe_push (pred);
2257 norm_preds->safe_push (pred_chain);
2260 /* A helper function that creates a predicate of the form
2261 OP != 0 and push it WORK_LIST. */
2263 inline static void
2264 push_to_worklist (tree op, vec<pred_info, va_heap, vl_ptr> *work_list,
2265 hash_set<tree> *mark_set)
2267 if (mark_set->contains (op))
2268 return;
2269 mark_set->add (op);
2271 pred_info arg_pred;
2272 arg_pred.pred_lhs = op;
2273 arg_pred.pred_rhs = integer_zero_node;
2274 arg_pred.cond_code = NE_EXPR;
2275 arg_pred.invert = false;
2276 work_list->safe_push (arg_pred);
2279 /* A helper that generates a pred_info from a gimple assignment
2280 CMP_ASSIGN with comparison rhs. */
2282 static pred_info
2283 get_pred_info_from_cmp (gimple *cmp_assign)
2285 pred_info n_pred;
2286 n_pred.pred_lhs = gimple_assign_rhs1 (cmp_assign);
2287 n_pred.pred_rhs = gimple_assign_rhs2 (cmp_assign);
2288 n_pred.cond_code = gimple_assign_rhs_code (cmp_assign);
2289 n_pred.invert = false;
2290 return n_pred;
2293 /* Returns true if the PHI is a degenerated phi with
2294 all args with the same value (relop). In that case, *PRED
2295 will be updated to that value. */
2297 static bool
2298 is_degenerated_phi (gimple *phi, pred_info *pred_p)
2300 int i, n;
2301 tree op0;
2302 gimple *def0;
2303 pred_info pred0;
2305 n = gimple_phi_num_args (phi);
2306 op0 = gimple_phi_arg_def (phi, 0);
2308 if (TREE_CODE (op0) != SSA_NAME)
2309 return false;
2311 def0 = SSA_NAME_DEF_STMT (op0);
2312 if (gimple_code (def0) != GIMPLE_ASSIGN)
2313 return false;
2314 if (TREE_CODE_CLASS (gimple_assign_rhs_code (def0)) != tcc_comparison)
2315 return false;
2316 pred0 = get_pred_info_from_cmp (def0);
2318 for (i = 1; i < n; ++i)
2320 gimple *def;
2321 pred_info pred;
2322 tree op = gimple_phi_arg_def (phi, i);
2324 if (TREE_CODE (op) != SSA_NAME)
2325 return false;
2327 def = SSA_NAME_DEF_STMT (op);
2328 if (gimple_code (def) != GIMPLE_ASSIGN)
2329 return false;
2330 if (TREE_CODE_CLASS (gimple_assign_rhs_code (def)) != tcc_comparison)
2331 return false;
2332 pred = get_pred_info_from_cmp (def);
2333 if (!pred_equal_p (pred, pred0))
2334 return false;
2337 *pred_p = pred0;
2338 return true;
2341 /* Normalize one predicate PRED
2342 1) if PRED can no longer be normlized, put it into NORM_PREDS.
2343 2) otherwise if PRED is of the form x != 0, follow x's definition
2344 and put normalized predicates into WORK_LIST. */
2346 static void
2347 normalize_one_pred_1 (pred_chain_union *norm_preds,
2348 pred_chain *norm_chain,
2349 pred_info pred,
2350 enum tree_code and_or_code,
2351 vec<pred_info, va_heap, vl_ptr> *work_list,
2352 hash_set<tree> *mark_set)
2354 if (!is_neq_zero_form_p (pred))
2356 if (and_or_code == BIT_IOR_EXPR)
2357 push_pred (norm_preds, pred);
2358 else
2359 norm_chain->safe_push (pred);
2360 return;
2363 gimple *def_stmt = SSA_NAME_DEF_STMT (pred.pred_lhs);
2365 if (gimple_code (def_stmt) == GIMPLE_PHI
2366 && is_degenerated_phi (def_stmt, &pred))
2367 work_list->safe_push (pred);
2368 else if (gimple_code (def_stmt) == GIMPLE_PHI && and_or_code == BIT_IOR_EXPR)
2370 int i, n;
2371 n = gimple_phi_num_args (def_stmt);
2373 /* If we see non zero constant, we should punt. The predicate
2374 * should be one guarding the phi edge. */
2375 for (i = 0; i < n; ++i)
2377 tree op = gimple_phi_arg_def (def_stmt, i);
2378 if (TREE_CODE (op) == INTEGER_CST && !integer_zerop (op))
2380 push_pred (norm_preds, pred);
2381 return;
2385 for (i = 0; i < n; ++i)
2387 tree op = gimple_phi_arg_def (def_stmt, i);
2388 if (integer_zerop (op))
2389 continue;
2391 push_to_worklist (op, work_list, mark_set);
2394 else if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
2396 if (and_or_code == BIT_IOR_EXPR)
2397 push_pred (norm_preds, pred);
2398 else
2399 norm_chain->safe_push (pred);
2401 else if (gimple_assign_rhs_code (def_stmt) == and_or_code)
2403 /* Avoid splitting up bit manipulations like x & 3 or y | 1. */
2404 if (is_gimple_min_invariant (gimple_assign_rhs2 (def_stmt)))
2406 /* But treat x & 3 as condition. */
2407 if (and_or_code == BIT_AND_EXPR)
2409 pred_info n_pred;
2410 n_pred.pred_lhs = gimple_assign_rhs1 (def_stmt);
2411 n_pred.pred_rhs = gimple_assign_rhs2 (def_stmt);
2412 n_pred.cond_code = and_or_code;
2413 n_pred.invert = false;
2414 norm_chain->safe_push (n_pred);
2417 else
2419 push_to_worklist (gimple_assign_rhs1 (def_stmt), work_list, mark_set);
2420 push_to_worklist (gimple_assign_rhs2 (def_stmt), work_list, mark_set);
2423 else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
2424 == tcc_comparison)
2426 pred_info n_pred = get_pred_info_from_cmp (def_stmt);
2427 if (and_or_code == BIT_IOR_EXPR)
2428 push_pred (norm_preds, n_pred);
2429 else
2430 norm_chain->safe_push (n_pred);
2432 else
2434 if (and_or_code == BIT_IOR_EXPR)
2435 push_pred (norm_preds, pred);
2436 else
2437 norm_chain->safe_push (pred);
2441 /* Normalize PRED and store the normalized predicates into NORM_PREDS. */
2443 static void
2444 normalize_one_pred (pred_chain_union *norm_preds, pred_info pred)
2446 vec<pred_info, va_heap, vl_ptr> work_list = vNULL;
2447 enum tree_code and_or_code = ERROR_MARK;
2448 pred_chain norm_chain = vNULL;
2450 if (!is_neq_zero_form_p (pred))
2452 push_pred (norm_preds, pred);
2453 return;
2456 gimple *def_stmt = SSA_NAME_DEF_STMT (pred.pred_lhs);
2457 if (gimple_code (def_stmt) == GIMPLE_ASSIGN)
2458 and_or_code = gimple_assign_rhs_code (def_stmt);
2459 if (and_or_code != BIT_IOR_EXPR && and_or_code != BIT_AND_EXPR)
2461 if (TREE_CODE_CLASS (and_or_code) == tcc_comparison)
2463 pred_info n_pred = get_pred_info_from_cmp (def_stmt);
2464 push_pred (norm_preds, n_pred);
2466 else
2467 push_pred (norm_preds, pred);
2468 return;
2471 work_list.safe_push (pred);
2472 hash_set<tree> mark_set;
2474 while (!work_list.is_empty ())
2476 pred_info a_pred = work_list.pop ();
2477 normalize_one_pred_1 (norm_preds, &norm_chain, a_pred, and_or_code,
2478 &work_list, &mark_set);
2480 if (and_or_code == BIT_AND_EXPR)
2481 norm_preds->safe_push (norm_chain);
2483 work_list.release ();
2486 static void
2487 normalize_one_pred_chain (pred_chain_union *norm_preds, pred_chain one_chain)
2489 vec<pred_info, va_heap, vl_ptr> work_list = vNULL;
2490 hash_set<tree> mark_set;
2491 pred_chain norm_chain = vNULL;
2492 size_t i;
2494 for (i = 0; i < one_chain.length (); i++)
2496 work_list.safe_push (one_chain[i]);
2497 mark_set.add (one_chain[i].pred_lhs);
2500 while (!work_list.is_empty ())
2502 pred_info a_pred = work_list.pop ();
2503 normalize_one_pred_1 (0, &norm_chain, a_pred, BIT_AND_EXPR, &work_list,
2504 &mark_set);
2507 norm_preds->safe_push (norm_chain);
2508 work_list.release ();
2511 /* Normalize predicate chains PREDS and returns the normalized one. */
2513 static pred_chain_union
2514 normalize_preds (pred_chain_union preds, gimple *use_or_def, bool is_use)
2516 pred_chain_union norm_preds = vNULL;
2517 size_t n = preds.length ();
2518 size_t i;
2520 if (dump_file && dump_flags & TDF_DETAILS)
2522 fprintf (dump_file, "[BEFORE NORMALIZATION --");
2523 dump_predicates (use_or_def, preds, is_use ? "[USE]:\n" : "[DEF]:\n");
2526 for (i = 0; i < n; i++)
2528 if (preds[i].length () != 1)
2529 normalize_one_pred_chain (&norm_preds, preds[i]);
2530 else
2532 normalize_one_pred (&norm_preds, preds[i][0]);
2533 preds[i].release ();
2537 if (dump_file)
2539 fprintf (dump_file, "[AFTER NORMALIZATION -- ");
2540 dump_predicates (use_or_def, norm_preds,
2541 is_use ? "[USE]:\n" : "[DEF]:\n");
2544 destroy_predicate_vecs (&preds);
2545 return norm_preds;
2548 /* Return TRUE if PREDICATE can be invalidated by any individual
2549 predicate in USE_GUARD. */
2551 static bool
2552 can_one_predicate_be_invalidated_p (pred_info predicate,
2553 pred_chain use_guard)
2555 if (dump_file && dump_flags & TDF_DETAILS)
2557 fprintf (dump_file, "Testing if this predicate: ");
2558 dump_pred_info (predicate);
2559 fprintf (dump_file, "\n...can be invalidated by a USE guard of: ");
2560 dump_pred_chain (use_guard);
2562 for (size_t i = 0; i < use_guard.length (); ++i)
2564 /* NOTE: This is a very simple check, and only understands an
2565 exact opposite. So, [i == 0] is currently only invalidated
2566 by [.NOT. i == 0] or [i != 0]. Ideally we should also
2567 invalidate with say [i > 5] or [i == 8]. There is certainly
2568 room for improvement here. */
2569 if (pred_neg_p (predicate, use_guard[i]))
2571 if (dump_file && dump_flags & TDF_DETAILS)
2573 fprintf (dump_file, " Predicate was invalidated by: ");
2574 dump_pred_info (use_guard[i]);
2575 fputc ('\n', dump_file);
2577 return true;
2580 return false;
2583 /* Return TRUE if all predicates in UNINIT_PRED are invalidated by
2584 USE_GUARD being true. */
2586 static bool
2587 can_chain_union_be_invalidated_p (pred_chain_union uninit_pred,
2588 pred_chain use_guard)
2590 if (uninit_pred.is_empty ())
2591 return false;
2592 if (dump_file && dump_flags & TDF_DETAILS)
2593 dump_predicates (NULL, uninit_pred,
2594 "Testing if anything here can be invalidated: ");
2595 for (size_t i = 0; i < uninit_pred.length (); ++i)
2597 pred_chain c = uninit_pred[i];
2598 size_t j;
2599 for (j = 0; j < c.length (); ++j)
2600 if (can_one_predicate_be_invalidated_p (c[j], use_guard))
2601 break;
2603 /* If we were unable to invalidate any predicate in C, then there
2604 is a viable path from entry to the PHI where the PHI takes
2605 an uninitialized value and continues to a use of the PHI. */
2606 if (j == c.length ())
2607 return false;
2609 return true;
2612 /* Return TRUE if none of the uninitialized operands in UNINT_OPNDS
2613 can actually happen if we arrived at a use for PHI.
2615 PHI_USE_GUARDS are the guard conditions for the use of the PHI. */
2617 static bool
2618 uninit_uses_cannot_happen (gphi *phi, unsigned uninit_opnds,
2619 pred_chain_union phi_use_guards)
2621 unsigned phi_args = gimple_phi_num_args (phi);
2622 if (phi_args > max_phi_args)
2623 return false;
2625 /* PHI_USE_GUARDS are OR'ed together. If we have more than one
2626 possible guard, there's no way of knowing which guard was true.
2627 Since we need to be absolutely sure that the uninitialized
2628 operands will be invalidated, bail. */
2629 if (phi_use_guards.length () != 1)
2630 return false;
2632 /* Look for the control dependencies of all the uninitialized
2633 operands and build guard predicates describing them. */
2634 pred_chain_union uninit_preds;
2635 bool ret = true;
2636 for (unsigned i = 0; i < phi_args; ++i)
2638 if (!MASK_TEST_BIT (uninit_opnds, i))
2639 continue;
2641 edge e = gimple_phi_arg_edge (phi, i);
2642 vec<edge> dep_chains[MAX_NUM_CHAINS];
2643 auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
2644 size_t num_chains = 0;
2645 int num_calls = 0;
2647 /* Build the control dependency chain for uninit operand `i'... */
2648 uninit_preds = vNULL;
2649 if (!compute_control_dep_chain (ENTRY_BLOCK_PTR_FOR_FN (cfun),
2650 e->src, dep_chains, &num_chains,
2651 &cur_chain, &num_calls))
2653 ret = false;
2654 break;
2656 /* ...and convert it into a set of predicates. */
2657 bool has_valid_preds
2658 = convert_control_dep_chain_into_preds (dep_chains, num_chains,
2659 &uninit_preds);
2660 for (size_t j = 0; j < num_chains; ++j)
2661 dep_chains[j].release ();
2662 if (!has_valid_preds)
2664 ret = false;
2665 break;
2667 simplify_preds (&uninit_preds, NULL, false);
2668 uninit_preds = normalize_preds (uninit_preds, NULL, false);
2670 /* Can the guard for this uninitialized operand be invalidated
2671 by the PHI use? */
2672 if (!can_chain_union_be_invalidated_p (uninit_preds, phi_use_guards[0]))
2674 ret = false;
2675 break;
2678 destroy_predicate_vecs (&uninit_preds);
2679 return ret;
2682 /* Computes the predicates that guard the use and checks
2683 if the incoming paths that have empty (or possibly
2684 empty) definition can be pruned/filtered. The function returns
2685 true if it can be determined that the use of PHI's def in
2686 USE_STMT is guarded with a predicate set not overlapping with
2687 predicate sets of all runtime paths that do not have a definition.
2689 Returns false if it is not or it cannot be determined. USE_BB is
2690 the bb of the use (for phi operand use, the bb is not the bb of
2691 the phi stmt, but the src bb of the operand edge).
2693 UNINIT_OPNDS is a bit vector. If an operand of PHI is uninitialized, the
2694 corresponding bit in the vector is 1. VISITED_PHIS is a pointer
2695 set of phis being visited.
2697 *DEF_PREDS contains the (memoized) defining predicate chains of PHI.
2698 If *DEF_PREDS is the empty vector, the defining predicate chains of
2699 PHI will be computed and stored into *DEF_PREDS as needed.
2701 VISITED_PHIS is a pointer set of phis being visited. */
2703 static bool
2704 is_use_properly_guarded (gimple *use_stmt,
2705 basic_block use_bb,
2706 gphi *phi,
2707 unsigned uninit_opnds,
2708 pred_chain_union *def_preds,
2709 hash_set<gphi *> *visited_phis)
2711 basic_block phi_bb;
2712 pred_chain_union preds = vNULL;
2713 bool has_valid_preds = false;
2714 bool is_properly_guarded = false;
2716 if (visited_phis->add (phi))
2717 return false;
2719 phi_bb = gimple_bb (phi);
2721 if (is_non_loop_exit_postdominating (use_bb, phi_bb))
2722 return false;
2724 has_valid_preds = find_predicates (&preds, phi_bb, use_bb);
2726 if (!has_valid_preds)
2728 destroy_predicate_vecs (&preds);
2729 return false;
2732 /* Try to prune the dead incoming phi edges. */
2733 is_properly_guarded
2734 = use_pred_not_overlap_with_undef_path_pred (preds, phi, uninit_opnds,
2735 visited_phis);
2737 /* We might be able to prove that if the control dependencies
2738 for UNINIT_OPNDS are true, that the control dependencies for
2739 USE_STMT can never be true. */
2740 if (!is_properly_guarded)
2741 is_properly_guarded |= uninit_uses_cannot_happen (phi, uninit_opnds,
2742 preds);
2744 if (is_properly_guarded)
2746 destroy_predicate_vecs (&preds);
2747 return true;
2750 if (def_preds->is_empty ())
2752 has_valid_preds = find_def_preds (def_preds, phi);
2754 if (!has_valid_preds)
2756 destroy_predicate_vecs (&preds);
2757 return false;
2760 simplify_preds (def_preds, phi, false);
2761 *def_preds = normalize_preds (*def_preds, phi, false);
2764 simplify_preds (&preds, use_stmt, true);
2765 preds = normalize_preds (preds, use_stmt, true);
2767 is_properly_guarded = is_superset_of (*def_preds, preds);
2769 destroy_predicate_vecs (&preds);
2770 return is_properly_guarded;
2773 /* Searches through all uses of a potentially
2774 uninitialized variable defined by PHI and returns a use
2775 statement if the use is not properly guarded. It returns
2776 NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
2777 holding the position(s) of uninit PHI operands. WORKLIST
2778 is the vector of candidate phis that may be updated by this
2779 function. ADDED_TO_WORKLIST is the pointer set tracking
2780 if the new phi is already in the worklist. */
2782 static gimple *
2783 find_uninit_use (gphi *phi, unsigned uninit_opnds,
2784 vec<gphi *> *worklist,
2785 hash_set<gphi *> *added_to_worklist)
2787 tree phi_result;
2788 use_operand_p use_p;
2789 gimple *use_stmt;
2790 imm_use_iterator iter;
2791 pred_chain_union def_preds = vNULL;
2792 gimple *ret = NULL;
2794 phi_result = gimple_phi_result (phi);
2796 FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
2798 basic_block use_bb;
2800 use_stmt = USE_STMT (use_p);
2801 if (is_gimple_debug (use_stmt))
2802 continue;
2804 if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
2805 use_bb = gimple_phi_arg_edge (use_phi,
2806 PHI_ARG_INDEX_FROM_USE (use_p))->src;
2807 else
2808 use_bb = gimple_bb (use_stmt);
2810 hash_set<gphi *> visited_phis;
2811 if (is_use_properly_guarded (use_stmt, use_bb, phi, uninit_opnds,
2812 &def_preds, &visited_phis))
2813 continue;
2815 if (dump_file && (dump_flags & TDF_DETAILS))
2817 fprintf (dump_file, "[CHECK]: Found unguarded use: ");
2818 print_gimple_stmt (dump_file, use_stmt, 0);
2820 /* Found one real use, return. */
2821 if (gimple_code (use_stmt) != GIMPLE_PHI)
2823 ret = use_stmt;
2824 break;
2827 /* Found a phi use that is not guarded,
2828 add the phi to the worklist. */
2829 if (!added_to_worklist->add (as_a<gphi *> (use_stmt)))
2831 if (dump_file && (dump_flags & TDF_DETAILS))
2833 fprintf (dump_file, "[WORKLIST]: Update worklist with phi: ");
2834 print_gimple_stmt (dump_file, use_stmt, 0);
2837 worklist->safe_push (as_a<gphi *> (use_stmt));
2838 possibly_undefined_names->add (phi_result);
2842 destroy_predicate_vecs (&def_preds);
2843 return ret;
2846 /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
2847 and gives warning if there exists a runtime path from the entry to a
2848 use of the PHI def that does not contain a definition. In other words,
2849 the warning is on the real use. The more dead paths that can be pruned
2850 by the compiler, the fewer false positives the warning is. WORKLIST
2851 is a vector of candidate phis to be examined. ADDED_TO_WORKLIST is
2852 a pointer set tracking if the new phi is added to the worklist or not. */
2854 static void
2855 warn_uninitialized_phi (gphi *phi, vec<gphi *> *worklist,
2856 hash_set<gphi *> *added_to_worklist)
2858 unsigned uninit_opnds;
2859 gimple *uninit_use_stmt = 0;
2860 tree uninit_op;
2861 int phiarg_index;
2862 location_t loc;
2864 /* Don't look at virtual operands. */
2865 if (virtual_operand_p (gimple_phi_result (phi)))
2866 return;
2868 uninit_opnds = compute_uninit_opnds_pos (phi);
2870 if (MASK_EMPTY (uninit_opnds))
2871 return;
2873 if (dump_file && (dump_flags & TDF_DETAILS))
2875 fprintf (dump_file, "[CHECK]: examining phi: ");
2876 print_gimple_stmt (dump_file, phi, 0);
2879 /* Now check if we have any use of the value without proper guard. */
2880 uninit_use_stmt = find_uninit_use (phi, uninit_opnds,
2881 worklist, added_to_worklist);
2883 /* All uses are properly guarded. */
2884 if (!uninit_use_stmt)
2885 return;
2887 phiarg_index = MASK_FIRST_SET_BIT (uninit_opnds);
2888 uninit_op = gimple_phi_arg_def (phi, phiarg_index);
2889 if (SSA_NAME_VAR (uninit_op) == NULL_TREE)
2890 return;
2891 if (gimple_phi_arg_has_location (phi, phiarg_index))
2892 loc = gimple_phi_arg_location (phi, phiarg_index);
2893 else
2894 loc = UNKNOWN_LOCATION;
2895 warn_uninit (OPT_Wmaybe_uninitialized, uninit_op, SSA_NAME_VAR (uninit_op),
2896 SSA_NAME_VAR (uninit_op),
2897 "%qD may be used uninitialized in this function",
2898 uninit_use_stmt, loc);
2901 static bool
2902 gate_warn_uninitialized (void)
2904 return warn_uninitialized || warn_maybe_uninitialized;
2907 namespace {
2909 const pass_data pass_data_late_warn_uninitialized =
2911 GIMPLE_PASS, /* type */
2912 "uninit", /* name */
2913 OPTGROUP_NONE, /* optinfo_flags */
2914 TV_NONE, /* tv_id */
2915 PROP_ssa, /* properties_required */
2916 0, /* properties_provided */
2917 0, /* properties_destroyed */
2918 0, /* todo_flags_start */
2919 0, /* todo_flags_finish */
2922 class pass_late_warn_uninitialized : public gimple_opt_pass
2924 public:
2925 pass_late_warn_uninitialized (gcc::context *ctxt)
2926 : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt)
2929 /* opt_pass methods: */
2930 opt_pass *clone () { return new pass_late_warn_uninitialized (m_ctxt); }
2931 virtual bool gate (function *) { return gate_warn_uninitialized (); }
2932 virtual unsigned int execute (function *);
2934 }; // class pass_late_warn_uninitialized
2936 unsigned int
2937 pass_late_warn_uninitialized::execute (function *fun)
2939 basic_block bb;
2940 gphi_iterator gsi;
2941 vec<gphi *> worklist = vNULL;
2943 calculate_dominance_info (CDI_DOMINATORS);
2944 calculate_dominance_info (CDI_POST_DOMINATORS);
2945 /* Re-do the plain uninitialized variable check, as optimization may have
2946 straightened control flow. Do this first so that we don't accidentally
2947 get a "may be" warning when we'd have seen an "is" warning later. */
2948 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/1);
2950 timevar_push (TV_TREE_UNINIT);
2952 possibly_undefined_names = new hash_set<tree>;
2953 hash_set<gphi *> added_to_worklist;
2955 /* Initialize worklist */
2956 FOR_EACH_BB_FN (bb, fun)
2957 for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2959 gphi *phi = gsi.phi ();
2960 size_t n, i;
2962 n = gimple_phi_num_args (phi);
2964 /* Don't look at virtual operands. */
2965 if (virtual_operand_p (gimple_phi_result (phi)))
2966 continue;
2968 for (i = 0; i < n; ++i)
2970 tree op = gimple_phi_arg_def (phi, i);
2971 if (TREE_CODE (op) == SSA_NAME && uninit_undefined_value_p (op))
2973 worklist.safe_push (phi);
2974 added_to_worklist.add (phi);
2975 if (dump_file && (dump_flags & TDF_DETAILS))
2977 fprintf (dump_file, "[WORKLIST]: add to initial list: ");
2978 print_gimple_stmt (dump_file, phi, 0);
2980 break;
2985 while (worklist.length () != 0)
2987 gphi *cur_phi = 0;
2988 cur_phi = worklist.pop ();
2989 warn_uninitialized_phi (cur_phi, &worklist, &added_to_worklist);
2992 worklist.release ();
2993 delete possibly_undefined_names;
2994 possibly_undefined_names = NULL;
2995 free_dominance_info (CDI_POST_DOMINATORS);
2996 timevar_pop (TV_TREE_UNINIT);
2997 return 0;
3000 } // anon namespace
3002 gimple_opt_pass *
3003 make_pass_late_warn_uninitialized (gcc::context *ctxt)
3005 return new pass_late_warn_uninitialized (ctxt);
3008 static unsigned int
3009 execute_early_warn_uninitialized (void)
3011 /* Currently, this pass runs always but
3012 execute_late_warn_uninitialized only runs with optimization. With
3013 optimization we want to warn about possible uninitialized as late
3014 as possible, thus don't do it here. However, without
3015 optimization we need to warn here about "may be uninitialized". */
3016 calculate_dominance_info (CDI_POST_DOMINATORS);
3018 warn_uninitialized_vars (/*warn_maybe_uninitialized=*/!optimize);
3020 /* Post-dominator information cannot be reliably updated. Free it
3021 after the use. */
3023 free_dominance_info (CDI_POST_DOMINATORS);
3024 return 0;
3027 namespace {
3029 const pass_data pass_data_early_warn_uninitialized =
3031 GIMPLE_PASS, /* type */
3032 "*early_warn_uninitialized", /* name */
3033 OPTGROUP_NONE, /* optinfo_flags */
3034 TV_TREE_UNINIT, /* tv_id */
3035 PROP_ssa, /* properties_required */
3036 0, /* properties_provided */
3037 0, /* properties_destroyed */
3038 0, /* todo_flags_start */
3039 0, /* todo_flags_finish */
3042 class pass_early_warn_uninitialized : public gimple_opt_pass
3044 public:
3045 pass_early_warn_uninitialized (gcc::context *ctxt)
3046 : gimple_opt_pass (pass_data_early_warn_uninitialized, ctxt)
3049 /* opt_pass methods: */
3050 virtual bool gate (function *) { return gate_warn_uninitialized (); }
3051 virtual unsigned int execute (function *)
3053 return execute_early_warn_uninitialized ();
3056 }; // class pass_early_warn_uninitialized
3058 } // anon namespace
3060 gimple_opt_pass *
3061 make_pass_early_warn_uninitialized (gcc::context *ctxt)
3063 return new pass_early_warn_uninitialized (ctxt);