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