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 "errors.h"
00028 #include "ggc.h"
00029 #include "tree.h"
00030 #include "basic-block.h"
00031 #include "diagnostic.h"
00032 #include "tree-inline.h"
00033 #include "tree-flow.h"
00034 #include "tree-gimple.h"
00035 #include "tree-dump.h"
00036 #include "timevar.h"
00037 #include "fibheap.h"
00038 #include "hashtab.h"
00039 #include "tree-iterator.h"
00040 #include "real.h"
00041 #include "alloc-pool.h"
00042 #include "tree-pass.h"
00043 #include "flags.h"
00044 #include "bitmap.h"
00045 #include "langhooks.h"
00046 #include "cfgloop.h"
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
00182
00183 typedef struct value_set_node
00184 {
00185
00186 tree expr;
00187
00188
00189 struct value_set_node *next;
00190 } *value_set_node_t;
00191
00192
00193
00194
00195
00196 typedef struct value_set
00197 {
00198
00199
00200 value_set_node_t head;
00201
00202
00203
00204
00205 value_set_node_t tail;
00206
00207
00208 size_t length;
00209
00210
00211
00212
00213 bool indexed;
00214
00215
00216
00217 bitmap values;
00218
00219 } *value_set_t;
00220
00221
00222
00223
00224 typedef struct bitmap_set
00225 {
00226 bitmap expressions;
00227 bitmap values;
00228 } *bitmap_set_t;
00229
00230
00231 typedef struct bb_value_sets
00232 {
00233
00234
00235 value_set_t exp_gen;
00236
00237
00238
00239 bitmap_set_t phi_gen;
00240
00241
00242
00243 bitmap_set_t tmp_gen;
00244
00245
00246
00247 bitmap_set_t avail_out;
00248
00249
00250
00251 value_set_t antic_in;
00252
00253
00254
00255
00256 bitmap_set_t new_sets;
00257 } *bb_value_sets_t;
00258
00259 #define EXP_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->exp_gen
00260 #define PHI_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->phi_gen
00261 #define TMP_GEN(BB) ((bb_value_sets_t) ((BB)->aux))->tmp_gen
00262 #define AVAIL_OUT(BB) ((bb_value_sets_t) ((BB)->aux))->avail_out
00263 #define ANTIC_IN(BB) ((bb_value_sets_t) ((BB)->aux))->antic_in
00264 #define NEW_SETS(BB) ((bb_value_sets_t) ((BB)->aux))->new_sets
00265
00266
00267
00268 static struct
00269 {
00270
00271 int eliminations;
00272
00273
00274 int insertions;
00275
00276
00277 int phis;
00278
00279
00280 int constified;
00281
00282 } pre_stats;
00283
00284
00285 static tree bitmap_find_leader (bitmap_set_t, tree);
00286 static tree find_leader (value_set_t, tree);
00287 static void value_insert_into_set (value_set_t, tree);
00288 static void bitmap_value_insert_into_set (bitmap_set_t, tree);
00289 static void bitmap_value_replace_in_set (bitmap_set_t, tree);
00290 static void insert_into_set (value_set_t, tree);
00291 static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
00292 static bool bitmap_set_contains_value (bitmap_set_t, tree);
00293 static bitmap_set_t bitmap_set_new (void);
00294 static value_set_t set_new (bool);
00295 static bool is_undefined_value (tree);
00296 static tree create_expression_by_pieces (basic_block, tree, tree);
00297
00298
00299
00300
00301
00302 static alloc_pool value_set_pool;
00303 static alloc_pool bitmap_set_pool;
00304 static alloc_pool value_set_node_pool;
00305 static alloc_pool binary_node_pool;
00306 static alloc_pool unary_node_pool;
00307 static alloc_pool reference_node_pool;
00308 static bitmap_obstack grand_bitmap_obstack;
00309
00310
00311
00312 static bitmap need_eh_cleanup;
00313
00314
00315
00316
00317 static htab_t phi_translate_table;
00318
00319
00320
00321
00322 typedef struct expr_pred_trans_d
00323 {
00324
00325 tree e;
00326
00327
00328 basic_block pred;
00329
00330
00331 tree v;
00332
00333
00334
00335 hashval_t hashcode;
00336 } *expr_pred_trans_t;
00337
00338
00339
00340 static hashval_t
00341 expr_pred_trans_hash (const void *p)
00342 {
00343 const expr_pred_trans_t ve = (expr_pred_trans_t) p;
00344 return ve->hashcode;
00345 }
00346
00347
00348
00349
00350 static int
00351 expr_pred_trans_eq (const void *p1, const void *p2)
00352 {
00353 const expr_pred_trans_t ve1 = (expr_pred_trans_t) p1;
00354 const expr_pred_trans_t ve2 = (expr_pred_trans_t) p2;
00355 basic_block b1 = ve1->pred;
00356 basic_block b2 = ve2->pred;
00357
00358
00359
00360
00361 if (b1 != b2)
00362 return false;
00363
00364
00365
00366 if (expressions_equal_p (ve1->e, ve2->e))
00367 return true;
00368
00369 return false;
00370 }
00371
00372
00373
00374
00375
00376 static inline tree
00377 phi_trans_lookup (tree e, basic_block pred)
00378 {
00379 void **slot;
00380 struct expr_pred_trans_d ept;
00381 ept.e = e;
00382 ept.pred = pred;
00383 ept.hashcode = vn_compute (e, (unsigned long) pred, NULL);
00384 slot = htab_find_slot_with_hash (phi_translate_table, &ept, ept.hashcode,
00385 NO_INSERT);
00386 if (!slot)
00387 return NULL;
00388 else
00389 return ((expr_pred_trans_t) *slot)->v;
00390 }
00391
00392
00393
00394
00395
00396 static inline void
00397 phi_trans_add (tree e, tree v, basic_block pred)
00398 {
00399 void **slot;
00400 expr_pred_trans_t new_pair = xmalloc (sizeof (*new_pair));
00401 new_pair->e = e;
00402 new_pair->pred = pred;
00403 new_pair->v = v;
00404 new_pair->hashcode = vn_compute (e, (unsigned long) pred, NULL);
00405 slot = htab_find_slot_with_hash (phi_translate_table, new_pair,
00406 new_pair->hashcode, INSERT);
00407 if (*slot)
00408 free (*slot);
00409 *slot = (void *) new_pair;
00410 }
00411
00412
00413
00414
00415 void
00416 add_to_value (tree v, tree e)
00417 {
00418
00419 if (is_gimple_min_invariant (v))
00420 return;
00421
00422 if (VALUE_HANDLE_EXPR_SET (v) == NULL)
00423 VALUE_HANDLE_EXPR_SET (v) = set_new (false);
00424
00425 insert_into_set (VALUE_HANDLE_EXPR_SET (v), e);
00426 }
00427
00428
00429
00430
00431 static inline bool
00432 value_exists_in_set_bitmap (value_set_t set, tree v)
00433 {
00434 if (!set->values)
00435 return false;
00436
00437 return bitmap_bit_p (set->values, VALUE_HANDLE_ID (v));
00438 }
00439
00440
00441
00442
00443 static void
00444 value_remove_from_set_bitmap (value_set_t set, tree v)
00445 {
00446 gcc_assert (set->indexed);
00447
00448 if (!set->values)
00449 return;
00450
00451 bitmap_clear_bit (set->values, VALUE_HANDLE_ID (v));
00452 }
00453
00454
00455
00456
00457
00458 static inline void
00459 value_insert_into_set_bitmap (value_set_t set, tree v)
00460 {
00461 gcc_assert (set->indexed);
00462
00463 if (set->values == NULL)
00464 set->values = BITMAP_ALLOC (&grand_bitmap_obstack);
00465
00466 bitmap_set_bit (set->values, VALUE_HANDLE_ID (v));
00467 }
00468
00469
00470
00471
00472 static bitmap_set_t
00473 bitmap_set_new (void)
00474 {
00475 bitmap_set_t ret = pool_alloc (bitmap_set_pool);
00476 ret->expressions = BITMAP_ALLOC (&grand_bitmap_obstack);
00477 ret->values = BITMAP_ALLOC (&grand_bitmap_obstack);
00478 return ret;
00479 }
00480
00481
00482
00483 static value_set_t
00484 set_new (bool indexed)
00485 {
00486 value_set_t ret;
00487 ret = pool_alloc (value_set_pool);
00488 ret->head = ret->tail = NULL;
00489 ret->length = 0;
00490 ret->indexed = indexed;
00491 ret->values = NULL;
00492 return ret;
00493 }
00494
00495
00496
00497 static void
00498 bitmap_insert_into_set (bitmap_set_t set, tree expr)
00499 {
00500 tree val;
00501
00502 gcc_assert (TREE_CODE (expr) == SSA_NAME);
00503 val = get_value_handle (expr);
00504
00505 gcc_assert (val);
00506 if (!is_gimple_min_invariant (val))
00507 {
00508 bitmap_set_bit (set->values, VALUE_HANDLE_ID (val));
00509 bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
00510 }
00511 }
00512
00513
00514
00515 static void
00516 insert_into_set (value_set_t set, tree expr)
00517 {
00518 value_set_node_t newnode = pool_alloc (value_set_node_pool);
00519 tree val = get_value_handle (expr);
00520 gcc_assert (val);
00521
00522 if (is_gimple_min_invariant (val))
00523 return;
00524
00525
00526
00527
00528 if (set->indexed)
00529 value_insert_into_set_bitmap (set, val);
00530
00531 newnode->next = NULL;
00532 newnode->expr = expr;
00533 set->length ++;
00534 if (set->head == NULL)
00535 {
00536 set->head = set->tail = newnode;
00537 }
00538 else
00539 {
00540 set->tail->next = newnode;
00541 set->tail = newnode;
00542 }
00543 }
00544
00545
00546
00547 static void
00548 bitmap_set_copy (bitmap_set_t dest, bitmap_set_t orig)
00549 {
00550 bitmap_copy (dest->expressions, orig->expressions);
00551 bitmap_copy (dest->values, orig->values);
00552 }
00553
00554
00555
00556 static void
00557 set_copy (value_set_t dest, value_set_t orig)
00558 {
00559 value_set_node_t node;
00560
00561 if (!orig || !orig->head)
00562 return;
00563
00564 for (node = orig->head;
00565 node;
00566 node = node->next)
00567 {
00568 insert_into_set (dest, node->expr);
00569 }
00570 }
00571
00572
00573
00574 static void
00575 set_remove (value_set_t set, tree expr)
00576 {
00577 value_set_node_t node, prev;
00578
00579
00580
00581 value_remove_from_set_bitmap (set, get_value_handle (expr));
00582 set->length--;
00583 prev = NULL;
00584 for (node = set->head;
00585 node != NULL;
00586 prev = node, node = node->next)
00587 {
00588 if (node->expr == expr)
00589 {
00590 if (prev == NULL)
00591 set->head = node->next;
00592 else
00593 prev->next= node->next;
00594
00595 if (node == set->tail)
00596 set->tail = prev;
00597 pool_free (value_set_node_pool, node);
00598 return;
00599 }
00600 }
00601 }
00602
00603
00604
00605 static bool
00606 set_contains_value (value_set_t set, tree val)
00607 {
00608
00609 if (is_gimple_min_invariant (val))
00610 return true;
00611
00612 if (set->length == 0)
00613 return false;
00614
00615 return value_exists_in_set_bitmap (set, val);
00616 }
00617
00618
00619 static bool
00620 bitmap_set_contains (bitmap_set_t set, tree expr)
00621 {
00622
00623 if (is_gimple_min_invariant (get_value_handle (expr)))
00624 return true;
00625
00626
00627 if (TREE_CODE (expr) != SSA_NAME)
00628 return false;
00629 return bitmap_bit_p (set->expressions, SSA_NAME_VERSION (expr));
00630 }
00631
00632
00633
00634
00635 static bool
00636 bitmap_set_contains_value (bitmap_set_t set, tree val)
00637 {
00638 if (is_gimple_min_invariant (val))
00639 return true;
00640 return bitmap_bit_p (set->values, VALUE_HANDLE_ID (val));
00641 }
00642
00643
00644
00645 static void
00646 bitmap_set_replace_value (bitmap_set_t set, tree lookfor, tree expr)
00647 {
00648 value_set_t exprset;
00649 value_set_node_t node;
00650 if (is_gimple_min_invariant (lookfor))
00651 return;
00652 if (!bitmap_set_contains_value (set, lookfor))
00653 return;
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 exprset = VALUE_HANDLE_EXPR_SET (lookfor);
00665 for (node = exprset->head; node; node = node->next)
00666 {
00667 if (TREE_CODE (node->expr) == SSA_NAME)
00668 {
00669 if (bitmap_bit_p (set->expressions, SSA_NAME_VERSION (node->expr)))
00670 {
00671 bitmap_clear_bit (set->expressions, SSA_NAME_VERSION (node->expr));
00672 bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
00673 return;
00674 }
00675 }
00676 }
00677 }
00678
00679
00680
00681 static value_set_t
00682 bitmap_set_subtract_from_value_set (value_set_t a, bitmap_set_t b,
00683 bool indexed)
00684 {
00685 value_set_t ret = set_new (indexed);
00686 value_set_node_t node;
00687 for (node = a->head;
00688 node;
00689 node = node->next)
00690 {
00691 if (!bitmap_set_contains (b, node->expr))
00692 insert_into_set (ret, node->expr);
00693 }
00694 return ret;
00695 }
00696
00697
00698
00699 static bool
00700 set_equal (value_set_t a, value_set_t b)
00701 {
00702 value_set_node_t node;
00703
00704 if (a->length != b->length)
00705 return false;
00706 for (node = a->head;
00707 node;
00708 node = node->next)
00709 {
00710 if (!set_contains_value (b, get_value_handle (node->expr)))
00711 return false;
00712 }
00713 return true;
00714 }
00715
00716
00717
00718
00719 static void
00720 bitmap_value_replace_in_set (bitmap_set_t set, tree expr)
00721 {
00722 tree val = get_value_handle (expr);
00723 if (bitmap_set_contains_value (set, val))
00724 bitmap_set_replace_value (set, val, expr);
00725 else
00726 bitmap_insert_into_set (set, expr);
00727 }
00728
00729
00730
00731
00732 static void
00733 bitmap_value_insert_into_set (bitmap_set_t set, tree expr)
00734 {
00735 tree val = get_value_handle (expr);
00736
00737 if (is_gimple_min_invariant (val))
00738 return;
00739
00740 if (!bitmap_set_contains_value (set, val))
00741 bitmap_insert_into_set (set, expr);
00742 }
00743
00744
00745
00746 static void
00747 value_insert_into_set (value_set_t set, tree expr)
00748 {
00749 tree val = get_value_handle (expr);
00750
00751
00752
00753 if (is_gimple_min_invariant (val))
00754 return;
00755
00756 if (!set_contains_value (set, val))
00757 insert_into_set (set, expr);
00758 }
00759
00760
00761
00762
00763 static void
00764 bitmap_print_value_set (FILE *outfile, bitmap_set_t set,
00765 const char *setname, int blockindex)
00766 {
00767 fprintf (outfile, "%s[%d] := { ", setname, blockindex);
00768 if (set)
00769 {
00770 bool first = true;
00771 unsigned i;
00772 bitmap_iterator bi;
00773
00774 EXECUTE_IF_SET_IN_BITMAP (set->expressions, 0, i, bi)
00775 {
00776 if (!first)
00777 fprintf (outfile, ", ");
00778 first = false;
00779 print_generic_expr (outfile, ssa_name (i), 0);
00780
00781 fprintf (outfile, " (");
00782 print_generic_expr (outfile, get_value_handle (ssa_name (i)), 0);
00783 fprintf (outfile, ") ");
00784 }
00785 }
00786 fprintf (outfile, " }\n");
00787 }
00788
00789
00790 static void
00791 print_value_set (FILE *outfile, value_set_t set,
00792 const char *setname, int blockindex)
00793 {
00794 value_set_node_t node;
00795 fprintf (outfile, "%s[%d] := { ", setname, blockindex);
00796 if (set)
00797 {
00798 for (node = set->head;
00799 node;
00800 node = node->next)
00801 {
00802 print_generic_expr (outfile, node->expr, 0);
00803
00804 fprintf (outfile, " (");
00805 print_generic_expr (outfile, get_value_handle (node->expr), 0);
00806 fprintf (outfile, ") ");
00807
00808 if (node->next)
00809 fprintf (outfile, ", ");
00810 }
00811 }
00812
00813 fprintf (outfile, " }\n");
00814 }
00815
00816
00817
00818 void
00819 print_value_expressions (FILE *outfile, tree val)
00820 {
00821 if (VALUE_HANDLE_EXPR_SET (val))
00822 {
00823 char s[10];
00824 sprintf (s, "VH.%04d", VALUE_HANDLE_ID (val));
00825 print_value_set (outfile, VALUE_HANDLE_EXPR_SET (val), s, 0);
00826 }
00827 }
00828
00829
00830 void
00831 debug_value_expressions (tree val)
00832 {
00833 print_value_expressions (stderr, val);
00834 }
00835
00836
00837 void debug_value_set (value_set_t, const char *, int);
00838
00839 void
00840 debug_value_set (value_set_t set, const char *setname, int blockindex)
00841 {
00842 print_value_set (stderr, set, setname, blockindex);
00843 }
00844
00845
00846
00847
00848
00849 static tree
00850 phi_translate (tree expr, value_set_t set, basic_block pred,
00851 basic_block phiblock)
00852 {
00853 tree phitrans = NULL;
00854 tree oldexpr = expr;
00855
00856 if (expr == NULL)
00857 return NULL;
00858
00859 if (is_gimple_min_invariant (expr))
00860 return expr;
00861
00862
00863 phitrans = phi_trans_lookup (expr, pred);
00864 if (phitrans)
00865 return phitrans;
00866
00867 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
00868 {
00869 case tcc_reference:
00870
00871 return NULL;
00872
00873 case tcc_binary:
00874 {
00875 tree oldop1 = TREE_OPERAND (expr, 0);
00876 tree oldop2 = TREE_OPERAND (expr, 1);
00877 tree newop1;
00878 tree newop2;
00879 tree newexpr;
00880
00881 newop1 = phi_translate (find_leader (set, oldop1),
00882 set, pred, phiblock);
00883 if (newop1 == NULL)
00884 return NULL;
00885 newop2 = phi_translate (find_leader (set, oldop2),
00886 set, pred, phiblock);
00887 if (newop2 == NULL)
00888 return NULL;
00889 if (newop1 != oldop1 || newop2 != oldop2)
00890 {
00891 newexpr = pool_alloc (binary_node_pool);
00892 memcpy (newexpr, expr, tree_size (expr));
00893 create_tree_ann (newexpr);
00894 TREE_OPERAND (newexpr, 0) = newop1 == oldop1 ? oldop1 : get_value_handle (newop1);
00895 TREE_OPERAND (newexpr, 1) = newop2 == oldop2 ? oldop2 : get_value_handle (newop2);
00896 vn_lookup_or_add (newexpr, NULL);
00897 expr = newexpr;
00898 phi_trans_add (oldexpr, newexpr, pred);
00899 }
00900 }
00901 return expr;
00902
00903 case tcc_unary:
00904 {
00905 tree oldop1 = TREE_OPERAND (expr, 0);
00906 tree newop1;
00907 tree newexpr;
00908
00909 newop1 = phi_translate (find_leader (set, oldop1),
00910 set, pred, phiblock);
00911 if (newop1 == NULL)
00912 return NULL;
00913 if (newop1 != oldop1)
00914 {
00915 newexpr = pool_alloc (unary_node_pool);
00916 memcpy (newexpr, expr, tree_size (expr));
00917 create_tree_ann (newexpr);
00918 TREE_OPERAND (newexpr, 0) = get_value_handle (newop1);
00919 vn_lookup_or_add (newexpr, NULL);
00920 expr = newexpr;
00921 phi_trans_add (oldexpr, newexpr, pred);
00922 }
00923 }
00924 return expr;
00925
00926 case tcc_exceptional:
00927 {
00928 tree phi = NULL;
00929 edge e;
00930 gcc_assert (TREE_CODE (expr) == SSA_NAME);
00931 if (TREE_CODE (SSA_NAME_DEF_STMT (expr)) == PHI_NODE)
00932 phi = SSA_NAME_DEF_STMT (expr);
00933 else
00934 return expr;
00935
00936 e = find_edge (pred, bb_for_stmt (phi));
00937 if (e)
00938 {
00939 if (is_undefined_value (PHI_ARG_DEF (phi, e->dest_idx)))
00940 return NULL;
00941 vn_lookup_or_add (PHI_ARG_DEF (phi, e->dest_idx), NULL);
00942 return PHI_ARG_DEF (phi, e->dest_idx);
00943 }
00944 }
00945 return expr;
00946
00947 default:
00948 gcc_unreachable ();
00949 }
00950 }
00951
00952 static void
00953 phi_translate_set (value_set_t dest, value_set_t set, basic_block pred,
00954 basic_block phiblock)
00955 {
00956 value_set_node_t node;
00957 for (node = set->head;
00958 node;
00959 node = node->next)
00960 {
00961 tree translated;
00962 translated = phi_translate (node->expr, set, pred, phiblock);
00963 phi_trans_add (node->expr, translated, pred);
00964
00965 if (translated != NULL)
00966 value_insert_into_set (dest, translated);
00967 }
00968 }
00969
00970
00971
00972
00973
00974 static tree
00975 bitmap_find_leader (bitmap_set_t set, tree val)
00976 {
00977 if (val == NULL)
00978 return NULL;
00979
00980 if (is_gimple_min_invariant (val))
00981 return val;
00982 if (bitmap_set_contains_value (set, val))
00983 {
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995 value_set_t exprset;
00996 value_set_node_t node;
00997 exprset = VALUE_HANDLE_EXPR_SET (val);
00998 for (node = exprset->head; node; node = node->next)
00999 {
01000 if (TREE_CODE (node->expr) == SSA_NAME)
01001 {
01002 if (bitmap_bit_p (set->expressions,
01003 SSA_NAME_VERSION (node->expr)))
01004 return node->expr;
01005 }
01006 }
01007 }
01008 return NULL;
01009 }
01010
01011
01012
01013
01014
01015
01016 static tree
01017 find_leader (value_set_t set, tree val)
01018 {
01019 value_set_node_t node;
01020
01021 if (val == NULL)
01022 return NULL;
01023
01024
01025 if (is_gimple_min_invariant (val))
01026 return val;
01027
01028 if (set->length == 0)
01029 return NULL;
01030
01031 if (value_exists_in_set_bitmap (set, val))
01032 {
01033 for (node = set->head;
01034 node;
01035 node = node->next)
01036 {
01037 if (get_value_handle (node->expr) == val)
01038 return node->expr;
01039 }
01040 }
01041
01042 return NULL;
01043 }
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 static bool
01055 valid_in_set (value_set_t set, tree expr)
01056 {
01057 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
01058 {
01059 case tcc_binary:
01060 {
01061 tree op1 = TREE_OPERAND (expr, 0);
01062 tree op2 = TREE_OPERAND (expr, 1);
01063 return set_contains_value (set, op1) && set_contains_value (set, op2);
01064 }
01065
01066 case tcc_unary:
01067 {
01068 tree op1 = TREE_OPERAND (expr, 0);
01069 return set_contains_value (set, op1);
01070 }
01071
01072 case tcc_reference:
01073
01074 return false;
01075
01076 case tcc_exceptional:
01077 gcc_assert (TREE_CODE (expr) == SSA_NAME);
01078 return true;
01079
01080 default:
01081
01082 gcc_unreachable ();
01083 }
01084 }
01085
01086
01087
01088
01089
01090 static void
01091 clean (value_set_t set)
01092 {
01093 value_set_node_t node;
01094 value_set_node_t next;
01095 node = set->head;
01096 while (node)
01097 {
01098 next = node->next;
01099 if (!valid_in_set (set, node->expr))
01100 set_remove (set, node->expr);
01101 node = next;
01102 }
01103 }
01104
01105 DEF_VEC_MALLOC_P (basic_block);
01106 sbitmap has_abnormal_preds;
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 static bool
01123 compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
01124 {
01125 basic_block son;
01126 bool changed = false;
01127 value_set_t S, old, ANTIC_OUT;
01128 value_set_node_t node;
01129
01130 ANTIC_OUT = S = NULL;
01131
01132
01133
01134 if (block_has_abnormal_pred_edge)
01135 goto maybe_dump_sets;
01136
01137 old = set_new (false);
01138 set_copy (old, ANTIC_IN (block));
01139 ANTIC_OUT = set_new (true);
01140
01141
01142 if (EDGE_COUNT (block->succs) == 0)
01143 ;
01144
01145
01146 else if (EDGE_COUNT (block->succs) == 1)
01147 {
01148 phi_translate_set (ANTIC_OUT, ANTIC_IN(EDGE_SUCC (block, 0)->dest),
01149 block, EDGE_SUCC (block, 0)->dest);
01150 }
01151
01152
01153 else
01154 {
01155 VEC (basic_block) * worklist;
01156 edge e;
01157 size_t i;
01158 basic_block bprime, first;
01159 edge_iterator ei;
01160
01161 worklist = VEC_alloc (basic_block, 2);
01162 FOR_EACH_EDGE (e, ei, block->succs)
01163 VEC_safe_push (basic_block, worklist, e->dest);
01164 first = VEC_index (basic_block, worklist, 0);
01165 set_copy (ANTIC_OUT, ANTIC_IN (first));
01166
01167 for (i = 1; VEC_iterate (basic_block, worklist, i, bprime); i++)
01168 {
01169 node = ANTIC_OUT->head;
01170 while (node)
01171 {
01172 tree val;
01173 value_set_node_t next = node->next;
01174 val = get_value_handle (node->expr);
01175 if (!set_contains_value (ANTIC_IN (bprime), val))
01176 set_remove (ANTIC_OUT, node->expr);
01177 node = next;
01178 }
01179 }
01180 VEC_free (basic_block, worklist);
01181 }
01182
01183
01184 S = bitmap_set_subtract_from_value_set (ANTIC_OUT, TMP_GEN (block), false);
01185
01186
01187 ANTIC_IN (block) = bitmap_set_subtract_from_value_set (EXP_GEN (block),
01188 TMP_GEN (block),
01189 true);
01190
01191
01192
01193 for (node = S->head; node; node = node->next)
01194 value_insert_into_set (ANTIC_IN (block), node->expr);
01195
01196 clean (ANTIC_IN (block));
01197 if (!set_equal (old, ANTIC_IN (block)))
01198 changed = true;
01199
01200 maybe_dump_sets:
01201 if (dump_file && (dump_flags & TDF_DETAILS))
01202 {
01203 if (ANTIC_OUT)
01204 print_value_set (dump_file, ANTIC_OUT, "ANTIC_OUT", block->index);
01205 print_value_set (dump_file, ANTIC_IN (block), "ANTIC_IN", block->index);
01206 if (S)
01207 print_value_set (dump_file, S, "S", block->index);
01208 }
01209
01210 for (son = first_dom_son (CDI_POST_DOMINATORS, block);
01211 son;
01212 son = next_dom_son (CDI_POST_DOMINATORS, son))
01213 {
01214 changed |= compute_antic_aux (son,
01215 TEST_BIT (has_abnormal_preds, son->index));
01216 }
01217 return changed;
01218 }
01219
01220
01221
01222 static void
01223 compute_antic (void)
01224 {
01225 bool changed = true;
01226 int num_iterations = 0;
01227 basic_block block;
01228
01229
01230
01231 has_abnormal_preds = sbitmap_alloc (last_basic_block);
01232 sbitmap_zero (has_abnormal_preds);
01233 FOR_EACH_BB (block)
01234 {
01235 edge_iterator ei;
01236 edge e;
01237
01238 FOR_EACH_EDGE (e, ei, block->preds)
01239 if (e->flags & EDGE_ABNORMAL)
01240 {
01241 SET_BIT (has_abnormal_preds, block->index);
01242 break;
01243 }
01244
01245
01246 ANTIC_IN (block) = set_new (true);
01247 }
01248
01249 ANTIC_IN (EXIT_BLOCK_PTR) = set_new (true);
01250
01251 while (changed)
01252 {
01253 num_iterations++;
01254 changed = false;
01255 changed = compute_antic_aux (EXIT_BLOCK_PTR, false);
01256 }
01257
01258 sbitmap_free (has_abnormal_preds);
01259
01260 if (dump_file && (dump_flags & TDF_STATS))
01261 fprintf (dump_file, "compute_antic required %d iterations\n", num_iterations);
01262 }
01263
01264 static VEC(tree_on_heap) *inserted_exprs;
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274 static tree
01275 find_or_generate_expression (basic_block block, tree expr, tree stmts)
01276 {
01277 tree genop = bitmap_find_leader (AVAIL_OUT (block), expr);
01278
01279
01280
01281
01282 if (genop == NULL)
01283 {
01284 genop = VALUE_HANDLE_EXPR_SET (expr)->head->expr;
01285 gcc_assert (UNARY_CLASS_P (genop)
01286 || BINARY_CLASS_P (genop)
01287 || REFERENCE_CLASS_P (genop));
01288 genop = create_expression_by_pieces (block, genop, stmts);
01289 }
01290 return genop;
01291 }
01292
01293 #define NECESSARY(stmt) stmt->common.asm_written_flag
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308 static tree
01309 create_expression_by_pieces (basic_block block, tree expr, tree stmts)
01310 {
01311 tree name = NULL_TREE;
01312 tree newexpr = NULL_TREE;
01313 tree v;
01314
01315 switch (TREE_CODE_CLASS (TREE_CODE (expr)))
01316 {
01317 case tcc_binary:
01318 {
01319 tree_stmt_iterator tsi;
01320 tree forced_stmts;
01321 tree genop1, genop2;
01322 tree temp;
01323 tree folded;
01324 tree op1 = TREE_OPERAND (expr, 0);
01325 tree op2 = TREE_OPERAND (expr, 1);
01326 genop1 = find_or_generate_expression (block, op1, stmts);
01327 genop2 = find_or_generate_expression (block, op2, stmts);
01328 temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
01329 add_referenced_tmp_var (temp);
01330
01331 folded = fold (build (TREE_CODE (expr), TREE_TYPE (expr),
01332 genop1, genop2));
01333 newexpr = force_gimple_operand (unshare_expr (folded),
01334 &forced_stmts, false, NULL);
01335 if (forced_stmts)
01336 {
01337 tsi = tsi_start (forced_stmts);
01338 for (; !tsi_end_p (tsi); tsi_next (&tsi))
01339 {
01340 tree stmt = tsi_stmt (tsi);
01341 tree forcedname = TREE_OPERAND (stmt, 0);
01342 tree forcedexpr = TREE_OPERAND (stmt, 1);
01343 tree val = vn_lookup_or_add (forcedexpr, NULL);
01344
01345 VEC_safe_push (tree_on_heap, inserted_exprs, stmt);
01346 vn_add (forcedname, val, NULL);
01347 bitmap_value_replace_in_set (NEW_SETS (block), forcedname);
01348 bitmap_value_replace_in_set (AVAIL_OUT (block), forcedname);
01349 }
01350
01351 tsi = tsi_last (stmts);
01352 tsi_link_after (&tsi, forced_stmts, TSI_CONTINUE_LINKING);
01353 }
01354 newexpr = build (MODIFY_EXPR, TREE_TYPE (expr),
01355 temp, newexpr);
01356 NECESSARY (newexpr) = 0;
01357 name = make_ssa_name (temp, newexpr);
01358 TREE_OPERAND (newexpr, 0) = name;
01359 tsi = tsi_last (stmts);
01360 tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
01361 VEC_safe_push (tree_on_heap, inserted_exprs, newexpr);
01362 pre_stats.insertions++;
01363 break;
01364 }
01365 case tcc_unary:
01366 {
01367 tree_stmt_iterator tsi;
01368 tree forced_stmts = NULL;
01369 tree genop1;
01370 tree temp;
01371 tree folded;
01372 tree op1 = TREE_OPERAND (expr, 0);
01373 genop1 = find_or_generate_expression (block, op1, stmts);
01374 temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
01375 add_referenced_tmp_var (temp);
01376 folded = fold (build (TREE_CODE (expr), TREE_TYPE (expr),
01377 genop1));
01378 newexpr = force_gimple_operand (unshare_expr (folded),
01379 &forced_stmts, false, NULL);
01380 if (forced_stmts)
01381 {
01382 tsi = tsi_start (forced_stmts);
01383 for (; !tsi_end_p (tsi); tsi_next (&tsi))
01384 {
01385 tree stmt = tsi_stmt (tsi);
01386 tree forcedname = TREE_OPERAND (stmt, 0);
01387 tree forcedexpr = TREE_OPERAND (stmt, 1);
01388 tree val = vn_lookup_or_add (forcedexpr, NULL);
01389
01390 VEC_safe_push (tree_on_heap, inserted_exprs, stmt);
01391 vn_add (forcedname, val, NULL);
01392 bitmap_value_replace_in_set (NEW_SETS (block), forcedname);
01393 bitmap_value_replace_in_set (AVAIL_OUT (block), forcedname);
01394 }
01395 tsi = tsi_last (stmts);
01396 tsi_link_after (&tsi, forced_stmts, TSI_CONTINUE_LINKING);
01397 }
01398 newexpr = build (MODIFY_EXPR, TREE_TYPE (expr),
01399 temp, newexpr);
01400 name = make_ssa_name (temp, newexpr);
01401 TREE_OPERAND (newexpr, 0) = name;
01402 NECESSARY (newexpr) = 0;
01403 tsi = tsi_last (stmts);
01404 tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
01405 VEC_safe_push (tree_on_heap, inserted_exprs, newexpr);
01406 pre_stats.insertions++;
01407
01408 break;
01409 }
01410 default:
01411 gcc_unreachable ();
01412
01413 }
01414 v = get_value_handle (expr);
01415 vn_add (name, v, NULL);
01416
01417
01418
01419
01420
01421 bitmap_value_replace_in_set (NEW_SETS (block), name);
01422 bitmap_value_replace_in_set (AVAIL_OUT (block), name);
01423 if (dump_file && (dump_flags & TDF_DETAILS))
01424 {
01425 fprintf (dump_file, "Inserted ");
01426 print_generic_expr (dump_file, newexpr, 0);
01427 fprintf (dump_file, " in predecessor %d\n", block->index);
01428 }
01429 return name;
01430 }
01431
01432
01433
01434
01435 static tree
01436 fully_constant_expression (tree t)
01437 {
01438 tree folded;
01439 folded = fold (t);
01440 if (folded && is_gimple_min_invariant (folded))
01441 return folded;
01442 return t;
01443 }
01444
01445
01446
01447
01448
01449
01450 static bool
01451 insert_into_preds_of_block (basic_block block, value_set_node_t node,
01452 tree *avail, const char *tmpname)
01453 {
01454 tree val = get_value_handle (node->expr);
01455 edge pred;
01456 bool insertions = false;
01457 bool nophi = false;
01458 basic_block bprime;
01459 tree eprime;
01460 edge_iterator ei;
01461 tree type = TREE_TYPE (avail[EDGE_PRED (block, 0)->src->index]);
01462 tree temp;
01463
01464 if (dump_file && (dump_flags & TDF_DETAILS))
01465 {
01466 fprintf (dump_file, "Found partial redundancy for expression ");
01467 print_generic_expr (dump_file, node->expr, 0);
01468 fprintf (dump_file, "\n");
01469 }
01470
01471
01472 if (block->loop_depth > 0 && EDGE_COUNT (block->preds) == 2)
01473 {
01474 bool firstinsideloop = false;
01475 bool secondinsideloop = false;
01476 firstinsideloop = flow_bb_inside_loop_p (block->loop_father,
01477 EDGE_PRED (block, 0)->src);
01478 secondinsideloop = flow_bb_inside_loop_p (block->loop_father,
01479 EDGE_PRED (block, 1)->src);
01480
01481 if (firstinsideloop ^ secondinsideloop)
01482 {
01483 if (dump_file && (dump_flags & TDF_DETAILS))
01484 fprintf (dump_file, "Skipping insertion of phi for partial redundancy: Looks like an induction variable\n");
01485 nophi = true;
01486 }
01487 }
01488
01489
01490
01491 FOR_EACH_EDGE (pred, ei, block->preds)
01492 {
01493 tree stmts = alloc_stmt_list ();
01494 tree builtexpr;
01495 bprime = pred->src;
01496 eprime = avail[bprime->index];
01497 if (BINARY_CLASS_P (eprime)
01498 || UNARY_CLASS_P (eprime))
01499 {
01500 builtexpr = create_expression_by_pieces (bprime,
01501 eprime,
01502 stmts);
01503 bsi_insert_on_edge (pred, stmts);
01504 avail[bprime->index] = builtexpr;
01505 insertions = true;
01506 }
01507 }
01508
01509
01510
01511
01512 if (nophi && insertions)
01513 return true;
01514 else if (nophi && !insertions)
01515 return false;
01516
01517
01518 temp = create_tmp_var (type, tmpname);
01519 add_referenced_tmp_var (temp);
01520 temp = create_phi_node (temp, block);
01521 NECESSARY (temp) = 0;
01522 VEC_safe_push (tree_on_heap, inserted_exprs, temp);
01523 FOR_EACH_EDGE (pred, ei, block->preds)
01524 add_phi_arg (temp, avail[pred->src->index], pred);
01525
01526 vn_add (PHI_RESULT (temp), val, NULL);
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542 bitmap_insert_into_set (PHI_GEN (block),
01543 PHI_RESULT (temp));
01544 bitmap_value_replace_in_set (AVAIL_OUT (block),
01545 PHI_RESULT (temp));
01546 bitmap_insert_into_set (NEW_SETS (block),
01547 PHI_RESULT (temp));
01548
01549 if (dump_file && (dump_flags & TDF_DETAILS))
01550 {
01551 fprintf (dump_file, "Created phi ");
01552 print_generic_expr (dump_file, temp, 0);
01553 fprintf (dump_file, " in block %d\n", block->index);
01554 }
01555 pre_stats.phis++;
01556 return true;
01557 }
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576 static bool
01577 insert_aux (basic_block block)
01578 {
01579 basic_block son;
01580 bool new_stuff = false;
01581
01582 if (block)
01583 {
01584 basic_block dom;
01585 dom = get_immediate_dominator (CDI_DOMINATORS, block);
01586 if (dom)
01587 {
01588 unsigned i;
01589 bitmap_iterator bi;
01590 bitmap_set_t newset = NEW_SETS (dom);
01591 if (newset)
01592 {
01593
01594
01595
01596
01597 EXECUTE_IF_SET_IN_BITMAP (newset->expressions, 0, i, bi)
01598 {
01599 bitmap_value_replace_in_set (NEW_SETS (block), ssa_name (i));
01600 bitmap_value_replace_in_set (AVAIL_OUT (block), ssa_name (i));
01601 }
01602 }
01603 if (EDGE_COUNT (block->preds) > 1)
01604 {
01605 value_set_node_t node;
01606 for (node = ANTIC_IN (block)->head;
01607 node;
01608 node = node->next)
01609 {
01610 if (BINARY_CLASS_P (node->expr)
01611 || UNARY_CLASS_P (node->expr))
01612 {
01613 tree *avail;
01614 tree val;
01615 bool by_some = false;
01616 bool cant_insert = false;
01617 bool all_same = true;
01618 tree first_s = NULL;
01619 edge pred;
01620 basic_block bprime;
01621 tree eprime = NULL_TREE;
01622 edge_iterator ei;
01623
01624 val = get_value_handle (node->expr);
01625 if (bitmap_set_contains_value (PHI_GEN (block), val))
01626 continue;
01627 if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
01628 {
01629 if (dump_file && (dump_flags & TDF_DETAILS))
01630 fprintf (dump_file, "Found fully redundant value\n");
01631 continue;
01632 }
01633
01634 avail = xcalloc (last_basic_block, sizeof (tree));
01635 FOR_EACH_EDGE (pred, ei, block->preds)
01636 {
01637 tree vprime;
01638 tree edoubleprime;
01639
01640
01641
01642
01643 if (EDGE_CRITICAL_P (pred))
01644 {
01645 cant_insert = true;
01646 break;
01647 }
01648 bprime = pred->src;
01649 eprime = phi_translate (node->expr,
01650 ANTIC_IN (block),
01651 bprime, block);
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662 if (eprime == NULL)
01663 {
01664 cant_insert = true;
01665 break;
01666 }
01667
01668 eprime = fully_constant_expression (eprime);
01669 vprime = get_value_handle (eprime);
01670 gcc_assert (vprime);
01671 edoubleprime = bitmap_find_leader (AVAIL_OUT (bprime),
01672 vprime);
01673 if (edoubleprime == NULL)
01674 {
01675 avail[bprime->index] = eprime;
01676 all_same = false;
01677 }
01678 else
01679 {
01680 avail[bprime->index] = edoubleprime;
01681 by_some = true;
01682 if (first_s == NULL)
01683 first_s = edoubleprime;
01684 else if (!operand_equal_p (first_s, edoubleprime,
01685 0))
01686 all_same = false;
01687 }
01688 }
01689
01690
01691
01692
01693 if (!cant_insert && !all_same && by_some)
01694 {
01695 if (insert_into_preds_of_block (block, node, avail,
01696 "prephitmp"))
01697 new_stuff = true;
01698 }
01699
01700
01701
01702 else if (!cant_insert && all_same && eprime
01703 && is_gimple_min_invariant (eprime)
01704 && !is_gimple_min_invariant (val))
01705 {
01706 value_set_t exprset = VALUE_HANDLE_EXPR_SET (val);
01707 value_set_node_t node;
01708 for (node = exprset->head; node; node = node->next)
01709 {
01710 if (TREE_CODE (node->expr) == SSA_NAME)
01711 {
01712 vn_add (node->expr, eprime, NULL);
01713 pre_stats.constified++;
01714 }
01715 }
01716 }
01717 free (avail);
01718 }
01719 }
01720 }
01721 }
01722 }
01723 for (son = first_dom_son (CDI_DOMINATORS, block);
01724 son;
01725 son = next_dom_son (CDI_DOMINATORS, son))
01726 {
01727 new_stuff |= insert_aux (son);
01728 }
01729
01730 return new_stuff;
01731 }
01732
01733
01734
01735 static void
01736 insert (void)
01737 {
01738 bool new_stuff = true;
01739 basic_block bb;
01740 int num_iterations = 0;
01741
01742 FOR_ALL_BB (bb)
01743 NEW_SETS (bb) = bitmap_set_new ();
01744
01745 while (new_stuff)
01746 {
01747 num_iterations++;
01748 new_stuff = false;
01749 new_stuff = insert_aux (ENTRY_BLOCK_PTR);
01750 }
01751 if (num_iterations > 2 && dump_file && (dump_flags & TDF_STATS))
01752 fprintf (dump_file, "insert required %d iterations\n", num_iterations);
01753 }
01754
01755
01756
01757
01758
01759 static bool
01760 is_undefined_value (tree expr)
01761 {
01762 return (TREE_CODE (expr) == SSA_NAME
01763 && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (expr))
01764
01765 && TREE_CODE (SSA_NAME_VAR (expr)) != PARM_DECL);
01766 }
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777 static inline void
01778 add_to_sets (tree var, tree expr, vuse_optype vuses, bitmap_set_t s1,
01779 bitmap_set_t s2)
01780 {
01781 tree val = vn_lookup_or_add (expr, vuses);
01782
01783
01784
01785
01786
01787 if (var != expr)
01788 vn_add (var, val, NULL);
01789
01790 if (s1)
01791 bitmap_insert_into_set (s1, var);
01792 bitmap_value_insert_into_set (s2, var);
01793 }
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804 static inline tree
01805 create_value_expr_from (tree expr, basic_block block, vuse_optype vuses)
01806 {
01807 int i;
01808 enum tree_code code = TREE_CODE (expr);
01809 tree vexpr;
01810
01811 gcc_assert (TREE_CODE_CLASS (code) == tcc_unary
01812 || TREE_CODE_CLASS (code) == tcc_binary
01813 || TREE_CODE_CLASS (code) == tcc_reference);
01814
01815 if (TREE_CODE_CLASS (code) == tcc_unary)
01816 vexpr = pool_alloc (unary_node_pool);
01817 else if (TREE_CODE_CLASS (code) == tcc_reference)
01818 vexpr = pool_alloc (reference_node_pool);
01819 else
01820 vexpr = pool_alloc (binary_node_pool);
01821
01822 memcpy (vexpr, expr, tree_size (expr));
01823
01824 for (i = 0; i < TREE_CODE_LENGTH (code); i++)
01825 {
01826 tree op = TREE_OPERAND (expr, i);
01827 if (op != NULL)
01828 {
01829 tree val = vn_lookup_or_add (op, vuses);
01830 if (!is_undefined_value (op))
01831 value_insert_into_set (EXP_GEN (block), op);
01832 if (TREE_CODE (val) == VALUE_HANDLE)
01833 TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
01834 TREE_OPERAND (vexpr, i) = val;
01835 }
01836 }
01837
01838 return vexpr;
01839 }
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852 static void
01853 compute_avail (void)
01854 {
01855 basic_block block, son;
01856 basic_block *worklist;
01857 size_t sp = 0;
01858 tree param;
01859
01860
01861
01862 for (param = DECL_ARGUMENTS (current_function_decl);
01863 param;
01864 param = TREE_CHAIN (param))
01865 {
01866 if (default_def (param) != NULL)
01867 {
01868 tree val;
01869 tree def = default_def (param);
01870 val = vn_lookup_or_add (def, NULL);
01871 bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), def);
01872 bitmap_value_insert_into_set (AVAIL_OUT (ENTRY_BLOCK_PTR), def);
01873 }
01874 }
01875
01876
01877 worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
01878
01879
01880
01881 for (son = first_dom_son (CDI_DOMINATORS, ENTRY_BLOCK_PTR);
01882 son;
01883 son = next_dom_son (CDI_DOMINATORS, son))
01884 worklist[sp++] = son;
01885
01886
01887 while (sp)
01888 {
01889 block_stmt_iterator bsi;
01890 tree stmt, phi;
01891 basic_block dom;
01892
01893
01894 block = worklist[--sp];
01895
01896
01897
01898 dom = get_immediate_dominator (CDI_DOMINATORS, block);
01899 if (dom)
01900 bitmap_set_copy (AVAIL_OUT (block), AVAIL_OUT (dom));
01901
01902
01903 for (phi = phi_nodes (block); phi; phi = PHI_CHAIN (phi))
01904
01905
01906 if (is_gimple_reg (PHI_RESULT (phi)))
01907 add_to_sets (PHI_RESULT (phi), PHI_RESULT (phi), NULL,
01908 PHI_GEN (block), AVAIL_OUT (block));
01909
01910
01911
01912 for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
01913 {
01914 stmt_ann_t ann;
01915 size_t j;
01916
01917 stmt = bsi_stmt (bsi);
01918 ann = stmt_ann (stmt);
01919 get_stmt_operands (stmt);
01920
01921
01922
01923
01924
01925 if (TREE_CODE (stmt) == MODIFY_EXPR
01926 && !ann->has_volatile_ops
01927 && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
01928 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (stmt, 0)))
01929 {
01930 tree lhs = TREE_OPERAND (stmt, 0);
01931 tree rhs = TREE_OPERAND (stmt, 1);
01932 vuse_optype vuses = STMT_VUSE_OPS (stmt);
01933
01934 STRIP_USELESS_TYPE_CONVERSION (rhs);
01935 if (TREE_CODE (rhs) == SSA_NAME
01936 || is_gimple_min_invariant (rhs))
01937 {
01938
01939
01940
01941 add_to_sets (lhs, rhs, vuses, TMP_GEN (block),
01942 AVAIL_OUT (block));
01943
01944 if (TREE_CODE (rhs) == SSA_NAME
01945 && !is_undefined_value (rhs))
01946 value_insert_into_set (EXP_GEN (block), rhs);
01947 continue;
01948 }
01949 else if (UNARY_CLASS_P (rhs) || BINARY_CLASS_P (rhs)
01950 || TREE_CODE (rhs) == INDIRECT_REF)
01951 {
01952
01953
01954
01955
01956 tree newt = create_value_expr_from (rhs, block, vuses);
01957 add_to_sets (lhs, newt, vuses, TMP_GEN (block),
01958 AVAIL_OUT (block));
01959 value_insert_into_set (EXP_GEN (block), newt);
01960 continue;
01961 }
01962 }
01963
01964
01965
01966
01967 for (j = 0; j < NUM_DEFS (STMT_DEF_OPS (stmt)); j++)
01968 {
01969 tree def = DEF_OP (STMT_DEF_OPS (stmt), j);
01970 add_to_sets (def, def, NULL, TMP_GEN (block),
01971 AVAIL_OUT (block));
01972 }
01973
01974 for (j = 0; j < NUM_USES (STMT_USE_OPS (stmt)); j++)
01975 {
01976 tree use = USE_OP (STMT_USE_OPS (stmt), j);
01977 add_to_sets (use, use, NULL, NULL, AVAIL_OUT (block));
01978 }
01979 }
01980
01981
01982
01983 for (son = first_dom_son (CDI_DOMINATORS, block);
01984 son;
01985 son = next_dom_son (CDI_DOMINATORS, son))
01986 worklist[sp++] = son;
01987 }
01988
01989 free (worklist);
01990 }
01991
01992
01993
01994
01995 static void
01996 eliminate (void)
01997 {
01998 basic_block b;
01999
02000 FOR_EACH_BB (b)
02001 {
02002 block_stmt_iterator i;
02003
02004 for (i = bsi_start (b); !bsi_end_p (i); bsi_next (&i))
02005 {
02006 tree stmt = bsi_stmt (i);
02007
02008
02009
02010
02011 if (TREE_CODE (stmt) == MODIFY_EXPR
02012 && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME
02013 && TREE_CODE (TREE_OPERAND (stmt ,1)) != SSA_NAME
02014 && !is_gimple_min_invariant (TREE_OPERAND (stmt, 1))
02015 && !stmt_ann (stmt)->has_volatile_ops)
02016 {
02017 tree lhs = TREE_OPERAND (stmt, 0);
02018 tree *rhs_p = &TREE_OPERAND (stmt, 1);
02019 tree sprime;
02020
02021 sprime = bitmap_find_leader (AVAIL_OUT (b),
02022 vn_lookup (lhs, NULL));
02023 if (sprime
02024 && sprime != lhs
02025 && (TREE_CODE (*rhs_p) != SSA_NAME
02026 || may_propagate_copy (*rhs_p, sprime)))
02027 {
02028 gcc_assert (sprime != *rhs_p);
02029
02030 if (dump_file && (dump_flags & TDF_DETAILS))
02031 {
02032 fprintf (dump_file, "Replaced ");
02033 print_generic_expr (dump_file, *rhs_p, 0);
02034 fprintf (dump_file, " with ");
02035 print_generic_expr (dump_file, sprime, 0);
02036 fprintf (dump_file, " in ");
02037 print_generic_stmt (dump_file, stmt, 0);
02038 }
02039 if (TREE_CODE (sprime) == SSA_NAME)
02040 NECESSARY (SSA_NAME_DEF_STMT (sprime)) = 1;
02041 pre_stats.eliminations++;
02042 propagate_tree_value (rhs_p, sprime);
02043 modify_stmt (stmt);
02044
02045
02046
02047 if (maybe_clean_eh_stmt (stmt))
02048 {
02049 bitmap_set_bit (need_eh_cleanup,
02050 bb_for_stmt (stmt)->index);
02051 if (dump_file && (dump_flags & TDF_DETAILS))
02052 fprintf (dump_file, " Removed EH side effects.\n");
02053 }
02054 }
02055 }
02056 }
02057 }
02058 }
02059
02060
02061
02062
02063
02064
02065
02066
02067 static inline void
02068 mark_operand_necessary (tree op, VEC(tree_on_heap) **worklist)
02069 {
02070 tree stmt;
02071 int ver;
02072
02073 gcc_assert (op);
02074
02075 ver = SSA_NAME_VERSION (op);
02076
02077 stmt = SSA_NAME_DEF_STMT (op);
02078 gcc_assert (stmt);
02079
02080 if (NECESSARY (stmt)
02081 || IS_EMPTY_STMT (stmt))
02082 return;
02083
02084 NECESSARY (stmt) = 1;
02085 VEC_safe_push (tree_on_heap, *worklist, stmt);
02086 }
02087
02088
02089
02090
02091
02092
02093 static void
02094 remove_dead_inserted_code (void)
02095 {
02096 VEC (tree_on_heap) *worklist = NULL;
02097 int i;
02098 tree t;
02099
02100 for (i = 0; VEC_iterate (tree_on_heap, inserted_exprs, i, t); i++)
02101 {
02102 if (NECESSARY (t))
02103 VEC_safe_push (tree_on_heap, worklist, t);
02104 }
02105 while (VEC_length (tree_on_heap, worklist) > 0)
02106 {
02107 t = VEC_pop (tree_on_heap, worklist);
02108 if (TREE_CODE (t) == PHI_NODE)
02109 {
02110
02111
02112
02113
02114
02115
02116 int k;
02117 for (k = 0; k < PHI_NUM_ARGS (t); k++)
02118 {
02119 tree arg = PHI_ARG_DEF (t, k);
02120 if (TREE_CODE (arg) == SSA_NAME)
02121 mark_operand_necessary (arg, &worklist);
02122 }
02123 }
02124 else
02125 {
02126
02127
02128
02129 ssa_op_iter iter;
02130 tree use;
02131
02132 get_stmt_operands (t);
02133
02134
02135
02136
02137
02138
02139 FOR_EACH_SSA_TREE_OPERAND (use, t, iter, SSA_OP_ALL_USES)
02140 mark_operand_necessary (use, &worklist);
02141 }
02142 }
02143 for (i = 0; VEC_iterate (tree_on_heap, inserted_exprs, i, t); i++)
02144 {
02145 if (!NECESSARY (t))
02146 {
02147 block_stmt_iterator bsi;
02148 if (dump_file && (dump_flags & TDF_DETAILS))
02149 {
02150 fprintf (dump_file, "Removing unnecessary insertion:");
02151 print_generic_stmt (dump_file, t, 0);
02152 }
02153 if (TREE_CODE (t) == PHI_NODE)
02154 {
02155 remove_phi_node (t, NULL, bb_for_stmt (t));
02156 }
02157 else
02158 {
02159 bsi = bsi_for_stmt (t);
02160 bsi_remove (&bsi);
02161 }
02162 }
02163 }
02164 VEC_free (tree_on_heap, worklist);
02165 }
02166
02167
02168 static void
02169 init_pre (bool do_fre)
02170 {
02171 basic_block bb;
02172
02173 inserted_exprs = NULL;
02174 vn_init ();
02175 if (!do_fre)
02176 current_loops = loop_optimizer_init (dump_file);
02177 connect_infinite_loops_to_exit ();
02178 memset (&pre_stats, 0, sizeof (pre_stats));
02179
02180
02181
02182
02183
02184
02185
02186
02187 if (EDGE_COUNT (EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest->preds) > 1)
02188 if (!(EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->flags & EDGE_ABNORMAL))
02189 split_edge (EDGE_SUCC (ENTRY_BLOCK_PTR, 0));
02190
02191 FOR_ALL_BB (bb)
02192 bb->aux = xcalloc (1, sizeof (struct bb_value_sets));
02193
02194 bitmap_obstack_initialize (&grand_bitmap_obstack);
02195 phi_translate_table = htab_create (511, expr_pred_trans_hash,
02196 expr_pred_trans_eq, free);
02197 value_set_pool = create_alloc_pool ("Value sets",
02198 sizeof (struct value_set), 30);
02199 bitmap_set_pool = create_alloc_pool ("Bitmap sets",
02200 sizeof (struct bitmap_set), 30);
02201 value_set_node_pool = create_alloc_pool ("Value set nodes",
02202 sizeof (struct value_set_node), 30);
02203 calculate_dominance_info (CDI_POST_DOMINATORS);
02204 calculate_dominance_info (CDI_DOMINATORS);
02205 binary_node_pool = create_alloc_pool ("Binary tree nodes",
02206 tree_code_size (PLUS_EXPR), 30);
02207 unary_node_pool = create_alloc_pool ("Unary tree nodes",
02208 tree_code_size (NEGATE_EXPR), 30);
02209 reference_node_pool = create_alloc_pool ("Reference tree nodes",
02210 tree_code_size (ARRAY_REF), 30);
02211 FOR_ALL_BB (bb)
02212 {
02213 EXP_GEN (bb) = set_new (true);
02214 PHI_GEN (bb) = bitmap_set_new ();
02215 TMP_GEN (bb) = bitmap_set_new ();
02216 AVAIL_OUT (bb) = bitmap_set_new ();
02217 }
02218
02219 need_eh_cleanup = BITMAP_ALLOC (NULL);
02220 }
02221
02222
02223
02224
02225 static void
02226 fini_pre (bool do_fre)
02227 {
02228 basic_block bb;
02229 unsigned int i;
02230
02231 VEC_free (tree_on_heap, inserted_exprs);
02232 bitmap_obstack_release (&grand_bitmap_obstack);
02233 free_alloc_pool (value_set_pool);
02234 free_alloc_pool (bitmap_set_pool);
02235 free_alloc_pool (value_set_node_pool);
02236 free_alloc_pool (binary_node_pool);
02237 free_alloc_pool (reference_node_pool);
02238 free_alloc_pool (unary_node_pool);
02239 htab_delete (phi_translate_table);
02240 remove_fake_exit_edges ();
02241
02242 FOR_ALL_BB (bb)
02243 {
02244 free (bb->aux);
02245 bb->aux = NULL;
02246 }
02247
02248 free_dominance_info (CDI_POST_DOMINATORS);
02249 vn_delete ();
02250
02251 if (!bitmap_empty_p (need_eh_cleanup))
02252 {
02253 tree_purge_all_dead_eh_edges (need_eh_cleanup);
02254 cleanup_tree_cfg ();
02255 }
02256
02257 BITMAP_FREE (need_eh_cleanup);
02258
02259
02260
02261 for (i = 0; i < num_ssa_names; i++)
02262 {
02263 tree name = ssa_name (i);
02264
02265 if (!name)
02266 continue;
02267
02268 if (SSA_NAME_VALUE (name)
02269 && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
02270 SSA_NAME_VALUE (name) = NULL;
02271 }
02272 if (!do_fre && current_loops)
02273 {
02274 loop_optimizer_finalize (current_loops, dump_file);
02275 current_loops = NULL;
02276 }
02277 }
02278
02279
02280
02281
02282
02283 static void
02284 execute_pre (bool do_fre)
02285 {
02286 init_pre (do_fre);
02287
02288
02289 compute_avail ();
02290
02291 if (dump_file && (dump_flags & TDF_DETAILS))
02292 {
02293 basic_block bb;
02294
02295 FOR_ALL_BB (bb)
02296 {
02297 print_value_set (dump_file, EXP_GEN (bb), "exp_gen", bb->index);
02298 bitmap_print_value_set (dump_file, TMP_GEN (bb), "tmp_gen",
02299 bb->index);
02300 bitmap_print_value_set (dump_file, AVAIL_OUT (bb), "avail_out",
02301 bb->index);
02302 }
02303 }
02304
02305
02306
02307
02308
02309
02310 if (!do_fre && n_basic_blocks < 4000)
02311 {
02312 compute_antic ();
02313 insert ();
02314 }
02315
02316
02317 eliminate ();
02318
02319
02320 if (dump_file && (dump_flags & TDF_STATS))
02321 {
02322 fprintf (dump_file, "Insertions:%d\n", pre_stats.insertions);
02323 fprintf (dump_file, "New PHIs:%d\n", pre_stats.phis);
02324 fprintf (dump_file, "Eliminated:%d\n", pre_stats.eliminations);
02325 fprintf (dump_file, "Constified:%d\n", pre_stats.constified);
02326 }
02327
02328 bsi_commit_edge_inserts ();
02329 if (!do_fre)
02330 remove_dead_inserted_code ();
02331 fini_pre (do_fre);
02332
02333 }
02334
02335
02336
02337
02338 static void
02339 do_pre (void)
02340 {
02341 execute_pre (false);
02342 }
02343
02344 static bool
02345 gate_pre (void)
02346 {
02347 return flag_tree_pre != 0;
02348 }
02349
02350 struct tree_opt_pass pass_pre =
02351 {
02352 "pre",
02353 gate_pre,
02354 do_pre,
02355 NULL,
02356 NULL,
02357 0,
02358 TV_TREE_PRE,
02359 PROP_no_crit_edges | PROP_cfg
02360 | PROP_ssa | PROP_alias,
02361 0,
02362 0,
02363 0,
02364 TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa,
02365 0
02366 };
02367
02368
02369
02370
02371 static void
02372 do_fre (void)
02373 {
02374 execute_pre (true);
02375 }
02376
02377 static bool
02378 gate_fre (void)
02379 {
02380 return flag_tree_fre != 0;
02381 }
02382
02383 struct tree_opt_pass pass_fre =
02384 {
02385 "fre",
02386 gate_fre,
02387 do_fre,
02388 NULL,
02389 NULL,
02390 0,
02391 TV_TREE_FRE,
02392 PROP_cfg | PROP_ssa | PROP_alias,
02393 0,
02394 0,
02395 0,
02396 TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa,
02397 0
02398 };