00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "ggc.h"
00028 #include "tree.h"
00029 #include "basic-block.h"
00030 #include "diagnostic.h"
00031 #include "tree-inline.h"
00032 #include "tree-flow.h"
00033 #include "tree-gimple.h"
00034 #include "tree-dump.h"
00035 #include "timevar.h"
00036 #include "fibheap.h"
00037 #include "hashtab.h"
00038 #include "tree-iterator.h"
00039 #include "real.h"
00040 #include "alloc-pool.h"
00041 #include "tree-pass.h"
00042 #include "flags.h"
00043 #include "bitmap.h"
00044 #include "langhooks.h"
00045 #include "cfgloop.h"
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 static bool in_fre = false;
00182
00183
00184
00185 typedef struct value_set_node
00186 {
00187
00188 tree expr;
00189
00190
00191 struct value_set_node *next;
00192 } *value_set_node_t;
00193
00194
00195
00196
00197
00198 typedef struct value_set
00199 {
00200
00201
00202 value_set_node_t head;
00203
00204
00205
00206
00207 value_set_node_t tail;
00208
00209
00210 size_t length;
00211
00212
00213
00214
00215 bool indexed;
00216
00217
00218
00219 bitmap values;
00220
00221 } *value_set_t;
00222
00223
00224
00225
00226 typedef struct bitmap_set
00227 {
00228 bitmap expressions;
00229 bitmap values;
00230 } *bitmap_set_t;
00231
00232
00233 typedef struct bb_value_sets
00234 {
00235
00236
00237 value_set_t exp_gen;
00238
00239
00240
00241 bitmap_set_t phi_gen;
00242
00243
00244
00245 bitmap_set_t tmp_gen;
00246
00247
00248
00249 bitmap_set_t avail_out;
00250
00251
00252
00253 value_set_t antic_in;
00254
00255
00256
00257
00258 bitmap_set_t new_sets;
00259
00260
00261
00262 bitmap rvuse_in;
00263 bitmap rvuse_out;
00264 bitmap rvuse_gen;
00265 bitmap rvuse_kill;
00266
00267
00268
00269
00270 value_set_t antic_safe_loads;
00271 } *bb_value_sets_t;
00272
00273 #define EXP_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->exp_gen
00274 #define PHI_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->phi_gen
00275 #define TMP_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->tmp_gen
00276 #define AVAIL_OUT(BB) ((bb_value_sets_t) ((BB)->aux))->avail_out
00277 #define ANTIC_IN(BB) ((bb_value_sets_t) ((BB)->aux))->antic_in
00278 #define RVUSE_IN(BB) ((bb_value_sets_t) ((BB)->aux))->rvuse_in
00279 #define RVUSE_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->rvuse_gen
00280 #define RVUSE_KILL(BB) ((bb_value_sets_t) ((BB)->aux))->rvuse_kill
00281 #define RVUSE_OUT(BB) ((bb_value_sets_t) ((BB)->aux))->rvuse_out
00282 #define NEW_SETS(BB) ((bb_value_sets_t) ((BB)->aux))->new_sets
00283 #define ANTIC_SAFE_LOADS(BB) ((bb_value_sets_t) ((BB)->aux))->antic_safe_loads
00284
00285
00286
00287 static struct
00288 {
00289
00290 int eliminations;
00291
00292
00293 int insertions;
00294
00295
00296 int phis;
00297
00298
00299 int constified;
00300
00301 } pre_stats;
00302
00303
00304 static tree bitmap_find_leader (bitmap_set_t, tree);
00305 static tree find_leader (value_set_t, tree);
00306 static void value_insert_into_set (value_set_t, tree);
00307 static void bitmap_value_insert_into_set (bitmap_set_t, tree);
00308 static void bitmap_value_replace_in_set (bitmap_set_t, tree);
00309 static void insert_into_set (value_set_t, tree);
00310 static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
00311 static bool bitmap_set_contains_value (bitmap_set_t, tree);
00312 static bitmap_set_t bitmap_set_new (void);
00313 static value_set_t set_new (bool);
00314 static bool is_undefined_value (tree);
00315 static tree create_expression_by_pieces (basic_block, tree, tree);
00316 static tree find_or_generate_expression (basic_block, tree, tree);
00317
00318
00319
00320
00321
00322 static alloc_pool value_set_pool;
00323 static alloc_pool bitmap_set_pool;
00324 static alloc_pool value_set_node_pool;
00325 static alloc_pool binary_node_pool;
00326 static alloc_pool unary_node_pool;
00327 static alloc_pool reference_node_pool;
00328 static alloc_pool comparison_node_pool;
00329 static alloc_pool expression_node_pool;
00330 static alloc_pool list_node_pool;
00331 static alloc_pool modify_expr_node_pool;
00332 static bitmap_obstack grand_bitmap_obstack;
00333
00334
00335
00336
00337
00338 static tree pretemp;
00339 static tree storetemp;
00340 static tree mergephitemp;
00341 static tree prephitemp;
00342
00343
00344
00345 static bitmap need_eh_cleanup;
00346
00347
00348
00349
00350 static htab_t phi_translate_table;
00351
00352
00353
00354
00355 typedef struct expr_pred_trans_d
00356 {
00357
00358 tree e;
00359
00360
00361 basic_block pred;
00362
00363
00364 VEC (tree, gc) *vuses;
00365
00366
00367 tree v;
00368
00369
00370
00371
00372 hashval_t hashcode;
00373 } *expr_pred_trans_t;
00374
00375
00376
00377 static hashval_t
00378 expr_pred_trans_hash (const void *p)
00379 {
00380 const expr_pred_trans_t ve = (expr_pred_trans_t) p;
00381 return ve->hashcode;
00382 }
00383
00384
00385
00386
00387 static int
00388 expr_pred_trans_eq (const void *p1, const void *p2)
00389 {
00390 const expr_pred_trans_t ve1 = (expr_pred_trans_t) p1;
00391 const expr_pred_trans_t ve2 = (expr_pred_trans_t) p2;
00392 basic_block b1 = ve1->pred;
00393 basic_block b2 = ve2->pred;
00394 int i;
00395 tree vuse1;
00396
00397
00398
00399 if (b1 != b2)
00400 return false;
00401
00402
00403
00404
00405 if (!expressions_equal_p (ve1->e, ve2->e))
00406 return false;
00407
00408
00409 if (ve1->vuses == ve2->vuses)
00410 return true;
00411
00412 if (VEC_length (tree, ve1->vuses) != VEC_length (tree, ve2->vuses))
00413 return false;
00414
00415 for (i = 0; VEC_iterate (tree, ve1->vuses, i, vuse1); i++)
00416 {
00417 if (VEC_index (tree, ve2->vuses, i) != vuse1)
00418 return false;
00419 }
00420
00421 return true;
00422 }
00423
00424
00425
00426
00427
00428 static inline tree
00429 phi_trans_lookup (tree e, basic_block pred, VEC (tree, gc) *vuses)
00430 {
00431 void **slot;
00432 struct expr_pred_trans_d ept;
00433
00434 ept.e = e;
00435 ept.pred = pred;
00436 ept.vuses = vuses;
00437 ept.hashcode = vn_compute (e, (unsigned long) pred);
00438 slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode,
00439 NO_INSERT);
00440 if (!slot)
00441 return NULL;
00442 else
00443 return ((expr_pred_trans_t) *slot)->v;
00444 }
00445
00446
00447
00448
00449
00450 static inline void
00451 phi_trans_add (tree e, tree v, basic_block pred, VEC (tree, gc) *vuses)
00452 {
00453 void **slot;
00454 expr_pred_trans_t new_pair = XNEW (struct expr_pred_trans_d);
00455 new_pair->e = e;
00456 new_pair->pred = pred;
00457 new_pair->vuses = vuses;
00458 new_pair->v = v;
00459 new_pair->hashcode = vn_compute (e, (unsigned long) pred);
00460 slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
00461 new_pair->hashcode, INSERT);
00462 if (*slot)
00463 free (*slot);
00464 *slot = (void *) new_pair;
00465 }
00466
00467
00468
00469
00470 void
00471 add_to_value (tree v, tree e)
00472 {
00473
00474 if (is_gimple_min_invariant (v))
00475 return;
00476
00477 if (VALUE_HANDLE_EXPR_SET (v) == NULL)
00478 VALUE_HANDLE_EXPR_SET (v) = set_new (false);
00479
00480 insert_into_set (VALUE_HANDLE_EXPR_SET (v), e);
00481 }
00482
00483
00484
00485
00486 static inline bool
00487 value_exists_in_set_bitmap (value_set_t set, tree v)
00488 {
00489 if (!set->values)
00490 return false;
00491
00492 return bitmap_bit_p (set->values, VALUE_HANDLE_ID (v));
00493 }
00494
00495
00496
00497
00498 static void
00499 value_remove_from_set_bitmap (value_set_t set, tree v)
00500 {
00501 gcc_assert (set->indexed);
00502
00503 if (!set->values)
00504 return;
00505
00506 bitmap_clear_bit (set->values, VALUE_HANDLE_ID (v));
00507 }
00508
00509
00510
00511
00512
00513 static inline void
00514 value_insert_into_set_bitmap (value_set_t set, tree v)
00515 {
00516 gcc_assert (set->indexed);
00517
00518 if (set->values == NULL)
00519 set->values = BITMAP_ALLOC (&grand_bitmap_obstack);
00520
00521 bitmap_set_bit (set->values, VALUE_HANDLE_ID (v));
00522 }
00523
00524
00525
00526
00527 static bitmap_set_t
00528 bitmap_set_new (void)
00529 {
00530 bitmap_set_t ret = (bitmap_set_t) pool_alloc (bitmap_set_pool);
00531 ret->expressions = BITMAP_ALLOC (&grand_bitmap_obstack);
00532 ret->values = BITMAP_ALLOC (&grand_bitmap_obstack);
00533 return ret;
00534 }
00535
00536
00537
00538 static value_set_t
00539 set_new (bool indexed)
00540 {
00541 value_set_t ret;
00542 ret = (value_set_t) pool_alloc (value_set_pool);
00543 ret->head = ret->tail = NULL;
00544 ret->length = 0;
00545 ret->indexed = indexed;
00546 ret->values = NULL;
00547 return ret;
00548 }
00549
00550
00551
00552 static void
00553 bitmap_insert_into_set (bitmap_set_t set, tree expr)
00554 {
00555 tree val;
00556
00557 gcc_assert (TREE_CODE (expr) == SSA_NAME);
00558 val = get_value_handle (expr);
00559
00560 gcc_assert (val);
00561 if (!is_gimple_min_invariant (val))
00562 {
00563 bitmap_set_bit (set->values, VALUE_HANDLE_ID (val));
00564 bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
00565 }
00566 }
00567
00568
00569
00570 static void
00571 insert_into_set (value_set_t set, tree expr)
00572 {
00573 value_set_node_t newnode = (value_set_node_t) pool_alloc (value_set_node_pool);
00574 tree val = get_value_handle (expr);
00575 gcc_assert (val);
00576
00577 if (is_gimple_min_invariant (val))
00578 return;
00579
00580
00581
00582
00583 if (set->indexed)
00584 value_insert_into_set_bitmap (set, val);
00585
00586 newnode->next = NULL;
00587 newnode->expr = expr;
00588 set->length ++;
00589 if (set->head == NULL)
00590 {
00591 set->head = set->tail = newnode;
00592 }
00593 else
00594 {
00595 set->tail->next = newnode;
00596 set->tail = newnode;
00597 }
00598 }
00599
00600
00601
00602 static void
00603 bitmap_set_copy (bitmap_set_t dest, bitmap_set_t orig)
00604 {
00605 bitmap_copy (dest->expressions, orig->expressions);
00606 bitmap_copy (dest->values, orig->values);
00607 }
00608
00609
00610
00611 static void
00612 bitmap_set_and (bitmap_set_t dest, bitmap_set_t orig)
00613 {
00614 bitmap_iterator bi;
00615 unsigned int i;
00616 bitmap temp = BITMAP_ALLOC (&grand_bitmap_obstack);
00617
00618 bitmap_and_into (dest->values, orig->values);
00619 bitmap_copy (temp, dest->expressions);
00620 EXECUTE_IF_SET_IN_BITMAP (temp, 0, i, bi)
00621 {
00622 tree name = ssa_name (i);
00623 tree val = get_value_handle (name);
00624 if (!bitmap_bit_p (dest->values, VALUE_HANDLE_ID (val)))
00625 bitmap_clear_bit (dest->expressions, i);
00626 }
00627 BITMAP_FREE (temp);
00628 }
00629
00630
00631
00632 static void
00633 bitmap_set_and_compl (bitmap_set_t dest, bitmap_set_t orig)
00634 {
00635 bitmap_iterator bi;
00636 unsigned int i;
00637 bitmap temp = BITMAP_ALLOC (&grand_bitmap_obstack);
00638
00639 bitmap_and_compl_into (dest->values, orig->values);
00640 bitmap_copy (temp, dest->expressions);
00641 EXECUTE_IF_SET_IN_BITMAP (temp, 0, i, bi)
00642 {
00643 tree name = ssa_name (i);
00644 tree val = get_value_handle (name);
00645 if (!bitmap_bit_p (dest->values, VALUE_HANDLE_ID (val)))
00646 bitmap_clear_bit (dest->expressions, i);
00647 }
00648 BITMAP_FREE (temp);
00649 }
00650
00651
00652
00653 static bool
00654 bitmap_set_empty_p (bitmap_set_t set)
00655 {
00656 return bitmap_empty_p (set->values);
00657 }
00658
00659
00660
00661 static void
00662 set_copy (value_set_t dest, value_set_t orig)
00663 {
00664 value_set_node_t node;
00665
00666 if (!orig || !orig->head)
00667 return;
00668
00669 for (node = orig->head;
00670 node;
00671 node = node->next)
00672 {
00673 insert_into_set (dest, node->expr);
00674 }
00675 }
00676
00677
00678
00679 static void
00680 set_remove (value_set_t set, tree expr)
00681 {
00682 value_set_node_t node, prev;
00683
00684
00685
00686 value_remove_from_set_bitmap (set, get_value_handle (expr));
00687 set->length--;
00688 prev = NULL;
00689 for (node = set->head;
00690 node != NULL;
00691 prev = node, node = node->next)
00692 {
00693 if (node->expr == expr)
00694 {
00695 if (prev == NULL)
00696 set->head = node->next;
00697 else
00698 prev->next= node->next;
00699
00700 if (node == set->tail)
00701 set->tail = prev;
00702 pool_free (value_set_node_pool, node);
00703 return;
00704 }
00705 }
00706 }
00707
00708
00709
00710 static bool
00711 set_contains_value (value_set_t set, tree val)
00712 {
00713
00714 if (is_gimple_min_invariant (val))
00715 return true;
00716
00717 if (!set || set->length == 0)
00718 return false;
00719
00720 return value_exists_in_set_bitmap (set, val);
00721 }
00722
00723
00724 static bool
00725 bitmap_set_contains (bitmap_set_t set, tree expr)
00726 {
00727
00728 if (is_gimple_min_invariant (get_value_handle (expr)))
00729 return true;
00730
00731
00732 if (TREE_CODE (expr) != SSA_NAME)
00733 return false;
00734 return bitmap_bit_p (set->expressions, SSA_NAME_VERSION (expr));
00735 }
00736
00737
00738
00739
00740 static bool
00741 bitmap_set_contains_value (bitmap_set_t set, tree val)
00742 {
00743 if (is_gimple_min_invariant (val))
00744 return true;
00745 return bitmap_bit_p (set->values, VALUE_HANDLE_ID (val));
00746 }
00747
00748
00749
00750 static void
00751 bitmap_set_replace_value (bitmap_set_t set, tree lookfor, tree expr)
00752 {
00753 value_set_t exprset;
00754 value_set_node_t node;
00755 if (is_gimple_min_invariant (lookfor))
00756 return;
00757 if (!bitmap_set_contains_value (set, lookfor))
00758 return;
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769 exprset = VALUE_HANDLE_EXPR_SET (lookfor);
00770 for (node = exprset->head; node; node = node->next)
00771 {
00772 if (TREE_CODE (node->expr) == SSA_NAME)
00773 {
00774 if (bitmap_bit_p (set->expressions, SSA_NAME_VERSION (node->expr)))
00775 {
00776 bitmap_clear_bit (set->expressions, SSA_NAME_VERSION (node->expr));
00777 bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
00778 return;
00779 }
00780 }
00781 }
00782 }
00783
00784
00785
00786 static value_set_t
00787 bitmap_set_subtract_from_value_set (value_set_t a, bitmap_set_t b,
00788 bool indexed)
00789 {
00790 value_set_t ret = set_new (indexed);
00791 value_set_node_t node;
00792 for (node = a->head;
00793 node;
00794 node = node->next)
00795 {
00796 if (!bitmap_set_contains (b, node->expr))
00797 insert_into_set (ret, node->expr);
00798 }
00799 return ret;
00800 }
00801
00802
00803
00804 static bool
00805 set_equal (value_set_t a, value_set_t b)
00806 {
00807 value_set_node_t node;
00808
00809 if (a->length != b->length)
00810 return false;
00811 for (node = a->head;
00812 node;
00813 node = node->next)
00814 {
00815 if (!set_contains_value (b, get_value_handle (node->expr)))
00816 return false;
00817 }
00818 return true;
00819 }
00820
00821
00822
00823
00824 static void
00825 bitmap_value_replace_in_set (bitmap_set_t set, tree expr)
00826 {
00827 tree val = get_value_handle (expr);
00828 if (bitmap_set_contains_value (set, val))
00829 bitmap_set_replace_value (set, val, expr);
00830 else
00831 bitmap_insert_into_set (set, expr);
00832 }
00833
00834
00835
00836
00837 static void
00838 bitmap_value_insert_into_set (bitmap_set_t set, tree expr)
00839 {
00840 tree val = get_value_handle (expr);
00841
00842 if (is_gimple_min_invariant (val))
00843 return;
00844
00845 if (!bitmap_set_contains_value (set, val))
00846 bitmap_insert_into_set (set, expr);
00847 }
00848
00849
00850
00851 static void
00852 value_insert_into_set (value_set_t set, tree expr)
00853 {
00854 tree val = get_value_handle (expr);
00855
00856
00857
00858 if (is_gimple_min_invariant (val))
00859 return;
00860
00861 if (!set_contains_value (set, val))
00862 insert_into_set (set, expr);
00863 }
00864
00865
00866
00867
00868 static void
00869 bitmap_print_value_set (FILE *outfile, bitmap_set_t set,
00870 const char *setname, int blockindex)
00871 {
00872 fprintf (outfile, "%s[%d] := { ", setname, blockindex);
00873 if (set)
00874 {
00875 bool first = true;
00876 unsigned i;
00877 bitmap_iterator bi;
00878
00879 EXECUTE_IF_SET_IN_BITMAP (set->expressions, 0, i, bi)
00880 {
00881 if (!first)
00882 fprintf (outfile, ", ");
00883 first = false;
00884 print_generic_expr (outfile, ssa_name (i), 0);
00885
00886 fprintf (outfile, " (");
00887 print_generic_expr (outfile, get_value_handle (ssa_name (i)), 0);
00888 fprintf (outfile, ") ");
00889 }
00890 }
00891 fprintf (outfile, " }\n");
00892 }
00893
00894
00895 static void
00896 print_value_set (FILE *outfile, value_set_t set,
00897 const char *setname, int blockindex)
00898 {
00899 value_set_node_t node;
00900 fprintf (outfile, "%s[%d] := { ", setname, blockindex);
00901 if (set)
00902 {
00903 for (node = set->head;
00904 node;
00905 node = node->next)
00906 {
00907 print_generic_expr (outfile, node->expr, 0);
00908
00909 fprintf (outfile, " (");
00910 print_generic_expr (outfile, get_value_handle (node->expr), 0);
00911 fprintf (outfile, ") ");
00912
00913 if (node->next)
00914 fprintf (outfile, ", ");
00915 }
00916 }
00917
00918 fprintf (outfile, " }\n");
00919 }
00920
00921
00922
00923 void
00924 print_value_expressions (FILE *outfile, tree val)
00925 {
00926 if (VALUE_HANDLE_EXPR_SET (val))
00927 {
00928 char s[10];
00929 sprintf (s, "VH.%04d", VALUE_HANDLE_ID (val));
00930 print_value_set (outfile, VALUE_HANDLE_EXPR_SET (val), s, 0);
00931 }
00932 }
00933
00934
00935 void
00936 debug_value_expressions (tree val)
00937 {
00938 print_value_expressions (stderr, val);
00939 }
00940
00941
00942 void debug_value_set (value_set_t, const char *, int);
00943
00944 void
00945 debug_value_set (value_set_t set, const char *setname, int blockindex)
00946 {
00947 print_value_set (stderr, set, setname, blockindex);
00948 }
00949
00950
00951
00952
00953 static tree
00954 fully_constant_expression (tree t)
00955 {
00956 tree folded;
00957 folded = fold (t);
00958 if (folded && is_gimple_min_invariant (folded))
00959 return folded;
00960 return t;
00961 }
00962
00963
00964
00965
00966
00967 static tree
00968 pool_copy_list (tree list)
00969 {
00970 tree head;
00971 tree prev, next;
00972
00973 if (list == 0)
00974 return 0;
00975 head = (tree) pool_alloc (list_node_pool);
00976
00977 memcpy (head, list, tree_size (list));
00978 prev = head;
00979
00980 next = TREE_CHAIN (list);
00981 while (next)
00982 {
00983 TREE_CHAIN (prev) = (tree) pool_alloc (list_node_pool);
00984 memcpy (TREE_CHAIN (prev), next, tree_size (next));
00985 prev = TREE_CHAIN (prev);
00986 next = TREE_CHAIN (next);
00987 }
00988 return head;
00989 }
00990
00991
00992
00993
00994 static VEC(tree, gc) *
00995 translate_vuses_through_block (VEC (tree, gc) *vuses, basic_block block)
00996 {
00997 tree oldvuse;
00998 VEC(tree, gc) *result = NULL;
00999 int i;
01000
01001 for (i = 0; VEC_iterate (tree, vuses, i, oldvuse); i++)
01002 {
01003 tree phi = SSA_NAME_DEF_STMT (oldvuse);
01004 if (TREE_CODE (phi) == PHI_NODE)
01005 {
01006 edge e = find_edge (block, bb_for_stmt (phi));
01007 if (e)
01008 {
01009 tree def = PHI_ARG_DEF (phi, e->dest_idx);
01010 if (def != oldvuse)
01011 {
01012 if (!result)
01013 result = VEC_copy (tree, gc, vuses);
01014 VEC_replace (tree, result, i, def);
01015 }
01016 }
01017 }
01018 }
01019 if (result)
01020 {
01021 sort_vuses (result);
01022 return result;
01023 }
01024 return vuses;
01025
01026 }
01027
01028
01029
01030
01031 static tree
01032 phi_translate (tree expr, value_set_t set, basic_block pred,
01033 basic_block phiblock)
01034 {
01035 tree phitrans = NULL;
01036 tree oldexpr = expr;
01037 if (expr == NULL)
01038 return NULL;
01039
01040 if (is_gimple_min_invariant (expr))
01041 return expr;
01042
01043
01044 if (EXPR_P (expr))
01045 {
01046 tree vh;
01047
01048 vh = get_value_handle (expr);
01049 if (vh && TREE_CODE (vh) == VALUE_HANDLE)
01050 phitrans = phi_trans_lookup (expr, pred, VALUE_HANDLE_VUSES (vh));
01051 else
01052 phitrans = phi_trans_lookup (expr, pred, NULL);
01053 }
01054 else
01055 phitrans = phi_trans_lookup (expr, pred, NULL);
01056
01057 if (phitrans)
01058 return phitrans;
01059
01060 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
01061 {
01062 case tcc_expression:
01063 {
01064 if (TREE_CODE (expr) != CALL_EXPR)
01065 return NULL;
01066 else
01067 {
01068 tree oldop0 = TREE_OPERAND (expr, 0);
01069 tree oldarglist = TREE_OPERAND (expr, 1);
01070 tree oldop2 = TREE_OPERAND (expr, 2);
01071 tree newop0;
01072 tree newarglist;
01073 tree newop2 = NULL;
01074 tree oldwalker;
01075 tree newwalker;
01076 tree newexpr;
01077 tree vh = get_value_handle (expr);
01078 bool listchanged = false;
01079 VEC (tree, gc) *vuses = VALUE_HANDLE_VUSES (vh);
01080 VEC (tree, gc) *tvuses;
01081
01082
01083
01084
01085
01086
01087
01088
01089 newop0 = phi_translate (find_leader (set, oldop0),
01090 set, pred, phiblock);
01091 if (newop0 == NULL)
01092 return NULL;
01093 if (oldop2)
01094 {
01095 newop2 = phi_translate (find_leader (set, oldop2),
01096 set, pred, phiblock);
01097 if (newop2 == NULL)
01098 return NULL;
01099 }
01100
01101
01102
01103
01104
01105
01106
01107 newarglist = pool_copy_list (oldarglist);
01108 for (oldwalker = oldarglist, newwalker = newarglist;
01109 oldwalker && newwalker;
01110 oldwalker = TREE_CHAIN (oldwalker),
01111 newwalker = TREE_CHAIN (newwalker))
01112 {
01113
01114 tree oldval = TREE_VALUE (oldwalker);
01115 tree newval;
01116 if (oldval)
01117 {
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128 if (AGGREGATE_TYPE_P (TREE_TYPE (oldval)))
01129 return NULL;
01130 newval = phi_translate (find_leader (set, oldval),
01131 set, pred, phiblock);
01132 if (newval == NULL)
01133 return NULL;
01134 if (newval != oldval)
01135 {
01136 listchanged = true;
01137 TREE_VALUE (newwalker) = get_value_handle (newval);
01138 }
01139 }
01140 }
01141 if (listchanged)
01142 vn_lookup_or_add (newarglist, NULL);
01143
01144 tvuses = translate_vuses_through_block (vuses, pred);
01145
01146 if (listchanged || (newop0 != oldop0) || (oldop2 != newop2)
01147 || vuses != tvuses)
01148 {
01149 newexpr = (tree) pool_alloc (expression_node_pool);
01150 memcpy (newexpr, expr, tree_size (expr));
01151 TREE_OPERAND (newexpr, 0) = newop0 == oldop0 ? oldop0 : get_value_handle (newop0);
01152 TREE_OPERAND (newexpr, 1) = listchanged ? newarglist : oldarglist;
01153 TREE_OPERAND (newexpr, 2) = newop2 == oldop2 ? oldop2 : get_value_handle (newop2);
01154 newexpr->common.ann = NULL;
01155 vn_lookup_or_add_with_vuses (newexpr, tvuses);
01156 expr = newexpr;
01157 phi_trans_add (oldexpr, newexpr, pred, tvuses);
01158 }
01159 }
01160 }
01161 return expr;
01162
01163 case tcc_declaration:
01164 {
01165 VEC (tree, gc) * oldvuses = NULL;
01166 VEC (tree, gc) * newvuses = NULL;
01167
01168 oldvuses = VALUE_HANDLE_VUSES (get_value_handle (expr));
01169 if (oldvuses)
01170 newvuses = translate_vuses_through_block (oldvuses, pred);
01171
01172 if (oldvuses != newvuses)
01173 vn_lookup_or_add_with_vuses (expr, newvuses);
01174
01175 phi_trans_add (oldexpr, expr, pred, newvuses);
01176 }
01177 return expr;
01178
01179 case tcc_reference:
01180 {
01181 tree oldop0 = TREE_OPERAND (expr, 0);
01182 tree oldop1 = NULL;
01183 tree newop0;
01184 tree newop1 = NULL;
01185 tree oldop2 = NULL;
01186 tree newop2 = NULL;
01187 tree oldop3 = NULL;
01188 tree newop3 = NULL;
01189 tree newexpr;
01190 VEC (tree, gc) * oldvuses = NULL;
01191 VEC (tree, gc) * newvuses = NULL;
01192
01193 if (TREE_CODE (expr) != INDIRECT_REF
01194 && TREE_CODE (expr) != COMPONENT_REF
01195 && TREE_CODE (expr) != ARRAY_REF)
01196 return NULL;
01197
01198 newop0 = phi_translate (find_leader (set, oldop0),
01199 set, pred, phiblock);
01200 if (newop0 == NULL)
01201 return NULL;
01202
01203 if (TREE_CODE (expr) == ARRAY_REF)
01204 {
01205 oldop1 = TREE_OPERAND (expr, 1);
01206 newop1 = phi_translate (find_leader (set, oldop1),
01207 set, pred, phiblock);
01208
01209 if (newop1 == NULL)
01210 return NULL;
01211 oldop2 = TREE_OPERAND (expr, 2);
01212 if (oldop2)
01213 {
01214 newop2 = phi_translate (find_leader (set, oldop2),
01215 set, pred, phiblock);
01216
01217 if (newop2 == NULL)
01218 return NULL;
01219 }
01220 oldop3 = TREE_OPERAND (expr, 3);
01221 if (oldop3)
01222 {
01223 newop3 = phi_translate (find_leader (set, oldop3),
01224 set, pred, phiblock);
01225
01226 if (newop3 == NULL)
01227 return NULL;
01228 }
01229 }
01230
01231 oldvuses = VALUE_HANDLE_VUSES (get_value_handle (expr));
01232 if (oldvuses)
01233 newvuses = translate_vuses_through_block (oldvuses, pred);
01234
01235 if (newop0 != oldop0 || newvuses != oldvuses
01236 || newop1 != oldop1
01237 || newop2 != oldop2
01238 || newop3 != oldop3)
01239 {
01240 tree t;
01241
01242 newexpr = pool_alloc (reference_node_pool);
01243 memcpy (newexpr, expr, tree_size (expr));
01244 TREE_OPERAND (newexpr, 0) = get_value_handle (newop0);
01245 if (TREE_CODE (expr) == ARRAY_REF)
01246 {
01247 TREE_OPERAND (newexpr, 1) = get_value_handle (newop1);
01248 if (newop2)
01249 TREE_OPERAND (newexpr, 2) = get_value_handle (newop2);
01250 if (newop3)
01251 TREE_OPERAND (newexpr, 3) = get_value_handle (newop3);
01252 }
01253
01254 t = fully_constant_expression (newexpr);
01255
01256 if (t != newexpr)
01257 {
01258 pool_free (reference_node_pool, newexpr);
01259 newexpr = t;
01260 }
01261 else
01262 {
01263 newexpr->common.ann = NULL;
01264 vn_lookup_or_add_with_vuses (newexpr, newvuses);
01265 }
01266 expr = newexpr;
01267 phi_trans_add (oldexpr, newexpr, pred, newvuses);
01268 }
01269 }
01270 return expr;
01271 break;
01272
01273 case tcc_binary:
01274 case tcc_comparison:
01275 {
01276 tree oldop1 = TREE_OPERAND (expr, 0);
01277 tree oldop2 = TREE_OPERAND (expr, 1);
01278 tree newop1;
01279 tree newop2;
01280 tree newexpr;
01281
01282 newop1 = phi_translate (find_leader (set, oldop1),
01283 set, pred, phiblock);
01284 if (newop1 == NULL)
01285 return NULL;
01286 newop2 = phi_translate (find_leader (set, oldop2),
01287 set, pred, phiblock);
01288 if (newop2 == NULL)
01289 return NULL;
01290 if (newop1 != oldop1 || newop2 != oldop2)
01291 {
01292 tree t;
01293 newexpr = (tree) pool_alloc (binary_node_pool);
01294 memcpy (newexpr, expr, tree_size (expr));
01295 TREE_OPERAND (newexpr, 0) = newop1 == oldop1 ? oldop1 : get_value_handle (newop1);
01296 TREE_OPERAND (newexpr, 1) = newop2 == oldop2 ? oldop2 : get_value_handle (newop2);
01297 t = fully_constant_expression (newexpr);
01298 if (t != newexpr)
01299 {
01300 pool_free (binary_node_pool, newexpr);
01301 newexpr = t;
01302 }
01303 else
01304 {
01305 newexpr->common.ann = NULL;
01306 vn_lookup_or_add (newexpr, NULL);
01307 }
01308 expr = newexpr;
01309 phi_trans_add (oldexpr, newexpr, pred, NULL);
01310 }
01311 }
01312 return expr;
01313
01314 case tcc_unary:
01315 {
01316 tree oldop1 = TREE_OPERAND (expr, 0);
01317 tree newop1;
01318 tree newexpr;
01319
01320 newop1 = phi_translate (find_leader (set, oldop1),
01321 set, pred, phiblock);
01322 if (newop1 == NULL)
01323 return NULL;
01324 if (newop1 != oldop1)
01325 {
01326 tree t;
01327 newexpr = (tree) pool_alloc (unary_node_pool);
01328 memcpy (newexpr, expr, tree_size (expr));
01329 TREE_OPERAND (newexpr, 0) = get_value_handle (newop1);
01330 t = fully_constant_expression (newexpr);
01331 if (t != newexpr)
01332 {
01333 pool_free (unary_node_pool, newexpr);
01334 newexpr = t;
01335 }
01336 else
01337 {
01338 newexpr->common.ann = NULL;
01339 vn_lookup_or_add (newexpr, NULL);
01340 }
01341 expr = newexpr;
01342 phi_trans_add (oldexpr, newexpr, pred, NULL);
01343 }
01344 }
01345 return expr;
01346
01347 case tcc_exceptional:
01348 {
01349 tree phi = NULL;
01350 edge e;
01351 gcc_assert (TREE_CODE (expr) == SSA_NAME);
01352 if (TREE_CODE (SSA_NAME_DEF_STMT (expr)) == PHI_NODE)
01353 phi = SSA_NAME_DEF_STMT (expr);
01354 else
01355 return expr;
01356
01357 e = find_edge (pred, bb_for_stmt (phi));
01358 if (e)
01359 {
01360 if (is_undefined_value (PHI_ARG_DEF (phi, e->dest_idx)))
01361 return NULL;
01362 vn_lookup_or_add (PHI_ARG_DEF (phi, e->dest_idx), NULL);
01363 return PHI_ARG_DEF (phi, e->dest_idx);
01364 }
01365 }
01366 return expr;
01367
01368 default:
01369 gcc_unreachable ();
01370 }
01371 }
01372
01373
01374
01375
01376
01377 static void
01378 phi_translate_set (value_set_t dest, value_set_t set, basic_block pred,
01379 basic_block phiblock)
01380 {
01381 value_set_node_t node;
01382 for (node = set->head;
01383 node;
01384 node = node->next)
01385 {
01386 tree translated;
01387
01388 translated = phi_translate (node->expr, set, pred, phiblock);
01389
01390
01391
01392 if (translated && !is_gimple_min_invariant (translated))
01393 {
01394 tree vh = get_value_handle (translated);
01395 VEC (tree, gc) *vuses;
01396
01397
01398
01399 vuses = !is_gimple_min_invariant (vh)
01400 ? VALUE_HANDLE_VUSES (vh) : NULL;
01401 phi_trans_add (node->expr, translated, pred, vuses);
01402 }
01403
01404 if (translated != NULL)
01405 value_insert_into_set (dest, translated);
01406 }
01407 }
01408
01409
01410
01411
01412
01413 static tree
01414 bitmap_find_leader (bitmap_set_t set, tree val)
01415 {
01416 if (val == NULL)
01417 return NULL;
01418
01419 if (is_gimple_min_invariant (val))
01420 return val;
01421 if (bitmap_set_contains_value (set, val))
01422 {
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434 value_set_t exprset;
01435 value_set_node_t node;
01436 exprset = VALUE_HANDLE_EXPR_SET (val);
01437 for (node = exprset->head; node; node = node->next)
01438 {
01439 if (TREE_CODE (node->expr) == SSA_NAME)
01440 {
01441 if (bitmap_bit_p (set->expressions,
01442 SSA_NAME_VERSION (node->expr)))
01443 return node->expr;
01444 }
01445 }
01446 }
01447 return NULL;
01448 }
01449
01450
01451
01452
01453
01454
01455 static tree
01456 find_leader (value_set_t set, tree val)
01457 {
01458 value_set_node_t node;
01459
01460 if (val == NULL)
01461 return NULL;
01462
01463
01464 if (is_gimple_min_invariant (val))
01465 return val;
01466
01467 if (set->length == 0)
01468 return NULL;
01469
01470 if (value_exists_in_set_bitmap (set, val))
01471 {
01472 for (node = set->head;
01473 node;
01474 node = node->next)
01475 {
01476 if (get_value_handle (node->expr) == val)
01477 return node->expr;
01478 }
01479 }
01480
01481 return NULL;
01482 }
01483
01484
01485
01486
01487
01488 static bitmap
01489 get_representative (bitmap *map, int id)
01490 {
01491 if (map[id] != NULL)
01492 return map[id];
01493 return NULL;
01494 }
01495
01496
01497
01498
01499
01500
01501 static bool
01502 vuses_dies_in_block_x (VEC (tree, gc) *vuses, basic_block block)
01503 {
01504 int i;
01505 tree vuse;
01506
01507 for (i = 0; VEC_iterate (tree, vuses, i, vuse); i++)
01508 {
01509
01510
01511
01512 if (!bitmap_bit_p (RVUSE_IN (block), SSA_NAME_VERSION (vuse))
01513 || bitmap_bit_p (RVUSE_KILL (block), SSA_NAME_VERSION (vuse)))
01514 return true;
01515 }
01516 return false;
01517 }
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528 static bool
01529 valid_in_set (value_set_t set, tree expr, basic_block block)
01530 {
01531 tree vh = get_value_handle (expr);
01532 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
01533 {
01534 case tcc_binary:
01535 case tcc_comparison:
01536 {
01537 tree op1 = TREE_OPERAND (expr, 0);
01538 tree op2 = TREE_OPERAND (expr, 1);
01539 return set_contains_value (set, op1) && set_contains_value (set, op2);
01540 }
01541
01542 case tcc_unary:
01543 {
01544 tree op1 = TREE_OPERAND (expr, 0);
01545 return set_contains_value (set, op1);
01546 }
01547
01548 case tcc_expression:
01549 {
01550 if (TREE_CODE (expr) == CALL_EXPR)
01551 {
01552 tree op0 = TREE_OPERAND (expr, 0);
01553 tree arglist = TREE_OPERAND (expr, 1);
01554 tree op2 = TREE_OPERAND (expr, 2);
01555
01556
01557 if (!set_contains_value (set, op0)
01558 || (op2 && !set_contains_value (set, op2)))
01559 return false;
01560
01561
01562 for (; arglist; arglist = TREE_CHAIN (arglist))
01563 {
01564 if (!set_contains_value (set, TREE_VALUE (arglist)))
01565 return false;
01566 }
01567 return !vuses_dies_in_block_x (VALUE_HANDLE_VUSES (vh), block);
01568 }
01569 return false;
01570 }
01571
01572 case tcc_reference:
01573 {
01574 if (TREE_CODE (expr) == INDIRECT_REF
01575 || TREE_CODE (expr) == COMPONENT_REF
01576 || TREE_CODE (expr) == ARRAY_REF)
01577 {
01578 tree op0 = TREE_OPERAND (expr, 0);
01579 gcc_assert (is_gimple_min_invariant (op0)
01580 || TREE_CODE (op0) == VALUE_HANDLE);
01581 if (!set_contains_value (set, op0))
01582 return false;
01583 if (TREE_CODE (expr) == ARRAY_REF)
01584 {
01585 tree op1 = TREE_OPERAND (expr, 1);
01586 tree op2 = TREE_OPERAND (expr, 2);
01587 tree op3 = TREE_OPERAND (expr, 3);
01588 gcc_assert (is_gimple_min_invariant (op1)
01589 || TREE_CODE (op1) == VALUE_HANDLE);
01590 if (!set_contains_value (set, op1))
01591 return false;
01592 gcc_assert (!op2 || is_gimple_min_invariant (op2)
01593 || TREE_CODE (op2) == VALUE_HANDLE);
01594 if (op2
01595 && !set_contains_value (set, op2))
01596 return false;
01597 gcc_assert (!op3 || is_gimple_min_invariant (op3)
01598 || TREE_CODE (op3) == VALUE_HANDLE);
01599 if (op3
01600 && !set_contains_value (set, op3))
01601 return false;
01602 }
01603 return set_contains_value (ANTIC_SAFE_LOADS (block),
01604 vh)
01605 || !vuses_dies_in_block_x (VALUE_HANDLE_VUSES (vh),
01606 block);
01607 }
01608 }
01609 return false;
01610
01611 case tcc_exceptional:
01612 gcc_assert (TREE_CODE (expr) == SSA_NAME);
01613 return true;
01614
01615 case tcc_declaration:
01616 return !vuses_dies_in_block_x (VALUE_HANDLE_VUSES (vh), block);
01617
01618 default:
01619
01620 gcc_unreachable ();
01621 }
01622 }
01623
01624
01625
01626
01627
01628 static void
01629 clean (value_set_t set, basic_block block)
01630 {
01631 value_set_node_t node;
01632 value_set_node_t next;
01633 node = set->head;
01634 while (node)
01635 {
01636 next = node->next;
01637 if (!valid_in_set (set, node->expr, block))
01638 set_remove (set, node->expr);
01639 node = next;
01640 }
01641 }
01642
01643 static sbitmap has_abnormal_preds;
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659 static bool
01660 compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
01661 {
01662 basic_block son;
01663 bool changed = false;
01664 value_set_t S, old, ANTIC_OUT;
01665 value_set_node_t node;
01666
01667 ANTIC_OUT = S = NULL;
01668
01669
01670
01671 if (block_has_abnormal_pred_edge)
01672 goto maybe_dump_sets;
01673
01674 old = set_new (false);
01675 set_copy (old, ANTIC_IN (block));
01676 ANTIC_OUT = set_new (true);
01677
01678
01679 if (EDGE_COUNT (block->succs) == 0)
01680 ;
01681
01682
01683 else if (single_succ_p (block))
01684 {
01685 phi_translate_set (ANTIC_OUT, ANTIC_IN (single_succ (block)),
01686 block, single_succ (block));
01687 }
01688
01689
01690 else
01691 {
01692 VEC(basic_block, heap) * worklist;
01693 edge e;
01694 size_t i;
01695 basic_block bprime, first;
01696 edge_iterator ei;
01697
01698 worklist = VEC_alloc (basic_block, heap, EDGE_COUNT (block->succs));
01699 FOR_EACH_EDGE (e, ei, block->succs)
01700 VEC_quick_push (basic_block, worklist, e->dest);
01701 first = VEC_index (basic_block, worklist, 0);
01702 set_copy (ANTIC_OUT, ANTIC_IN (first));
01703
01704 for (i = 1; VEC_iterate (basic_block, worklist, i, bprime); i++)
01705 {
01706 node = ANTIC_OUT->head;
01707 while (node)
01708 {
01709 tree val;
01710 value_set_node_t next = node->next;
01711
01712 val = get_value_handle (node->expr);
01713 if (!set_contains_value (ANTIC_IN (bprime), val))
01714 set_remove (ANTIC_OUT, node->expr);
01715 node = next;
01716 }
01717 }
01718 VEC_free (basic_block, heap, worklist);
01719 }
01720
01721
01722 S = bitmap_set_subtract_from_value_set (ANTIC_OUT, TMP_GEN (block), false);
01723
01724
01725 ANTIC_IN (block) = bitmap_set_subtract_from_value_set (EXP_GEN (block),
01726 TMP_GEN (block),
01727 true);
01728
01729
01730
01731 for (node = S->head; node; node = node->next)
01732 value_insert_into_set (ANTIC_IN (block), node->expr);
01733
01734 clean (ANTIC_IN (block), block);
01735 if (!set_equal (old, ANTIC_IN (block)))
01736 changed = true;
01737
01738 maybe_dump_sets:
01739 if (dump_file && (dump_flags & TDF_DETAILS))
01740 {
01741 if (ANTIC_OUT)
01742 print_value_set (dump_file, ANTIC_OUT, "ANTIC_OUT", block->index);
01743
01744 if (ANTIC_SAFE_LOADS (block))
01745 print_value_set (dump_file, ANTIC_SAFE_LOADS (block),
01746 "ANTIC_SAFE_LOADS", block->index);
01747 print_value_set (dump_file, ANTIC_IN (block), "ANTIC_IN", block->index);
01748
01749 if (S)
01750 print_value_set (dump_file, S, "S", block->index);
01751 }
01752
01753 for (son = first_dom_son (CDI_POST_DOMINATORS, block);
01754 son;
01755 son = next_dom_son (CDI_POST_DOMINATORS, son))
01756 {
01757 changed |= compute_antic_aux (son,
01758 TEST_BIT (has_abnormal_preds, son->index));
01759 }
01760 return changed;
01761 }
01762
01763
01764
01765 static void
01766 compute_antic (void)
01767 {
01768 bool changed = true;
01769 int num_iterations = 0;
01770 basic_block block;
01771
01772
01773
01774 has_abnormal_preds = sbitmap_alloc (last_basic_block);
01775 sbitmap_zero (has_abnormal_preds);
01776 FOR_EACH_BB (block)
01777 {
01778 edge_iterator ei;
01779 edge e;
01780
01781 FOR_EACH_EDGE (e, ei, block->preds)
01782 if (e->flags & EDGE_ABNORMAL)
01783 {
01784 SET_BIT (has_abnormal_preds, block->index);
01785 break;
01786 }
01787
01788
01789 ANTIC_IN (block) = set_new (true);
01790 }
01791
01792 ANTIC_IN (EXIT_BLOCK_PTR) = set_new (true);
01793
01794 while (changed)
01795 {
01796 num_iterations++;
01797 changed = false;
01798 changed = compute_antic_aux (EXIT_BLOCK_PTR, false);
01799 }
01800
01801 sbitmap_free (has_abnormal_preds);
01802
01803 if (dump_file && (dump_flags & TDF_STATS))
01804 fprintf (dump_file, "compute_antic required %d iterations\n", num_iterations);
01805 }
01806
01807
01808 static void
01809 dump_bitmap_of_names (FILE *out, bitmap names)
01810 {
01811 bitmap_iterator bi;
01812 unsigned int i;
01813
01814 fprintf (out, " { ");
01815 EXECUTE_IF_SET_IN_BITMAP (names, 0, i, bi)
01816 {
01817 print_generic_expr (out, ssa_name (i), 0);
01818 fprintf (out, " ");
01819 }
01820 fprintf (out, "}\n");
01821 }
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831 static bitmap *vuse_names;
01832 static void
01833 compute_vuse_representatives (void)
01834 {
01835 tree phi;
01836 basic_block bb;
01837 VEC (tree, heap) *phis = NULL;
01838 bool changed = true;
01839 size_t i;
01840
01841 FOR_EACH_BB (bb)
01842 {
01843 for (phi = phi_nodes (bb);
01844 phi;
01845 phi = PHI_CHAIN (phi))
01846 if (!is_gimple_reg (PHI_RESULT (phi)))
01847 VEC_safe_push (tree, heap, phis, phi);
01848 }
01849
01850 while (changed)
01851 {
01852 changed = false;
01853
01854 for (i = 0; VEC_iterate (tree, phis, i, phi); i++)
01855 {
01856 size_t ver = SSA_NAME_VERSION (PHI_RESULT (phi));
01857 use_operand_p usep;
01858 ssa_op_iter iter;
01859
01860 if (vuse_names[ver] == NULL)
01861 {
01862 vuse_names[ver] = BITMAP_ALLOC (&grand_bitmap_obstack);
01863 bitmap_set_bit (vuse_names[ver], ver);
01864 }
01865 FOR_EACH_PHI_ARG (usep, phi, iter, SSA_OP_ALL_USES)
01866 {
01867 tree use = USE_FROM_PTR (usep);
01868 bitmap usebitmap = get_representative (vuse_names,
01869 SSA_NAME_VERSION (use));
01870 if (usebitmap != NULL)
01871 {
01872 changed |= bitmap_ior_into (vuse_names[ver],
01873 usebitmap);
01874 }
01875 else
01876 {
01877 changed |= !bitmap_bit_p (vuse_names[ver],
01878 SSA_NAME_VERSION (use));
01879 if (changed)
01880 bitmap_set_bit (vuse_names[ver],
01881 SSA_NAME_VERSION (use));
01882 }
01883 }
01884 }
01885 }
01886
01887 if (dump_file && (dump_flags & TDF_DETAILS))
01888 for (i = 0; VEC_iterate (tree, phis, i, phi); i++)
01889 {
01890 bitmap reps = get_representative (vuse_names,
01891 SSA_NAME_VERSION (PHI_RESULT (phi)));
01892 if (reps)
01893 {
01894 print_generic_expr (dump_file, PHI_RESULT (phi), 0);
01895 fprintf (dump_file, " represents ");
01896 dump_bitmap_of_names (dump_file, reps);
01897 }
01898 }
01899 VEC_free (tree, heap, phis);
01900 }
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931 static void
01932 compute_rvuse_and_antic_safe (void)
01933 {
01934
01935 size_t i;
01936 tree phi;
01937 basic_block bb;
01938 int *postorder;
01939 bool changed = true;
01940 unsigned int *first_store_uid;
01941
01942 first_store_uid = xcalloc (n_basic_blocks, sizeof (unsigned int));
01943
01944 compute_vuse_representatives ();
01945
01946 FOR_ALL_BB (bb)
01947 {
01948 RVUSE_IN (bb) = BITMAP_ALLOC (&grand_bitmap_obstack);
01949 RVUSE_GEN (bb) = BITMAP_ALLOC (&grand_bitmap_obstack);
01950 RVUSE_KILL (bb) = BITMAP_ALLOC (&grand_bitmap_obstack);
01951 RVUSE_OUT (bb) = BITMAP_ALLOC (&grand_bitmap_obstack);
01952 ANTIC_SAFE_LOADS (bb) = NULL;
01953 }
01954
01955
01956 for (i = 0; i < num_ssa_names; i++)
01957 {
01958 tree name = ssa_name (i);
01959 if (name && !is_gimple_reg (name)
01960 && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (name)))
01961 bitmap_set_bit (RVUSE_OUT (ENTRY_BLOCK_PTR),
01962 SSA_NAME_VERSION (name));
01963 }
01964
01965
01966
01967
01968
01969
01970 FOR_EACH_BB (bb)
01971 {
01972 block_stmt_iterator bsi;
01973 ssa_op_iter iter;
01974 def_operand_p defp;
01975 use_operand_p usep;
01976
01977 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
01978 {
01979 tree stmt = bsi_stmt (bsi);
01980
01981 if (first_store_uid[bb->index] == 0
01982 && !ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYUSE | SSA_OP_VMAYDEF
01983 | SSA_OP_VMUSTDEF | SSA_OP_VMUSTKILL))
01984 {
01985 first_store_uid[bb->index] = stmt_ann (stmt)->uid;
01986 }
01987
01988
01989 FOR_EACH_SSA_USE_OPERAND (usep, stmt, iter, SSA_OP_VIRTUAL_KILLS
01990 | SSA_OP_VMAYUSE)
01991 {
01992 tree use = USE_FROM_PTR (usep);
01993 bitmap repbit = get_representative (vuse_names,
01994 SSA_NAME_VERSION (use));
01995 if (repbit != NULL)
01996 {
01997 bitmap_and_compl_into (RVUSE_GEN (bb), repbit);
01998 bitmap_ior_into (RVUSE_KILL (bb), repbit);
01999 }
02000 else
02001 {
02002 bitmap_set_bit (RVUSE_KILL (bb), SSA_NAME_VERSION (use));
02003 bitmap_clear_bit (RVUSE_GEN (bb), SSA_NAME_VERSION (use));
02004 }
02005 }
02006 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_VIRTUAL_DEFS)
02007 {
02008 tree def = DEF_FROM_PTR (defp);
02009 bitmap_set_bit (RVUSE_GEN (bb), SSA_NAME_VERSION (def));
02010 }
02011 }
02012 }
02013
02014 FOR_EACH_BB (bb)
02015 {
02016 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
02017 {
02018 if (!is_gimple_reg (PHI_RESULT (phi)))
02019 {
02020 edge e;
02021 edge_iterator ei;
02022
02023 tree def = PHI_RESULT (phi);
02024
02025
02026
02027
02028 FOR_EACH_EDGE (e, ei, bb->preds)
02029 bitmap_set_bit (RVUSE_GEN (e->src), SSA_NAME_VERSION (def));
02030 }
02031 }
02032 }
02033
02034
02035
02036
02037
02038
02039 postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
02040 pre_and_rev_post_order_compute (NULL, postorder, false);
02041
02042 changed = true;
02043 while (changed)
02044 {
02045 int j;
02046 changed = false;
02047 for (j = 0; j < n_basic_blocks - NUM_FIXED_BLOCKS; j++)
02048 {
02049 edge e;
02050 edge_iterator ei;
02051 bb = BASIC_BLOCK (postorder[j]);
02052
02053 FOR_EACH_EDGE (e, ei, bb->preds)
02054 bitmap_ior_into (RVUSE_IN (bb), RVUSE_OUT (e->src));
02055
02056 changed |= bitmap_ior_and_compl (RVUSE_OUT (bb),
02057 RVUSE_GEN (bb),
02058 RVUSE_IN (bb),
02059 RVUSE_KILL (bb));
02060 }
02061 }
02062 free (postorder);
02063
02064 if (dump_file && (dump_flags & TDF_DETAILS))
02065 {
02066 FOR_ALL_BB (bb)
02067 {
02068 fprintf (dump_file, "RVUSE_IN (%d) =", bb->index);
02069 dump_bitmap_of_names (dump_file, RVUSE_IN (bb));
02070
02071 fprintf (dump_file, "RVUSE_KILL (%d) =", bb->index);
02072 dump_bitmap_of_names (dump_file, RVUSE_KILL (bb));
02073
02074 fprintf (dump_file, "RVUSE_GEN (%d) =", bb->index);
02075 dump_bitmap_of_names (dump_file, RVUSE_GEN (bb));
02076
02077 fprintf (dump_file, "RVUSE_OUT (%d) =", bb->index);
02078 dump_bitmap_of_names (dump_file, RVUSE_OUT (bb));
02079 }
02080 }
02081
02082 FOR_EACH_BB (bb)
02083 {
02084 value_set_node_t node;
02085 if (bitmap_empty_p (RVUSE_KILL (bb)))
02086 continue;
02087
02088 for (node = EXP_GEN (bb)->head; node; node = node->next)
02089 {
02090 if (REFERENCE_CLASS_P (node->expr))
02091 {
02092 tree vh = get_value_handle (node->expr);
02093 tree maybe = bitmap_find_leader (AVAIL_OUT (bb), vh);
02094
02095 if (maybe)
02096 {
02097 tree def = SSA_NAME_DEF_STMT (maybe);
02098
02099 if (bb_for_stmt (def) != bb)
02100 continue;
02101
02102 if (TREE_CODE (def) == PHI_NODE
02103 || stmt_ann (def)->uid < first_store_uid[bb->index])
02104 {
02105 if (ANTIC_SAFE_LOADS (bb) == NULL)
02106 ANTIC_SAFE_LOADS (bb) = set_new (true);
02107 value_insert_into_set (ANTIC_SAFE_LOADS (bb),
02108 node->expr);
02109 }
02110 }
02111 }
02112 }
02113 }
02114 free (first_store_uid);
02115 }
02116
02117
02118
02119
02120 static bool
02121 can_value_number_call (tree stmt)
02122 {
02123 tree call = get_call_expr_in (stmt);
02124
02125 if (call_expr_flags (call) & (ECF_PURE | ECF_CONST))
02126 return true;
02127 return false;
02128 }
02129
02130
02131
02132
02133 static bool
02134 can_value_number_operation (tree op)
02135 {
02136 return UNARY_CLASS_P (op)
02137 || BINARY_CLASS_P (op)
02138 || COMPARISON_CLASS_P (op)
02139 || REFERENCE_CLASS_P (op)
02140 || (TREE_CODE (op) == CALL_EXPR
02141 && can_value_number_call (op));
02142 }
02143
02144
02145
02146
02147
02148
02149 static bool
02150 can_PRE_operation (tree op)
02151 {
02152 return UNARY_CLASS_P (op)
02153 || BINARY_CLASS_P (op)
02154 || COMPARISON_CLASS_P (op)
02155 || TREE_CODE (op) == INDIRECT_REF
02156 || TREE_CODE (op) == COMPONENT_REF
02157 || TREE_CODE (op) == CALL_EXPR
02158 || TREE_CODE (op) == ARRAY_REF;
02159 }
02160
02161
02162
02163
02164
02165 static VEC(tree,heap) *inserted_exprs;
02166
02167
02168
02169
02170 static VEC(tree, heap) *need_creation;
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185 static tree
02186 create_component_ref_by_pieces (basic_block block, tree expr, tree stmts)
02187 {
02188 tree genop = expr;
02189 tree folded;
02190
02191 if (TREE_CODE (genop) == VALUE_HANDLE)
02192 {
02193 tree found = bitmap_find_leader (AVAIL_OUT (block), expr);
02194 if (found)
02195 return found;
02196 }
02197
02198 if (TREE_CODE (genop) == VALUE_HANDLE)
02199 genop = VALUE_HANDLE_EXPR_SET (expr)->head->expr;
02200
02201 switch TREE_CODE (genop)
02202 {
02203 case ARRAY_REF:
02204 {
02205 tree op0;
02206 tree op1, op2, op3;
02207 op0 = create_component_ref_by_pieces (block,
02208 TREE_OPERAND (genop, 0),
02209 stmts);
02210 op1 = TREE_OPERAND (genop, 1);
02211 if (TREE_CODE (op1) == VALUE_HANDLE)
02212 op1 = find_or_generate_expression (block, op1, stmts);
02213 op2 = TREE_OPERAND (genop, 2);
02214 if (op2 && TREE_CODE (op2) == VALUE_HANDLE)
02215 op2 = find_or_generate_expression (block, op2, stmts);
02216 op3 = TREE_OPERAND (genop, 3);
02217 if (op3 && TREE_CODE (op3) == VALUE_HANDLE)
02218 op3 = find_or_generate_expression (block, op3, stmts);
02219 folded = build4 (ARRAY_REF, TREE_TYPE (genop), op0, op1,
02220 op2, op3);
02221 return folded;
02222 }
02223 case COMPONENT_REF:
02224 {
02225 tree op0;
02226 tree op1;
02227 op0 = create_component_ref_by_pieces (block,
02228 TREE_OPERAND (genop, 0),
02229 stmts);
02230 op1 = VALUE_HANDLE_EXPR_SET (TREE_OPERAND (genop, 1))->head->expr;
02231 folded = fold_build3 (COMPONENT_REF, TREE_TYPE (genop), op0, op1,
02232 NULL_TREE);
02233 return folded;
02234 }
02235 break;
02236 case INDIRECT_REF:
02237 {
02238 tree op1 = TREE_OPERAND (genop, 0);
02239 tree genop1 = find_or_generate_expression (block, op1, stmts);
02240
02241 folded = fold_build1 (TREE_CODE (genop), TREE_TYPE (genop),
02242 genop1);
02243 return folded;
02244 }
02245 break;
02246 case VAR_DECL:
02247 case PARM_DECL:
02248 case RESULT_DECL:
02249 case SSA_NAME:
02250 case STRING_CST:
02251 return genop;
02252 default:
02253 gcc_unreachable ();
02254 }
02255
02256 return NULL_TREE;
02257 }
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268 static tree
02269 find_or_generate_expression (basic_block block, tree expr, tree stmts)
02270 {
02271 tree genop = bitmap_find_leader (AVAIL_OUT (block), expr);
02272
02273
02274
02275 if (genop == NULL)
02276 {
02277 genop = VALUE_HANDLE_EXPR_SET (expr)->head->expr;
02278
02279 gcc_assert (can_PRE_operation (genop));
02280 genop = create_expression_by_pieces (block, genop, stmts);
02281 }
02282 return genop;
02283 }
02284
02285 #define NECESSARY(stmt) stmt->common.asm_written_flag
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300 static tree
02301 create_expression_by_pieces (basic_block block, tree expr, tree stmts)
02302 {
02303 tree temp, name;
02304 tree folded, forced_stmts, newexpr;
02305 tree v;
02306 tree_stmt_iterator tsi;
02307
02308 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
02309 {
02310 case tcc_expression:
02311 {
02312 tree op0, op2;
02313 tree arglist;
02314 tree genop0, genop2;
02315 tree genarglist;
02316 tree walker, genwalker;
02317
02318 gcc_assert (TREE_CODE (expr) == CALL_EXPR);
02319 genop2 = NULL;
02320
02321 op0 = TREE_OPERAND (expr, 0);
02322 arglist = TREE_OPERAND (expr, 1);
02323 op2 = TREE_OPERAND (expr, 2);
02324
02325 genop0 = find_or_generate_expression (block, op0, stmts);
02326 genarglist = copy_list (arglist);
02327 for (walker = arglist, genwalker = genarglist;
02328 genwalker && walker;
02329 genwalker = TREE_CHAIN (genwalker), walker = TREE_CHAIN (walker))
02330 {
02331 TREE_VALUE (genwalker)
02332 = find_or_generate_expression (block, TREE_VALUE (walker),
02333 stmts);
02334 }
02335
02336 if (op2)
02337 genop2 = find_or_generate_expression (block, op2, stmts);
02338 folded = fold_build3 (TREE_CODE (expr), TREE_TYPE (expr),
02339 genop0, genarglist, genop2);
02340 break;
02341
02342
02343 }
02344 break;
02345 case tcc_reference:
02346 {
02347 if (TREE_CODE (expr) == COMPONENT_REF
02348 || TREE_CODE (expr) == ARRAY_REF)
02349 {
02350 folded = create_component_ref_by_pieces (block, expr, stmts);
02351 }
02352 else
02353 {
02354 tree op1 = TREE_OPERAND (expr, 0);
02355 tree genop1 = find_or_generate_expression (block, op1, stmts);
02356
02357 folded = fold_build1 (TREE_CODE (expr), TREE_TYPE (expr),
02358 genop1);
02359 }
02360 break;
02361 }
02362
02363 case tcc_binary:
02364 case tcc_comparison:
02365 {
02366 tree op1 = TREE_OPERAND (expr, 0);
02367 tree op2 = TREE_OPERAND (expr, 1);
02368 tree genop1 = find_or_generate_expression (block, op1, stmts);
02369 tree genop2 = find_or_generate_expression (block, op2, stmts);
02370 folded = fold_build2 (TREE_CODE (expr), TREE_TYPE (expr),
02371 genop1, genop2);
02372 break;
02373 }
02374
02375 case tcc_unary:
02376 {
02377 tree op1 = TREE_OPERAND (expr, 0);
02378 tree genop1 = find_or_generate_expression (block, op1, stmts);
02379 folded = fold_build1 (TREE_CODE (expr), TREE_TYPE (expr),
02380 genop1);
02381 break;
02382 }
02383
02384 default:
02385 gcc_unreachable ();
02386 }
02387
02388
02389
02390
02391
02392 newexpr = force_gimple_operand (unshare_expr (folded), &forced_stmts,
02393 false, NULL);
02394
02395
02396
02397 if (forced_stmts)
02398 {
02399 tsi = tsi_start (forced_stmts);
02400 for (; !tsi_end_p (tsi); tsi_next (&tsi))
02401 {
02402 tree stmt = tsi_stmt (tsi);
02403 tree forcedname = TREE_OPERAND (stmt, 0);
02404 tree forcedexpr = TREE_OPERAND (stmt, 1);
02405 tree val = vn_lookup_or_add (forcedexpr, NULL);
02406
02407 VEC_safe_push (tree, heap, inserted_exprs, stmt);
02408 vn_add (forcedname, val);
02409 bitmap_value_replace_in_set (NEW_SETS (block), forcedname);
02410 bitmap_value_replace_in_set (AVAIL_OUT (block), forcedname);
02411 mark_new_vars_to_rename (stmt);
02412 }
02413 tsi = tsi_last (stmts);
02414 tsi_link_after (&tsi, forced_stmts, TSI_CONTINUE_LINKING);
02415 }
02416
02417
02418
02419 if (!pretemp || TREE_TYPE (expr) != TREE_TYPE (pretemp))
02420 {
02421 pretemp = create_tmp_var (TREE_TYPE (expr), "pretmp");
02422 get_var_ann (pretemp);
02423 }
02424
02425 temp = pretemp;
02426 add_referenced_var (temp);
02427
02428 if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
02429 DECL_COMPLEX_GIMPLE_REG_P (temp) = 1;
02430
02431 newexpr = build2 (MODIFY_EXPR, TREE_TYPE (expr), temp, newexpr);
02432 name = make_ssa_name (temp, newexpr);
02433 TREE_OPERAND (newexpr, 0) = name;
02434 NECESSARY (newexpr) = 0;
02435
02436 tsi = tsi_last (stmts);
02437 tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
02438 VEC_safe_push (tree, heap, inserted_exprs, newexpr);
02439 mark_new_vars_to_rename (newexpr);
02440
02441
02442
02443
02444
02445
02446 v = get_value_handle (expr);
02447 vn_add (name, v);
02448 bitmap_value_replace_in_set (NEW_SETS (block), name);
02449 bitmap_value_replace_in_set (AVAIL_OUT (block), name);
02450
02451 pre_stats.insertions++;
02452 if (dump_file && (dump_flags & TDF_DETAILS))
02453 {
02454 fprintf (dump_file, "Inserted ");
02455 print_generic_expr (dump_file, newexpr, 0);
02456 fprintf (dump_file, " in predecessor %d\n", block->index);
02457 }
02458
02459 return name;
02460 }
02461
02462
02463
02464
02465
02466
02467 static bool
02468 insert_into_preds_of_block (basic_block block, value_set_node_t node,
02469 tree *avail)
02470 {
02471 tree val = get_value_handle (node->expr);
02472 edge pred;
02473 bool insertions = false;
02474 bool nophi = false;
02475 basic_block bprime;
02476 tree eprime;
02477 edge_iterator ei;
02478 tree type = TREE_TYPE (avail[EDGE_PRED (block, 0)->src->index]);
02479 tree temp;
02480
02481 if (dump_file && (dump_flags & TDF_DETAILS))
02482 {
02483 fprintf (dump_file, "Found partial redundancy for expression ");
02484 print_generic_expr (dump_file, node->expr, 0);
02485 fprintf (dump_file, " (");
02486 print_generic_expr (dump_file, val, 0);
02487 fprintf (dump_file, ")");
02488 fprintf (dump_file, "\n");
02489 }
02490
02491
02492 if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2
02493 && TREE_CODE_CLASS (TREE_CODE (node->expr)) != tcc_reference )
02494 {
02495 bool firstinsideloop = false;
02496 bool secondinsideloop = false;
02497 firstinsideloop = flow_bb_inside_loop_p (block->loop_father,
02498 EDGE_PRED (block, 0)->src);
02499 secondinsideloop = flow_bb_inside_loop_p (block->loop_father,
02500 EDGE_PRED (block, 1)->src);
02501
02502 if (firstinsideloop ^ secondinsideloop)
02503 {
02504 if (dump_file && (dump_flags & TDF_DETAILS))
02505 fprintf (dump_file, "Skipping insertion of phi for partial redundancy: Looks like an induction variable\n");
02506 nophi = true;
02507 }
02508 }
02509
02510
02511
02512 FOR_EACH_EDGE (pred, ei, block->preds)
02513 {
02514 tree stmts = alloc_stmt_list ();
02515 tree builtexpr;
02516 bprime = pred->src;
02517 eprime = avail[bprime->index];
02518
02519 if (can_PRE_operation (eprime))
02520 {
02521 #ifdef ENABLE_CHECKING
02522 tree vh;
02523
02524
02525 vh = TREE_CODE (eprime) == VALUE_HANDLE
02526 ? eprime
02527 : get_value_handle (eprime);
02528
02529
02530 if (TREE_CODE (vh) == VALUE_HANDLE)
02531 {
02532 int i;
02533 tree vuse;
02534 for (i = 0;
02535 VEC_iterate (tree, VALUE_HANDLE_VUSES (vh), i, vuse);
02536 i++)
02537 {
02538 size_t id = SSA_NAME_VERSION (vuse);
02539 gcc_assert (bitmap_bit_p (RVUSE_OUT (bprime), id)
02540 || IS_EMPTY_STMT (SSA_NAME_DEF_STMT (vuse)));
02541 }
02542 }
02543 #endif
02544 builtexpr = create_expression_by_pieces (bprime,
02545 eprime,
02546 stmts);
02547 bsi_insert_on_edge (pred, stmts);
02548 avail[bprime->index] = builtexpr;
02549 insertions = true;
02550 }
02551 }
02552
02553
02554
02555
02556 if (nophi && insertions)
02557 return true;
02558 else if (nophi && !insertions)
02559 return false;
02560
02561
02562 if (!prephitemp || TREE_TYPE (prephitemp) != type)
02563 {
02564 prephitemp = create_tmp_var (type, "prephitmp");
02565 get_var_ann (prephitemp);
02566 }
02567
02568 temp = prephitemp;
02569 add_referenced_var (temp);
02570
02571 if (TREE_CODE (type) == COMPLEX_TYPE)
02572 DECL_COMPLEX_GIMPLE_REG_P (temp) = 1;
02573 temp = create_phi_node (temp, block);
02574
02575 NECESSARY (temp) = 0;
02576 VEC_safe_push (tree, heap, inserted_exprs, temp);
02577 FOR_EACH_EDGE (pred, ei, block->preds)
02578 add_phi_arg (temp, avail[pred->src->index], pred);
02579
02580 vn_add (PHI_RESULT (temp), val);
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596 bitmap_insert_into_set (PHI_GEN (block),
02597 PHI_RESULT (temp));
02598 bitmap_value_replace_in_set (AVAIL_OUT (block),
02599 PHI_RESULT (temp));
02600 bitmap_insert_into_set (NEW_SETS (block),
02601 PHI_RESULT (temp));
02602
02603 if (dump_file && (dump_flags & TDF_DETAILS))
02604 {
02605 fprintf (dump_file, "Created phi ");
02606 print_generic_expr (dump_file, temp, 0);
02607 fprintf (dump_file, " in block %d\n", block->index);
02608 }
02609 pre_stats.phis++;
02610 return true;
02611 }
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630 static bool
02631 insert_aux (basic_block block)
02632 {
02633 basic_block son;
02634 bool new_stuff = false;
02635
02636 if (block)
02637 {
02638 basic_block dom;
02639 dom = get_immediate_dominator (CDI_DOMINATORS, block);
02640 if (dom)
02641 {
02642 unsigned i;
02643 bitmap_iterator bi;
02644 bitmap_set_t newset = NEW_SETS (dom);
02645 if (newset)
02646 {
02647
02648
02649
02650
02651 EXECUTE_IF_SET_IN_BITMAP (newset->expressions, 0, i, bi)
02652 {
02653 bitmap_value_replace_in_set (NEW_SETS (block), ssa_name (i));
02654 bitmap_value_replace_in_set (AVAIL_OUT (block), ssa_name (i));
02655 }
02656 }
02657 if (!single_pred_p (block))
02658 {
02659 value_set_node_t node;
02660 for (node = ANTIC_IN (block)->head;
02661 node;
02662 node = node->next)
02663 {
02664 if (can_PRE_operation (node->expr)
02665 && !AGGREGATE_TYPE_P (TREE_TYPE (node->expr)))
02666 {
02667 tree *avail;
02668 tree val;
02669 bool by_some = false;
02670 bool cant_insert = false;
02671 bool all_same = true;
02672 tree first_s = NULL;
02673 edge pred;
02674 basic_block bprime;
02675 tree eprime = NULL_TREE;
02676 edge_iterator ei;
02677
02678 val = get_value_handle (node->expr);
02679 if (bitmap_set_contains_value (PHI_GEN (block), val))
02680 continue;
02681 if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
02682 {
02683 if (dump_file && (dump_flags & TDF_DETAILS))
02684 fprintf (dump_file, "Found fully redundant value\n");
02685 continue;
02686 }
02687
02688 avail = XCNEWVEC (tree, last_basic_block);
02689 FOR_EACH_EDGE (pred, ei, block->preds)
02690 {
02691 tree vprime;
02692 tree edoubleprime;
02693
02694
02695
02696
02697 if (EDGE_CRITICAL_P (pred))
02698 {
02699 cant_insert = true;
02700 break;
02701 }
02702 bprime = pred->src;
02703 eprime = phi_translate (node->expr,
02704 ANTIC_IN (block),
02705 bprime, block);
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716 if (eprime == NULL)
02717 {
02718 cant_insert = true;
02719 break;
02720 }
02721
02722 eprime = fully_constant_expression (eprime);
02723 vprime = get_value_handle (eprime);
02724 gcc_assert (vprime);
02725 edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
02726 vprime);
02727 if (edoubleprime == NULL)
02728 {
02729 avail[bprime->index] = eprime;
02730 all_same = false;
02731 }
02732 else
02733 {
02734 avail[bprime->index] = edoubleprime;
02735 by_some = true;
02736 if (first_s == NULL)
02737 first_s = edoubleprime;
02738 else if (!operand_equal_p (first_s, edoubleprime,
02739 0))
02740 all_same = false;
02741 }
02742 }
02743
02744
02745
02746
02747 if (!cant_insert && !all_same && by_some)
02748 {
02749 if (insert_into_preds_of_block (block, node, avail))
02750 new_stuff = true;
02751 }
02752
02753
02754
02755 else if (!cant_insert && all_same && eprime
02756 && is_gimple_min_invariant (eprime)
02757 && !is_gimple_min_invariant (val))
02758 {
02759 value_set_t exprset = VALUE_HANDLE_EXPR_SET (val);
02760 value_set_node_t node;
02761
02762 for (node = exprset->head; node; node = node->next)
02763 {
02764 if (TREE_CODE (node->expr) == SSA_NAME)
02765 {
02766 vn_add (node->expr, eprime);
02767 pre_stats.constified++;
02768 }
02769 }
02770 }
02771 free (avail);
02772 }
02773 }
02774 }
02775 }
02776 }
02777 for (son = first_dom_son (CDI_DOMINATORS, block);
02778 son;
02779 son = next_dom_son (CDI_DOMINATORS, son))
02780 {
02781 new_stuff |= insert_aux (son);
02782 }
02783
02784 return new_stuff;
02785 }
02786
02787
02788
02789 static void
02790 insert (void)
02791 {
02792 bool new_stuff = true;
02793 basic_block bb;
02794 int num_iterations = 0;
02795
02796 FOR_ALL_BB (bb)
02797 NEW_SETS (bb) = bitmap_set_new ();
02798
02799 while (new_stuff)
02800 {
02801 num_iterations++;
02802 new_stuff = false;
02803 new_stuff = insert_aux (ENTRY_BLOCK_PTR);
02804 }
02805 if (num_iterations > 2 && dump_file && (dump_flags & TDF_STATS))
02806 fprintf (dump_file, "insert required %d iterations\n", num_iterations);
02807 }
02808
02809
02810
02811
02812
02813 static bool
02814 is_undefined_value (tree expr)
02815 {
02816 return (TREE_CODE (expr) == SSA_NAME
02817 && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (expr))
02818
02819 && TREE_CODE (SSA_NAME_VAR (expr)) != PARM_DECL);
02820 }
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831 static inline void
02832 add_to_sets (tree var, tree expr, tree stmt, bitmap_set_t s1,
02833 bitmap_set_t s2)
02834 {
02835 tree val = vn_lookup_or_add (expr, stmt);
02836
02837
02838
02839
02840
02841 if (var != expr)
02842 vn_add (var, val);
02843
02844 if (s1)
02845 bitmap_insert_into_set (s1, var);
02846 bitmap_value_insert_into_set (s2, var);
02847 }
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857 static inline tree
02858 create_value_expr_from (tree expr, basic_block block, tree stmt)
02859 {
02860 int i;
02861 enum tree_code code = TREE_CODE (expr);
02862 tree vexpr;
02863 alloc_pool pool;
02864
02865 gcc_assert (TREE_CODE_CLASS (code) == tcc_unary
02866 || TREE_CODE_CLASS (code) == tcc_binary
02867 || TREE_CODE_CLASS (code) == tcc_comparison
02868 || TREE_CODE_CLASS (code) == tcc_reference
02869 || TREE_CODE_CLASS (code) == tcc_expression
02870 || TREE_CODE_CLASS (code) == tcc_exceptional
02871 || TREE_CODE_CLASS (code) == tcc_declaration);
02872
02873 if (TREE_CODE_CLASS (code) == tcc_unary)
02874 pool = unary_node_pool;
02875 else if (TREE_CODE_CLASS (code) == tcc_reference)
02876 pool = reference_node_pool;
02877 else if (TREE_CODE_CLASS (code) == tcc_binary)
02878 pool = binary_node_pool;
02879 else if (TREE_CODE_CLASS (code) == tcc_comparison)
02880 pool = comparison_node_pool;
02881 else if (TREE_CODE_CLASS (code) == tcc_exceptional)
02882 {
02883 gcc_assert (code == TREE_LIST);
02884 pool = list_node_pool;
02885 }
02886 else
02887 {
02888 gcc_assert (code == CALL_EXPR);
02889 pool = expression_node_pool;
02890 }
02891
02892 vexpr = (tree) pool_alloc (pool);
02893 memcpy (vexpr, expr, tree_size (expr));
02894
02895
02896
02897
02898
02899
02900
02901
02902 if (code == TREE_LIST)
02903 {
02904 tree op = NULL_TREE;
02905 tree temp = NULL_TREE;
02906 if (TREE_CHAIN (vexpr))
02907 temp = create_value_expr_from (TREE_CHAIN (vexpr), block, stmt);
02908 TREE_CHAIN (vexpr) = temp ? temp : TREE_CHAIN (vexpr);
02909
02910
02911
02912 if (REFERENCE_CLASS_P (TREE_VALUE (vexpr)))
02913 {
02914 tree tempop;
02915 op = TREE_VALUE (vexpr);
02916 tempop = create_value_expr_from (op, block, stmt);
02917 op = tempop ? tempop : op;
02918
02919 TREE_VALUE (vexpr) = vn_lookup_or_add (op, stmt);
02920 }
02921 else
02922 {
02923 op = TREE_VALUE (vexpr);
02924 TREE_VALUE (vexpr) = vn_lookup_or_add (TREE_VALUE (vexpr), NULL);
02925 }
02926
02927
02928 if (!is_undefined_value (op))
02929 value_insert_into_set (EXP_GEN (block), op);
02930
02931 return vexpr;
02932 }
02933
02934 for (i = 0; i < TREE_CODE_LENGTH (code); i++)
02935 {
02936 tree val, op;
02937
02938 op = TREE_OPERAND (expr, i);
02939 if (op == NULL_TREE)
02940 continue;
02941
02942
02943 if (REFERENCE_CLASS_P (op))
02944 {
02945 tree tempop = create_value_expr_from (op, block, stmt);
02946 op = tempop ? tempop : op;
02947 val = vn_lookup_or_add (op, stmt);
02948 }
02949 else if (TREE_CODE (op) == TREE_LIST)
02950 {
02951 tree tempop;
02952
02953 gcc_assert (TREE_CODE (expr) == CALL_EXPR);
02954 tempop = create_value_expr_from (op, block, stmt);
02955
02956 op = tempop ? tempop : op;
02957 vn_lookup_or_add (op, NULL);
02958
02959
02960
02961 val = op;
02962 }
02963 else
02964
02965 val = vn_lookup_or_add (op, NULL);
02966
02967 if (!is_undefined_value (op) && TREE_CODE (op) != TREE_LIST)
02968 value_insert_into_set (EXP_GEN (block), op);
02969
02970 if (TREE_CODE (val) == VALUE_HANDLE)
02971 TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
02972
02973 TREE_OPERAND (vexpr, i) = val;
02974 }
02975
02976 return vexpr;
02977 }
02978
02979
02980
02981
02982
02983
02984
02985 static void
02986 insert_extra_phis (basic_block block, basic_block dom)
02987 {
02988
02989 if (!single_pred_p (block))
02990 {
02991 edge e;
02992 edge_iterator ei;
02993 bool first = true;
02994 bitmap_set_t tempset = bitmap_set_new ();
02995
02996 FOR_EACH_EDGE (e, ei, block->preds)
02997 {
02998
02999 if (e->flags & EDGE_ABNORMAL)
03000 return;
03001
03002 if (first)
03003 {
03004 bitmap_set_copy (tempset, AVAIL_OUT (e->src));
03005 first = false;
03006 }
03007 else
03008 bitmap_set_and (tempset, AVAIL_OUT (e->src));
03009 }
03010
03011 if (dom)
03012 bitmap_set_and_compl (tempset, AVAIL_OUT (dom));
03013
03014 if (!bitmap_set_empty_p (tempset))
03015 {
03016 unsigned int i;
03017 bitmap_iterator bi;
03018
03019 EXECUTE_IF_SET_IN_BITMAP (tempset->expressions, 0, i, bi)
03020 {
03021 tree name = ssa_name (i);
03022 tree val = get_value_handle (name);
03023 tree temp;
03024
03025 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
03026 continue;
03027
03028 if (!mergephitemp
03029 || TREE_TYPE (name) != TREE_TYPE (mergephitemp))
03030 {
03031 mergephitemp = create_tmp_var (TREE_TYPE (name),
03032 "mergephitmp");
03033 get_var_ann (mergephitemp);
03034 }
03035 temp = mergephitemp;
03036
03037 if (dump_file && (dump_flags & TDF_DETAILS))
03038 {
03039 fprintf (dump_file, "Creating phi ");
03040 print_generic_expr (dump_file, temp, 0);
03041 fprintf (dump_file, " to merge available but not dominating values ");
03042 }
03043
03044 add_referenced_var (temp);
03045 temp = create_phi_node (temp, block);
03046 NECESSARY (temp) = 0;
03047 VEC_safe_push (tree, heap, inserted_exprs, temp);
03048
03049 FOR_EACH_EDGE (e, ei, block->preds)
03050 {
03051 tree leader = bitmap_find_leader (AVAIL_OUT (e->src), val);
03052
03053 gcc_assert (leader);
03054 add_phi_arg (temp, leader, e);
03055
03056 if (dump_file && (dump_flags & TDF_DETAILS))
03057 {
03058 print_generic_expr (dump_file, leader, 0);
03059 fprintf (dump_file, " in block %d,", e->src->index);
03060 }
03061 }
03062
03063 vn_add (PHI_RESULT (temp), val);
03064
03065 if (dump_file && (dump_flags & TDF_DETAILS))
03066 fprintf (dump_file, "\n");
03067 }
03068 }
03069 }
03070 }
03071
03072
03073
03074
03075
03076 static bool
03077 try_look_through_load (tree lhs, tree mem_ref, tree stmt, basic_block block)
03078 {
03079 tree store_stmt = NULL;
03080 tree rhs;
03081 ssa_op_iter i;
03082 tree vuse;
03083
03084 FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, i, SSA_OP_VIRTUAL_USES)
03085 {
03086 tree def_stmt;
03087
03088 gcc_assert (TREE_CODE (vuse) == SSA_NAME);
03089 def_stmt = SSA_NAME_DEF_STMT (vuse);
03090
03091
03092
03093
03094
03095
03096 if (!def_stmt
03097 || TREE_CODE (def_stmt) != MODIFY_EXPR
03098 || !ZERO_SSA_OPERANDS (def_stmt, SSA_OP_VIRTUAL_USES))
03099 return false;
03100
03101
03102
03103
03104 if (store_stmt && store_stmt != def_stmt)
03105 return false;
03106 else
03107 {
03108
03109
03110 if (!operand_equal_p (TREE_OPERAND (def_stmt, 0), mem_ref, 0))
03111 return false;
03112
03113
03114
03115 store_stmt = def_stmt;
03116 }
03117 }
03118
03119
03120
03121
03122 rhs = TREE_OPERAND (store_stmt, 1);
03123 if ((TREE_CODE (rhs) == SSA_NAME
03124 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs))
03125 || is_gimple_min_invariant (rhs)
03126 || TREE_CODE (rhs) == ADDR_EXPR
03127 || TREE_INVARIANT (rhs))
03128 {
03129
03130
03131
03132
03133 add_to_sets (lhs, rhs, store_stmt, TMP_GEN (block), AVAIL_OUT (block));
03134 if (TREE_CODE (rhs) == SSA_NAME
03135 && !is_undefined_value (rhs))
03136 value_insert_into_set (EXP_GEN (block), rhs);
03137 return true;
03138 }
03139
03140 return false;
03141 }
03142
03143
03144
03145
03146
03147 static tree
03148 poolify_tree (tree node)
03149 {
03150 switch (TREE_CODE (node))
03151 {
03152 case INDIRECT_REF:
03153 {
03154 tree temp = pool_alloc (reference_node_pool);
03155 memcpy (temp, node, tree_size (node));
03156 TREE_OPERAND (temp, 0) = poolify_tree (TREE_OPERAND (temp, 0));
03157 return temp;
03158 }
03159 break;
03160 case MODIFY_EXPR:
03161 {
03162 tree temp = pool_alloc (modify_expr_node_pool);
03163 memcpy (temp, node, tree_size (node));
03164 TREE_OPERAND (temp, 0) = poolify_tree (TREE_OPERAND (temp, 0));
03165 TREE_OPERAND (temp, 1) = poolify_tree (TREE_OPERAND (temp, 1));
03166 return temp;
03167 }
03168 break;
03169 case SSA_NAME:
03170 case INTEGER_CST:
03171 case STRING_CST:
03172 case REAL_CST:
03173 case PARM_DECL:
03174 case VAR_DECL:
03175 case RESULT_DECL:
03176 return node;
03177 default:
03178 gcc_unreachable ();
03179 }
03180 }
03181
03182 static tree modify_expr_template;
03183
03184
03185
03186 static tree
03187 poolify_modify_expr (tree type, tree op1, tree op2)
03188 {
03189 if (modify_expr_template == NULL)
03190 modify_expr_template = build2 (MODIFY_EXPR, type, op1, op2);
03191
03192 TREE_OPERAND (modify_expr_template, 0) = op1;
03193 TREE_OPERAND (modify_expr_template, 1) = op2;
03194 TREE_TYPE (modify_expr_template) = type;
03195
03196 return poolify_tree (modify_expr_template);
03197 }
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212 static void
03213 insert_fake_stores (void)
03214 {
03215 basic_block block;
03216
03217 FOR_ALL_BB (block)
03218 {
03219 block_stmt_iterator bsi;
03220 for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
03221 {
03222 tree stmt = bsi_stmt (bsi);
03223
03224
03225
03226
03227
03228 if (TREE_CODE (stmt) == MODIFY_EXPR
03229 && TREE_CODE (TREE_OPERAND (stmt, 0)) == INDIRECT_REF
03230 && !AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 0)))
03231 && TREE_CODE (TREE_TYPE (TREE_OPERAND (stmt, 0))) != COMPLEX_TYPE)
03232 {
03233 ssa_op_iter iter;
03234 def_operand_p defp;
03235 tree lhs = TREE_OPERAND (stmt, 0);
03236 tree rhs = TREE_OPERAND (stmt, 1);
03237 tree new;
03238 bool notokay = false;
03239
03240 FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_VIRTUAL_DEFS)
03241 {
03242 tree defvar = DEF_FROM_PTR (defp);
03243 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (defvar))
03244 {
03245 notokay = true;
03246 break;
03247 }
03248 }
03249
03250 if (notokay)
03251 continue;
03252
03253 if (!storetemp || TREE_TYPE (rhs) != TREE_TYPE (storetemp))
03254 {
03255 storetemp = create_tmp_var (TREE_TYPE (rhs), "storetmp");
03256 get_var_ann (storetemp);
03257 }
03258
03259 new = poolify_modify_expr (TREE_TYPE (stmt), storetemp, lhs);
03260
03261 lhs = make_ssa_name (storetemp, new);
03262 TREE_OPERAND (new, 0) = lhs;
03263 create_ssa_artficial_load_stmt (new, stmt);
03264
03265 NECESSARY (new) = 0;
03266 VEC_safe_push (tree, heap, inserted_exprs, new);
03267 VEC_safe_push (tree, heap, need_creation, new);
03268 bsi_insert_after (&bsi, new, BSI_NEW_STMT);
03269 }
03270 }
03271 }
03272 }
03273
03274
03275
03276
03277
03278 static void
03279 realify_fake_stores (void)
03280 {
03281 unsigned int i;
03282 tree stmt;
03283
03284 for (i = 0; VEC_iterate (tree, need_creation, i, stmt); i++)
03285 {
03286 if (NECESSARY (stmt))
03287 {
03288 block_stmt_iterator bsi;
03289 tree newstmt;
03290
03291
03292 add_referenced_var (SSA_NAME_VAR (TREE_OPERAND (stmt, 0)));
03293
03294
03295
03296
03297
03298 bsi = bsi_for_stmt (stmt);
03299 bsi_prev (&bsi);
03300 newstmt = build2 (MODIFY_EXPR, void_type_node,
03301 TREE_OPERAND (stmt, 0),
03302 TREE_OPERAND (bsi_stmt (bsi), 1));
03303 SSA_NAME_DEF_STMT (TREE_OPERAND (newstmt, 0)) = newstmt;
03304 bsi_insert_before (&bsi, newstmt, BSI_SAME_STMT);
03305 bsi = bsi_for_stmt (stmt);
03306 bsi_remove (&bsi, true);
03307 }
03308 else
03309 release_defs (stmt);
03310 }
03311 }
03312
03313
03314
03315
03316
03317
03318
03319
03320 static bool
03321 try_combine_conversion (tree *expr_p)
03322 {
03323 tree expr = *expr_p;
03324 tree t;
03325
03326 if (!((TREE_CODE (expr) == NOP_EXPR
03327 || TREE_CODE (expr) == CONVERT_EXPR)
03328 && TREE_CODE (TREE_OPERAND (expr, 0)) == VALUE_HANDLE
03329 && !VALUE_HANDLE_VUSES (TREE_OPERAND (expr, 0))))
03330 return false;
03331
03332 t = fold_unary (TREE_CODE (expr), TREE_TYPE (expr),
03333 VALUE_HANDLE_EXPR_SET (TREE_OPERAND (expr, 0))->head->expr);
03334 if (!t)
03335 return false;
03336
03337
03338
03339 STRIP_USELESS_TYPE_CONVERSION (t);
03340
03341
03342
03343 if (!(TREE_CODE (t) == VALUE_HANDLE
03344 || is_gimple_min_invariant (t)))
03345 t = vn_lookup (t, NULL);
03346
03347 if (t && t != expr)
03348 {
03349 *expr_p = t;
03350 return true;
03351 }
03352 return false;
03353 }
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365 static void
03366 compute_avail (void)
03367 {
03368 basic_block block, son;
03369 basic_block *worklist;
03370 size_t sp = 0;
03371 tree param;
03372
03373
03374 for (param = DECL_ARGUMENTS (current_function_decl);
03375 param;
03376 param = TREE_CHAIN (param))
03377 {
03378 if (default_def (param) != NULL)
03379 {
03380 tree def = default_def (param);
03381 vn_lookup_or_add (def, NULL);
03382 bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), def);
03383 bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), def);
03384 }
03385 }
03386
03387
03388 if (cfun->static_chain_decl)
03389 {
03390 param = cfun->static_chain_decl;
03391 if (default_def (param) != NULL)
03392 {
03393 tree def = default_def (param);
03394 vn_lookup_or_add (def, NULL);
03395 bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), def);
03396 bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), def);
03397 }
03398 }
03399
03400
03401 worklist = XNEWVEC (basic_block, n_basic_blocks);
03402
03403
03404
03405 for (son = first_dom_son (CDI_DOMINATORS, ENTRY_BLOCK_PTR);
03406 son;
03407 son = next_dom_son (CDI_DOMINATORS, son))
03408 worklist[sp++] = son;
03409
03410
03411 while (sp)
03412 {
03413 block_stmt_iterator bsi;
03414 tree stmt, phi;
03415 basic_block dom;
03416 unsigned int stmt_uid = 1;
03417
03418
03419 block = worklist[--sp];
03420
03421
03422
03423 dom = get_immediate_dominator (CDI_DOMINATORS, block);
03424 if (dom)
03425 bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
03426
03427 if (!in_fre)
03428 insert_extra_phis (block, dom);
03429
03430
03431 for (phi = phi_nodes (block); phi; phi = PHI_CHAIN (phi))
03432
03433
03434 if (is_gimple_reg (PHI_RESULT (phi)))
03435 add_to_sets (PHI_RESULT (phi), PHI_RESULT (phi), NULL,
03436 PHI_GEN (block), AVAIL_OUT (block));
03437
03438
03439
03440 for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
03441 {
03442 stmt_ann_t ann;
03443 ssa_op_iter iter;
03444 tree op;
03445
03446 stmt = bsi_stmt (bsi);
03447 ann = stmt_ann (stmt);
03448
03449 ann->uid = stmt_uid++;
03450
03451
03452
03453
03454
03455 if (TREE_CODE (stmt) == MODIFY_EXPR
03456 && !ann->has_volatile_ops
03457 && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
03458 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (stmt, 0)))
03459 {
03460 tree lhs = TREE_OPERAND (stmt, 0);
03461 tree rhs = TREE_OPERAND (stmt, 1);
03462
03463
03464 if (TREE_CODE (lhs) == SSA_NAME
03465 && !ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_USES)
03466 && try_look_through_load (lhs, rhs, stmt, block))
03467 continue;
03468
03469 STRIP_USELESS_TYPE_CONVERSION (rhs);
03470 if (can_value_number_operation (rhs))
03471 {
03472
03473
03474
03475 tree newt = create_value_expr_from (rhs, block, stmt);
03476 if (newt)
03477 {
03478
03479
03480
03481 if (try_combine_conversion (&newt))
03482 vn_add (lhs, newt);
03483 else
03484 {
03485 tree val = vn_lookup_or_add (newt, stmt);
03486 vn_add (lhs, val);
03487 value_insert_into_set (EXP_GEN (block), newt);
03488 }
03489 bitmap_insert_into_set (TMP_GEN (block), lhs);
03490 bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
03491 continue;
03492 }
03493 }
03494 else if ((TREE_CODE (rhs) == SSA_NAME
03495 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs))
03496 || is_gimple_min_invariant (rhs)
03497 || TREE_CODE (rhs) == ADDR_EXPR
03498 || TREE_INVARIANT (rhs)
03499 || DECL_P (rhs))
03500 {
03501
03502
03503
03504 add_to_sets (lhs, rhs, stmt, TMP_GEN (block),
03505 AVAIL_OUT (block));
03506
03507 if (TREE_CODE (rhs) == SSA_NAME
03508 && !is_undefined_value (rhs))
03509 value_insert_into_set (EXP_GEN (block), rhs);
03510 continue;
03511 }
03512 }
03513
03514
03515
03516
03517 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
03518 add_to_sets (op, op, NULL, TMP_GEN (block), AVAIL_OUT (block));
03519
03520 FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
03521 add_to_sets (op, op, NULL, NULL , AVAIL_OUT (block));
03522 }
03523
03524
03525
03526 for (son = first_dom_son (CDI_DOMINATORS, block);
03527 son;
03528 son = next_dom_son (CDI_DOMINATORS, son))
03529 worklist[sp++] = son;
03530 }
03531
03532 free (worklist);
03533 }
03534
03535
03536
03537
03538 static void
03539 eliminate (void)
03540 {
03541 basic_block b;
03542
03543 FOR_EACH_BB (b)
03544 {
03545 block_stmt_iterator i;
03546
03547 for (i = bsi_start (b); !bsi_end_p (i); bsi_next (&i))
03548 {
03549 tree stmt = bsi_stmt (i);
03550
03551
03552
03553
03554 if (TREE_CODE (stmt) == MODIFY_EXPR
03555 && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
03556 && TREE_CODE (TREE_OPERAND (stmt ,1)) != SSA_NAME
03557 && !is_gimple_min_invariant (TREE_OPERAND (stmt, 1))
03558 && !stmt_ann (stmt)->has_volatile_ops)
03559 {
03560 tree lhs = TREE_OPERAND (stmt, 0);
03561 tree *rhs_p = &TREE_OPERAND (stmt, 1);
03562 tree sprime;
03563
03564 sprime = bitmap_find_leader (AVAIL_OUT (b),
03565 vn_lookup (lhs, NULL));
03566 if (sprime
03567 && sprime != lhs
03568 && (TREE_CODE (*rhs_p) != SSA_NAME
03569 || may_propagate_copy (*rhs_p, sprime)))
03570 {
03571 gcc_assert (sprime != *rhs_p);
03572
03573 if (dump_file && (dump_flags & TDF_DETAILS))
03574 {
03575 fprintf (dump_file, "Replaced ");
03576 print_generic_expr (dump_file, *rhs_p, 0);
03577 fprintf (dump_file, " with ");
03578 print_generic_expr (dump_file, sprime, 0);
03579 fprintf (dump_file, " in ");
03580 print_generic_stmt (dump_file, stmt, 0);
03581 }
03582
03583 if (TREE_CODE (sprime) == SSA_NAME)
03584 NECESSARY (SSA_NAME_DEF_STMT (sprime)) = 1;
03585
03586
03587
03588 if (TREE_CODE (*rhs_p) != SSA_NAME
03589 && !tree_ssa_useless_type_conversion_1 (TREE_TYPE (*rhs_p),
03590 TREE_TYPE (sprime)))
03591 sprime = fold_convert (TREE_TYPE (*rhs_p), sprime);
03592
03593 pre_stats.eliminations++;
03594 propagate_tree_value (rhs_p, sprime);
03595 update_stmt (stmt);
03596
03597
03598
03599 if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
03600 {
03601 bitmap_set_bit (need_eh_cleanup,
03602 bb_for_stmt (stmt)->index);
03603 if (dump_file && (dump_flags & TDF_DETAILS))
03604 fprintf (dump_file, " Removed EH side effects.\n");
03605 }
03606 }
03607 }
03608 }
03609 }
03610 }
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620 static inline tree
03621 mark_operand_necessary (tree op)
03622 {
03623 tree stmt;
03624
03625 gcc_assert (op);
03626
03627 if (TREE_CODE (op) != SSA_NAME)
03628 return NULL;
03629
03630 stmt = SSA_NAME_DEF_STMT (op);
03631 gcc_assert (stmt);
03632
03633 if (NECESSARY (stmt)
03634 || IS_EMPTY_STMT (stmt))
03635 return NULL;
03636
03637 NECESSARY (stmt) = 1;
03638 return stmt;
03639 }
03640
03641
03642
03643
03644
03645
03646 static void
03647 remove_dead_inserted_code (void)
03648 {
03649 VEC(tree,heap) *worklist = NULL;
03650 int i;
03651 tree t;
03652
03653 worklist = VEC_alloc (tree, heap, VEC_length (tree, inserted_exprs));
03654 for (i = 0; VEC_iterate (tree, inserted_exprs, i, t); i++)
03655 {
03656 if (NECESSARY (t))
03657 VEC_quick_push (tree, worklist, t);
03658 }
03659 while (VEC_length (tree, worklist) > 0)
03660 {
03661 t = VEC_pop (tree, worklist);
03662
03663
03664
03665
03666 if (TREE_CODE (t) == PHI_NODE)
03667 {
03668 int k;
03669
03670 VEC_reserve (tree, heap, worklist, PHI_NUM_ARGS (t));
03671 for (k = 0; k < PHI_NUM_ARGS (t); k++)
03672 {
03673 tree arg = PHI_ARG_DEF (t, k);
03674 if (TREE_CODE (arg) == SSA_NAME)
03675 {
03676 arg = mark_operand_necessary (arg);
03677 if (arg)
03678 VEC_quick_push (tree, worklist, arg);
03679 }
03680 }
03681 }
03682 else
03683 {
03684
03685
03686
03687 ssa_op_iter iter;
03688 tree use;
03689
03690
03691
03692
03693
03694
03695 FOR_EACH_SSA_TREE_OPERAND (use, t, iter, SSA_OP_ALL_USES)
03696 {
03697 tree n = mark_operand_necessary (use);
03698 if (n)
03699 VEC_safe_push (tree, heap, worklist, n);
03700 }
03701 }
03702 }
03703
03704 for (i = 0; VEC_iterate (tree, inserted_exprs, i, t); i++)
03705 {
03706 if (!NECESSARY (t))
03707 {
03708 block_stmt_iterator bsi;
03709
03710 if (dump_file && (dump_flags & TDF_DETAILS))
03711 {
03712 fprintf (dump_file, "Removing unnecessary insertion:");
03713 print_generic_stmt (dump_file, t, 0);
03714 }
03715
03716 if (TREE_CODE (t) == PHI_NODE)
03717 {
03718 remove_phi_node (t, NULL);
03719 }
03720 else
03721 {
03722 bsi = bsi_for_stmt (t);
03723 bsi_remove (&bsi, true);
03724 release_defs (t);
03725 }
03726 }
03727 }
03728 VEC_free (tree, heap, worklist);
03729 }
03730
03731
03732
03733 static void
03734 init_pre (bool do_fre)
03735 {
03736 basic_block bb;
03737
03738 in_fre = do_fre;
03739
03740 inserted_exprs = NULL;
03741 need_creation = NULL;
03742 pretemp = NULL_TREE;
03743 storetemp = NULL_TREE;
03744 mergephitemp = NULL_TREE;
03745 prephitemp = NULL_TREE;
03746
03747 vn_init ();
03748 if (!do_fre)
03749 current_loops = loop_optimizer_init (LOOPS_NORMAL);
03750
03751 connect_infinite_loops_to_exit ();
03752 memset (&pre_stats, 0, sizeof (pre_stats));
03753
03754
03755
03756
03757
03758
03759
03760
03761 if (!single_pred_p (single_succ (ENTRY_BLOCK_PTR)))
03762 if (!(single_succ_edge (ENTRY_BLOCK_PTR)->flags & EDGE_ABNORMAL))
03763 split_edge (single_succ_edge (ENTRY_BLOCK_PTR));
03764
03765 FOR_ALL_BB (bb)
03766 bb->aux = xcalloc (1, sizeof (struct bb_value_sets));
03767
03768 bitmap_obstack_initialize (&grand_bitmap_obstack);
03769 phi_translate_table = htab_create (511, expr_pred_trans_hash,
03770 expr_pred_trans_eq, free);
03771 value_set_pool = create_alloc_pool ("Value sets",
03772 sizeof (struct value_set), 30);
03773 bitmap_set_pool = create_alloc_pool ("Bitmap sets",
03774 sizeof (struct bitmap_set), 30);
03775 value_set_node_pool = create_alloc_pool ("Value set nodes",
03776 sizeof (struct value_set_node), 30);
03777 calculate_dominance_info (CDI_POST_DOMINATORS);
03778 calculate_dominance_info (CDI_DOMINATORS);
03779 binary_node_pool = create_alloc_pool ("Binary tree nodes",
03780 tree_code_size (PLUS_EXPR), 30);
03781 unary_node_pool = create_alloc_pool ("Unary tree nodes",
03782 tree_code_size (NEGATE_EXPR), 30);
03783 reference_node_pool = create_alloc_pool ("Reference tree nodes",
03784 tree_code_size (ARRAY_REF), 30);
03785 expression_node_pool = create_alloc_pool ("Expression tree nodes",
03786 tree_code_size (CALL_EXPR), 30);
03787 list_node_pool = create_alloc_pool ("List tree nodes",
03788 tree_code_size (TREE_LIST), 30);
03789 comparison_node_pool = create_alloc_pool ("Comparison tree nodes",
03790 tree_code_size (EQ_EXPR), 30);
03791 modify_expr_node_pool = create_alloc_pool ("MODIFY_EXPR nodes",
03792 tree_code_size (MODIFY_EXPR),
03793 30);
03794 modify_expr_template = NULL;
03795
03796 FOR_ALL_BB (bb)
03797 {
03798 EXP_GEN (bb) = set_new (true);
03799 PHI_GEN (bb) = bitmap_set_new ();
03800 TMP_GEN (bb) = bitmap_set_new ();
03801 AVAIL_OUT (bb) = bitmap_set_new ();
03802 }
03803
03804 need_eh_cleanup = BITMAP_ALLOC (NULL);
03805 }
03806
03807
03808
03809
03810 static void
03811 fini_pre (bool do_fre)
03812 {
03813 basic_block bb;
03814 unsigned int i;
03815
03816 VEC_free (tree, heap, inserted_exprs);
03817 VEC_free (tree, heap, need_creation);
03818 bitmap_obstack_release (&grand_bitmap_obstack);
03819 free_alloc_pool (value_set_pool);
03820 free_alloc_pool (bitmap_set_pool);
03821 free_alloc_pool (value_set_node_pool);
03822 free_alloc_pool (binary_node_pool);
03823 free_alloc_pool (reference_node_pool);
03824 free_alloc_pool (unary_node_pool);
03825 free_alloc_pool (list_node_pool);
03826 free_alloc_pool (expression_node_pool);
03827 free_alloc_pool (comparison_node_pool);
03828 free_alloc_pool (modify_expr_node_pool);
03829 htab_delete (phi_translate_table);
03830 remove_fake_exit_edges ();
03831
03832 FOR_ALL_BB (bb)
03833 {
03834 free (bb->aux);
03835 bb->aux = NULL;
03836 }
03837
03838 free_dominance_info (CDI_POST_DOMINATORS);
03839 vn_delete ();
03840
03841 if (!bitmap_empty_p (need_eh_cleanup))
03842 {
03843 tree_purge_all_dead_eh_edges (need_eh_cleanup);
03844 cleanup_tree_cfg ();
03845 }
03846
03847 BITMAP_FREE (need_eh_cleanup);
03848
03849
03850
03851 for (i = 0; i < num_ssa_names; i++)
03852 {
03853 tree name = ssa_name (i);
03854
03855 if (!name)
03856 continue;
03857
03858 if (SSA_NAME_VALUE (name)
03859 && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
03860 SSA_NAME_VALUE (name) = NULL;
03861 }
03862 if (!do_fre && current_loops)
03863 {
03864 loop_optimizer_finalize (current_loops);
03865 current_loops = NULL;
03866 }
03867 }
03868
03869
03870
03871
03872 static void
03873 execute_pre (bool do_fre)
03874 {
03875 init_pre (do_fre);
03876
03877 if (!do_fre)
03878 insert_fake_stores ();
03879
03880
03881 compute_avail ();
03882
03883 if (dump_file && (dump_flags & TDF_DETAILS))
03884 {
03885 basic_block bb;
03886
03887 FOR_ALL_BB (bb)
03888 {
03889 print_value_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
03890 bitmap_print_value_set (dump_file, TMP_GEN (bb), "tmp_gen",
03891 bb->index);
03892 bitmap_print_value_set (dump_file, AVAIL_OUT (bb), "avail_out",
03893 bb->index);
03894 }
03895 }
03896
03897
03898
03899
03900
03901
03902 if (!do_fre && n_basic_blocks < 4000)
03903 {
03904 vuse_names = XCNEWVEC (bitmap, num_ssa_names);
03905 compute_rvuse_and_antic_safe ();
03906 compute_antic ();
03907 insert ();
03908 free (vuse_names);
03909 }
03910
03911
03912 eliminate ();
03913
03914
03915 if (dump_file && (dump_flags & TDF_STATS))
03916 {
03917 fprintf (dump_file, "Insertions: %d\n", pre_stats.insertions);
03918 fprintf (dump_file, "New PHIs: %d\n", pre_stats.phis);
03919 fprintf (dump_file, "Eliminated: %d\n", pre_stats.eliminations);
03920 fprintf (dump_file, "Constified: %d\n", pre_stats.constified);
03921 }
03922
03923 bsi_commit_edge_inserts ();
03924
03925 if (!do_fre)
03926 {
03927 remove_dead_inserted_code ();
03928 realify_fake_stores ();
03929 }
03930
03931 fini_pre (do_fre);
03932
03933 }
03934
03935
03936
03937 static unsigned int
03938 do_pre (void)
03939 {
03940 execute_pre (false);
03941 return 0;
03942 }
03943
03944 static bool
03945 gate_pre (void)
03946 {
03947 return flag_tree_pre != 0;
03948 }
03949
03950 struct tree_opt_pass pass_pre =
03951 {
03952 "pre",
03953 gate_pre,
03954 do_pre,
03955 NULL,
03956 NULL,
03957 0,
03958 TV_TREE_PRE,
03959 PROP_no_crit_edges | PROP_cfg
03960 | PROP_ssa | PROP_alias,
03961 0,
03962 0,
03963 0,
03964 TODO_update_ssa_only_virtuals | TODO_dump_func | TODO_ggc_collect
03965 | TODO_verify_ssa,
03966 0
03967 };
03968
03969
03970
03971
03972 static unsigned int
03973 execute_fre (void)
03974 {
03975 execute_pre (true);
03976 return 0;
03977 }
03978
03979 static bool
03980 gate_fre (void)
03981 {
03982 return flag_tree_fre != 0;
03983 }
03984
03985 struct tree_opt_pass pass_fre =
03986 {
03987 "fre",
03988 gate_fre,
03989 execute_fre,
03990 NULL,
03991 NULL,
03992 0,
03993 TV_TREE_FRE,
03994 PROP_cfg | PROP_ssa | PROP_alias,
03995 0,
03996 0,
03997 0,
03998 TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa,
03999 0
04000 };