00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "tree.h"
00027 #include "flags.h"
00028 #include "rtl.h"
00029 #include "tm_p.h"
00030 #include "ggc.h"
00031 #include "basic-block.h"
00032 #include "output.h"
00033 #include "errors.h"
00034 #include "expr.h"
00035 #include "function.h"
00036 #include "diagnostic.h"
00037 #include "timevar.h"
00038 #include "tree-dump.h"
00039 #include "tree-flow.h"
00040 #include "domwalk.h"
00041 #include "real.h"
00042 #include "tree-pass.h"
00043 #include "tree-ssa-propagate.h"
00044 #include "langhooks.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 struct edge_info
00064 {
00065
00066
00067 tree lhs;
00068 tree rhs;
00069
00070
00071
00072
00073
00074 tree *cond_equivalences;
00075 unsigned int max_cond_equivalences;
00076
00077
00078 edge redirection_target;
00079 };
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 static htab_t avail_exprs;
00090
00091
00092
00093
00094
00095
00096 static VEC(tree_on_heap) *avail_exprs_stack;
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 static VEC(tree_on_heap) *block_defs_stack;
00110
00111
00112
00113
00114
00115
00116
00117
00118 static VEC(tree_on_heap) *stmts_to_rescan;
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 struct expr_hash_elt
00132 {
00133
00134 tree lhs;
00135
00136
00137 tree rhs;
00138
00139
00140 stmt_ann_t ann;
00141
00142
00143 hashval_t hash;
00144 };
00145
00146
00147
00148
00149
00150 static VEC(tree_on_heap) *const_and_copies_stack;
00151
00152
00153
00154 static bitmap nonzero_vars;
00155
00156
00157
00158
00159
00160
00161 static VEC(tree_on_heap) *nonzero_vars_stack;
00162
00163
00164 static bool cfg_altered;
00165
00166
00167
00168 static bitmap need_eh_cleanup;
00169
00170
00171 struct opt_stats_d
00172 {
00173 long num_stmts;
00174 long num_exprs_considered;
00175 long num_re;
00176 };
00177
00178 static struct opt_stats_d opt_stats;
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 struct vrp_element
00212 {
00213
00214
00215
00216
00217
00218
00219 tree low;
00220 tree high;
00221
00222
00223
00224 tree cond;
00225
00226
00227
00228 basic_block bb;
00229 };
00230
00231
00232
00233
00234
00235 static htab_t vrp_data;
00236
00237
00238
00239 struct vrp_hash_elt
00240 {
00241 tree var;
00242 varray_type records;
00243 };
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 static VEC(tree_on_heap) *vrp_variables_stack;
00255
00256 struct eq_expr_value
00257 {
00258 tree src;
00259 tree dst;
00260 };
00261
00262
00263 static void optimize_stmt (struct dom_walk_data *,
00264 basic_block bb,
00265 block_stmt_iterator);
00266 static tree lookup_avail_expr (tree, bool);
00267 static hashval_t vrp_hash (const void *);
00268 static int vrp_eq (const void *, const void *);
00269 static hashval_t avail_expr_hash (const void *);
00270 static hashval_t real_avail_expr_hash (const void *);
00271 static int avail_expr_eq (const void *, const void *);
00272 static void htab_statistics (FILE *, htab_t);
00273 static void record_cond (tree, tree);
00274 static void record_const_or_copy (tree, tree);
00275 static void record_equality (tree, tree);
00276 static tree update_rhs_and_lookup_avail_expr (tree, tree, bool);
00277 static tree simplify_rhs_and_lookup_avail_expr (struct dom_walk_data *,
00278 tree, int);
00279 static tree simplify_cond_and_lookup_avail_expr (tree, stmt_ann_t, int);
00280 static tree simplify_switch_and_lookup_avail_expr (tree, int);
00281 static tree find_equivalent_equality_comparison (tree);
00282 static void record_range (tree, basic_block);
00283 static bool extract_range_from_cond (tree, tree *, tree *, int *);
00284 static void record_equivalences_from_phis (basic_block);
00285 static void record_equivalences_from_incoming_edge (basic_block);
00286 static bool eliminate_redundant_computations (struct dom_walk_data *,
00287 tree, stmt_ann_t);
00288 static void record_equivalences_from_stmt (tree, int, stmt_ann_t);
00289 static void thread_across_edge (struct dom_walk_data *, edge);
00290 static void dom_opt_finalize_block (struct dom_walk_data *, basic_block);
00291 static void dom_opt_initialize_block (struct dom_walk_data *, basic_block);
00292 static void propagate_to_outgoing_edges (struct dom_walk_data *, basic_block);
00293 static void remove_local_expressions_from_table (void);
00294 static void restore_vars_to_original_value (void);
00295 static void restore_currdefs_to_original_value (void);
00296 static void register_definitions_for_stmt (tree);
00297 static edge single_incoming_edge_ignoring_loop_edges (basic_block);
00298 static void restore_nonzero_vars_to_original_value (void);
00299 static inline bool unsafe_associative_fp_binop (tree);
00300
00301
00302
00303 static tree
00304 local_fold (tree t)
00305 {
00306 t = fold (t);
00307
00308
00309
00310
00311 STRIP_USELESS_TYPE_CONVERSION (t);
00312
00313 return t;
00314 }
00315
00316
00317
00318
00319 static struct edge_info *
00320 allocate_edge_info (edge e)
00321 {
00322 struct edge_info *edge_info;
00323
00324 edge_info = xcalloc (1, sizeof (struct edge_info));
00325
00326 e->aux = edge_info;
00327 return edge_info;
00328 }
00329
00330
00331
00332
00333
00334
00335
00336 static void
00337 free_all_edge_infos (void)
00338 {
00339 basic_block bb;
00340 edge_iterator ei;
00341 edge e;
00342
00343 FOR_EACH_BB (bb)
00344 {
00345 FOR_EACH_EDGE (e, ei, bb->preds)
00346 {
00347 struct edge_info *edge_info = e->aux;
00348
00349 if (edge_info)
00350 {
00351 e->aux = edge_info->redirection_target;
00352 if (edge_info->cond_equivalences)
00353 free (edge_info->cond_equivalences);
00354 free (edge_info);
00355 }
00356 }
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365
00366 static void
00367 tree_ssa_dominator_optimize (void)
00368 {
00369 struct dom_walk_data walk_data;
00370 unsigned int i;
00371
00372 memset (&opt_stats, 0, sizeof (opt_stats));
00373
00374 for (i = 0; i < num_referenced_vars; i++)
00375 var_ann (referenced_var (i))->current_def = NULL;
00376
00377
00378 avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
00379 vrp_data = htab_create (ceil_log2 (num_ssa_names), vrp_hash, vrp_eq, free);
00380 avail_exprs_stack = VEC_alloc (tree_on_heap, 20);
00381 block_defs_stack = VEC_alloc (tree_on_heap, 20);
00382 const_and_copies_stack = VEC_alloc (tree_on_heap, 20);
00383 nonzero_vars_stack = VEC_alloc (tree_on_heap, 20);
00384 vrp_variables_stack = VEC_alloc (tree_on_heap, 20);
00385 stmts_to_rescan = VEC_alloc (tree_on_heap, 20);
00386 nonzero_vars = BITMAP_ALLOC (NULL);
00387 need_eh_cleanup = BITMAP_ALLOC (NULL);
00388
00389
00390 walk_data.walk_stmts_backward = false;
00391 walk_data.dom_direction = CDI_DOMINATORS;
00392 walk_data.initialize_block_local_data = NULL;
00393 walk_data.before_dom_children_before_stmts = dom_opt_initialize_block;
00394 walk_data.before_dom_children_walk_stmts = optimize_stmt;
00395 walk_data.before_dom_children_after_stmts = propagate_to_outgoing_edges;
00396 walk_data.after_dom_children_before_stmts = NULL;
00397 walk_data.after_dom_children_walk_stmts = NULL;
00398 walk_data.after_dom_children_after_stmts = dom_opt_finalize_block;
00399
00400
00401
00402 walk_data.global_data = NULL;
00403 walk_data.block_local_data_size = 0;
00404
00405
00406 init_walk_dominator_tree (&walk_data);
00407
00408 calculate_dominance_info (CDI_DOMINATORS);
00409
00410
00411
00412
00413
00414
00415 do
00416 {
00417
00418 cfg_altered = false;
00419
00420
00421 walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
00422
00423
00424
00425
00426
00427
00428 if (!bitmap_empty_p (vars_to_rename))
00429 {
00430 rewrite_into_ssa (false);
00431 bitmap_clear (vars_to_rename);
00432 }
00433
00434 free_all_edge_infos ();
00435
00436
00437 cfg_altered = thread_through_all_blocks ();
00438
00439
00440
00441 if (!bitmap_empty_p (need_eh_cleanup))
00442 {
00443 cfg_altered |= tree_purge_all_dead_eh_edges (need_eh_cleanup);
00444 bitmap_zero (need_eh_cleanup);
00445 }
00446
00447 free_dominance_info (CDI_DOMINATORS);
00448 cfg_altered = cleanup_tree_cfg ();
00449 calculate_dominance_info (CDI_DOMINATORS);
00450
00451 rewrite_ssa_into_ssa ();
00452
00453
00454 bitmap_clear (nonzero_vars);
00455 htab_empty (avail_exprs);
00456 htab_empty (vrp_data);
00457
00458 for (i = 0; i < num_referenced_vars; i++)
00459 var_ann (referenced_var (i))->current_def = NULL;
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 for (i = 0; i < num_ssa_names; i++)
00470 {
00471 tree name = ssa_name (i);
00472 tree value;
00473
00474 if (!name)
00475 continue;
00476
00477 value = SSA_NAME_VALUE (name);
00478 if (value && !is_gimple_min_invariant (value))
00479 SSA_NAME_VALUE (name) = NULL;
00480 }
00481 }
00482 while (optimize > 1 && cfg_altered);
00483
00484
00485 if (dump_file && (dump_flags & TDF_STATS))
00486 dump_dominator_optimization_stats (dump_file);
00487
00488
00489 htab_delete (avail_exprs);
00490 htab_delete (vrp_data);
00491
00492
00493
00494
00495
00496
00497 fini_walk_dominator_tree (&walk_data);
00498
00499
00500 BITMAP_FREE (nonzero_vars);
00501 BITMAP_FREE (need_eh_cleanup);
00502
00503 VEC_free (tree_on_heap, block_defs_stack);
00504 VEC_free (tree_on_heap, avail_exprs_stack);
00505 VEC_free (tree_on_heap, const_and_copies_stack);
00506 VEC_free (tree_on_heap, nonzero_vars_stack);
00507 VEC_free (tree_on_heap, vrp_variables_stack);
00508 VEC_free (tree_on_heap, stmts_to_rescan);
00509 }
00510
00511 static bool
00512 gate_dominator (void)
00513 {
00514 return flag_tree_dom != 0;
00515 }
00516
00517 struct tree_opt_pass pass_dominator =
00518 {
00519 "dom",
00520 gate_dominator,
00521 tree_ssa_dominator_optimize,
00522 NULL,
00523 NULL,
00524 0,
00525 TV_TREE_SSA_DOMINATOR_OPTS,
00526 PROP_cfg | PROP_ssa | PROP_alias,
00527 0,
00528 0,
00529 0,
00530 TODO_dump_func | TODO_rename_vars
00531 | TODO_verify_ssa,
00532 0
00533 };
00534
00535
00536
00537
00538
00539 static void
00540 thread_across_edge (struct dom_walk_data *walk_data, edge e)
00541 {
00542 block_stmt_iterator bsi;
00543 tree stmt = NULL;
00544 tree phi;
00545
00546
00547 for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
00548 {
00549 tree src = PHI_ARG_DEF_FROM_EDGE (phi, e);
00550 tree dst = PHI_RESULT (phi);
00551
00552
00553
00554
00555 if (src != dst
00556 && TREE_CODE (src) == SSA_NAME
00557 && TREE_CODE (SSA_NAME_DEF_STMT (src)) == PHI_NODE
00558 && bb_for_stmt (SSA_NAME_DEF_STMT (src)) == e->dest)
00559 return;
00560
00561 record_const_or_copy (dst, src);
00562 register_new_def (dst, &block_defs_stack);
00563 }
00564
00565 for (bsi = bsi_start (e->dest); ! bsi_end_p (bsi); bsi_next (&bsi))
00566 {
00567 tree lhs, cached_lhs;
00568
00569 stmt = bsi_stmt (bsi);
00570
00571
00572 if (IS_EMPTY_STMT (stmt) || TREE_CODE (stmt) == LABEL_EXPR)
00573 continue;
00574
00575
00576
00577
00578 if (TREE_CODE (stmt) != MODIFY_EXPR
00579 || TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
00580 break;
00581
00582
00583
00584
00585
00586
00587 if (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME)
00588 cached_lhs = TREE_OPERAND (stmt, 1);
00589 else
00590 cached_lhs = lookup_avail_expr (stmt, false);
00591
00592 lhs = TREE_OPERAND (stmt, 0);
00593
00594
00595 if (lhs == cached_lhs)
00596 break;
00597
00598
00599
00600 if (!cached_lhs)
00601 {
00602
00603 stmt_ann_t ann = stmt_ann (stmt);
00604 use_optype uses = USE_OPS (ann);
00605 vuse_optype vuses = VUSE_OPS (ann);
00606 tree *uses_copy = xmalloc (NUM_USES (uses) * sizeof (tree));
00607 tree *vuses_copy = xmalloc (NUM_VUSES (vuses) * sizeof (tree));
00608 unsigned int i;
00609
00610
00611
00612 for (i = 0; i < NUM_USES (uses); i++)
00613 {
00614 tree tmp = NULL;
00615
00616 uses_copy[i] = USE_OP (uses, i);
00617 if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME)
00618 tmp = SSA_NAME_VALUE (USE_OP (uses, i));
00619 if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
00620 SET_USE_OP (uses, i, tmp);
00621 }
00622
00623
00624 for (i = 0; i < NUM_VUSES (vuses); i++)
00625 {
00626 tree tmp = NULL;
00627
00628 vuses_copy[i] = VUSE_OP (vuses, i);
00629 if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME)
00630 tmp = SSA_NAME_VALUE (VUSE_OP (vuses, i));
00631 if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
00632 SET_VUSE_OP (vuses, i, tmp);
00633 }
00634
00635
00636 cached_lhs = lookup_avail_expr (stmt, false);
00637
00638
00639 for (i = 0; i < NUM_USES (uses); i++)
00640 SET_USE_OP (uses, i, uses_copy[i]);
00641
00642 for (i = 0; i < NUM_VUSES (vuses); i++)
00643 SET_VUSE_OP (vuses, i, vuses_copy[i]);
00644
00645 free (uses_copy);
00646 free (vuses_copy);
00647
00648
00649
00650 if (! cached_lhs)
00651 break;
00652 }
00653
00654
00655
00656 if (TREE_CODE (cached_lhs) != SSA_NAME)
00657 break;
00658
00659
00660
00661 if (SSA_NAME_VAR (cached_lhs) != SSA_NAME_VAR (lhs))
00662 break;
00663
00664
00665
00666 if (var_ann (SSA_NAME_VAR (lhs))->current_def != cached_lhs)
00667 break;
00668
00669
00670
00671
00672
00673
00674
00675
00676 record_const_or_copy (lhs, cached_lhs);
00677 register_new_def (lhs, &block_defs_stack);
00678 }
00679
00680
00681
00682 if (stmt
00683 && (TREE_CODE (stmt) == COND_EXPR
00684 || TREE_CODE (stmt) == SWITCH_EXPR))
00685 {
00686 tree cond, cached_lhs;
00687
00688
00689
00690 if (TREE_CODE (stmt) == COND_EXPR)
00691 cond = COND_EXPR_COND (stmt);
00692 else
00693 cond = SWITCH_COND (stmt);
00694
00695 if (COMPARISON_CLASS_P (cond))
00696 {
00697 tree dummy_cond, op0, op1;
00698 enum tree_code cond_code;
00699
00700 op0 = TREE_OPERAND (cond, 0);
00701 op1 = TREE_OPERAND (cond, 1);
00702 cond_code = TREE_CODE (cond);
00703
00704
00705 if (TREE_CODE (op0) == SSA_NAME)
00706 {
00707 tree tmp = SSA_NAME_VALUE (op0);
00708 if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
00709 op0 = tmp;
00710 }
00711
00712 if (TREE_CODE (op1) == SSA_NAME)
00713 {
00714 tree tmp = SSA_NAME_VALUE (op1);
00715 if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
00716 op1 = tmp;
00717 }
00718
00719
00720
00721 dummy_cond = walk_data->global_data;
00722 if (! dummy_cond)
00723 {
00724 dummy_cond = build (cond_code, boolean_type_node, op0, op1);
00725 dummy_cond = build (COND_EXPR, void_type_node,
00726 dummy_cond, NULL, NULL);
00727 walk_data->global_data = dummy_cond;
00728 }
00729 else
00730 {
00731 TREE_SET_CODE (COND_EXPR_COND (dummy_cond), cond_code);
00732 TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op0;
00733 TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1) = op1;
00734 }
00735
00736
00737
00738 cached_lhs = local_fold (COND_EXPR_COND (dummy_cond));
00739 if (! is_gimple_min_invariant (cached_lhs))
00740 {
00741 cached_lhs = lookup_avail_expr (dummy_cond, false);
00742 if (!cached_lhs || ! is_gimple_min_invariant (cached_lhs))
00743 cached_lhs = simplify_cond_and_lookup_avail_expr (dummy_cond,
00744 NULL,
00745 false);
00746 }
00747 }
00748
00749
00750
00751 else if (TREE_CODE (cond) == SSA_NAME)
00752 {
00753 cached_lhs = cond;
00754 cached_lhs = SSA_NAME_VALUE (cached_lhs);
00755 if (cached_lhs && ! is_gimple_min_invariant (cached_lhs))
00756 cached_lhs = 0;
00757 }
00758 else
00759 cached_lhs = lookup_avail_expr (stmt, false);
00760
00761 if (cached_lhs)
00762 {
00763 edge taken_edge = find_taken_edge (e->dest, cached_lhs);
00764 basic_block dest = (taken_edge ? taken_edge->dest : NULL);
00765
00766 if (dest == e->dest)
00767 return;
00768
00769
00770
00771
00772
00773 if (dest)
00774 {
00775 struct edge_info *edge_info;
00776
00777 update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e),
00778 e->count, taken_edge);
00779 if (e->aux)
00780 edge_info = e->aux;
00781 else
00782 edge_info = allocate_edge_info (e);
00783 edge_info->redirection_target = taken_edge;
00784 bb_ann (e->dest)->incoming_edge_threaded = true;
00785 }
00786 }
00787 }
00788 }
00789
00790
00791
00792
00793
00794
00795 static void
00796 dom_opt_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
00797 basic_block bb)
00798 {
00799 if (dump_file && (dump_flags & TDF_DETAILS))
00800 fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index);
00801
00802
00803
00804 VEC_safe_push (tree_on_heap, avail_exprs_stack, NULL_TREE);
00805 VEC_safe_push (tree_on_heap, block_defs_stack, NULL_TREE);
00806 VEC_safe_push (tree_on_heap, const_and_copies_stack, NULL_TREE);
00807 VEC_safe_push (tree_on_heap, nonzero_vars_stack, NULL_TREE);
00808 VEC_safe_push (tree_on_heap, vrp_variables_stack, NULL_TREE);
00809
00810 record_equivalences_from_incoming_edge (bb);
00811
00812
00813 record_equivalences_from_phis (bb);
00814 }
00815
00816
00817
00818
00819 static void
00820 initialize_hash_element (tree expr, tree lhs, struct expr_hash_elt *element)
00821 {
00822
00823
00824
00825
00826
00827 if (COMPARISON_CLASS_P (expr) || TREE_CODE (expr) == TRUTH_NOT_EXPR)
00828 {
00829 element->ann = NULL;
00830 element->rhs = expr;
00831 }
00832 else if (TREE_CODE (expr) == COND_EXPR)
00833 {
00834 element->ann = stmt_ann (expr);
00835 element->rhs = COND_EXPR_COND (expr);
00836 }
00837 else if (TREE_CODE (expr) == SWITCH_EXPR)
00838 {
00839 element->ann = stmt_ann (expr);
00840 element->rhs = SWITCH_COND (expr);
00841 }
00842 else if (TREE_CODE (expr) == RETURN_EXPR && TREE_OPERAND (expr, 0))
00843 {
00844 element->ann = stmt_ann (expr);
00845 element->rhs = TREE_OPERAND (TREE_OPERAND (expr, 0), 1);
00846 }
00847 else
00848 {
00849 element->ann = stmt_ann (expr);
00850 element->rhs = TREE_OPERAND (expr, 1);
00851 }
00852
00853 element->lhs = lhs;
00854 element->hash = avail_expr_hash (element);
00855 }
00856
00857
00858
00859
00860 static void
00861 remove_local_expressions_from_table (void)
00862 {
00863
00864 while (VEC_length (tree_on_heap, avail_exprs_stack) > 0)
00865 {
00866 struct expr_hash_elt element;
00867 tree expr = VEC_pop (tree_on_heap, avail_exprs_stack);
00868
00869 if (expr == NULL_TREE)
00870 break;
00871
00872 initialize_hash_element (expr, NULL, &element);
00873 htab_remove_elt_with_hash (avail_exprs, &element, element.hash);
00874 }
00875 }
00876
00877
00878
00879
00880 static void
00881 restore_nonzero_vars_to_original_value (void)
00882 {
00883 while (VEC_length (tree_on_heap, nonzero_vars_stack) > 0)
00884 {
00885 tree name = VEC_pop (tree_on_heap, nonzero_vars_stack);
00886
00887 if (name == NULL)
00888 break;
00889
00890 bitmap_clear_bit (nonzero_vars, SSA_NAME_VERSION (name));
00891 }
00892 }
00893
00894
00895
00896
00897
00898 static void
00899 restore_vars_to_original_value (void)
00900 {
00901 while (VEC_length (tree_on_heap, const_and_copies_stack) > 0)
00902 {
00903 tree prev_value, dest;
00904
00905 dest = VEC_pop (tree_on_heap, const_and_copies_stack);
00906
00907 if (dest == NULL)
00908 break;
00909
00910 prev_value = VEC_pop (tree_on_heap, const_and_copies_stack);
00911 SSA_NAME_VALUE (dest) = prev_value;
00912 }
00913 }
00914
00915
00916
00917 static void
00918 restore_currdefs_to_original_value (void)
00919 {
00920
00921 while (VEC_length (tree_on_heap, block_defs_stack) > 0)
00922 {
00923 tree tmp = VEC_pop (tree_on_heap, block_defs_stack);
00924 tree saved_def, var;
00925
00926 if (tmp == NULL_TREE)
00927 break;
00928
00929
00930
00931
00932
00933 if (TREE_CODE (tmp) == SSA_NAME)
00934 {
00935 saved_def = tmp;
00936 var = SSA_NAME_VAR (saved_def);
00937 }
00938 else
00939 {
00940 saved_def = NULL;
00941 var = tmp;
00942 }
00943
00944 var_ann (var)->current_def = saved_def;
00945 }
00946 }
00947
00948
00949
00950
00951
00952 static void
00953 dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
00954 {
00955 tree last;
00956
00957
00958
00959
00960
00961 if (EDGE_COUNT (bb->succs) == 1
00962 && (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) == 0
00963 && (get_immediate_dominator (CDI_DOMINATORS, EDGE_SUCC (bb, 0)->dest) != bb
00964 || phi_nodes (EDGE_SUCC (bb, 0)->dest)))
00965
00966 {
00967 thread_across_edge (walk_data, EDGE_SUCC (bb, 0));
00968 }
00969 else if ((last = last_stmt (bb))
00970 && TREE_CODE (last) == COND_EXPR
00971 && (COMPARISON_CLASS_P (COND_EXPR_COND (last))
00972 || TREE_CODE (COND_EXPR_COND (last)) == SSA_NAME)
00973 && EDGE_COUNT (bb->succs) == 2
00974 && (EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL) == 0
00975 && (EDGE_SUCC (bb, 1)->flags & EDGE_ABNORMAL) == 0)
00976 {
00977 edge true_edge, false_edge;
00978
00979 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
00980
00981
00982
00983 if (get_immediate_dominator (CDI_DOMINATORS, true_edge->dest) != bb
00984 || phi_nodes (true_edge->dest))
00985 {
00986 struct edge_info *edge_info;
00987 unsigned int i;
00988
00989
00990
00991
00992 VEC_safe_push (tree_on_heap, avail_exprs_stack, NULL_TREE);
00993 VEC_safe_push (tree_on_heap, block_defs_stack, NULL_TREE);
00994 VEC_safe_push (tree_on_heap, const_and_copies_stack, NULL_TREE);
00995
00996 edge_info = true_edge->aux;
00997
00998
00999
01000 if (edge_info)
01001 {
01002 tree *cond_equivalences = edge_info->cond_equivalences;
01003 tree lhs = edge_info->lhs;
01004 tree rhs = edge_info->rhs;
01005
01006
01007
01008
01009
01010
01011 if (lhs
01012 && TREE_CODE (COND_EXPR_COND (last)) == SSA_NAME
01013 && TREE_CODE (edge_info->rhs) == SSA_NAME
01014 && SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs))
01015 record_const_or_copy (lhs, rhs);
01016
01017
01018
01019 if (cond_equivalences)
01020 for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
01021 {
01022 tree expr = cond_equivalences[i];
01023 tree value = cond_equivalences[i + 1];
01024
01025 record_cond (expr, value);
01026 }
01027 }
01028
01029
01030 thread_across_edge (walk_data, true_edge);
01031
01032
01033
01034 remove_local_expressions_from_table ();
01035 restore_vars_to_original_value ();
01036 restore_currdefs_to_original_value ();
01037 }
01038
01039
01040 if (get_immediate_dominator (CDI_DOMINATORS, false_edge->dest) != bb
01041 || phi_nodes (false_edge->dest))
01042 {
01043 struct edge_info *edge_info;
01044 unsigned int i;
01045
01046 edge_info = false_edge->aux;
01047
01048
01049
01050 if (edge_info)
01051 {
01052 tree *cond_equivalences = edge_info->cond_equivalences;
01053 tree lhs = edge_info->lhs;
01054 tree rhs = edge_info->rhs;
01055
01056
01057
01058
01059
01060
01061 if (lhs
01062 && TREE_CODE (COND_EXPR_COND (last)) == SSA_NAME)
01063 record_const_or_copy (lhs, rhs);
01064
01065
01066
01067 if (cond_equivalences)
01068 for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
01069 {
01070 tree expr = cond_equivalences[i];
01071 tree value = cond_equivalences[i + 1];
01072
01073 record_cond (expr, value);
01074 }
01075 }
01076
01077 thread_across_edge (walk_data, false_edge);
01078
01079
01080
01081
01082 }
01083 }
01084
01085 remove_local_expressions_from_table ();
01086 restore_nonzero_vars_to_original_value ();
01087 restore_vars_to_original_value ();
01088 restore_currdefs_to_original_value ();
01089
01090
01091
01092
01093
01094
01095
01096 while (VEC_length (tree_on_heap, vrp_variables_stack) > 0)
01097 {
01098 tree var = VEC_pop (tree_on_heap, vrp_variables_stack);
01099 struct vrp_hash_elt vrp_hash_elt, *vrp_hash_elt_p;
01100 void **slot;
01101
01102
01103
01104
01105
01106
01107 varray_type var_vrp_records;
01108
01109 if (var == NULL)
01110 break;
01111
01112 vrp_hash_elt.var = var;
01113 vrp_hash_elt.records = NULL;
01114
01115 slot = htab_find_slot (vrp_data, &vrp_hash_elt, NO_INSERT);
01116
01117 vrp_hash_elt_p = (struct vrp_hash_elt *) *slot;
01118 var_vrp_records = vrp_hash_elt_p->records;
01119
01120 while (VARRAY_ACTIVE_SIZE (var_vrp_records) > 0)
01121 {
01122 struct vrp_element *element
01123 = (struct vrp_element *)VARRAY_TOP_GENERIC_PTR (var_vrp_records);
01124
01125 if (element->bb != bb)
01126 break;
01127
01128 VARRAY_POP (var_vrp_records);
01129 }
01130 }
01131
01132
01133
01134 while (VEC_length (tree_on_heap, stmts_to_rescan) > 0)
01135 {
01136 tree stmt = VEC_last (tree_on_heap, stmts_to_rescan);
01137 basic_block stmt_bb = bb_for_stmt (stmt);
01138
01139 if (stmt_bb != bb)
01140 break;
01141
01142 VEC_pop (tree_on_heap, stmts_to_rescan);
01143 mark_new_vars_to_rename (stmt, vars_to_rename);
01144 }
01145 }
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157 static void
01158 record_equivalences_from_phis (basic_block bb)
01159 {
01160 tree phi;
01161
01162 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
01163 {
01164 tree lhs = PHI_RESULT (phi);
01165 tree rhs = NULL;
01166 int i;
01167
01168 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
01169 {
01170 tree t = PHI_ARG_DEF (phi, i);
01171
01172
01173
01174
01175 if (lhs == t)
01176 continue;
01177
01178
01179
01180 if (rhs == NULL)
01181 rhs = t;
01182
01183
01184
01185 else if (! operand_equal_for_phi_arg_p (rhs, t))
01186 break;
01187 }
01188
01189
01190
01191 if (!rhs)
01192 rhs = lhs;
01193
01194
01195
01196
01197
01198
01199
01200 if (i == PHI_NUM_ARGS (phi)
01201 && may_propagate_copy (lhs, rhs))
01202 SSA_NAME_VALUE (lhs) = rhs;
01203
01204
01205
01206 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
01207 {
01208 if (!PHI_ARG_NONZERO (phi, i))
01209 break;
01210 }
01211
01212 if (i == PHI_NUM_ARGS (phi))
01213 bitmap_set_bit (nonzero_vars, SSA_NAME_VERSION (PHI_RESULT (phi)));
01214
01215 register_new_def (lhs, &block_defs_stack);
01216 }
01217 }
01218
01219
01220
01221 static edge
01222 single_incoming_edge_ignoring_loop_edges (basic_block bb)
01223 {
01224 edge retval = NULL;
01225 edge e;
01226 edge_iterator ei;
01227
01228 FOR_EACH_EDGE (e, ei, bb->preds)
01229 {
01230
01231
01232 if (dominated_by_p (CDI_DOMINATORS, e->src, e->dest))
01233 continue;
01234
01235
01236
01237 if (retval)
01238 return NULL;
01239
01240
01241
01242 retval = e;
01243 }
01244
01245 return retval;
01246 }
01247
01248
01249
01250
01251 static void
01252 record_equivalences_from_incoming_edge (basic_block bb)
01253 {
01254 edge e;
01255 basic_block parent;
01256 struct edge_info *edge_info;
01257
01258
01259
01260
01261 parent = get_immediate_dominator (CDI_DOMINATORS, bb);
01262
01263 e = single_incoming_edge_ignoring_loop_edges (bb);
01264
01265
01266
01267 if (e && e->src == parent)
01268 {
01269 unsigned int i;
01270
01271 edge_info = e->aux;
01272
01273 if (edge_info)
01274 {
01275 tree lhs = edge_info->lhs;
01276 tree rhs = edge_info->rhs;
01277 tree *cond_equivalences = edge_info->cond_equivalences;
01278
01279 if (lhs)
01280 record_equality (lhs, rhs);
01281
01282 if (cond_equivalences)
01283 {
01284 bool recorded_range = false;
01285 for (i = 0; i < edge_info->max_cond_equivalences; i += 2)
01286 {
01287 tree expr = cond_equivalences[i];
01288 tree value = cond_equivalences[i + 1];
01289
01290 record_cond (expr, value);
01291
01292
01293
01294
01295
01296 if (! recorded_range
01297 && COMPARISON_CLASS_P (expr)
01298 && value == boolean_true_node
01299 && TREE_CONSTANT (TREE_OPERAND (expr, 1)))
01300 {
01301 record_range (expr, bb);
01302 recorded_range = true;
01303 }
01304 }
01305 }
01306 }
01307 }
01308 }
01309
01310
01311
01312 void
01313 dump_dominator_optimization_stats (FILE *file)
01314 {
01315 long n_exprs;
01316
01317 fprintf (file, "Total number of statements: %6ld\n\n",
01318 opt_stats.num_stmts);
01319 fprintf (file, "Exprs considered for dominator optimizations: %6ld\n",
01320 opt_stats.num_exprs_considered);
01321
01322 n_exprs = opt_stats.num_exprs_considered;
01323 if (n_exprs == 0)
01324 n_exprs = 1;
01325
01326 fprintf (file, " Redundant expressions eliminated: %6ld (%.0f%%)\n",
01327 opt_stats.num_re, PERCENT (opt_stats.num_re,
01328 n_exprs));
01329
01330 fprintf (file, "\nHash table statistics:\n");
01331
01332 fprintf (file, " avail_exprs: ");
01333 htab_statistics (file, avail_exprs);
01334 }
01335
01336
01337
01338
01339 void
01340 debug_dominator_optimization_stats (void)
01341 {
01342 dump_dominator_optimization_stats (stderr);
01343 }
01344
01345
01346
01347
01348 static void
01349 htab_statistics (FILE *file, htab_t htab)
01350 {
01351 fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
01352 (long) htab_size (htab),
01353 (long) htab_elements (htab),
01354 htab_collisions (htab));
01355 }
01356
01357
01358
01359
01360
01361 static void
01362 record_var_is_nonzero (tree var)
01363 {
01364 int indx = SSA_NAME_VERSION (var);
01365
01366 if (bitmap_bit_p (nonzero_vars, indx))
01367 return;
01368
01369
01370 bitmap_set_bit (nonzero_vars, indx);
01371
01372
01373
01374 VEC_safe_push (tree_on_heap, nonzero_vars_stack, var);
01375 }
01376
01377
01378
01379
01380 static void
01381 record_cond (tree cond, tree value)
01382 {
01383 struct expr_hash_elt *element = xmalloc (sizeof (struct expr_hash_elt));
01384 void **slot;
01385
01386 initialize_hash_element (cond, value, element);
01387
01388 slot = htab_find_slot_with_hash (avail_exprs, (void *)element,
01389 element->hash, INSERT);
01390 if (*slot == NULL)
01391 {
01392 *slot = (void *) element;
01393 VEC_safe_push (tree_on_heap, avail_exprs_stack, cond);
01394 }
01395 else
01396 free (element);
01397 }
01398
01399
01400
01401
01402
01403 static void
01404 build_and_record_new_cond (enum tree_code new_code, tree op0, tree op1, tree *p)
01405 {
01406 *p = build2 (new_code, boolean_type_node, op0, op1);
01407 p++;
01408 *p = boolean_true_node;
01409 }
01410
01411
01412
01413
01414
01415
01416
01417 static void
01418 record_conditions (struct edge_info *edge_info, tree cond, tree inverted)
01419 {
01420 tree op0, op1;
01421
01422 if (!COMPARISON_CLASS_P (cond))
01423 return;
01424
01425 op0 = TREE_OPERAND (cond, 0);
01426 op1 = TREE_OPERAND (cond, 1);
01427
01428 switch (TREE_CODE (cond))
01429 {
01430 case LT_EXPR:
01431 case GT_EXPR:
01432 edge_info->max_cond_equivalences = 12;
01433 edge_info->cond_equivalences = xmalloc (12 * sizeof (tree));
01434 build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR
01435 ? LE_EXPR : GE_EXPR),
01436 op0, op1, &edge_info->cond_equivalences[4]);
01437 build_and_record_new_cond (ORDERED_EXPR, op0, op1,
01438 &edge_info->cond_equivalences[6]);
01439 build_and_record_new_cond (NE_EXPR, op0, op1,
01440 &edge_info->cond_equivalences[8]);
01441 build_and_record_new_cond (LTGT_EXPR, op0, op1,
01442 &edge_info->cond_equivalences[10]);
01443 break;
01444
01445 case GE_EXPR:
01446 case LE_EXPR:
01447 edge_info->max_cond_equivalences = 6;
01448 edge_info->cond_equivalences = xmalloc (6 * sizeof (tree));
01449 build_and_record_new_cond (ORDERED_EXPR, op0, op1,
01450 &edge_info->cond_equivalences[4]);
01451 break;
01452
01453 case EQ_EXPR:
01454 edge_info->max_cond_equivalences = 10;
01455 edge_info->cond_equivalences = xmalloc (10 * sizeof (tree));
01456 build_and_record_new_cond (ORDERED_EXPR, op0, op1,
01457 &edge_info->cond_equivalences[4]);
01458 build_and_record_new_cond (LE_EXPR, op0, op1,
01459 &edge_info->cond_equivalences[6]);
01460 build_and_record_new_cond (GE_EXPR, op0, op1,
01461 &edge_info->cond_equivalences[8]);
01462 break;
01463
01464 case UNORDERED_EXPR:
01465 edge_info->max_cond_equivalences = 16;
01466 edge_info->cond_equivalences = xmalloc (16 * sizeof (tree));
01467 build_and_record_new_cond (NE_EXPR, op0, op1,
01468 &edge_info->cond_equivalences[4]);
01469 build_and_record_new_cond (UNLE_EXPR, op0, op1,
01470 &edge_info->cond_equivalences[6]);
01471 build_and_record_new_cond (UNGE_EXPR, op0, op1,
01472 &edge_info->cond_equivalences[8]);
01473 build_and_record_new_cond (UNEQ_EXPR, op0, op1,
01474 &edge_info->cond_equivalences[10]);
01475 build_and_record_new_cond (UNLT_EXPR, op0, op1,
01476 &edge_info->cond_equivalences[12]);
01477 build_and_record_new_cond (UNGT_EXPR, op0, op1,
01478 &edge_info->cond_equivalences[14]);
01479 break;
01480
01481 case UNLT_EXPR:
01482 case UNGT_EXPR:
01483 edge_info->max_cond_equivalences = 8;
01484 edge_info->cond_equivalences = xmalloc (8 * sizeof (tree));
01485 build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR
01486 ? UNLE_EXPR : UNGE_EXPR),
01487 op0, op1, &edge_info->cond_equivalences[4]);
01488 build_and_record_new_cond (NE_EXPR, op0, op1,
01489 &edge_info->cond_equivalences[6]);
01490 break;
01491
01492 case UNEQ_EXPR:
01493 edge_info->max_cond_equivalences = 8;
01494 edge_info->cond_equivalences = xmalloc (8 * sizeof (tree));
01495 build_and_record_new_cond (UNLE_EXPR, op0, op1,
01496 &edge_info->cond_equivalences[4]);
01497 build_and_record_new_cond (UNGE_EXPR, op0, op1,
01498 &edge_info->cond_equivalences[6]);
01499 break;
01500
01501 case LTGT_EXPR:
01502 edge_info->max_cond_equivalences = 8;
01503 edge_info->cond_equivalences = xmalloc (8 * sizeof (tree));
01504 build_and_record_new_cond (NE_EXPR, op0, op1,
01505 &edge_info->cond_equivalences[4]);
01506 build_and_record_new_cond (ORDERED_EXPR, op0, op1,
01507 &edge_info->cond_equivalences[6]);
01508 break;
01509
01510 default:
01511 edge_info->max_cond_equivalences = 4;
01512 edge_info->cond_equivalences = xmalloc (4 * sizeof (tree));
01513 break;
01514 }
01515
01516
01517
01518 edge_info->cond_equivalences[0] = cond;
01519 edge_info->cond_equivalences[1] = boolean_true_node;
01520 edge_info->cond_equivalences[2] = inverted;
01521 edge_info->cond_equivalences[3] = boolean_false_node;
01522 }
01523
01524
01525
01526
01527 static void
01528 record_const_or_copy_1 (tree x, tree y, tree prev_x)
01529 {
01530 SSA_NAME_VALUE (x) = y;
01531
01532 VEC_safe_push (tree_on_heap, const_and_copies_stack, prev_x);
01533 VEC_safe_push (tree_on_heap, const_and_copies_stack, x);
01534 }
01535
01536
01537
01538
01539
01540
01541
01542
01543 static int
01544 loop_depth_of_name (tree x)
01545 {
01546 tree defstmt;
01547 basic_block defbb;
01548
01549
01550 if (TREE_CODE (x) != SSA_NAME)
01551 return 0;
01552
01553
01554
01555
01556 defstmt = SSA_NAME_DEF_STMT (x);
01557 defbb = bb_for_stmt (defstmt);
01558 if (!defbb)
01559 return 0;
01560
01561 return defbb->loop_depth;
01562 }
01563
01564
01565
01566
01567
01568 static void
01569 record_const_or_copy (tree x, tree y)
01570 {
01571 tree prev_x = SSA_NAME_VALUE (x);
01572
01573 if (TREE_CODE (y) == SSA_NAME)
01574 {
01575 tree tmp = SSA_NAME_VALUE (y);
01576 if (tmp)
01577 y = tmp;
01578 }
01579
01580 record_const_or_copy_1 (x, y, prev_x);
01581 }
01582
01583
01584
01585
01586 static void
01587 record_equality (tree x, tree y)
01588 {
01589 tree prev_x = NULL, prev_y = NULL;
01590
01591 if (TREE_CODE (x) == SSA_NAME)
01592 prev_x = SSA_NAME_VALUE (x);
01593 if (TREE_CODE (y) == SSA_NAME)
01594 prev_y = SSA_NAME_VALUE (y);
01595
01596
01597
01598
01599
01600 if (TREE_INVARIANT (y))
01601 ;
01602 else if (TREE_INVARIANT (x) || (loop_depth_of_name (x) <= loop_depth_of_name (y)))
01603 prev_x = x, x = y, y = prev_x, prev_x = prev_y;
01604 else if (prev_x && TREE_INVARIANT (prev_x))
01605 x = y, y = prev_x, prev_x = prev_y;
01606 else if (prev_y && TREE_CODE (prev_y) != VALUE_HANDLE)
01607 y = prev_y;
01608
01609
01610 if (TREE_CODE (x) != SSA_NAME)
01611 return;
01612
01613
01614
01615
01616
01617 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (x)))
01618 && (TREE_CODE (y) != REAL_CST
01619 || REAL_VALUES_EQUAL (dconst0, TREE_REAL_CST (y))))
01620 return;
01621
01622 record_const_or_copy_1 (x, y, prev_x);
01623 }
01624
01625
01626
01627
01628 static inline bool
01629 unsafe_associative_fp_binop (tree exp)
01630 {
01631 enum tree_code code = TREE_CODE (exp);
01632 return !(!flag_unsafe_math_optimizations
01633 && (code == MULT_EXPR || code == PLUS_EXPR
01634 || code == MINUS_EXPR)
01635 && FLOAT_TYPE_P (TREE_TYPE (exp)));
01636 }
01637
01638
01639
01640
01641
01642
01643
01644
01645 static tree
01646 simplify_rhs_and_lookup_avail_expr (struct dom_walk_data *walk_data,
01647 tree stmt, int insert)
01648 {
01649 tree rhs = TREE_OPERAND (stmt, 1);
01650 enum tree_code rhs_code = TREE_CODE (rhs);
01651 tree result = NULL;
01652
01653
01654
01655
01656
01657
01658 if ((rhs_code == BIT_NOT_EXPR || rhs_code == NEGATE_EXPR)
01659 && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
01660 {
01661
01662 tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
01663
01664
01665 if (TREE_CODE (rhs_def_stmt) == MODIFY_EXPR
01666 && TREE_CODE (TREE_OPERAND (rhs_def_stmt, 1)) == rhs_code)
01667 {
01668 tree rhs_def_operand;
01669
01670 rhs_def_operand = TREE_OPERAND (TREE_OPERAND (rhs_def_stmt, 1), 0);
01671
01672
01673 if (TREE_CODE (rhs_def_operand) == SSA_NAME
01674 && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand))
01675 result = update_rhs_and_lookup_avail_expr (stmt,
01676 rhs_def_operand,
01677 insert);
01678 }
01679 }
01680
01681
01682
01683
01684
01685 if ((associative_tree_code (rhs_code) || rhs_code == MINUS_EXPR)
01686 && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
01687 && is_gimple_min_invariant (TREE_OPERAND (rhs, 1)))
01688 {
01689 tree rhs_def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
01690
01691
01692 if (TREE_CODE (rhs_def_stmt) == MODIFY_EXPR)
01693 {
01694 tree rhs_def_rhs = TREE_OPERAND (rhs_def_stmt, 1);
01695 enum tree_code rhs_def_code = TREE_CODE (rhs_def_rhs);
01696
01697 if ((rhs_code == rhs_def_code && unsafe_associative_fp_binop (rhs))
01698 || (rhs_code == PLUS_EXPR && rhs_def_code == MINUS_EXPR)
01699 || (rhs_code == MINUS_EXPR && rhs_def_code == PLUS_EXPR))
01700 {
01701 tree def_stmt_op0 = TREE_OPERAND (rhs_def_rhs, 0);
01702 tree def_stmt_op1 = TREE_OPERAND (rhs_def_rhs, 1);
01703
01704 if (TREE_CODE (def_stmt_op0) == SSA_NAME
01705 && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def_stmt_op0)
01706 && is_gimple_min_invariant (def_stmt_op1))
01707 {
01708 tree outer_const = TREE_OPERAND (rhs, 1);
01709 tree type = TREE_TYPE (TREE_OPERAND (stmt, 0));
01710 tree t;
01711
01712
01713
01714
01715 if (FLOAT_TYPE_P (type)
01716 && !flag_unsafe_math_optimizations
01717 && (rhs_def_code == PLUS_EXPR
01718 || rhs_def_code == MINUS_EXPR))
01719 {
01720 bool neg = false;
01721
01722 neg ^= (rhs_code == MINUS_EXPR);
01723 neg ^= (rhs_def_code == MINUS_EXPR);
01724 neg ^= real_isneg (TREE_REAL_CST_PTR (outer_const));
01725 neg ^= real_isneg (TREE_REAL_CST_PTR (def_stmt_op1));
01726
01727 if (neg)
01728 goto dont_fold_assoc;
01729 }
01730
01731
01732
01733
01734
01735 if (rhs_def_code != rhs_code)
01736 {
01737 if (rhs_def_code == MINUS_EXPR)
01738 t = build (MINUS_EXPR, type, outer_const, def_stmt_op1);
01739 else
01740 t = build (MINUS_EXPR, type, def_stmt_op1, outer_const);
01741 rhs_code = PLUS_EXPR;
01742 }
01743 else if (rhs_def_code == MINUS_EXPR)
01744 t = build (PLUS_EXPR, type, def_stmt_op1, outer_const);
01745 else
01746 t = build (rhs_def_code, type, def_stmt_op1, outer_const);
01747 t = local_fold (t);
01748 t = build (rhs_code, type, def_stmt_op0, t);
01749 t = local_fold (t);
01750
01751
01752
01753 if (TREE_CODE (t) == SSA_NAME
01754 || (UNARY_CLASS_P (t)
01755 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
01756 || ((BINARY_CLASS_P (t) || COMPARISON_CLASS_P (t))
01757 && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
01758 && is_gimple_val (TREE_OPERAND (t, 1))))
01759 result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
01760 }
01761 }
01762 }
01763 dont_fold_assoc:;
01764 }
01765
01766
01767
01768
01769 if ((rhs_code == TRUNC_DIV_EXPR || rhs_code == TRUNC_MOD_EXPR)
01770 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
01771 && integer_pow2p (TREE_OPERAND (rhs, 1)))
01772 {
01773 tree val;
01774 tree op = TREE_OPERAND (rhs, 0);
01775
01776 if (TYPE_UNSIGNED (TREE_TYPE (op)))
01777 {
01778 val = integer_one_node;
01779 }
01780 else
01781 {
01782 tree dummy_cond = walk_data->global_data;
01783
01784 if (! dummy_cond)
01785 {
01786 dummy_cond = build (GT_EXPR, boolean_type_node,
01787 op, integer_zero_node);
01788 dummy_cond = build (COND_EXPR, void_type_node,
01789 dummy_cond, NULL, NULL);
01790 walk_data->global_data = dummy_cond;
01791 }
01792 else
01793 {
01794 TREE_SET_CODE (COND_EXPR_COND (dummy_cond), GT_EXPR);
01795 TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op;
01796 TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1)
01797 = integer_zero_node;
01798 }
01799 val = simplify_cond_and_lookup_avail_expr (dummy_cond, NULL, false);
01800 }
01801
01802 if (val && integer_onep (val))
01803 {
01804 tree t;
01805 tree op0 = TREE_OPERAND (rhs, 0);
01806 tree op1 = TREE_OPERAND (rhs, 1);
01807
01808 if (rhs_code == TRUNC_DIV_EXPR)
01809 t = build (RSHIFT_EXPR, TREE_TYPE (op0), op0,
01810 build_int_cst (NULL_TREE, tree_log2 (op1)));
01811 else
01812 t = build (BIT_AND_EXPR, TREE_TYPE (op0), op0,
01813 local_fold (build (MINUS_EXPR, TREE_TYPE (op1),
01814 op1, integer_one_node)));
01815
01816 result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
01817 }
01818 }
01819
01820
01821 if (rhs_code == ABS_EXPR
01822 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))))
01823 {
01824 tree val;
01825 tree op = TREE_OPERAND (rhs, 0);
01826 tree type = TREE_TYPE (op);
01827
01828 if (TYPE_UNSIGNED (type))
01829 {
01830 val = integer_zero_node;
01831 }
01832 else
01833 {
01834 tree dummy_cond = walk_data->global_data;
01835
01836 if (! dummy_cond)
01837 {
01838 dummy_cond = build (LE_EXPR, boolean_type_node,
01839 op, integer_zero_node);
01840 dummy_cond = build (COND_EXPR, void_type_node,
01841 dummy_cond, NULL, NULL);
01842 walk_data->global_data = dummy_cond;
01843 }
01844 else
01845 {
01846 TREE_SET_CODE (COND_EXPR_COND (dummy_cond), LE_EXPR);
01847 TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op;
01848 TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1)
01849 = build_int_cst (type, 0);
01850 }
01851 val = simplify_cond_and_lookup_avail_expr (dummy_cond, NULL, false);
01852
01853 if (!val)
01854 {
01855 TREE_SET_CODE (COND_EXPR_COND (dummy_cond), GE_EXPR);
01856 TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op;
01857 TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1)
01858 = build_int_cst (type, 0);
01859
01860 val = simplify_cond_and_lookup_avail_expr (dummy_cond,
01861 NULL, false);
01862
01863 if (val)
01864 {
01865 if (integer_zerop (val))
01866 val = integer_one_node;
01867 else if (integer_onep (val))
01868 val = integer_zero_node;
01869 }
01870 }
01871 }
01872
01873 if (val
01874 && (integer_onep (val) || integer_zerop (val)))
01875 {
01876 tree t;
01877
01878 if (integer_onep (val))
01879 t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
01880 else
01881 t = op;
01882
01883 result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
01884 }
01885 }
01886
01887
01888
01889 if (TREE_CODE (rhs) == INDIRECT_REF || TREE_CODE (rhs) == ARRAY_REF)
01890 {
01891 tree t = fold_read_from_constant_string (rhs);
01892
01893 if (t)
01894 result = update_rhs_and_lookup_avail_expr (stmt, t, insert);
01895 }
01896
01897 return result;
01898 }
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919 static tree
01920 find_equivalent_equality_comparison (tree cond)
01921 {
01922 tree op0 = TREE_OPERAND (cond, 0);
01923 tree op1 = TREE_OPERAND (cond, 1);
01924 tree def_stmt = SSA_NAME_DEF_STMT (op0);
01925
01926
01927
01928 if (def_stmt && TREE_CODE (def_stmt) == MODIFY_EXPR)
01929 {
01930 tree def_rhs = TREE_OPERAND (def_stmt, 1);
01931
01932
01933
01934
01935
01936
01937
01938 if ((POINTER_TYPE_P (TREE_TYPE (op0))
01939 && TREE_CODE (TREE_TYPE (TREE_TYPE (op0))) == FUNCTION_TYPE)
01940 || (POINTER_TYPE_P (TREE_TYPE (op1))
01941 && TREE_CODE (TREE_TYPE (TREE_TYPE (op1))) == FUNCTION_TYPE))
01942 return NULL;
01943
01944
01945 if ((TREE_CODE (def_rhs) == NOP_EXPR
01946 || TREE_CODE (def_rhs) == CONVERT_EXPR)
01947 && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME)
01948 {
01949 tree def_rhs_inner = TREE_OPERAND (def_rhs, 0);
01950 tree def_rhs_inner_type = TREE_TYPE (def_rhs_inner);
01951 tree new;
01952
01953 if (TYPE_PRECISION (def_rhs_inner_type)
01954 > TYPE_PRECISION (TREE_TYPE (def_rhs)))
01955 return NULL;
01956
01957
01958
01959
01960
01961
01962
01963 if (POINTER_TYPE_P (def_rhs_inner_type)
01964 && TREE_CODE (TREE_TYPE (def_rhs_inner_type)) == FUNCTION_TYPE)
01965 return NULL;
01966
01967
01968
01969
01970
01971
01972
01973
01974 new = build1 (TREE_CODE (def_rhs), def_rhs_inner_type, op1);
01975 new = local_fold (new);
01976 if (is_gimple_val (new) && tree_int_cst_equal (new, op1))
01977 return build (TREE_CODE (cond), TREE_TYPE (cond),
01978 def_rhs_inner, new);
01979 }
01980 }
01981 return NULL;
01982 }
01983
01984
01985
01986
01987
01988
01989 static tree
01990 simplify_cond_and_lookup_avail_expr (tree stmt,
01991 stmt_ann_t ann,
01992 int insert)
01993 {
01994 tree cond = COND_EXPR_COND (stmt);
01995
01996 if (COMPARISON_CLASS_P (cond))
01997 {
01998 tree op0 = TREE_OPERAND (cond, 0);
01999 tree op1 = TREE_OPERAND (cond, 1);
02000
02001 if (TREE_CODE (op0) == SSA_NAME && is_gimple_min_invariant (op1))
02002 {
02003 int limit;
02004 tree low, high, cond_low, cond_high;
02005 int lowequal, highequal, swapped, no_overlap, subset, cond_inverted;
02006 varray_type vrp_records;
02007 struct vrp_element *element;
02008 struct vrp_hash_elt vrp_hash_elt, *vrp_hash_elt_p;
02009 void **slot;
02010
02011
02012
02013
02014
02015 if (TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
02016 {
02017 tree new_cond = find_equivalent_equality_comparison (cond);
02018
02019 if (new_cond)
02020 {
02021
02022
02023 COND_EXPR_COND (stmt) = new_cond;
02024
02025
02026
02027 if (ann)
02028 modify_stmt (stmt);
02029
02030
02031
02032 new_cond = lookup_avail_expr (stmt, insert);
02033 if (new_cond)
02034 return new_cond;
02035
02036
02037 op0 = TREE_OPERAND (cond, 0);
02038 op1 = TREE_OPERAND (cond, 1);
02039 }
02040 }
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052 vrp_hash_elt.var = op0;
02053 vrp_hash_elt.records = NULL;
02054 slot = htab_find_slot (vrp_data, &vrp_hash_elt, NO_INSERT);
02055 if (slot == NULL)
02056 return NULL;
02057
02058 vrp_hash_elt_p = (struct vrp_hash_elt *) *slot;
02059 vrp_records = vrp_hash_elt_p->records;
02060 if (vrp_records == NULL)
02061 return NULL;
02062
02063 limit = VARRAY_ACTIVE_SIZE (vrp_records);
02064
02065
02066
02067
02068 if (limit == 0
02069 || ! extract_range_from_cond (cond, &cond_high,
02070 &cond_low, &cond_inverted))
02071 return NULL;
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095 element
02096 = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records, limit - 1);
02097
02098 if (element->high && element->low)
02099 {
02100
02101
02102
02103 low = element->low;
02104 high = element->high;
02105 }
02106 else
02107 {
02108 tree tmp_high, tmp_low;
02109 int dummy;
02110
02111
02112
02113
02114
02115
02116
02117 if (! extract_range_from_cond (element->cond, &tmp_high,
02118 &tmp_low, &dummy))
02119 gcc_unreachable ();
02120 else
02121 gcc_assert (dummy == 0);
02122
02123
02124
02125
02126 if (limit == 1)
02127 {
02128 low = tmp_low;
02129 high = tmp_high;
02130 }
02131 else
02132 {
02133
02134 struct vrp_element *prev
02135 = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records,
02136 limit - 2);
02137 low = prev->low;
02138 high = prev->high;
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149 low = (tree_int_cst_compare (low, tmp_low) == 1
02150 ? low : tmp_low);
02151 high = (tree_int_cst_compare (high, tmp_high) == -1
02152 ? high : tmp_high);
02153 }
02154
02155
02156 element->low = low;
02157 element->high = high;
02158
02159 }
02160
02161
02162
02163
02164
02165
02166
02167
02168 lowequal = tree_int_cst_equal (low, cond_low);
02169 highequal = tree_int_cst_equal (high, cond_high);
02170
02171 if (lowequal && highequal)
02172 return (cond_inverted ? boolean_false_node : boolean_true_node);
02173
02174
02175
02176
02177 swapped = 0;
02178 if (tree_int_cst_compare (low, cond_low) == 1
02179 || (lowequal
02180 && tree_int_cst_compare (cond_high, high) == 1))
02181 {
02182 tree temp;
02183
02184 swapped = 1;
02185 temp = low;
02186 low = cond_low;
02187 cond_low = temp;
02188 temp = high;
02189 high = cond_high;
02190 cond_high = temp;
02191 }
02192
02193
02194
02195 no_overlap = tree_int_cst_lt (high, cond_low);
02196 subset = tree_int_cst_compare (cond_high, high) != 1;
02197
02198
02199
02200
02201 if (no_overlap)
02202 return (cond_inverted ? boolean_true_node : boolean_false_node);
02203
02204
02205
02206
02207
02208 if (subset && swapped)
02209 return (cond_inverted ? boolean_false_node : boolean_true_node);
02210
02211
02212
02213
02214 low = tree_int_cst_compare (low, cond_low) == 1 ? low : cond_low;
02215 high = tree_int_cst_compare (high, cond_high) == -1 ? high : cond_high;
02216
02217
02218
02219 if (TREE_CODE (cond) != EQ_EXPR
02220 && TREE_CODE (cond) != NE_EXPR
02221 && tree_int_cst_equal (low, high))
02222 {
02223 TREE_SET_CODE (cond, EQ_EXPR);
02224 TREE_OPERAND (cond, 1) = high;
02225 }
02226 }
02227 }
02228 return 0;
02229 }
02230
02231
02232
02233
02234
02235 static tree
02236 simplify_switch_and_lookup_avail_expr (tree stmt, int insert)
02237 {
02238 tree cond = SWITCH_COND (stmt);
02239 tree def, to, ti;
02240
02241
02242
02243
02244 if (TREE_CODE (cond) == SSA_NAME)
02245 {
02246 def = SSA_NAME_DEF_STMT (cond);
02247 if (TREE_CODE (def) == MODIFY_EXPR)
02248 {
02249 def = TREE_OPERAND (def, 1);
02250 if (TREE_CODE (def) == NOP_EXPR)
02251 {
02252 int need_precision;
02253 bool fail;
02254
02255 def = TREE_OPERAND (def, 0);
02256
02257 #ifdef ENABLE_CHECKING
02258
02259 gcc_assert (is_gimple_val (def));
02260 #endif
02261
02262 to = TREE_TYPE (cond);
02263 ti = TREE_TYPE (def);
02264
02265
02266
02267
02268 need_precision = TYPE_PRECISION (ti);
02269 fail = false;
02270 if (TYPE_UNSIGNED (to) && !TYPE_UNSIGNED (ti))
02271 fail = true;
02272 else if (!TYPE_UNSIGNED (to) && TYPE_UNSIGNED (ti))
02273 need_precision += 1;
02274 if (TYPE_PRECISION (to) < need_precision)
02275 fail = true;
02276
02277 if (!fail)
02278 {
02279 SWITCH_COND (stmt) = def;
02280 modify_stmt (stmt);
02281
02282 return lookup_avail_expr (stmt, insert);
02283 }
02284 }
02285 }
02286 }
02287
02288 return 0;
02289 }
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301 static void
02302 cprop_into_successor_phis (basic_block bb, bitmap nonzero_vars)
02303 {
02304 edge e;
02305 edge_iterator ei;
02306
02307
02308
02309 FOR_EACH_EDGE (e, ei, bb->succs)
02310 {
02311 tree phi;
02312 int indx;
02313
02314
02315
02316 if (e->flags & EDGE_ABNORMAL)
02317 continue;
02318
02319 phi = phi_nodes (e->dest);
02320 if (! phi)
02321 continue;
02322
02323 indx = e->dest_idx;
02324 for ( ; phi; phi = PHI_CHAIN (phi))
02325 {
02326 tree new;
02327 use_operand_p orig_p;
02328 tree orig;
02329
02330
02331
02332 orig_p = PHI_ARG_DEF_PTR (phi, indx);
02333 orig = USE_FROM_PTR (orig_p);
02334 if (TREE_CODE (orig) != SSA_NAME)
02335 continue;
02336
02337
02338
02339 if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (orig)))
02340 PHI_ARG_NONZERO (phi, indx) = true;
02341
02342
02343
02344 new = SSA_NAME_VALUE (orig);
02345 if (new
02346 && (TREE_CODE (new) == SSA_NAME
02347 || is_gimple_min_invariant (new))
02348 && may_propagate_copy (orig, new))
02349 {
02350 propagate_value (orig_p, new);
02351 }
02352 }
02353 }
02354 }
02355
02356
02357
02358
02359 static void
02360 record_edge_info (basic_block bb)
02361 {
02362 block_stmt_iterator bsi = bsi_last (bb);
02363 struct edge_info *edge_info;
02364
02365 if (! bsi_end_p (bsi))
02366 {
02367 tree stmt = bsi_stmt (bsi);
02368
02369 if (stmt && TREE_CODE (stmt) == SWITCH_EXPR)
02370 {
02371 tree cond = SWITCH_COND (stmt);
02372
02373 if (TREE_CODE (cond) == SSA_NAME)
02374 {
02375 tree labels = SWITCH_LABELS (stmt);
02376 int i, n_labels = TREE_VEC_LENGTH (labels);
02377 tree *info = xcalloc (n_basic_blocks, sizeof (tree));
02378 edge e;
02379 edge_iterator ei;
02380
02381 for (i = 0; i < n_labels; i++)
02382 {
02383 tree label = TREE_VEC_ELT (labels, i);
02384 basic_block target_bb = label_to_block (CASE_LABEL (label));
02385
02386 if (CASE_HIGH (label)
02387 || !CASE_LOW (label)
02388 || info[target_bb->index])
02389 info[target_bb->index] = error_mark_node;
02390 else
02391 info[target_bb->index] = label;
02392 }
02393
02394 FOR_EACH_EDGE (e, ei, bb->succs)
02395 {
02396 basic_block target_bb = e->dest;
02397 tree node = info[target_bb->index];
02398
02399 if (node != NULL && node != error_mark_node)
02400 {
02401 tree x = fold_convert (TREE_TYPE (cond), CASE_LOW (node));
02402 edge_info = allocate_edge_info (e);
02403 edge_info->lhs = cond;
02404 edge_info->rhs = x;
02405 }
02406 }
02407 free (info);
02408 }
02409 }
02410
02411
02412 if (stmt && TREE_CODE (stmt) == COND_EXPR)
02413 {
02414 tree cond = COND_EXPR_COND (stmt);
02415 edge true_edge;
02416 edge false_edge;
02417
02418 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
02419
02420
02421
02422 if (SSA_VAR_P (cond))
02423 {
02424 struct edge_info *edge_info;
02425
02426 edge_info = allocate_edge_info (true_edge);
02427 edge_info->lhs = cond;
02428 edge_info->rhs = constant_boolean_node (1, TREE_TYPE (cond));
02429
02430 edge_info = allocate_edge_info (false_edge);
02431 edge_info->lhs = cond;
02432 edge_info->rhs = constant_boolean_node (0, TREE_TYPE (cond));
02433 }
02434
02435 else if (COMPARISON_CLASS_P (cond))
02436 {
02437 tree op0 = TREE_OPERAND (cond, 0);
02438 tree op1 = TREE_OPERAND (cond, 1);
02439
02440
02441
02442
02443 if ((TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR)
02444 && TREE_CODE (op0) == SSA_NAME
02445 && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
02446 && is_gimple_min_invariant (op1))
02447 {
02448 if (TREE_CODE (cond) == EQ_EXPR)
02449 {
02450 edge_info = allocate_edge_info (true_edge);
02451 edge_info->lhs = op0;
02452 edge_info->rhs = (integer_zerop (op1)
02453 ? boolean_false_node
02454 : boolean_true_node);
02455
02456 edge_info = allocate_edge_info (false_edge);
02457 edge_info->lhs = op0;
02458 edge_info->rhs = (integer_zerop (op1)
02459 ? boolean_true_node
02460 : boolean_false_node);
02461 }
02462 else
02463 {
02464 edge_info = allocate_edge_info (true_edge);
02465 edge_info->lhs = op0;
02466 edge_info->rhs = (integer_zerop (op1)
02467 ? boolean_true_node
02468 : boolean_false_node);
02469
02470 edge_info = allocate_edge_info (false_edge);
02471 edge_info->lhs = op0;
02472 edge_info->rhs = (integer_zerop (op1)
02473 ? boolean_false_node
02474 : boolean_true_node);
02475 }
02476 }
02477
02478 else if (is_gimple_min_invariant (op0)
02479 && (TREE_CODE (op1) == SSA_NAME
02480 || is_gimple_min_invariant (op1)))
02481 {
02482 tree inverted = invert_truthvalue (cond);
02483 struct edge_info *edge_info;
02484
02485 edge_info = allocate_edge_info (true_edge);
02486 record_conditions (edge_info, cond, inverted);
02487
02488 if (TREE_CODE (cond) == EQ_EXPR)
02489 {
02490 edge_info->lhs = op1;
02491 edge_info->rhs = op0;
02492 }
02493
02494 edge_info = allocate_edge_info (false_edge);
02495 record_conditions (edge_info, inverted, cond);
02496
02497 if (TREE_CODE (cond) == NE_EXPR)
02498 {
02499 edge_info->lhs = op1;
02500 edge_info->rhs = op0;
02501 }
02502 }
02503
02504 else if (TREE_CODE (op0) == SSA_NAME
02505 && (is_gimple_min_invariant (op1)
02506 || TREE_CODE (op1) == SSA_NAME))
02507 {
02508 tree inverted = invert_truthvalue (cond);
02509 struct edge_info *edge_info;
02510
02511 edge_info = allocate_edge_info (true_edge);
02512 record_conditions (edge_info, cond, inverted);
02513
02514 if (TREE_CODE (cond) == EQ_EXPR)
02515 {
02516 edge_info->lhs = op0;
02517 edge_info->rhs = op1;
02518 }
02519
02520 edge_info = allocate_edge_info (false_edge);
02521 record_conditions (edge_info, inverted, cond);
02522
02523 if (TREE_CODE (cond) == NE_EXPR)
02524 {
02525 edge_info->lhs = op0;
02526 edge_info->rhs = op1;
02527 }
02528 }
02529 }
02530
02531
02532 }
02533 }
02534 }
02535
02536
02537
02538
02539
02540
02541
02542 static void
02543 propagate_to_outgoing_edges (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
02544 basic_block bb)
02545 {
02546
02547 record_edge_info (bb);
02548 cprop_into_successor_phis (bb, nonzero_vars);
02549 }
02550
02551
02552
02553
02554
02555
02556
02557 static bool
02558 eliminate_redundant_computations (struct dom_walk_data *walk_data,
02559 tree stmt, stmt_ann_t ann)
02560 {
02561 v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
02562 tree *expr_p, def = NULL_TREE;
02563 bool insert = true;
02564 tree cached_lhs;
02565 bool retval = false;
02566
02567 if (TREE_CODE (stmt) == MODIFY_EXPR)
02568 def = TREE_OPERAND (stmt, 0);
02569
02570
02571
02572 if (ann->makes_aliased_stores
02573 || ! def
02574 || TREE_CODE (def) != SSA_NAME
02575 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
02576 || NUM_V_MAY_DEFS (v_may_defs) != 0)
02577 insert = false;
02578
02579
02580 cached_lhs = lookup_avail_expr (stmt, insert);
02581
02582
02583
02584
02585 if (! cached_lhs && TREE_CODE (stmt) == MODIFY_EXPR)
02586 cached_lhs = simplify_rhs_and_lookup_avail_expr (walk_data, stmt, insert);
02587
02588
02589
02590 else if (! cached_lhs && TREE_CODE (stmt) == COND_EXPR)
02591 cached_lhs = simplify_cond_and_lookup_avail_expr (stmt, ann, insert);
02592
02593 else if (!cached_lhs && TREE_CODE (stmt) == SWITCH_EXPR)
02594 cached_lhs = simplify_switch_and_lookup_avail_expr (stmt, insert);
02595
02596 opt_stats.num_exprs_considered++;
02597
02598
02599 if (TREE_CODE (stmt) == COND_EXPR)
02600 expr_p = &COND_EXPR_COND (stmt);
02601 else if (TREE_CODE (stmt) == SWITCH_EXPR)
02602 expr_p = &SWITCH_COND (stmt);
02603 else if (TREE_CODE (stmt) == RETURN_EXPR && TREE_OPERAND (stmt, 0))
02604 expr_p = &TREE_OPERAND (TREE_OPERAND (stmt, 0), 1);
02605 else
02606 expr_p = &TREE_OPERAND (stmt, 1);
02607
02608
02609
02610
02611
02612
02613 if (cached_lhs
02614 && (TREE_CODE (cached_lhs) != SSA_NAME
02615 || may_propagate_copy (*expr_p, cached_lhs)))
02616 {
02617 if (dump_file && (dump_flags & TDF_DETAILS))
02618 {
02619 fprintf (dump_file, " Replaced redundant expr '");
02620 print_generic_expr (dump_file, *expr_p, dump_flags);
02621 fprintf (dump_file, "' with '");
02622 print_generic_expr (dump_file, cached_lhs, dump_flags);
02623 fprintf (dump_file, "'\n");
02624 }
02625
02626 opt_stats.num_re++;
02627
02628 #if defined ENABLE_CHECKING
02629 gcc_assert (TREE_CODE (cached_lhs) == SSA_NAME
02630 || is_gimple_min_invariant (cached_lhs));
02631 #endif
02632
02633 if (TREE_CODE (cached_lhs) == ADDR_EXPR
02634 || (POINTER_TYPE_P (TREE_TYPE (*expr_p))
02635 && is_gimple_min_invariant (cached_lhs)))
02636 retval = true;
02637
02638 propagate_tree_value (expr_p, cached_lhs);
02639 modify_stmt (stmt);
02640 }
02641 return retval;
02642 }
02643
02644
02645
02646
02647
02648 static void
02649 record_equivalences_from_stmt (tree stmt,
02650 int may_optimize_p,
02651 stmt_ann_t ann)
02652 {
02653 tree lhs = TREE_OPERAND (stmt, 0);
02654 enum tree_code lhs_code = TREE_CODE (lhs);
02655 int i;
02656
02657 if (lhs_code == SSA_NAME)
02658 {
02659 tree rhs = TREE_OPERAND (stmt, 1);
02660
02661
02662 STRIP_USELESS_TYPE_CONVERSION (rhs);
02663
02664
02665
02666
02667
02668
02669
02670 if (may_optimize_p
02671 && (TREE_CODE (rhs) == SSA_NAME
02672 || is_gimple_min_invariant (rhs)))
02673 SSA_NAME_VALUE (lhs) = rhs;
02674
02675
02676
02677
02678 while (TREE_CODE (rhs) == NOP_EXPR
02679 || TREE_CODE (rhs) == CONVERT_EXPR)
02680 rhs = TREE_OPERAND (rhs, 0);
02681
02682 if (alloca_call_p (rhs)
02683 || (TREE_CODE (rhs) == ADDR_EXPR
02684 && DECL_P (TREE_OPERAND (rhs, 0))
02685 && ! DECL_WEAK (TREE_OPERAND (rhs, 0))))
02686 record_var_is_nonzero (lhs);
02687
02688
02689
02690
02691 if (TREE_CODE (rhs) == BIT_IOR_EXPR
02692 && integer_nonzerop (TREE_OPERAND (rhs, 1)))
02693 record_var_is_nonzero (lhs);
02694 }
02695
02696
02697
02698
02699 if (flag_delete_null_pointer_checks)
02700 for (i = 0; i < 2; i++)
02701 {
02702 tree t = TREE_OPERAND (stmt, i);
02703
02704
02705 while (TREE_CODE (t) == COMPONENT_REF)
02706 t = TREE_OPERAND (t, 0);
02707
02708
02709 if (INDIRECT_REF_P (t))
02710 {
02711 tree op = TREE_OPERAND (t, 0);
02712
02713
02714
02715 while (TREE_CODE (op) == SSA_NAME)
02716 {
02717 tree def = SSA_NAME_DEF_STMT (op);
02718
02719 record_var_is_nonzero (op);
02720
02721
02722
02723 if (def
02724 && TREE_CODE (def) == MODIFY_EXPR
02725 && TREE_CODE (TREE_OPERAND (def, 1)) == NOP_EXPR)
02726 op = TREE_OPERAND (TREE_OPERAND (def, 1), 0);
02727 else
02728 break;
02729 }
02730 }
02731 }
02732
02733
02734
02735
02736
02737 if (!ann->has_volatile_ops
02738 && (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME
02739 || is_gimple_min_invariant (TREE_OPERAND (stmt, 1)))
02740 && !is_gimple_reg (lhs))
02741 {
02742 tree rhs = TREE_OPERAND (stmt, 1);
02743 tree new;
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753 if (lhs_code == COMPONENT_REF
02754 && DECL_BIT_FIELD (TREE_OPERAND (lhs, 1)))
02755 {
02756 if (TREE_CONSTANT (rhs))
02757 rhs = widen_bitfield (rhs, TREE_OPERAND (lhs, 1), lhs);
02758 else
02759 rhs = NULL;
02760
02761
02762 if (rhs && ! is_gimple_min_invariant (rhs))
02763 rhs = NULL;
02764 }
02765
02766 if (rhs)
02767 {
02768
02769 new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs);
02770
02771 create_ssa_artficial_load_stmt (&(ann->operands), new);
02772
02773
02774
02775 lookup_avail_expr (new, true);
02776 }
02777 }
02778 }
02779
02780
02781
02782
02783 static bool
02784 cprop_operand (tree stmt, use_operand_p op_p)
02785 {
02786 bool may_have_exposed_new_symbols = false;
02787 tree val;
02788 tree op = USE_FROM_PTR (op_p);
02789
02790
02791
02792
02793 val = SSA_NAME_VALUE (op);
02794 if (val && TREE_CODE (val) != VALUE_HANDLE)
02795 {
02796 tree op_type, val_type;
02797
02798
02799
02800
02801
02802
02803 if (!is_gimple_reg (op)
02804 && (get_virtual_var (val) != get_virtual_var (op)
02805 || TREE_CODE (val) != SSA_NAME))
02806 return false;
02807
02808
02809 if (TREE_CODE (stmt) == ASM_EXPR
02810 && !may_propagate_copy_into_asm (op))
02811 return false;
02812
02813
02814 op_type = TREE_TYPE (op);
02815 val_type = TREE_TYPE (val);
02816
02817
02818
02819 while (POINTER_TYPE_P (op_type) && POINTER_TYPE_P (val_type))
02820 {
02821 op_type = TREE_TYPE (op_type);
02822 val_type = TREE_TYPE (val_type);
02823 }
02824
02825
02826
02827
02828
02829 if (TREE_CODE (val) != SSA_NAME)
02830 {
02831 if (!lang_hooks.types_compatible_p (op_type, val_type))
02832 {
02833 val = fold_convert (TREE_TYPE (op), val);
02834 if (!is_gimple_min_invariant (val))
02835 return false;
02836 }
02837 }
02838
02839
02840
02841
02842 else if (!may_propagate_copy (op, val))
02843 return false;
02844
02845
02846
02847
02848
02849
02850 if (loop_depth_of_name (val) > loop_depth_of_name (op))
02851 return false;
02852
02853
02854 if (dump_file && (dump_flags & TDF_DETAILS))
02855 {
02856 fprintf (dump_file, " Replaced '");
02857 print_generic_expr (dump_file, op, dump_flags);
02858 fprintf (dump_file, "' with %s '",
02859 (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
02860 print_generic_expr (dump_file, val, dump_flags);
02861 fprintf (dump_file, "'\n");
02862 }
02863
02864
02865
02866 if (TREE_CODE (val) == ADDR_EXPR
02867 || (POINTER_TYPE_P (TREE_TYPE (op))
02868 && is_gimple_min_invariant (val)))
02869 may_have_exposed_new_symbols = true;
02870
02871 propagate_value (op_p, val);
02872
02873
02874
02875
02876 modify_stmt (stmt);
02877 }
02878 return may_have_exposed_new_symbols;
02879 }
02880
02881
02882
02883
02884
02885
02886
02887 static bool
02888 cprop_into_stmt (tree stmt)
02889 {
02890 bool may_have_exposed_new_symbols = false;
02891 use_operand_p op_p;
02892 ssa_op_iter iter;
02893 tree rhs;
02894
02895 FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_ALL_USES)
02896 {
02897 if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
02898 may_have_exposed_new_symbols |= cprop_operand (stmt, op_p);
02899 }
02900
02901 if (may_have_exposed_new_symbols)
02902 {
02903 rhs = get_rhs (stmt);
02904 if (rhs && TREE_CODE (rhs) == ADDR_EXPR)
02905 recompute_tree_invarant_for_addr_expr (rhs);
02906 }
02907
02908 return may_have_exposed_new_symbols;
02909 }
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927 static void
02928 optimize_stmt (struct dom_walk_data *walk_data, basic_block bb,
02929 block_stmt_iterator si)
02930 {
02931 stmt_ann_t ann;
02932 tree stmt;
02933 bool may_optimize_p;
02934 bool may_have_exposed_new_symbols = false;
02935
02936 stmt = bsi_stmt (si);
02937
02938 get_stmt_operands (stmt);
02939 ann = stmt_ann (stmt);
02940 opt_stats.num_stmts++;
02941 may_have_exposed_new_symbols = false;
02942
02943 if (dump_file && (dump_flags & TDF_DETAILS))
02944 {
02945 fprintf (dump_file, "Optimizing statement ");
02946 print_generic_stmt (dump_file, stmt, TDF_SLIM);
02947 }
02948
02949
02950 may_have_exposed_new_symbols = cprop_into_stmt (stmt);
02951
02952
02953
02954 if (ann->modified)
02955 {
02956
02957
02958 if (fold_stmt (bsi_stmt_ptr (si)))
02959 {
02960 stmt = bsi_stmt (si);
02961 ann = stmt_ann (stmt);
02962
02963 if (dump_file && (dump_flags & TDF_DETAILS))
02964 {
02965 fprintf (dump_file, " Folded to: ");
02966 print_generic_stmt (dump_file, stmt, TDF_SLIM);
02967 }
02968 }
02969
02970
02971
02972
02973
02974
02975 may_have_exposed_new_symbols = true;
02976 }
02977
02978
02979
02980 may_optimize_p = (!ann->has_volatile_ops
02981 && ((TREE_CODE (stmt) == RETURN_EXPR
02982 && TREE_OPERAND (stmt, 0)
02983 && TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR
02984 && ! (TREE_SIDE_EFFECTS
02985 (TREE_OPERAND (TREE_OPERAND (stmt, 0), 1))))
02986 || (TREE_CODE (stmt) == MODIFY_EXPR
02987 && ! TREE_SIDE_EFFECTS (TREE_OPERAND (stmt, 1)))
02988 || TREE_CODE (stmt) == COND_EXPR
02989 || TREE_CODE (stmt) == SWITCH_EXPR));
02990
02991 if (may_optimize_p)
02992 may_have_exposed_new_symbols
02993 |= eliminate_redundant_computations (walk_data, stmt, ann);
02994
02995
02996 if (TREE_CODE (stmt) == MODIFY_EXPR)
02997 record_equivalences_from_stmt (stmt,
02998 may_optimize_p,
02999 ann);
03000
03001 register_definitions_for_stmt (stmt);
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029 if (ann->modified)
03030 {
03031 tree val = NULL;
03032
03033 if (TREE_CODE (stmt) == COND_EXPR)
03034 val = COND_EXPR_COND (stmt);
03035 else if (TREE_CODE (stmt) == SWITCH_EXPR)
03036 val = SWITCH_COND (stmt);
03037
03038 if (val && TREE_CODE (val) == INTEGER_CST && find_taken_edge (bb, val))
03039 cfg_altered = true;
03040
03041
03042
03043 if (maybe_clean_eh_stmt (stmt))
03044 {
03045 bitmap_set_bit (need_eh_cleanup, bb->index);
03046 if (dump_file && (dump_flags & TDF_DETAILS))
03047 fprintf (dump_file, " Flagged to clear EH edges.\n");
03048 }
03049 }
03050
03051 if (may_have_exposed_new_symbols)
03052 VEC_safe_push (tree_on_heap, stmts_to_rescan, bsi_stmt (si));
03053 }
03054
03055
03056
03057
03058
03059
03060
03061
03062 static tree
03063 update_rhs_and_lookup_avail_expr (tree stmt, tree new_rhs, bool insert)
03064 {
03065 tree cached_lhs = NULL;
03066
03067
03068 if (insert)
03069 {
03070 struct expr_hash_elt element;
03071
03072 initialize_hash_element (stmt, NULL, &element);
03073 htab_remove_elt_with_hash (avail_exprs, &element, element.hash);
03074 }
03075
03076
03077 TREE_OPERAND (stmt, 1) = new_rhs;
03078
03079
03080 cached_lhs = lookup_avail_expr (stmt, insert);
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103 if (insert)
03104 VEC_pop (tree_on_heap, avail_exprs_stack);
03105
03106
03107
03108 modify_stmt (stmt);
03109
03110 return cached_lhs;
03111 }
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125 static tree
03126 lookup_avail_expr (tree stmt, bool insert)
03127 {
03128 void **slot;
03129 tree lhs;
03130 tree temp;
03131 struct expr_hash_elt *element = xmalloc (sizeof (struct expr_hash_elt));
03132
03133 lhs = TREE_CODE (stmt) == MODIFY_EXPR ? TREE_OPERAND (stmt, 0) : NULL;
03134
03135 initialize_hash_element (stmt, lhs, element);
03136
03137
03138
03139
03140 if (TREE_CODE (element->rhs) == SSA_NAME
03141 || is_gimple_min_invariant (element->rhs))
03142 {
03143 free (element);
03144 return NULL_TREE;
03145 }
03146
03147
03148
03149 if ((TREE_CODE (element->rhs) == EQ_EXPR
03150 || TREE_CODE (element->rhs) == NE_EXPR)
03151 && TREE_CODE (TREE_OPERAND (element->rhs, 0)) == SSA_NAME
03152 && integer_zerop (TREE_OPERAND (element->rhs, 1)))
03153 {
03154 int indx = SSA_NAME_VERSION (TREE_OPERAND (element->rhs, 0));
03155
03156 if (bitmap_bit_p (nonzero_vars, indx))
03157 {
03158 tree t = element->rhs;
03159 free (element);
03160
03161 if (TREE_CODE (t) == EQ_EXPR)
03162 return boolean_false_node;
03163 else
03164 return boolean_true_node;
03165 }
03166 }
03167
03168
03169 slot = htab_find_slot_with_hash (avail_exprs, element, element->hash,
03170 (insert ? INSERT : NO_INSERT));
03171 if (slot == NULL)
03172 {
03173 free (element);
03174 return NULL_TREE;
03175 }
03176
03177 if (*slot == NULL)
03178 {
03179 *slot = (void *) element;
03180 VEC_safe_push (tree_on_heap, avail_exprs_stack,
03181 stmt ? stmt : element->rhs);
03182 return NULL_TREE;
03183 }
03184
03185
03186
03187 lhs = ((struct expr_hash_elt *)*slot)->lhs;
03188
03189
03190
03191 if (TREE_CODE (lhs) == SSA_NAME)
03192 {
03193 temp = SSA_NAME_VALUE (lhs);
03194 if (temp && TREE_CODE (temp) != VALUE_HANDLE)
03195 lhs = temp;
03196 }
03197
03198 free (element);
03199 return lhs;
03200 }
03201
03202
03203
03204
03205
03206
03207
03208 static bool
03209 extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p)
03210 {
03211 tree op1 = TREE_OPERAND (cond, 1);
03212 tree high, low, type;
03213 int inverted;
03214
03215 type = TREE_TYPE (op1);
03216
03217
03218
03219
03220
03221 if (TREE_CODE (type) != INTEGER_TYPE
03222
03223 || TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
03224 || TREE_CODE (TYPE_MAX_VALUE (type)) != INTEGER_CST)
03225 return 0;
03226
03227 switch (TREE_CODE (cond))
03228 {
03229 case EQ_EXPR:
03230 high = low = op1;
03231 inverted = 0;
03232 break;
03233
03234 case NE_EXPR:
03235 high = low = op1;
03236 inverted = 1;
03237 break;
03238
03239 case GE_EXPR:
03240 low = op1;
03241 high = TYPE_MAX_VALUE (type);
03242 inverted = 0;
03243 break;
03244
03245 case GT_EXPR:
03246 high = TYPE_MAX_VALUE (type);
03247 if (!tree_int_cst_lt (op1, high))
03248 return 0;
03249 low = int_const_binop (PLUS_EXPR, op1, integer_one_node, 1);
03250 inverted = 0;
03251 break;
03252
03253 case LE_EXPR:
03254 high = op1;
03255 low = TYPE_MIN_VALUE (type);
03256 inverted = 0;
03257 break;
03258
03259 case LT_EXPR:
03260 low = TYPE_MIN_VALUE (type);
03261 if (!tree_int_cst_lt (low, op1))
03262 return 0;
03263 high = int_const_binop (MINUS_EXPR, op1, integer_one_node, 1);
03264 inverted = 0;
03265 break;
03266
03267 default:
03268 return 0;
03269 }
03270
03271 *hi_p = high;
03272 *lo_p = low;
03273 *inverted_p = inverted;
03274 return 1;
03275 }
03276
03277
03278
03279 static void
03280 record_range (tree cond, basic_block bb)
03281 {
03282 enum tree_code code = TREE_CODE (cond);
03283
03284
03285
03286
03287 if ((code == LT_EXPR || code == LE_EXPR || code == GT_EXPR
03288 || code == GE_EXPR || code == EQ_EXPR)
03289 && TREE_CODE (TREE_TYPE (TREE_OPERAND (cond, 1))) == INTEGER_TYPE)
03290 {
03291 struct vrp_hash_elt *vrp_hash_elt;
03292 struct vrp_element *element;
03293 varray_type *vrp_records_p;
03294 void **slot;
03295
03296
03297 vrp_hash_elt = xmalloc (sizeof (struct vrp_hash_elt));
03298 vrp_hash_elt->var = TREE_OPERAND (cond, 0);
03299 vrp_hash_elt->records = NULL;
03300 slot = htab_find_slot (vrp_data, vrp_hash_elt, INSERT);
03301
03302 if (*slot == NULL)
03303 *slot = (void *) vrp_hash_elt;
03304 else
03305 free (vrp_hash_elt);
03306
03307 vrp_hash_elt = (struct vrp_hash_elt *) *slot;
03308 vrp_records_p = &vrp_hash_elt->records;
03309
03310 element = ggc_alloc (sizeof (struct vrp_element));
03311 element->low = NULL;
03312 element->high = NULL;
03313 element->cond = cond;
03314 element->bb = bb;
03315
03316 if (*vrp_records_p == NULL)
03317 VARRAY_GENERIC_PTR_INIT (*vrp_records_p, 2, "vrp records");
03318
03319 VARRAY_PUSH_GENERIC_PTR (*vrp_records_p, element);
03320 VEC_safe_push (tree_on_heap, vrp_variables_stack, TREE_OPERAND (cond, 0));
03321 }
03322 }
03323
03324
03325
03326
03327
03328
03329
03330 static hashval_t
03331 vrp_hash (const void *p)
03332 {
03333 tree var = ((struct vrp_hash_elt *)p)->var;
03334
03335 return SSA_NAME_VERSION (var);
03336 }
03337
03338 static int
03339 vrp_eq (const void *p1, const void *p2)
03340 {
03341 tree var1 = ((struct vrp_hash_elt *)p1)->var;
03342 tree var2 = ((struct vrp_hash_elt *)p2)->var;
03343
03344 return var1 == var2;
03345 }
03346
03347
03348
03349
03350
03351 static hashval_t
03352 avail_expr_hash (const void *p)
03353 {
03354 stmt_ann_t ann = ((struct expr_hash_elt *)p)->ann;
03355 tree rhs = ((struct expr_hash_elt *)p)->rhs;
03356 hashval_t val = 0;
03357 size_t i;
03358 vuse_optype vuses;
03359
03360
03361
03362
03363 val = iterative_hash_expr (rhs, val);
03364
03365
03366
03367
03368 if (!ann)
03369 return val;
03370
03371
03372
03373
03374
03375 vuses = VUSE_OPS (ann);
03376 for (i = 0; i < NUM_VUSES (vuses); i++)
03377 val = iterative_hash_expr (VUSE_OP (vuses, i), val);
03378
03379 return val;
03380 }
03381
03382 static hashval_t
03383 real_avail_expr_hash (const void *p)
03384 {
03385 return ((const struct expr_hash_elt *)p)->hash;
03386 }
03387
03388 static int
03389 avail_expr_eq (const void *p1, const void *p2)
03390 {
03391 stmt_ann_t ann1 = ((struct expr_hash_elt *)p1)->ann;
03392 tree rhs1 = ((struct expr_hash_elt *)p1)->rhs;
03393 stmt_ann_t ann2 = ((struct expr_hash_elt *)p2)->ann;
03394 tree rhs2 = ((struct expr_hash_elt *)p2)->rhs;
03395
03396
03397 if (rhs1 == rhs2 && ann1 == ann2)
03398 return true;
03399
03400
03401 if (TREE_CODE (rhs1) != TREE_CODE (rhs2))
03402 return false;
03403
03404
03405
03406 if ((TREE_TYPE (rhs1) == TREE_TYPE (rhs2)
03407 || lang_hooks.types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2)))
03408 && operand_equal_p (rhs1, rhs2, OEP_PURE_SAME))
03409 {
03410 vuse_optype ops1 = NULL;
03411 vuse_optype ops2 = NULL;
03412 size_t num_ops1 = 0;
03413 size_t num_ops2 = 0;
03414 size_t i;
03415
03416 if (ann1)
03417 {
03418 ops1 = VUSE_OPS (ann1);
03419 num_ops1 = NUM_VUSES (ops1);
03420 }
03421
03422 if (ann2)
03423 {
03424 ops2 = VUSE_OPS (ann2);
03425 num_ops2 = NUM_VUSES (ops2);
03426 }
03427
03428
03429
03430 if (num_ops1 != num_ops2)
03431 return false;
03432
03433 for (i = 0; i < num_ops1; i++)
03434 if (VUSE_OP (ops1, i) != VUSE_OP (ops2, i))
03435 return false;
03436
03437 gcc_assert (((struct expr_hash_elt *)p1)->hash
03438 == ((struct expr_hash_elt *)p2)->hash);
03439 return true;
03440 }
03441
03442 return false;
03443 }
03444
03445
03446
03447
03448
03449 static void
03450 register_definitions_for_stmt (tree stmt)
03451 {
03452 tree def;
03453 ssa_op_iter iter;
03454
03455 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
03456 {
03457
03458
03459
03460 register_new_def (def, &block_defs_stack);
03461 }
03462 }
03463