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