00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "tree.h"
00026 #include "flags.h"
00027 #include "rtl.h"
00028 #include "tm_p.h"
00029 #include "ggc.h"
00030 #include "langhooks.h"
00031 #include "hard-reg-set.h"
00032 #include "basic-block.h"
00033 #include "output.h"
00034 #include "errors.h"
00035 #include "expr.h"
00036 #include "function.h"
00037 #include "diagnostic.h"
00038 #include "bitmap.h"
00039 #include "pointer-set.h"
00040 #include "tree-flow.h"
00041 #include "tree-gimple.h"
00042 #include "tree-inline.h"
00043 #include "varray.h"
00044 #include "timevar.h"
00045 #include "hashtab.h"
00046 #include "tree-dump.h"
00047 #include "tree-pass.h"
00048
00049
00050
00051
00052
00053 edge
00054 ssa_redirect_edge (edge e, basic_block dest)
00055 {
00056 tree phi, next;
00057 tree list = NULL, *last = &list;
00058 tree src, dst, node;
00059
00060
00061 for (phi = phi_nodes (e->dest); phi; phi = next)
00062 {
00063 next = PHI_CHAIN (phi);
00064
00065 if (PHI_ARG_DEF (phi, e->dest_idx) == NULL_TREE)
00066 continue;
00067
00068 src = PHI_ARG_DEF (phi, e->dest_idx);
00069 dst = PHI_RESULT (phi);
00070 node = build_tree_list (dst, src);
00071 *last = node;
00072 last = &TREE_CHAIN (node);
00073 }
00074
00075 e = redirect_edge_succ_nodup (e, dest);
00076 PENDING_STMT (e) = list;
00077
00078 return e;
00079 }
00080
00081
00082
00083
00084 void
00085 flush_pending_stmts (edge e)
00086 {
00087 tree phi, arg;
00088
00089 if (!PENDING_STMT (e))
00090 return;
00091
00092 for (phi = phi_nodes (e->dest), arg = PENDING_STMT (e);
00093 phi;
00094 phi = PHI_CHAIN (phi), arg = TREE_CHAIN (arg))
00095 {
00096 tree def = TREE_VALUE (arg);
00097 add_phi_arg (phi, def, e);
00098 }
00099
00100 PENDING_STMT (e) = NULL;
00101 }
00102
00103
00104
00105
00106
00107
00108 static bool
00109 verify_ssa_name (tree ssa_name, bool is_virtual)
00110 {
00111 if (TREE_CODE (ssa_name) != SSA_NAME)
00112 {
00113 error ("Expected an SSA_NAME object");
00114 return true;
00115 }
00116
00117 if (TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name)))
00118 {
00119 error ("Type mismatch between an SSA_NAME and its symbol.");
00120 return true;
00121 }
00122
00123 if (SSA_NAME_IN_FREE_LIST (ssa_name))
00124 {
00125 error ("Found an SSA_NAME that had been released into the free pool");
00126 return true;
00127 }
00128
00129 if (is_virtual && is_gimple_reg (ssa_name))
00130 {
00131 error ("Found a virtual definition for a GIMPLE register");
00132 return true;
00133 }
00134
00135 if (!is_virtual && !is_gimple_reg (ssa_name))
00136 {
00137 error ("Found a real definition for a non-register");
00138 return true;
00139 }
00140
00141 return false;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 static bool
00158 verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
00159 tree stmt, bool is_virtual)
00160 {
00161 if (verify_ssa_name (ssa_name, is_virtual))
00162 goto err;
00163
00164 if (definition_block[SSA_NAME_VERSION (ssa_name)])
00165 {
00166 error ("SSA_NAME created in two different blocks %i and %i",
00167 definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
00168 goto err;
00169 }
00170
00171 definition_block[SSA_NAME_VERSION (ssa_name)] = bb;
00172
00173 if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
00174 {
00175 error ("SSA_NAME_DEF_STMT is wrong");
00176 fprintf (stderr, "Expected definition statement:\n");
00177 print_generic_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), TDF_VOPS);
00178 fprintf (stderr, "\nActual definition statement:\n");
00179 print_generic_stmt (stderr, stmt, TDF_VOPS);
00180 goto err;
00181 }
00182
00183 return false;
00184
00185 err:
00186 fprintf (stderr, "while verifying SSA_NAME ");
00187 print_generic_expr (stderr, ssa_name, 0);
00188 fprintf (stderr, " in statement\n");
00189 print_generic_stmt (stderr, stmt, TDF_VOPS);
00190
00191 return true;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 static bool
00213 verify_use (basic_block bb, basic_block def_bb, tree ssa_name,
00214 tree stmt, bool check_abnormal, bool is_virtual,
00215 bitmap names_defined_in_bb)
00216 {
00217 bool err = false;
00218
00219 err = verify_ssa_name (ssa_name, is_virtual);
00220 TREE_VISITED (ssa_name) = 1;
00221
00222 if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name))
00223 && var_ann (SSA_NAME_VAR (ssa_name))->default_def == ssa_name)
00224 ;
00225 else if (!def_bb)
00226 {
00227 error ("Missing definition");
00228 err = true;
00229 }
00230 else if (bb != def_bb
00231 && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
00232 {
00233 error ("Definition in block %i does not dominate use in block %i",
00234 def_bb->index, bb->index);
00235 err = true;
00236 }
00237 else if (bb == def_bb
00238 && names_defined_in_bb != NULL
00239 && !bitmap_bit_p (names_defined_in_bb, SSA_NAME_VERSION (ssa_name)))
00240 {
00241 error ("Definition in block %i follows the use", def_bb->index);
00242 err = true;
00243 }
00244
00245 if (check_abnormal
00246 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
00247 {
00248 error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI should be set");
00249 err = true;
00250 }
00251
00252 if (err)
00253 {
00254 fprintf (stderr, "for SSA_NAME: ");
00255 print_generic_expr (stderr, ssa_name, TDF_VOPS);
00256 fprintf (stderr, "in statement:\n");
00257 print_generic_stmt (stderr, stmt, TDF_VOPS);
00258 }
00259
00260 return err;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 static bool
00272 verify_phi_args (tree phi, basic_block bb, basic_block *definition_block)
00273 {
00274 edge e;
00275 bool err = false;
00276 unsigned i, phi_num_args = PHI_NUM_ARGS (phi);
00277
00278 if (EDGE_COUNT (bb->preds) != phi_num_args)
00279 {
00280 error ("Incoming edge count does not match number of PHI arguments\n");
00281 err = true;
00282 goto error;
00283 }
00284
00285 for (i = 0; i < phi_num_args; i++)
00286 {
00287 tree op = PHI_ARG_DEF (phi, i);
00288
00289 e = EDGE_PRED (bb, i);
00290
00291 if (op == NULL_TREE)
00292 {
00293 error ("PHI argument is missing for edge %d->%d\n",
00294 e->src->index,
00295 e->dest->index);
00296 err = true;
00297 goto error;
00298 }
00299
00300 if (TREE_CODE (op) != SSA_NAME && !is_gimple_min_invariant (op))
00301 {
00302 error ("PHI argument is not SSA_NAME, or invariant");
00303 err = true;
00304 }
00305
00306 if (TREE_CODE (op) == SSA_NAME)
00307 err = verify_use (e->src, definition_block[SSA_NAME_VERSION (op)], op,
00308 phi, e->flags & EDGE_ABNORMAL,
00309 !is_gimple_reg (PHI_RESULT (phi)),
00310 NULL);
00311
00312 if (e->dest != bb)
00313 {
00314 error ("Wrong edge %d->%d for PHI argument\n",
00315 e->src->index, e->dest->index, bb->index);
00316 err = true;
00317 }
00318
00319 if (err)
00320 {
00321 fprintf (stderr, "PHI argument\n");
00322 print_generic_stmt (stderr, op, TDF_VOPS);
00323 goto error;
00324 }
00325 }
00326
00327 error:
00328 if (err)
00329 {
00330 fprintf (stderr, "for PHI node\n");
00331 print_generic_stmt (stderr, phi, TDF_VOPS);
00332 }
00333
00334
00335 return err;
00336 }
00337
00338
00339 static void
00340 verify_flow_insensitive_alias_info (void)
00341 {
00342 size_t i;
00343 tree var;
00344 bitmap visited = BITMAP_ALLOC (NULL);
00345
00346 for (i = 0; i < num_referenced_vars; i++)
00347 {
00348 size_t j;
00349 var_ann_t ann;
00350 varray_type may_aliases;
00351
00352 var = referenced_var (i);
00353 ann = var_ann (var);
00354 may_aliases = ann->may_aliases;
00355
00356 for (j = 0; may_aliases && j < VARRAY_ACTIVE_SIZE (may_aliases); j++)
00357 {
00358 tree alias = VARRAY_TREE (may_aliases, j);
00359
00360 bitmap_set_bit (visited, var_ann (alias)->uid);
00361
00362 if (!may_be_aliased (alias))
00363 {
00364 error ("Non-addressable variable inside an alias set.");
00365 debug_variable (alias);
00366 goto err;
00367 }
00368 }
00369 }
00370
00371 for (i = 0; i < num_referenced_vars; i++)
00372 {
00373 var_ann_t ann;
00374
00375 var = referenced_var (i);
00376 ann = var_ann (var);
00377
00378 if (ann->mem_tag_kind == NOT_A_TAG
00379 && ann->is_alias_tag
00380 && !bitmap_bit_p (visited, ann->uid))
00381 {
00382 error ("Addressable variable that is an alias tag but is not in any alias set.");
00383 goto err;
00384 }
00385 }
00386
00387 BITMAP_FREE (visited);
00388 return;
00389
00390 err:
00391 debug_variable (var);
00392 internal_error ("verify_flow_insensitive_alias_info failed.");
00393 }
00394
00395
00396 static void
00397 verify_flow_sensitive_alias_info (void)
00398 {
00399 size_t i;
00400 tree ptr;
00401
00402 for (i = 1; i < num_ssa_names; i++)
00403 {
00404 tree var;
00405 var_ann_t ann;
00406 struct ptr_info_def *pi;
00407
00408
00409 ptr = ssa_name (i);
00410 if (!ptr)
00411 continue;
00412
00413
00414
00415 if (!POINTER_TYPE_P (TREE_TYPE (ptr)) || !TREE_VISITED (ptr))
00416 continue;
00417
00418
00419
00420
00421
00422 var = SSA_NAME_VAR (ptr);
00423 if (TREE_CODE (var) == RESULT_DECL
00424 && is_gimple_reg (ptr))
00425 continue;
00426
00427 pi = SSA_NAME_PTR_INFO (ptr);
00428 if (pi == NULL)
00429 continue;
00430
00431 ann = var_ann (var);
00432 if (pi->is_dereferenced && !pi->name_mem_tag && !ann->type_mem_tag)
00433 {
00434 error ("Dereferenced pointers should have a name or a type tag");
00435 goto err;
00436 }
00437
00438 if (pi->name_mem_tag
00439 && !pi->pt_malloc
00440 && (pi->pt_vars == NULL || bitmap_empty_p (pi->pt_vars)))
00441 {
00442 error ("Pointers with a memory tag, should have points-to sets or point to malloc");
00443 goto err;
00444 }
00445
00446 if (pi->value_escapes_p
00447 && pi->name_mem_tag
00448 && !is_call_clobbered (pi->name_mem_tag))
00449 {
00450 error ("Pointer escapes but its name tag is not call-clobbered.");
00451 goto err;
00452 }
00453 }
00454
00455 return;
00456
00457 err:
00458 debug_variable (ptr);
00459 internal_error ("verify_flow_sensitive_alias_info failed.");
00460 }
00461
00462 DEF_VEC_MALLOC_P (bitmap);
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 static void
00476 verify_name_tags (void)
00477 {
00478 size_t i;
00479 size_t j;
00480 bitmap first, second;
00481 VEC (tree) *name_tag_reps = NULL;
00482 VEC (bitmap) *pt_vars_for_reps = NULL;
00483 bitmap type_aliases = BITMAP_ALLOC (NULL);
00484
00485
00486 for (i = 0; i < num_ssa_names; i++)
00487 {
00488 struct ptr_info_def *pi;
00489 tree tmt, ptr = ssa_name (i);
00490
00491 if (ptr == NULL_TREE)
00492 continue;
00493
00494 pi = SSA_NAME_PTR_INFO (ptr);
00495
00496 if (!TREE_VISITED (ptr)
00497 || !POINTER_TYPE_P (TREE_TYPE (ptr))
00498 || !pi
00499 || !pi->name_mem_tag
00500 || TREE_VISITED (pi->name_mem_tag))
00501 continue;
00502
00503 TREE_VISITED (pi->name_mem_tag) = 1;
00504
00505 if (pi->pt_vars == NULL)
00506 continue;
00507
00508 VEC_safe_push (tree, name_tag_reps, ptr);
00509 VEC_safe_push (bitmap, pt_vars_for_reps, pi->pt_vars);
00510
00511
00512
00513 tmt = var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
00514 if (tmt)
00515 {
00516 size_t i;
00517 varray_type aliases = var_ann (tmt)->may_aliases;
00518 bitmap_clear (type_aliases);
00519 for (i = 0; aliases && i < VARRAY_ACTIVE_SIZE (aliases); i++)
00520 {
00521 tree alias = VARRAY_TREE (aliases, i);
00522 bitmap_set_bit (type_aliases, var_ann (alias)->uid);
00523 }
00524
00525
00526
00527
00528 bitmap_set_bit (type_aliases, var_ann (tmt)->uid);
00529
00530 if (bitmap_equal_p (type_aliases, pi->pt_vars))
00531 continue;
00532
00533 if (!bitmap_intersect_compl_p (type_aliases, pi->pt_vars))
00534 {
00535 error ("Alias set of a pointer's type tag should be a superset of the corresponding name tag");
00536 debug_variable (tmt);
00537 debug_variable (pi->name_mem_tag);
00538 goto err;
00539 }
00540 }
00541 }
00542
00543
00544
00545 for (i = 0; VEC_iterate (bitmap, pt_vars_for_reps, i, first); i++)
00546 {
00547 for (j = i + 1; VEC_iterate (bitmap, pt_vars_for_reps, j, second); j++)
00548 {
00549 if (bitmap_equal_p (first, second))
00550 {
00551 error ("Two different pointers with identical points-to sets but different name tags");
00552 debug_variable (VEC_index (tree, name_tag_reps, j));
00553 goto err;
00554 }
00555 }
00556 }
00557
00558
00559 for (i = 0; i < num_ssa_names; i++)
00560 {
00561 if (ssa_name (i))
00562 {
00563 tree ptr = ssa_name (i);
00564 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
00565 if (!TREE_VISITED (ptr)
00566 || !POINTER_TYPE_P (TREE_TYPE (ptr))
00567 || !pi
00568 || !pi->name_mem_tag)
00569 continue;
00570 TREE_VISITED (pi->name_mem_tag) = 0;
00571 }
00572 }
00573
00574 VEC_free (bitmap, pt_vars_for_reps);
00575 BITMAP_FREE (type_aliases);
00576 return;
00577
00578 err:
00579 debug_variable (VEC_index (tree, name_tag_reps, i));
00580 internal_error ("verify_name_tags failed");
00581 }
00582
00583
00584
00585
00586 static void
00587 verify_alias_info (void)
00588 {
00589 verify_flow_sensitive_alias_info ();
00590 verify_name_tags ();
00591 verify_flow_insensitive_alias_info ();
00592 }
00593
00594
00595
00596
00597
00598 void
00599 verify_ssa (void)
00600 {
00601 size_t i;
00602 basic_block bb;
00603 basic_block *definition_block = xcalloc (num_ssa_names, sizeof (basic_block));
00604 ssa_op_iter iter;
00605 tree op;
00606 enum dom_state orig_dom_state = dom_computed[CDI_DOMINATORS];
00607 bitmap names_defined_in_bb = BITMAP_ALLOC (NULL);
00608
00609 timevar_push (TV_TREE_SSA_VERIFY);
00610
00611
00612 for (i = 1; i < num_ssa_names; i++)
00613 {
00614 tree name = ssa_name (i);
00615 if (name)
00616 {
00617 tree stmt;
00618 TREE_VISITED (name) = 0;
00619
00620 stmt = SSA_NAME_DEF_STMT (name);
00621 if (!IS_EMPTY_STMT (stmt))
00622 {
00623 basic_block bb = bb_for_stmt (stmt);
00624 verify_def (bb, definition_block,
00625 name, stmt, !is_gimple_reg (name));
00626
00627 }
00628 }
00629 }
00630
00631 calculate_dominance_info (CDI_DOMINATORS);
00632
00633
00634
00635 FOR_EACH_BB (bb)
00636 {
00637 edge e;
00638 tree phi;
00639 edge_iterator ei;
00640 block_stmt_iterator bsi;
00641
00642
00643 FOR_EACH_EDGE (e, ei, bb->preds)
00644 {
00645 if (e->aux)
00646 {
00647 error ("AUX pointer initialized for edge %d->%d\n", e->src->index,
00648 e->dest->index);
00649 goto err;
00650 }
00651 }
00652
00653
00654 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00655 {
00656 if (verify_phi_args (phi, bb, definition_block))
00657 goto err;
00658 bitmap_set_bit (names_defined_in_bb,
00659 SSA_NAME_VERSION (PHI_RESULT (phi)));
00660 }
00661
00662
00663 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
00664 {
00665 tree stmt = bsi_stmt (bsi);
00666
00667 get_stmt_operands (stmt);
00668
00669 if (stmt_ann (stmt)->makes_aliased_stores
00670 && NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0)
00671 {
00672 error ("Statement makes aliased stores, but has no V_MAY_DEFS");
00673 print_generic_stmt (stderr, stmt, TDF_VOPS);
00674 goto err;
00675 }
00676
00677 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
00678 {
00679 if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
00680 op, stmt, false, !is_gimple_reg (op),
00681 names_defined_in_bb))
00682 goto err;
00683 }
00684
00685 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
00686 {
00687 bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
00688 }
00689 }
00690
00691 bitmap_clear (names_defined_in_bb);
00692 }
00693
00694
00695 verify_alias_info ();
00696
00697 free (definition_block);
00698
00699
00700 if (orig_dom_state == DOM_NONE)
00701 free_dominance_info (CDI_DOMINATORS);
00702 else
00703 dom_computed[CDI_DOMINATORS] = orig_dom_state;
00704
00705 BITMAP_FREE (names_defined_in_bb);
00706 timevar_pop (TV_TREE_SSA_VERIFY);
00707 return;
00708
00709 err:
00710 internal_error ("verify_ssa failed.");
00711 }
00712
00713
00714
00715
00716 void
00717 init_tree_ssa (void)
00718 {
00719 VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
00720 call_clobbered_vars = BITMAP_ALLOC (NULL);
00721 addressable_vars = BITMAP_ALLOC (NULL);
00722 init_ssa_operands ();
00723 init_ssanames ();
00724 init_phinodes ();
00725 global_var = NULL_TREE;
00726 aliases_computed_p = false;
00727 }
00728
00729
00730
00731
00732 void
00733 delete_tree_ssa (void)
00734 {
00735 size_t i;
00736 basic_block bb;
00737 block_stmt_iterator bsi;
00738
00739
00740 FOR_EACH_BB (bb)
00741 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
00742 {
00743 tree stmt = bsi_stmt (bsi);
00744 release_defs (stmt);
00745 ggc_free (stmt->common.ann);
00746 stmt->common.ann = NULL;
00747 }
00748
00749
00750 if (referenced_vars)
00751 {
00752 for (i = 0; i < num_referenced_vars; i++)
00753 {
00754 tree var = referenced_var (i);
00755 ggc_free (var->common.ann);
00756 var->common.ann = NULL;
00757 }
00758 referenced_vars = NULL;
00759 }
00760
00761 fini_ssanames ();
00762 fini_phinodes ();
00763 fini_ssa_operands ();
00764
00765 global_var = NULL_TREE;
00766 BITMAP_FREE (call_clobbered_vars);
00767 call_clobbered_vars = NULL;
00768 BITMAP_FREE (addressable_vars);
00769 addressable_vars = NULL;
00770 modified_noreturn_calls = NULL;
00771 aliases_computed_p = false;
00772 }
00773
00774
00775
00776
00777
00778 bool
00779 tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
00780 {
00781 if (inner_type == outer_type)
00782 return true;
00783
00784
00785 if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type))
00786 return false;
00787
00788
00789
00790
00791 if (lang_hooks.types_compatible_p (inner_type, outer_type))
00792 return true;
00793
00794
00795
00796
00797
00798
00799
00800 else if (POINTER_TYPE_P (inner_type)
00801 && POINTER_TYPE_P (outer_type)
00802 && TYPE_REF_CAN_ALIAS_ALL (inner_type)
00803 == TYPE_REF_CAN_ALIAS_ALL (outer_type)
00804 && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
00805 return true;
00806
00807
00808
00809
00810 else if (POINTER_TYPE_P (inner_type)
00811 && POINTER_TYPE_P (outer_type)
00812 && TYPE_VOLATILE (TREE_TYPE (outer_type))
00813 != TYPE_VOLATILE (TREE_TYPE (inner_type)))
00814 return false;
00815
00816
00817
00818 else if (POINTER_TYPE_P (inner_type)
00819 && POINTER_TYPE_P (outer_type)
00820 && TYPE_REF_CAN_ALIAS_ALL (inner_type)
00821 == TYPE_REF_CAN_ALIAS_ALL (outer_type)
00822 && lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
00823 TREE_TYPE (outer_type)))
00824 return true;
00825
00826
00827
00828
00829
00830
00831
00832
00833 else if (INTEGRAL_TYPE_P (inner_type)
00834 && INTEGRAL_TYPE_P (outer_type)
00835 && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
00836 && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
00837 {
00838 bool first_boolean = (TREE_CODE (inner_type) == BOOLEAN_TYPE);
00839 bool second_boolean = (TREE_CODE (outer_type) == BOOLEAN_TYPE);
00840 if (first_boolean == second_boolean)
00841 return true;
00842 }
00843
00844
00845 else if (TREE_CODE (inner_type) == COMPLEX_TYPE
00846 && TREE_CODE (outer_type) == COMPLEX_TYPE
00847 && tree_ssa_useless_type_conversion_1 (TREE_TYPE (outer_type),
00848 TREE_TYPE (inner_type)))
00849 return true;
00850
00851 return false;
00852 }
00853
00854
00855
00856
00857 bool
00858 tree_ssa_useless_type_conversion (tree expr)
00859 {
00860
00861
00862
00863
00864 if (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR
00865 || TREE_CODE (expr) == VIEW_CONVERT_EXPR
00866 || TREE_CODE (expr) == NON_LVALUE_EXPR)
00867 return tree_ssa_useless_type_conversion_1 (TREE_TYPE (expr),
00868 TREE_TYPE (TREE_OPERAND (expr,
00869 0)));
00870
00871
00872 return false;
00873 }
00874
00875
00876
00877 bool
00878 stmt_references_memory_p (tree stmt)
00879 {
00880 stmt_ann_t ann;
00881
00882 get_stmt_operands (stmt);
00883 ann = stmt_ann (stmt);
00884
00885 if (ann->has_volatile_ops)
00886 return true;
00887
00888 return (NUM_VUSES (VUSE_OPS (ann)) > 0
00889 || NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
00890 || NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0);
00891 }
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 static bool
00908 walk_use_def_chains_1 (tree var, walk_use_def_chains_fn fn, void *data,
00909 struct pointer_set_t *visited, bool is_dfs)
00910 {
00911 tree def_stmt;
00912
00913 if (pointer_set_insert (visited, var))
00914 return false;
00915
00916 def_stmt = SSA_NAME_DEF_STMT (var);
00917
00918 if (TREE_CODE (def_stmt) != PHI_NODE)
00919 {
00920
00921 return fn (var, def_stmt, data);
00922 }
00923 else
00924 {
00925 int i;
00926
00927
00928
00929 if (!is_dfs)
00930 for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
00931 if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
00932 return true;
00933
00934
00935 for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
00936 {
00937 tree arg = PHI_ARG_DEF (def_stmt, i);
00938 if (TREE_CODE (arg) == SSA_NAME
00939 && walk_use_def_chains_1 (arg, fn, data, visited, is_dfs))
00940 return true;
00941 }
00942
00943
00944
00945 if (is_dfs)
00946 for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
00947 if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
00948 return true;
00949 }
00950
00951 return false;
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977 void
00978 walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
00979 bool is_dfs)
00980 {
00981 tree def_stmt;
00982
00983 gcc_assert (TREE_CODE (var) == SSA_NAME);
00984
00985 def_stmt = SSA_NAME_DEF_STMT (var);
00986
00987
00988
00989 if (TREE_CODE (def_stmt) != PHI_NODE)
00990 (*fn) (var, def_stmt, data);
00991 else
00992 {
00993 struct pointer_set_t *visited = pointer_set_create ();
00994 walk_use_def_chains_1 (var, fn, data, visited, is_dfs);
00995 pointer_set_destroy (visited);
00996 }
00997 }
00998
00999
01000
01001
01002
01003 static void
01004 propagate_into_addr (tree stmt, tree var, tree *x, tree repl)
01005 {
01006 tree new_var, ass_stmt, addr_var;
01007 basic_block bb;
01008 block_stmt_iterator bsi;
01009
01010
01011 if (TREE_CODE (repl) != ADDR_EXPR)
01012 return;
01013 addr_var = TREE_OPERAND (repl, 0);
01014
01015 while (handled_component_p (*x)
01016 || TREE_CODE (*x) == REALPART_EXPR
01017 || TREE_CODE (*x) == IMAGPART_EXPR)
01018 x = &TREE_OPERAND (*x, 0);
01019
01020 if (TREE_CODE (*x) != INDIRECT_REF
01021 || TREE_OPERAND (*x, 0) != var)
01022 return;
01023
01024 if (TREE_TYPE (*x) == TREE_TYPE (addr_var))
01025 {
01026 *x = addr_var;
01027 mark_new_vars_to_rename (stmt, vars_to_rename);
01028 return;
01029 }
01030
01031
01032
01033
01034 ass_stmt = build2 (MODIFY_EXPR, void_type_node, NULL_TREE, repl);
01035 new_var = duplicate_ssa_name (var, ass_stmt);
01036 TREE_OPERAND (*x, 0) = new_var;
01037 TREE_OPERAND (ass_stmt, 0) = new_var;
01038
01039 bb = bb_for_stmt (stmt);
01040 tree_block_label (bb);
01041 bsi = bsi_after_labels (bb);
01042 bsi_insert_after (&bsi, ass_stmt, BSI_NEW_STMT);
01043
01044 mark_new_vars_to_rename (stmt, vars_to_rename);
01045 }
01046
01047
01048
01049 static void
01050 replace_immediate_uses (tree var, tree repl)
01051 {
01052 int i, j, n;
01053 dataflow_t df;
01054 tree stmt;
01055 bool mark_new_vars;
01056 ssa_op_iter iter;
01057 use_operand_p use_p;
01058
01059 df = get_immediate_uses (SSA_NAME_DEF_STMT (var));
01060 n = num_immediate_uses (df);
01061
01062 for (i = 0; i < n; i++)
01063 {
01064 stmt = immediate_use (df, i);
01065
01066 if (TREE_CODE (stmt) == PHI_NODE)
01067 {
01068 for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
01069 if (PHI_ARG_DEF (stmt, j) == var)
01070 {
01071 SET_PHI_ARG_DEF (stmt, j, repl);
01072 if (TREE_CODE (repl) == SSA_NAME
01073 && PHI_ARG_EDGE (stmt, j)->flags & EDGE_ABNORMAL)
01074 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (repl) = 1;
01075 }
01076
01077 continue;
01078 }
01079
01080 get_stmt_operands (stmt);
01081 mark_new_vars = false;
01082 if (is_gimple_reg (SSA_NAME_VAR (var)))
01083 {
01084 if (TREE_CODE (stmt) == MODIFY_EXPR)
01085 {
01086 propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 0), repl);
01087 propagate_into_addr (stmt, var, &TREE_OPERAND (stmt, 1), repl);
01088 }
01089
01090 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
01091 if (USE_FROM_PTR (use_p) == var)
01092 {
01093 propagate_value (use_p, repl);
01094 mark_new_vars = POINTER_TYPE_P (TREE_TYPE (repl));
01095 }
01096 }
01097 else
01098 {
01099 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
01100 SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
01101 if (USE_FROM_PTR (use_p) == var)
01102 propagate_value (use_p, repl);
01103 }
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117 if (TREE_CODE (repl) != SSA_NAME)
01118 {
01119 tree tmp = stmt;
01120 fold_stmt (&tmp);
01121 mark_new_vars = true;
01122 if (tmp != stmt)
01123 {
01124 block_stmt_iterator si = bsi_for_stmt (stmt);
01125 mark_new_vars_to_rename (tmp, vars_to_rename);
01126 redirect_immediate_uses (stmt, tmp);
01127 bsi_replace (&si, tmp, true);
01128 stmt = bsi_stmt (si);
01129 }
01130 }
01131
01132
01133
01134
01135
01136
01137 if (mark_new_vars)
01138 mark_new_vars_to_rename (stmt, vars_to_rename);
01139 else
01140 modify_stmt (stmt);
01141 }
01142 }
01143
01144
01145
01146 static tree
01147 get_eq_name (tree *eq_to, tree var)
01148 {
01149 unsigned ver;
01150 tree val = var;
01151
01152 while (TREE_CODE (val) == SSA_NAME)
01153 {
01154 ver = SSA_NAME_VERSION (val);
01155 if (!eq_to[ver])
01156 break;
01157
01158 val = eq_to[ver];
01159 }
01160
01161 while (TREE_CODE (var) == SSA_NAME)
01162 {
01163 ver = SSA_NAME_VERSION (var);
01164 if (!eq_to[ver])
01165 break;
01166
01167 var = eq_to[ver];
01168 eq_to[ver] = val;
01169 }
01170
01171 return val;
01172 }
01173
01174
01175
01176
01177 static void
01178 check_phi_redundancy (tree phi, tree *eq_to)
01179 {
01180 tree val = NULL_TREE, def, res = PHI_RESULT (phi), stmt;
01181 unsigned i, ver = SSA_NAME_VERSION (res), n;
01182 dataflow_t df;
01183
01184
01185 if (PHI_NUM_ARGS (phi) > 16)
01186 return;
01187
01188 for (i = 0; i < (unsigned) PHI_NUM_ARGS (phi); i++)
01189 {
01190 def = PHI_ARG_DEF (phi, i);
01191
01192 if (TREE_CODE (def) == SSA_NAME)
01193 {
01194 def = get_eq_name (eq_to, def);
01195 if (def == res)
01196 continue;
01197 }
01198
01199 if (val
01200 && !operand_equal_for_phi_arg_p (val, def))
01201 return;
01202
01203 val = def;
01204 }
01205
01206
01207
01208 gcc_assert (val);
01209
01210 if (get_eq_name (eq_to, res) == val)
01211 return;
01212
01213 if (!may_propagate_copy (res, val))
01214 return;
01215
01216 eq_to[ver] = val;
01217
01218 df = get_immediate_uses (SSA_NAME_DEF_STMT (res));
01219 n = num_immediate_uses (df);
01220
01221 for (i = 0; i < n; i++)
01222 {
01223 stmt = immediate_use (df, i);
01224
01225 if (TREE_CODE (stmt) == PHI_NODE)
01226 check_phi_redundancy (stmt, eq_to);
01227 }
01228 }
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247 void
01248 kill_redundant_phi_nodes (void)
01249 {
01250 tree *eq_to;
01251 unsigned i, old_num_ssa_names;
01252 basic_block bb;
01253 tree phi, var, repl, stmt;
01254
01255
01256
01257
01258
01259
01260
01261
01262 eq_to = xcalloc (num_ssa_names, sizeof (tree));
01263
01264
01265
01266
01267
01268
01269 compute_immediate_uses (TDFA_USE_OPS | TDFA_USE_VOPS, NULL);
01270 old_num_ssa_names = num_ssa_names;
01271
01272 FOR_EACH_BB (bb)
01273 {
01274 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01275 {
01276 var = PHI_RESULT (phi);
01277 check_phi_redundancy (phi, eq_to);
01278 }
01279 }
01280
01281
01282 for (i = 0; i < old_num_ssa_names; i++)
01283 {
01284 if (!ssa_name (i))
01285 continue;
01286
01287 repl = get_eq_name (eq_to, ssa_name (i));
01288 if (repl != ssa_name (i))
01289 replace_immediate_uses (ssa_name (i), repl);
01290 }
01291
01292
01293 for (i = 0; i < old_num_ssa_names; i++)
01294 {
01295 if (!ssa_name (i))
01296 continue;
01297
01298 repl = get_eq_name (eq_to, ssa_name (i));
01299 if (repl != ssa_name (i))
01300 {
01301 stmt = SSA_NAME_DEF_STMT (ssa_name (i));
01302 remove_phi_node (stmt, NULL_TREE, bb_for_stmt (stmt));
01303 }
01304 }
01305
01306 free_df ();
01307 free (eq_to);
01308 }
01309
01310 struct tree_opt_pass pass_redundant_phi =
01311 {
01312 "redphi",
01313 NULL,
01314 kill_redundant_phi_nodes,
01315 NULL,
01316 NULL,
01317 0,
01318 TV_TREE_REDPHI,
01319 PROP_cfg | PROP_ssa | PROP_alias,
01320 0,
01321 0,
01322 0,
01323 TODO_dump_func | TODO_rename_vars
01324 | TODO_ggc_collect | TODO_verify_ssa,
01325 0
01326 };
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346 static void
01347 warn_uninit (tree t, const char *gmsgid, location_t *locus)
01348 {
01349 tree var = SSA_NAME_VAR (t);
01350 tree def = SSA_NAME_DEF_STMT (t);
01351
01352
01353
01354 if (!IS_EMPTY_STMT (def))
01355 return;
01356
01357
01358 if (TREE_CODE (var) == PARM_DECL)
01359 return;
01360
01361
01362 if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
01363 return;
01364
01365
01366
01367 if (TREE_NO_WARNING (var))
01368 return;
01369
01370 if (!locus)
01371 locus = &DECL_SOURCE_LOCATION (var);
01372 warning (gmsgid, locus, var);
01373 TREE_NO_WARNING (var) = 1;
01374 }
01375
01376
01377
01378
01379 static tree
01380 warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data)
01381 {
01382 location_t *locus = data;
01383 tree t = *tp;
01384
01385
01386 if (TREE_CODE (t) == SSA_NAME)
01387 {
01388 warn_uninit (t, "%H%qD is used uninitialized in this function", locus);
01389 *walk_subtrees = 0;
01390 }
01391 else if (IS_TYPE_OR_DECL_P (t))
01392 *walk_subtrees = 0;
01393
01394 return NULL_TREE;
01395 }
01396
01397
01398
01399
01400 static void
01401 warn_uninitialized_phi (tree phi)
01402 {
01403 int i, n = PHI_NUM_ARGS (phi);
01404
01405
01406 if (!is_gimple_reg (PHI_RESULT (phi)))
01407 return;
01408
01409 for (i = 0; i < n; ++i)
01410 {
01411 tree op = PHI_ARG_DEF (phi, i);
01412 if (TREE_CODE (op) == SSA_NAME)
01413 warn_uninit (op, "%H%qD may be used uninitialized in this function",
01414 NULL);
01415 }
01416 }
01417
01418 static void
01419 execute_early_warn_uninitialized (void)
01420 {
01421 block_stmt_iterator bsi;
01422 basic_block bb;
01423
01424 FOR_EACH_BB (bb)
01425 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
01426 walk_tree (bsi_stmt_ptr (bsi), warn_uninitialized_var,
01427 EXPR_LOCUS (bsi_stmt (bsi)), NULL);
01428 }
01429
01430 static void
01431 execute_late_warn_uninitialized (void)
01432 {
01433 basic_block bb;
01434 tree phi;
01435
01436
01437
01438
01439 execute_early_warn_uninitialized ();
01440
01441 FOR_EACH_BB (bb)
01442 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01443 warn_uninitialized_phi (phi);
01444 }
01445
01446 static bool
01447 gate_warn_uninitialized (void)
01448 {
01449 return warn_uninitialized != 0;
01450 }
01451
01452 struct tree_opt_pass pass_early_warn_uninitialized =
01453 {
01454 NULL,
01455 gate_warn_uninitialized,
01456 execute_early_warn_uninitialized,
01457 NULL,
01458 NULL,
01459 0,
01460 0,
01461 PROP_ssa,
01462 0,
01463 0,
01464 0,
01465 0,
01466 0
01467 };
01468
01469 struct tree_opt_pass pass_late_warn_uninitialized =
01470 {
01471 NULL,
01472 gate_warn_uninitialized,
01473 execute_late_warn_uninitialized,
01474 NULL,
01475 NULL,
01476 0,
01477 0,
01478 PROP_ssa,
01479 0,
01480 0,
01481 0,
01482 0,
01483 0
01484 };
01485