00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
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
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 #include "config.h"
00235 #include "system.h"
00236 #include "coretypes.h"
00237 #include "tm.h"
00238 #include "ggc.h"
00239 #include "tree.h"
00240 #include "real.h"
00241
00242
00243 #include "rtl.h"
00244 #include "basic-block.h"
00245 #include "diagnostic.h"
00246 #include "tree-flow.h"
00247 #include "tree-dump.h"
00248 #include "timevar.h"
00249 #include "cfgloop.h"
00250 #include "tree-chrec.h"
00251 #include "tree-scalar-evolution.h"
00252 #include "tree-pass.h"
00253 #include "flags.h"
00254 #include "params.h"
00255
00256 static tree analyze_scalar_evolution_1 (struct loop *, tree, tree);
00257 static tree resolve_mixers (struct loop *, tree);
00258
00259
00260
00261
00262 struct scev_info_str
00263 {
00264 tree var;
00265 tree chrec;
00266 };
00267
00268
00269 static unsigned nb_set_scev = 0;
00270 static unsigned nb_get_scev = 0;
00271
00272
00273
00274
00275
00276
00277 tree chrec_not_analyzed_yet;
00278
00279
00280
00281 tree chrec_dont_know;
00282
00283
00284
00285 tree chrec_known;
00286
00287 static bitmap already_instantiated;
00288
00289 static htab_t scalar_evolution_info;
00290
00291
00292
00293
00294 static inline struct scev_info_str *
00295 new_scev_info_str (tree var)
00296 {
00297 struct scev_info_str *res;
00298
00299 res = XNEW (struct scev_info_str);
00300 res->var = var;
00301 res->chrec = chrec_not_analyzed_yet;
00302
00303 return res;
00304 }
00305
00306
00307
00308 static hashval_t
00309 hash_scev_info (const void *elt)
00310 {
00311 return SSA_NAME_VERSION (((struct scev_info_str *) elt)->var);
00312 }
00313
00314
00315
00316 static int
00317 eq_scev_info (const void *e1, const void *e2)
00318 {
00319 const struct scev_info_str *elt1 = (const struct scev_info_str *) e1;
00320 const struct scev_info_str *elt2 = (const struct scev_info_str *) e2;
00321
00322 return elt1->var == elt2->var;
00323 }
00324
00325
00326
00327 static void
00328 del_scev_info (void *e)
00329 {
00330 free (e);
00331 }
00332
00333
00334
00335
00336
00337 static tree *
00338 find_var_scev_info (tree var)
00339 {
00340 struct scev_info_str *res;
00341 struct scev_info_str tmp;
00342 PTR *slot;
00343
00344 tmp.var = var;
00345 slot = htab_find_slot (scalar_evolution_info, &tmp, INSERT);
00346
00347 if (!*slot)
00348 *slot = new_scev_info_str (var);
00349 res = (struct scev_info_str *) *slot;
00350
00351 return &res->chrec;
00352 }
00353
00354
00355
00356
00357 bool
00358 chrec_contains_symbols_defined_in_loop (tree chrec, unsigned loop_nb)
00359 {
00360 if (chrec == NULL_TREE)
00361 return false;
00362
00363 if (TREE_INVARIANT (chrec))
00364 return false;
00365
00366 if (TREE_CODE (chrec) == VAR_DECL
00367 || TREE_CODE (chrec) == PARM_DECL
00368 || TREE_CODE (chrec) == FUNCTION_DECL
00369 || TREE_CODE (chrec) == LABEL_DECL
00370 || TREE_CODE (chrec) == RESULT_DECL
00371 || TREE_CODE (chrec) == FIELD_DECL)
00372 return true;
00373
00374 if (TREE_CODE (chrec) == SSA_NAME)
00375 {
00376 tree def = SSA_NAME_DEF_STMT (chrec);
00377 struct loop *def_loop = loop_containing_stmt (def);
00378 struct loop *loop = current_loops->parray[loop_nb];
00379
00380 if (def_loop == NULL)
00381 return false;
00382
00383 if (loop == def_loop || flow_loop_nested_p (loop, def_loop))
00384 return true;
00385
00386 return false;
00387 }
00388
00389 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
00390 {
00391 case 3:
00392 if (chrec_contains_symbols_defined_in_loop (TREE_OPERAND (chrec, 2),
00393 loop_nb))
00394 return true;
00395
00396 case 2:
00397 if (chrec_contains_symbols_defined_in_loop (TREE_OPERAND (chrec, 1),
00398 loop_nb))
00399 return true;
00400
00401 case 1:
00402 if (chrec_contains_symbols_defined_in_loop (TREE_OPERAND (chrec, 0),
00403 loop_nb))
00404 return true;
00405
00406 default:
00407 return false;
00408 }
00409 }
00410
00411
00412
00413 static bool
00414 loop_phi_node_p (tree phi)
00415 {
00416
00417
00418
00419
00420 return loop_containing_stmt (phi)->header == bb_for_stmt (phi);
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 static tree
00459 compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
00460 {
00461 bool val = false;
00462
00463 if (evolution_fn == chrec_dont_know)
00464 return chrec_dont_know;
00465
00466 else if (TREE_CODE (evolution_fn) == POLYNOMIAL_CHREC)
00467 {
00468 if (CHREC_VARIABLE (evolution_fn) >= (unsigned) loop->num)
00469 {
00470 struct loop *inner_loop =
00471 current_loops->parray[CHREC_VARIABLE (evolution_fn)];
00472 tree nb_iter = number_of_iterations_in_loop (inner_loop);
00473
00474 if (nb_iter == chrec_dont_know)
00475 return chrec_dont_know;
00476 else
00477 {
00478 tree res;
00479 tree type = chrec_type (nb_iter);
00480
00481
00482
00483 nb_iter = chrec_fold_minus (type, nb_iter,
00484 build_int_cst (type, 1));
00485
00486
00487
00488 res = chrec_apply (inner_loop->num, evolution_fn, nb_iter);
00489
00490
00491 return compute_overall_effect_of_inner_loop (loop, res);
00492 }
00493 }
00494 else
00495 return evolution_fn;
00496 }
00497
00498
00499 else if (no_evolution_in_loop_p (evolution_fn, loop->num, &val) && val)
00500 return evolution_fn;
00501
00502 else
00503 return chrec_dont_know;
00504 }
00505
00506
00507
00508
00509
00510 bool
00511 chrec_is_positive (tree chrec, bool *value)
00512 {
00513 bool value0, value1, value2;
00514 tree type, end_value, nb_iter;
00515
00516 switch (TREE_CODE (chrec))
00517 {
00518 case POLYNOMIAL_CHREC:
00519 if (!chrec_is_positive (CHREC_LEFT (chrec), &value0)
00520 || !chrec_is_positive (CHREC_RIGHT (chrec), &value1))
00521 return false;
00522
00523
00524 if (value0 == value1)
00525 {
00526 *value = value0;
00527 return true;
00528 }
00529
00530
00531
00532
00533
00534 if (!evolution_function_is_affine_p (chrec))
00535 return false;
00536
00537 nb_iter = number_of_iterations_in_loop
00538 (current_loops->parray[CHREC_VARIABLE (chrec)]);
00539
00540 if (chrec_contains_undetermined (nb_iter))
00541 return false;
00542
00543 type = chrec_type (nb_iter);
00544 nb_iter = chrec_fold_minus (type, nb_iter, build_int_cst (type, 1));
00545
00546 #if 0
00547
00548
00549 if (after_exit)
00550 nb_iter = chrec_fold_minus (type, nb_iter, build_int_cst (type, 1));
00551 #endif
00552
00553 end_value = chrec_apply (CHREC_VARIABLE (chrec), chrec, nb_iter);
00554
00555 if (!chrec_is_positive (end_value, &value2))
00556 return false;
00557
00558 *value = value0;
00559 return value0 == value1;
00560
00561 case INTEGER_CST:
00562 *value = (tree_int_cst_sgn (chrec) == 1);
00563 return true;
00564
00565 default:
00566 return false;
00567 }
00568 }
00569
00570
00571
00572 static void
00573 set_scalar_evolution (tree scalar, tree chrec)
00574 {
00575 tree *scalar_info;
00576
00577 if (TREE_CODE (scalar) != SSA_NAME)
00578 return;
00579
00580 scalar_info = find_var_scev_info (scalar);
00581
00582 if (dump_file)
00583 {
00584 if (dump_flags & TDF_DETAILS)
00585 {
00586 fprintf (dump_file, "(set_scalar_evolution \n");
00587 fprintf (dump_file, " (scalar = ");
00588 print_generic_expr (dump_file, scalar, 0);
00589 fprintf (dump_file, ")\n (scalar_evolution = ");
00590 print_generic_expr (dump_file, chrec, 0);
00591 fprintf (dump_file, "))\n");
00592 }
00593 if (dump_flags & TDF_STATS)
00594 nb_set_scev++;
00595 }
00596
00597 *scalar_info = chrec;
00598 }
00599
00600
00601
00602 static tree
00603 get_scalar_evolution (tree scalar)
00604 {
00605 tree res;
00606
00607 if (dump_file)
00608 {
00609 if (dump_flags & TDF_DETAILS)
00610 {
00611 fprintf (dump_file, "(get_scalar_evolution \n");
00612 fprintf (dump_file, " (scalar = ");
00613 print_generic_expr (dump_file, scalar, 0);
00614 fprintf (dump_file, ")\n");
00615 }
00616 if (dump_flags & TDF_STATS)
00617 nb_get_scev++;
00618 }
00619
00620 switch (TREE_CODE (scalar))
00621 {
00622 case SSA_NAME:
00623 res = *find_var_scev_info (scalar);
00624 break;
00625
00626 case REAL_CST:
00627 case INTEGER_CST:
00628 res = scalar;
00629 break;
00630
00631 default:
00632 res = chrec_not_analyzed_yet;
00633 break;
00634 }
00635
00636 if (dump_file && (dump_flags & TDF_DETAILS))
00637 {
00638 fprintf (dump_file, " (scalar_evolution = ");
00639 print_generic_expr (dump_file, res, 0);
00640 fprintf (dump_file, "))\n");
00641 }
00642
00643 return res;
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 static tree
00657 add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
00658 tree at_stmt)
00659 {
00660 tree type, left, right;
00661
00662 switch (TREE_CODE (chrec_before))
00663 {
00664 case POLYNOMIAL_CHREC:
00665 if (CHREC_VARIABLE (chrec_before) <= loop_nb)
00666 {
00667 unsigned var;
00668
00669 type = chrec_type (chrec_before);
00670
00671
00672 if (CHREC_VARIABLE (chrec_before) < loop_nb)
00673 {
00674 var = loop_nb;
00675 left = chrec_before;
00676 right = SCALAR_FLOAT_TYPE_P (type)
00677 ? build_real (type, dconst0)
00678 : build_int_cst (type, 0);
00679 }
00680 else
00681 {
00682 var = CHREC_VARIABLE (chrec_before);
00683 left = CHREC_LEFT (chrec_before);
00684 right = CHREC_RIGHT (chrec_before);
00685 }
00686
00687 to_add = chrec_convert (type, to_add, at_stmt);
00688 right = chrec_convert (type, right, at_stmt);
00689 right = chrec_fold_plus (type, right, to_add);
00690 return build_polynomial_chrec (var, left, right);
00691 }
00692 else
00693 {
00694
00695 left = add_to_evolution_1 (loop_nb, CHREC_LEFT (chrec_before),
00696 to_add, at_stmt);
00697 right = CHREC_RIGHT (chrec_before);
00698 right = chrec_convert (chrec_type (left), right, at_stmt);
00699 return build_polynomial_chrec (CHREC_VARIABLE (chrec_before),
00700 left, right);
00701 }
00702
00703 default:
00704
00705 if (chrec_before == chrec_dont_know)
00706 return chrec_dont_know;
00707
00708 left = chrec_before;
00709 right = chrec_convert (chrec_type (left), to_add, at_stmt);
00710 return build_polynomial_chrec (loop_nb, left, right);
00711 }
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 static tree
00849 add_to_evolution (unsigned loop_nb, tree chrec_before, enum tree_code code,
00850 tree to_add, tree at_stmt)
00851 {
00852 tree type = chrec_type (to_add);
00853 tree res = NULL_TREE;
00854
00855 if (to_add == NULL_TREE)
00856 return chrec_before;
00857
00858
00859
00860 if (TREE_CODE (to_add) == POLYNOMIAL_CHREC)
00861
00862 return chrec_dont_know;
00863
00864 if (dump_file && (dump_flags & TDF_DETAILS))
00865 {
00866 fprintf (dump_file, "(add_to_evolution \n");
00867 fprintf (dump_file, " (loop_nb = %d)\n", loop_nb);
00868 fprintf (dump_file, " (chrec_before = ");
00869 print_generic_expr (dump_file, chrec_before, 0);
00870 fprintf (dump_file, ")\n (to_add = ");
00871 print_generic_expr (dump_file, to_add, 0);
00872 fprintf (dump_file, ")\n");
00873 }
00874
00875 if (code == MINUS_EXPR)
00876 to_add = chrec_fold_multiply (type, to_add, SCALAR_FLOAT_TYPE_P (type)
00877 ? build_real (type, dconstm1)
00878 : build_int_cst_type (type, -1));
00879
00880 res = add_to_evolution_1 (loop_nb, chrec_before, to_add, at_stmt);
00881
00882 if (dump_file && (dump_flags & TDF_DETAILS))
00883 {
00884 fprintf (dump_file, " (res = ");
00885 print_generic_expr (dump_file, res, 0);
00886 fprintf (dump_file, "))\n");
00887 }
00888
00889 return res;
00890 }
00891
00892
00893
00894 static inline tree
00895 set_nb_iterations_in_loop (struct loop *loop,
00896 tree res)
00897 {
00898 tree type = chrec_type (res);
00899
00900 res = chrec_fold_plus (type, res, build_int_cst (type, 1));
00901
00902
00903
00904
00905
00906 if (TREE_CODE (res) == INTEGER_CST
00907 && (TREE_INT_CST_LOW (res) == 0
00908 || TREE_OVERFLOW (res)))
00909 res = chrec_dont_know;
00910
00911 if (dump_file && (dump_flags & TDF_DETAILS))
00912 {
00913 fprintf (dump_file, " (set_nb_iterations_in_loop = ");
00914 print_generic_expr (dump_file, res, 0);
00915 fprintf (dump_file, "))\n");
00916 }
00917
00918 loop->nb_iterations = res;
00919 return res;
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 static bool
00932 analyzable_condition (tree expr)
00933 {
00934 tree condition;
00935
00936 if (TREE_CODE (expr) != COND_EXPR)
00937 return false;
00938
00939 condition = TREE_OPERAND (expr, 0);
00940
00941 switch (TREE_CODE (condition))
00942 {
00943 case SSA_NAME:
00944 return true;
00945
00946 case LT_EXPR:
00947 case LE_EXPR:
00948 case GT_EXPR:
00949 case GE_EXPR:
00950 case EQ_EXPR:
00951 case NE_EXPR:
00952 return true;
00953
00954 default:
00955 return false;
00956 }
00957
00958 return false;
00959 }
00960
00961
00962
00963
00964
00965 tree
00966 get_loop_exit_condition (struct loop *loop)
00967 {
00968 tree res = NULL_TREE;
00969 edge exit_edge = loop->single_exit;
00970
00971
00972 if (dump_file && (dump_flags & TDF_DETAILS))
00973 fprintf (dump_file, "(get_loop_exit_condition \n ");
00974
00975 if (exit_edge)
00976 {
00977 tree expr;
00978
00979 expr = last_stmt (exit_edge->src);
00980 if (analyzable_condition (expr))
00981 res = expr;
00982 }
00983
00984 if (dump_file && (dump_flags & TDF_DETAILS))
00985 {
00986 print_generic_expr (dump_file, res, 0);
00987 fprintf (dump_file, ")\n");
00988 }
00989
00990 return res;
00991 }
00992
00993
00994
00995 static void
00996 get_exit_conditions_rec (struct loop *loop,
00997 VEC(tree,heap) **exit_conditions)
00998 {
00999 if (!loop)
01000 return;
01001
01002
01003 get_exit_conditions_rec (loop->inner, exit_conditions);
01004 get_exit_conditions_rec (loop->next, exit_conditions);
01005
01006 if (loop->single_exit)
01007 {
01008 tree loop_condition = get_loop_exit_condition (loop);
01009
01010 if (loop_condition)
01011 VEC_safe_push (tree, heap, *exit_conditions, loop_condition);
01012 }
01013 }
01014
01015
01016
01017
01018 static void
01019 select_loops_exit_conditions (struct loops *loops,
01020 VEC(tree,heap) **exit_conditions)
01021 {
01022 struct loop *function_body = loops->parray[0];
01023
01024 get_exit_conditions_rec (function_body->inner, exit_conditions);
01025 }
01026
01027
01028
01029
01030 typedef enum t_bool {
01031 t_false,
01032 t_true,
01033 t_dont_know
01034 } t_bool;
01035
01036
01037 static t_bool follow_ssa_edge (struct loop *loop, tree, tree, tree *, int);
01038
01039
01040
01041
01042 static t_bool
01043 follow_ssa_edge_in_rhs (struct loop *loop, tree at_stmt, tree rhs,
01044 tree halting_phi, tree *evolution_of_loop, int limit)
01045 {
01046 t_bool res = t_false;
01047 tree rhs0, rhs1;
01048 tree type_rhs = TREE_TYPE (rhs);
01049 tree evol;
01050
01051
01052
01053
01054
01055
01056
01057
01058 switch (TREE_CODE (rhs))
01059 {
01060 case NOP_EXPR:
01061
01062 res = follow_ssa_edge_in_rhs (loop, at_stmt, TREE_OPERAND (rhs, 0),
01063 halting_phi, evolution_of_loop, limit);
01064 *evolution_of_loop = chrec_convert (TREE_TYPE (rhs),
01065 *evolution_of_loop, at_stmt);
01066 break;
01067
01068 case INTEGER_CST:
01069
01070 res = t_false;
01071 break;
01072
01073 case SSA_NAME:
01074
01075 res = follow_ssa_edge
01076 (loop, SSA_NAME_DEF_STMT (rhs), halting_phi, evolution_of_loop, limit);
01077 break;
01078
01079 case PLUS_EXPR:
01080
01081 rhs0 = TREE_OPERAND (rhs, 0);
01082 rhs1 = TREE_OPERAND (rhs, 1);
01083 STRIP_TYPE_NOPS (rhs0);
01084 STRIP_TYPE_NOPS (rhs1);
01085
01086 if (TREE_CODE (rhs0) == SSA_NAME)
01087 {
01088 if (TREE_CODE (rhs1) == SSA_NAME)
01089 {
01090
01091
01092 evol = *evolution_of_loop;
01093 res = follow_ssa_edge
01094 (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
01095 &evol, limit);
01096
01097 if (res == t_true)
01098 *evolution_of_loop = add_to_evolution
01099 (loop->num,
01100 chrec_convert (type_rhs, evol, at_stmt),
01101 PLUS_EXPR, rhs1, at_stmt);
01102
01103 else if (res == t_false)
01104 {
01105 res = follow_ssa_edge
01106 (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
01107 evolution_of_loop, limit);
01108
01109 if (res == t_true)
01110 *evolution_of_loop = add_to_evolution
01111 (loop->num,
01112 chrec_convert (type_rhs, *evolution_of_loop, at_stmt),
01113 PLUS_EXPR, rhs0, at_stmt);
01114
01115 else if (res == t_dont_know)
01116 *evolution_of_loop = chrec_dont_know;
01117 }
01118
01119 else if (res == t_dont_know)
01120 *evolution_of_loop = chrec_dont_know;
01121 }
01122
01123 else
01124 {
01125
01126
01127 res = follow_ssa_edge
01128 (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
01129 evolution_of_loop, limit);
01130 if (res == t_true)
01131 *evolution_of_loop = add_to_evolution
01132 (loop->num, chrec_convert (type_rhs, *evolution_of_loop,
01133 at_stmt),
01134 PLUS_EXPR, rhs1, at_stmt);
01135
01136 else if (res == t_dont_know)
01137 *evolution_of_loop = chrec_dont_know;
01138 }
01139 }
01140
01141 else if (TREE_CODE (rhs1) == SSA_NAME)
01142 {
01143
01144
01145 res = follow_ssa_edge
01146 (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
01147 evolution_of_loop, limit);
01148 if (res == t_true)
01149 *evolution_of_loop = add_to_evolution
01150 (loop->num, chrec_convert (type_rhs, *evolution_of_loop,
01151 at_stmt),
01152 PLUS_EXPR, rhs0, at_stmt);
01153
01154 else if (res == t_dont_know)
01155 *evolution_of_loop = chrec_dont_know;
01156 }
01157
01158 else
01159
01160
01161
01162 res = t_false;
01163
01164 break;
01165
01166 case MINUS_EXPR:
01167
01168 rhs0 = TREE_OPERAND (rhs, 0);
01169 rhs1 = TREE_OPERAND (rhs, 1);
01170 STRIP_TYPE_NOPS (rhs0);
01171 STRIP_TYPE_NOPS (rhs1);
01172
01173 if (TREE_CODE (rhs0) == SSA_NAME)
01174 {
01175
01176
01177 res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
01178 evolution_of_loop, limit);
01179 if (res == t_true)
01180 *evolution_of_loop = add_to_evolution
01181 (loop->num, chrec_convert (type_rhs, *evolution_of_loop, at_stmt),
01182 MINUS_EXPR, rhs1, at_stmt);
01183
01184 else if (res == t_dont_know)
01185 *evolution_of_loop = chrec_dont_know;
01186 }
01187 else
01188
01189
01190
01191 res = t_false;
01192
01193 break;
01194
01195 case ASSERT_EXPR:
01196 {
01197
01198
01199 tree op0 = ASSERT_EXPR_VAR (rhs);
01200 if (TREE_CODE (op0) == SSA_NAME)
01201 res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (op0),
01202 halting_phi, evolution_of_loop, limit);
01203 else
01204 res = t_false;
01205 break;
01206 }
01207
01208
01209 default:
01210 res = t_false;
01211 break;
01212 }
01213
01214 return res;
01215 }
01216
01217
01218
01219 static bool
01220 backedge_phi_arg_p (tree phi, int i)
01221 {
01222 edge e = PHI_ARG_EDGE (phi, i);
01223
01224
01225
01226
01227 if (e->flags & EDGE_IRREDUCIBLE_LOOP)
01228 return true;
01229
01230 return false;
01231 }
01232
01233
01234
01235
01236
01237 static inline t_bool
01238 follow_ssa_edge_in_condition_phi_branch (int i,
01239 struct loop *loop,
01240 tree condition_phi,
01241 tree halting_phi,
01242 tree *evolution_of_branch,
01243 tree init_cond, int limit)
01244 {
01245 tree branch = PHI_ARG_DEF (condition_phi, i);
01246 *evolution_of_branch = chrec_dont_know;
01247
01248
01249
01250 if (backedge_phi_arg_p (condition_phi, i))
01251 return t_false;
01252
01253 if (TREE_CODE (branch) == SSA_NAME)
01254 {
01255 *evolution_of_branch = init_cond;
01256 return follow_ssa_edge (loop, SSA_NAME_DEF_STMT (branch), halting_phi,
01257 evolution_of_branch, limit);
01258 }
01259
01260
01261
01262
01263
01264
01265
01266
01267 return t_false;
01268 }
01269
01270
01271
01272
01273 static t_bool
01274 follow_ssa_edge_in_condition_phi (struct loop *loop,
01275 tree condition_phi,
01276 tree halting_phi,
01277 tree *evolution_of_loop, int limit)
01278 {
01279 int i;
01280 tree init = *evolution_of_loop;
01281 tree evolution_of_branch;
01282 t_bool res = follow_ssa_edge_in_condition_phi_branch (0, loop, condition_phi,
01283 halting_phi,
01284 &evolution_of_branch,
01285 init, limit);
01286 if (res == t_false || res == t_dont_know)
01287 return res;
01288
01289 *evolution_of_loop = evolution_of_branch;
01290
01291 for (i = 1; i < PHI_NUM_ARGS (condition_phi); i++)
01292 {
01293
01294
01295 if (*evolution_of_loop == chrec_dont_know)
01296 return t_true;
01297
01298 res = follow_ssa_edge_in_condition_phi_branch (i, loop, condition_phi,
01299 halting_phi,
01300 &evolution_of_branch,
01301 init, limit);
01302 if (res == t_false || res == t_dont_know)
01303 return res;
01304
01305 *evolution_of_loop = chrec_merge (*evolution_of_loop,
01306 evolution_of_branch);
01307 }
01308
01309 return t_true;
01310 }
01311
01312
01313
01314
01315
01316
01317 static t_bool
01318 follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
01319 tree loop_phi_node,
01320 tree halting_phi,
01321 tree *evolution_of_loop, int limit)
01322 {
01323 struct loop *loop = loop_containing_stmt (loop_phi_node);
01324 tree ev = analyze_scalar_evolution (loop, PHI_RESULT (loop_phi_node));
01325
01326
01327
01328 if (ev == PHI_RESULT (loop_phi_node))
01329 {
01330 t_bool res = t_false;
01331 int i;
01332
01333 for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
01334 {
01335 tree arg = PHI_ARG_DEF (loop_phi_node, i);
01336 basic_block bb;
01337
01338
01339 bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
01340 if (!flow_bb_inside_loop_p (loop, bb))
01341 res = follow_ssa_edge_in_rhs (outer_loop, loop_phi_node,
01342 arg, halting_phi,
01343 evolution_of_loop, limit);
01344 if (res == t_true)
01345 break;
01346 }
01347
01348
01349 if (res == t_true)
01350 *evolution_of_loop = chrec_dont_know;
01351
01352 return res;
01353 }
01354
01355
01356 ev = compute_overall_effect_of_inner_loop (loop, ev);
01357 return follow_ssa_edge_in_rhs (outer_loop, loop_phi_node, ev, halting_phi,
01358 evolution_of_loop, limit);
01359 }
01360
01361
01362
01363
01364 static t_bool
01365 follow_ssa_edge (struct loop *loop, tree def, tree halting_phi,
01366 tree *evolution_of_loop, int limit)
01367 {
01368 struct loop *def_loop;
01369
01370 if (TREE_CODE (def) == NOP_EXPR)
01371 return t_false;
01372
01373
01374 if (limit++ > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
01375 return t_dont_know;
01376
01377 def_loop = loop_containing_stmt (def);
01378
01379 switch (TREE_CODE (def))
01380 {
01381 case PHI_NODE:
01382 if (!loop_phi_node_p (def))
01383
01384
01385
01386
01387 return follow_ssa_edge_in_condition_phi
01388 (loop, def, halting_phi, evolution_of_loop, limit);
01389
01390
01391
01392
01393 if (def == halting_phi)
01394 return t_true;
01395
01396
01397
01398
01399 if (def_loop == loop)
01400 return t_false;
01401
01402
01403 if (flow_loop_nested_p (loop, def_loop))
01404 return follow_ssa_edge_inner_loop_phi
01405 (loop, def, halting_phi, evolution_of_loop, limit);
01406
01407
01408 return t_false;
01409
01410 case MODIFY_EXPR:
01411 return follow_ssa_edge_in_rhs (loop, def,
01412 TREE_OPERAND (def, 1),
01413 halting_phi,
01414 evolution_of_loop, limit);
01415
01416 default:
01417
01418
01419
01420 return t_false;
01421 }
01422 }
01423
01424
01425
01426
01427
01428
01429 static tree
01430 analyze_evolution_in_loop (tree loop_phi_node,
01431 tree init_cond)
01432 {
01433 int i;
01434 tree evolution_function = chrec_not_analyzed_yet;
01435 struct loop *loop = loop_containing_stmt (loop_phi_node);
01436 basic_block bb;
01437
01438 if (dump_file && (dump_flags & TDF_DETAILS))
01439 {
01440 fprintf (dump_file, "(analyze_evolution_in_loop \n");
01441 fprintf (dump_file, " (loop_phi_node = ");
01442 print_generic_expr (dump_file, loop_phi_node, 0);
01443 fprintf (dump_file, ")\n");
01444 }
01445
01446 for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
01447 {
01448 tree arg = PHI_ARG_DEF (loop_phi_node, i);
01449 tree ssa_chain, ev_fn;
01450 t_bool res;
01451
01452
01453 bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
01454 if (!flow_bb_inside_loop_p (loop, bb))
01455 continue;
01456
01457 if (TREE_CODE (arg) == SSA_NAME)
01458 {
01459 ssa_chain = SSA_NAME_DEF_STMT (arg);
01460
01461
01462 ev_fn = init_cond;
01463 res = follow_ssa_edge (loop, ssa_chain, loop_phi_node, &ev_fn, 0);
01464 }
01465 else
01466 res = t_false;
01467
01468
01469
01470
01471
01472
01473
01474 if (res != t_true)
01475 ev_fn = chrec_dont_know;
01476
01477
01478
01479 evolution_function = chrec_merge (evolution_function, ev_fn);
01480 }
01481
01482 if (dump_file && (dump_flags & TDF_DETAILS))
01483 {
01484 fprintf (dump_file, " (evolution_function = ");
01485 print_generic_expr (dump_file, evolution_function, 0);
01486 fprintf (dump_file, "))\n");
01487 }
01488
01489 return evolution_function;
01490 }
01491
01492
01493
01494
01495
01496
01497
01498
01499 static tree
01500 analyze_initial_condition (tree loop_phi_node)
01501 {
01502 int i;
01503 tree init_cond = chrec_not_analyzed_yet;
01504 struct loop *loop = bb_for_stmt (loop_phi_node)->loop_father;
01505
01506 if (dump_file && (dump_flags & TDF_DETAILS))
01507 {
01508 fprintf (dump_file, "(analyze_initial_condition \n");
01509 fprintf (dump_file, " (loop_phi_node = \n");
01510 print_generic_expr (dump_file, loop_phi_node, 0);
01511 fprintf (dump_file, ")\n");
01512 }
01513
01514 for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
01515 {
01516 tree branch = PHI_ARG_DEF (loop_phi_node, i);
01517 basic_block bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
01518
01519
01520
01521 if (flow_bb_inside_loop_p (loop, bb))
01522 continue;
01523
01524 if (init_cond == chrec_not_analyzed_yet)
01525 {
01526 init_cond = branch;
01527 continue;
01528 }
01529
01530 if (TREE_CODE (branch) == SSA_NAME)
01531 {
01532 init_cond = chrec_dont_know;
01533 break;
01534 }
01535
01536 init_cond = chrec_merge (init_cond, branch);
01537 }
01538
01539
01540 if (init_cond == chrec_not_analyzed_yet)
01541 init_cond = chrec_dont_know;
01542
01543 if (dump_file && (dump_flags & TDF_DETAILS))
01544 {
01545 fprintf (dump_file, " (init_cond = ");
01546 print_generic_expr (dump_file, init_cond, 0);
01547 fprintf (dump_file, "))\n");
01548 }
01549
01550 return init_cond;
01551 }
01552
01553
01554
01555 static tree
01556 interpret_loop_phi (struct loop *loop, tree loop_phi_node)
01557 {
01558 tree res;
01559 struct loop *phi_loop = loop_containing_stmt (loop_phi_node);
01560 tree init_cond;
01561
01562 if (phi_loop != loop)
01563 {
01564 struct loop *subloop;
01565 tree evolution_fn = analyze_scalar_evolution
01566 (phi_loop, PHI_RESULT (loop_phi_node));
01567
01568
01569 subloop = superloop_at_depth (phi_loop, loop->depth + 1);
01570
01571
01572 res = compute_overall_effect_of_inner_loop (subloop, evolution_fn);
01573 return res;
01574 }
01575
01576
01577 init_cond = analyze_initial_condition (loop_phi_node);
01578 res = analyze_evolution_in_loop (loop_phi_node, init_cond);
01579
01580 return res;
01581 }
01582
01583
01584
01585
01586
01587 static tree
01588 interpret_condition_phi (struct loop *loop, tree condition_phi)
01589 {
01590 int i;
01591 tree res = chrec_not_analyzed_yet;
01592
01593 for (i = 0; i < PHI_NUM_ARGS (condition_phi); i++)
01594 {
01595 tree branch_chrec;
01596
01597 if (backedge_phi_arg_p (condition_phi, i))
01598 {
01599 res = chrec_dont_know;
01600 break;
01601 }
01602
01603 branch_chrec = analyze_scalar_evolution
01604 (loop, PHI_ARG_DEF (condition_phi, i));
01605
01606 res = chrec_merge (res, branch_chrec);
01607 }
01608
01609 return res;
01610 }
01611
01612
01613
01614
01615
01616
01617
01618
01619 static tree
01620 interpret_rhs_modify_expr (struct loop *loop, tree at_stmt,
01621 tree opnd1, tree type)
01622 {
01623 tree res, opnd10, opnd11, chrec10, chrec11;
01624
01625 if (is_gimple_min_invariant (opnd1))
01626 return chrec_convert (type, opnd1, at_stmt);
01627
01628 switch (TREE_CODE (opnd1))
01629 {
01630 case PLUS_EXPR:
01631 opnd10 = TREE_OPERAND (opnd1, 0);
01632 opnd11 = TREE_OPERAND (opnd1, 1);
01633 chrec10 = analyze_scalar_evolution (loop, opnd10);
01634 chrec11 = analyze_scalar_evolution (loop, opnd11);
01635 chrec10 = chrec_convert (type, chrec10, at_stmt);
01636 chrec11 = chrec_convert (type, chrec11, at_stmt);
01637 res = chrec_fold_plus (type, chrec10, chrec11);
01638 break;
01639
01640 case MINUS_EXPR:
01641 opnd10 = TREE_OPERAND (opnd1, 0);
01642 opnd11 = TREE_OPERAND (opnd1, 1);
01643 chrec10 = analyze_scalar_evolution (loop, opnd10);
01644 chrec11 = analyze_scalar_evolution (loop, opnd11);
01645 chrec10 = chrec_convert (type, chrec10, at_stmt);
01646 chrec11 = chrec_convert (type, chrec11, at_stmt);
01647 res = chrec_fold_minus (type, chrec10, chrec11);
01648 break;
01649
01650 case NEGATE_EXPR:
01651 opnd10 = TREE_OPERAND (opnd1, 0);
01652 chrec10 = analyze_scalar_evolution (loop, opnd10);
01653 chrec10 = chrec_convert (type, chrec10, at_stmt);
01654
01655 res = chrec_fold_multiply (type, chrec10,
01656 fold_convert (type, integer_minus_one_node));
01657 break;
01658
01659 case MULT_EXPR:
01660 opnd10 = TREE_OPERAND (opnd1, 0);
01661 opnd11 = TREE_OPERAND (opnd1, 1);
01662 chrec10 = analyze_scalar_evolution (loop, opnd10);
01663 chrec11 = analyze_scalar_evolution (loop, opnd11);
01664 chrec10 = chrec_convert (type, chrec10, at_stmt);
01665 chrec11 = chrec_convert (type, chrec11, at_stmt);
01666 res = chrec_fold_multiply (type, chrec10, chrec11);
01667 break;
01668
01669 case SSA_NAME:
01670 res = chrec_convert (type, analyze_scalar_evolution (loop, opnd1),
01671 at_stmt);
01672 break;
01673
01674 case ASSERT_EXPR:
01675 opnd10 = ASSERT_EXPR_VAR (opnd1);
01676 res = chrec_convert (type, analyze_scalar_evolution (loop, opnd10),
01677 at_stmt);
01678 break;
01679
01680 case NOP_EXPR:
01681 case CONVERT_EXPR:
01682 opnd10 = TREE_OPERAND (opnd1, 0);
01683 chrec10 = analyze_scalar_evolution (loop, opnd10);
01684 res = chrec_convert (type, chrec10, at_stmt);
01685 break;
01686
01687 default:
01688 res = chrec_dont_know;
01689 break;
01690 }
01691
01692 return res;
01693 }
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706 static tree
01707 compute_scalar_evolution_in_loop (struct loop *wrto_loop,
01708 struct loop *def_loop,
01709 tree ev)
01710 {
01711 tree res;
01712 if (def_loop == wrto_loop)
01713 return ev;
01714
01715 def_loop = superloop_at_depth (def_loop, wrto_loop->depth + 1);
01716 res = compute_overall_effect_of_inner_loop (def_loop, ev);
01717
01718 return analyze_scalar_evolution_1 (wrto_loop, res, chrec_not_analyzed_yet);
01719 }
01720
01721
01722
01723
01724 static tree
01725 fold_used_pointer_cast (tree expr)
01726 {
01727 tree op;
01728 tree type, inner_type;
01729
01730 if (TREE_CODE (expr) != NOP_EXPR && TREE_CODE (expr) != CONVERT_EXPR)
01731 return expr;
01732
01733 op = TREE_OPERAND (expr, 0);
01734 if (TREE_CODE (op) != POLYNOMIAL_CHREC)
01735 return expr;
01736
01737 type = TREE_TYPE (expr);
01738 inner_type = TREE_TYPE (op);
01739
01740 if (!INTEGRAL_TYPE_P (inner_type)
01741 || TYPE_PRECISION (inner_type) != TYPE_PRECISION (type))
01742 return expr;
01743
01744 return build_polynomial_chrec (CHREC_VARIABLE (op),
01745 chrec_convert (type, CHREC_LEFT (op), NULL_TREE),
01746 chrec_convert (type, CHREC_RIGHT (op), NULL_TREE));
01747 }
01748
01749
01750
01751
01752 static bool
01753 pointer_offset_p (tree expr)
01754 {
01755 if (TREE_CODE (expr) == INTEGER_CST)
01756 return true;
01757
01758 if ((TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR)
01759 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))))
01760 return true;
01761
01762 return false;
01763 }
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823 static tree
01824 fold_used_pointer (tree expr, tree at_stmt)
01825 {
01826 tree op0, op1, new0, new1;
01827 enum tree_code code = TREE_CODE (expr);
01828
01829 if (code == PLUS_EXPR
01830 || code == MINUS_EXPR)
01831 {
01832 op0 = TREE_OPERAND (expr, 0);
01833 op1 = TREE_OPERAND (expr, 1);
01834
01835 if (pointer_offset_p (op1))
01836 {
01837 new0 = fold_used_pointer (op0, at_stmt);
01838 new1 = fold_used_pointer_cast (op1);
01839 }
01840 else if (code == PLUS_EXPR && pointer_offset_p (op0))
01841 {
01842 new0 = fold_used_pointer_cast (op0);
01843 new1 = fold_used_pointer (op1, at_stmt);
01844 }
01845 else
01846 return expr;
01847
01848 if (new0 == op0 && new1 == op1)
01849 return expr;
01850
01851 new0 = chrec_convert (TREE_TYPE (expr), new0, at_stmt);
01852 new1 = chrec_convert (TREE_TYPE (expr), new1, at_stmt);
01853
01854 if (code == PLUS_EXPR)
01855 expr = chrec_fold_plus (TREE_TYPE (expr), new0, new1);
01856 else
01857 expr = chrec_fold_minus (TREE_TYPE (expr), new0, new1);
01858
01859 return expr;
01860 }
01861 else
01862 return fold_used_pointer_cast (expr);
01863 }
01864
01865
01866
01867 static bool
01868 pointer_used_p (tree ptr)
01869 {
01870 use_operand_p use_p;
01871 imm_use_iterator imm_iter;
01872 tree stmt, rhs;
01873 struct ptr_info_def *pi = get_ptr_info (ptr);
01874 var_ann_t v_ann = var_ann (SSA_NAME_VAR (ptr));
01875
01876
01877
01878 if ((pi != NULL && pi->name_mem_tag != NULL)
01879 || v_ann->symbol_mem_tag)
01880 return true;
01881
01882 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, ptr)
01883 {
01884 stmt = USE_STMT (use_p);
01885 if (TREE_CODE (stmt) == COND_EXPR)
01886 return true;
01887
01888 if (TREE_CODE (stmt) != MODIFY_EXPR)
01889 continue;
01890
01891 rhs = TREE_OPERAND (stmt, 1);
01892 if (!COMPARISON_CLASS_P (rhs))
01893 continue;
01894
01895 if (TREE_OPERAND (stmt, 0) == ptr
01896 || TREE_OPERAND (stmt, 1) == ptr)
01897 return true;
01898 }
01899
01900 return false;
01901 }
01902
01903
01904
01905 static tree
01906 analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
01907 {
01908 tree def, type = TREE_TYPE (var);
01909 basic_block bb;
01910 struct loop *def_loop;
01911
01912 if (loop == NULL || TREE_CODE (type) == VECTOR_TYPE)
01913 return chrec_dont_know;
01914
01915 if (TREE_CODE (var) != SSA_NAME)
01916 return interpret_rhs_modify_expr (loop, NULL_TREE, var, type);
01917
01918 def = SSA_NAME_DEF_STMT (var);
01919 bb = bb_for_stmt (def);
01920 def_loop = bb ? bb->loop_father : NULL;
01921
01922 if (bb == NULL
01923 || !flow_bb_inside_loop_p (loop, bb))
01924 {
01925
01926 res = var;
01927 goto set_and_end;
01928 }
01929
01930 if (res != chrec_not_analyzed_yet)
01931 {
01932 if (loop != bb->loop_father)
01933 res = compute_scalar_evolution_in_loop
01934 (find_common_loop (loop, bb->loop_father), bb->loop_father, res);
01935
01936 goto set_and_end;
01937 }
01938
01939 if (loop != def_loop)
01940 {
01941 res = analyze_scalar_evolution_1 (def_loop, var, chrec_not_analyzed_yet);
01942 res = compute_scalar_evolution_in_loop (loop, def_loop, res);
01943
01944 goto set_and_end;
01945 }
01946
01947 switch (TREE_CODE (def))
01948 {
01949 case MODIFY_EXPR:
01950 res = interpret_rhs_modify_expr (loop, def, TREE_OPERAND (def, 1), type);
01951
01952 if (POINTER_TYPE_P (type)
01953 && !automatically_generated_chrec_p (res)
01954 && pointer_used_p (var))
01955 res = fold_used_pointer (res, def);
01956 break;
01957
01958 case PHI_NODE:
01959 if (loop_phi_node_p (def))
01960 res = interpret_loop_phi (loop, def);
01961 else
01962 res = interpret_condition_phi (loop, def);
01963 break;
01964
01965 default:
01966 res = chrec_dont_know;
01967 break;
01968 }
01969
01970 set_and_end:
01971
01972
01973 if (res == chrec_dont_know)
01974 res = var;
01975
01976 if (loop == def_loop)
01977 set_scalar_evolution (var, res);
01978
01979 return res;
01980 }
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998 tree
01999 analyze_scalar_evolution (struct loop *loop, tree var)
02000 {
02001 tree res;
02002
02003 if (dump_file && (dump_flags & TDF_DETAILS))
02004 {
02005 fprintf (dump_file, "(analyze_scalar_evolution \n");
02006 fprintf (dump_file, " (loop_nb = %d)\n", loop->num);
02007 fprintf (dump_file, " (scalar = ");
02008 print_generic_expr (dump_file, var, 0);
02009 fprintf (dump_file, ")\n");
02010 }
02011
02012 res = analyze_scalar_evolution_1 (loop, var, get_scalar_evolution (var));
02013
02014 if (TREE_CODE (var) == SSA_NAME && res == chrec_dont_know)
02015 res = var;
02016
02017 if (dump_file && (dump_flags & TDF_DETAILS))
02018 fprintf (dump_file, ")\n");
02019
02020 return res;
02021 }
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031 static tree
02032 analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop,
02033 tree version, bool *folded_casts)
02034 {
02035 bool val = false;
02036 tree ev = version, tmp;
02037
02038 if (folded_casts)
02039 *folded_casts = false;
02040 while (1)
02041 {
02042 tmp = analyze_scalar_evolution (use_loop, ev);
02043 ev = resolve_mixers (use_loop, tmp);
02044
02045 if (folded_casts && tmp != ev)
02046 *folded_casts = true;
02047
02048 if (use_loop == wrto_loop)
02049 return ev;
02050
02051
02052
02053
02054 if (!no_evolution_in_loop_p (ev, use_loop->num, &val)
02055 || !val)
02056 return chrec_dont_know;
02057
02058 use_loop = use_loop->outer;
02059 }
02060 }
02061
02062
02063
02064 static tree
02065 get_instantiated_value (htab_t cache, tree version)
02066 {
02067 struct scev_info_str *info, pattern;
02068
02069 pattern.var = version;
02070 info = (struct scev_info_str *) htab_find (cache, &pattern);
02071
02072 if (info)
02073 return info->chrec;
02074 else
02075 return NULL_TREE;
02076 }
02077
02078
02079
02080 static void
02081 set_instantiated_value (htab_t cache, tree version, tree val)
02082 {
02083 struct scev_info_str *info, pattern;
02084 PTR *slot;
02085
02086 pattern.var = version;
02087 slot = htab_find_slot (cache, &pattern, INSERT);
02088
02089 if (!*slot)
02090 *slot = new_scev_info_str (version);
02091 info = (struct scev_info_str *) *slot;
02092 info->chrec = val;
02093 }
02094
02095
02096
02097
02098 static tree
02099 loop_closed_phi_def (tree var)
02100 {
02101 struct loop *loop;
02102 edge exit;
02103 tree phi;
02104
02105 if (var == NULL_TREE
02106 || TREE_CODE (var) != SSA_NAME)
02107 return NULL_TREE;
02108
02109 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (var));
02110 exit = loop->single_exit;
02111 if (!exit)
02112 return NULL_TREE;
02113
02114 for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
02115 if (PHI_ARG_DEF_FROM_EDGE (phi, exit) == var)
02116 return PHI_RESULT (phi);
02117
02118 return NULL_TREE;
02119 }
02120
02121
02122
02123
02124
02125
02126
02127
02128 enum
02129 {
02130 INSERT_SUPERLOOP_CHRECS = 1,
02131
02132 FOLD_CONVERSIONS = 2
02133
02134
02135 };
02136
02137 static tree
02138 instantiate_parameters_1 (struct loop *loop, tree chrec, int flags, htab_t cache,
02139 int size_expr)
02140 {
02141 tree res, op0, op1, op2;
02142 basic_block def_bb;
02143 struct loop *def_loop;
02144 tree type = chrec_type (chrec);
02145
02146
02147 if (size_expr++ > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
02148 return chrec_dont_know;
02149
02150 if (automatically_generated_chrec_p (chrec)
02151 || is_gimple_min_invariant (chrec))
02152 return chrec;
02153
02154 switch (TREE_CODE (chrec))
02155 {
02156 case SSA_NAME:
02157 def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (chrec));
02158
02159
02160
02161 if (!def_bb
02162 || (!(flags & INSERT_SUPERLOOP_CHRECS)
02163 && !flow_bb_inside_loop_p (loop, def_bb)))
02164 return chrec;
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175 res = get_instantiated_value (cache, chrec);
02176 if (res)
02177 return res;
02178
02179
02180
02181
02182
02183 res = !flow_bb_inside_loop_p (loop, def_bb) ? chrec : chrec_dont_know;
02184 set_instantiated_value (cache, chrec, res);
02185
02186
02187
02188
02189
02190
02191 if (bitmap_bit_p (already_instantiated, SSA_NAME_VERSION (chrec)))
02192 return res;
02193
02194 def_loop = find_common_loop (loop, def_bb->loop_father);
02195
02196
02197
02198 bitmap_set_bit (already_instantiated, SSA_NAME_VERSION (chrec));
02199 res = analyze_scalar_evolution (def_loop, chrec);
02200
02201
02202 if (TREE_CODE (res) == SSA_NAME
02203 && (loop_containing_stmt (SSA_NAME_DEF_STMT (res)) == NULL
02204 || (loop_containing_stmt (SSA_NAME_DEF_STMT (res))->depth
02205 > def_loop->depth)))
02206 {
02207 if (res == chrec)
02208 res = loop_closed_phi_def (chrec);
02209 else
02210 res = chrec;
02211
02212 if (res == NULL_TREE)
02213 res = chrec_dont_know;
02214 }
02215
02216 else if (res != chrec_dont_know)
02217 res = instantiate_parameters_1 (loop, res, flags, cache, size_expr);
02218
02219 bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec));
02220
02221
02222 set_instantiated_value (cache, chrec, res);
02223 return res;
02224
02225 case POLYNOMIAL_CHREC:
02226 op0 = instantiate_parameters_1 (loop, CHREC_LEFT (chrec),
02227 flags, cache, size_expr);
02228 if (op0 == chrec_dont_know)
02229 return chrec_dont_know;
02230
02231 op1 = instantiate_parameters_1 (loop, CHREC_RIGHT (chrec),
02232 flags, cache, size_expr);
02233 if (op1 == chrec_dont_know)
02234 return chrec_dont_know;
02235
02236 if (CHREC_LEFT (chrec) != op0
02237 || CHREC_RIGHT (chrec) != op1)
02238 {
02239 op1 = chrec_convert (chrec_type (op0), op1, NULL_TREE);
02240 chrec = build_polynomial_chrec (CHREC_VARIABLE (chrec), op0, op1);
02241 }
02242 return chrec;
02243
02244 case PLUS_EXPR:
02245 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02246 flags, cache, size_expr);
02247 if (op0 == chrec_dont_know)
02248 return chrec_dont_know;
02249
02250 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02251 flags, cache, size_expr);
02252 if (op1 == chrec_dont_know)
02253 return chrec_dont_know;
02254
02255 if (TREE_OPERAND (chrec, 0) != op0
02256 || TREE_OPERAND (chrec, 1) != op1)
02257 {
02258 op0 = chrec_convert (type, op0, NULL_TREE);
02259 op1 = chrec_convert (type, op1, NULL_TREE);
02260 chrec = chrec_fold_plus (type, op0, op1);
02261 }
02262 return chrec;
02263
02264 case MINUS_EXPR:
02265 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02266 flags, cache, size_expr);
02267 if (op0 == chrec_dont_know)
02268 return chrec_dont_know;
02269
02270 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02271 flags, cache, size_expr);
02272 if (op1 == chrec_dont_know)
02273 return chrec_dont_know;
02274
02275 if (TREE_OPERAND (chrec, 0) != op0
02276 || TREE_OPERAND (chrec, 1) != op1)
02277 {
02278 op0 = chrec_convert (type, op0, NULL_TREE);
02279 op1 = chrec_convert (type, op1, NULL_TREE);
02280 chrec = chrec_fold_minus (type, op0, op1);
02281 }
02282 return chrec;
02283
02284 case MULT_EXPR:
02285 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02286 flags, cache, size_expr);
02287 if (op0 == chrec_dont_know)
02288 return chrec_dont_know;
02289
02290 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02291 flags, cache, size_expr);
02292 if (op1 == chrec_dont_know)
02293 return chrec_dont_know;
02294
02295 if (TREE_OPERAND (chrec, 0) != op0
02296 || TREE_OPERAND (chrec, 1) != op1)
02297 {
02298 op0 = chrec_convert (type, op0, NULL_TREE);
02299 op1 = chrec_convert (type, op1, NULL_TREE);
02300 chrec = chrec_fold_multiply (type, op0, op1);
02301 }
02302 return chrec;
02303
02304 case NOP_EXPR:
02305 case CONVERT_EXPR:
02306 case NON_LVALUE_EXPR:
02307 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02308 flags, cache, size_expr);
02309 if (op0 == chrec_dont_know)
02310 return chrec_dont_know;
02311
02312 if (flags & FOLD_CONVERSIONS)
02313 {
02314 tree tmp = chrec_convert_aggressive (TREE_TYPE (chrec), op0);
02315 if (tmp)
02316 return tmp;
02317 }
02318
02319 if (op0 == TREE_OPERAND (chrec, 0))
02320 return chrec;
02321
02322
02323
02324
02325 if (flags & FOLD_CONVERSIONS)
02326 return fold_convert (TREE_TYPE (chrec), op0);
02327
02328 return chrec_convert (TREE_TYPE (chrec), op0, NULL_TREE);
02329
02330 case SCEV_NOT_KNOWN:
02331 return chrec_dont_know;
02332
02333 case SCEV_KNOWN:
02334 return chrec_known;
02335
02336 default:
02337 break;
02338 }
02339
02340 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
02341 {
02342 case 3:
02343 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02344 flags, cache, size_expr);
02345 if (op0 == chrec_dont_know)
02346 return chrec_dont_know;
02347
02348 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02349 flags, cache, size_expr);
02350 if (op1 == chrec_dont_know)
02351 return chrec_dont_know;
02352
02353 op2 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 2),
02354 flags, cache, size_expr);
02355 if (op2 == chrec_dont_know)
02356 return chrec_dont_know;
02357
02358 if (op0 == TREE_OPERAND (chrec, 0)
02359 && op1 == TREE_OPERAND (chrec, 1)
02360 && op2 == TREE_OPERAND (chrec, 2))
02361 return chrec;
02362
02363 return fold_build3 (TREE_CODE (chrec),
02364 TREE_TYPE (chrec), op0, op1, op2);
02365
02366 case 2:
02367 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02368 flags, cache, size_expr);
02369 if (op0 == chrec_dont_know)
02370 return chrec_dont_know;
02371
02372 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02373 flags, cache, size_expr);
02374 if (op1 == chrec_dont_know)
02375 return chrec_dont_know;
02376
02377 if (op0 == TREE_OPERAND (chrec, 0)
02378 && op1 == TREE_OPERAND (chrec, 1))
02379 return chrec;
02380 return fold_build2 (TREE_CODE (chrec), TREE_TYPE (chrec), op0, op1);
02381
02382 case 1:
02383 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02384 flags, cache, size_expr);
02385 if (op0 == chrec_dont_know)
02386 return chrec_dont_know;
02387 if (op0 == TREE_OPERAND (chrec, 0))
02388 return chrec;
02389 return fold_build1 (TREE_CODE (chrec), TREE_TYPE (chrec), op0);
02390
02391 case 0:
02392 return chrec;
02393
02394 default:
02395 break;
02396 }
02397
02398
02399 return chrec_dont_know;
02400 }
02401
02402
02403
02404
02405
02406 tree
02407 instantiate_parameters (struct loop *loop,
02408 tree chrec)
02409 {
02410 tree res;
02411 htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
02412
02413 if (dump_file && (dump_flags & TDF_DETAILS))
02414 {
02415 fprintf (dump_file, "(instantiate_parameters \n");
02416 fprintf (dump_file, " (loop_nb = %d)\n", loop->num);
02417 fprintf (dump_file, " (chrec = ");
02418 print_generic_expr (dump_file, chrec, 0);
02419 fprintf (dump_file, ")\n");
02420 }
02421
02422 res = instantiate_parameters_1 (loop, chrec, INSERT_SUPERLOOP_CHRECS, cache,
02423 0);
02424
02425 if (dump_file && (dump_flags & TDF_DETAILS))
02426 {
02427 fprintf (dump_file, " (res = ");
02428 print_generic_expr (dump_file, res, 0);
02429 fprintf (dump_file, "))\n");
02430 }
02431
02432 htab_delete (cache);
02433
02434 return res;
02435 }
02436
02437
02438
02439
02440
02441
02442 static tree
02443 resolve_mixers (struct loop *loop, tree chrec)
02444 {
02445 htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
02446 tree ret = instantiate_parameters_1 (loop, chrec, FOLD_CONVERSIONS, cache, 0);
02447 htab_delete (cache);
02448 return ret;
02449 }
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471 tree
02472 number_of_iterations_in_loop (struct loop *loop)
02473 {
02474 tree res, type;
02475 edge exit;
02476 struct tree_niter_desc niter_desc;
02477
02478
02479
02480 res = loop->nb_iterations;
02481 if (res)
02482 return res;
02483 res = chrec_dont_know;
02484
02485 if (dump_file && (dump_flags & TDF_DETAILS))
02486 fprintf (dump_file, "(number_of_iterations_in_loop\n");
02487
02488 exit = loop->single_exit;
02489 if (!exit)
02490 goto end;
02491
02492 if (!number_of_iterations_exit (loop, exit, &niter_desc, false))
02493 goto end;
02494
02495 type = TREE_TYPE (niter_desc.niter);
02496 if (integer_nonzerop (niter_desc.may_be_zero))
02497 res = build_int_cst (type, 0);
02498 else if (integer_zerop (niter_desc.may_be_zero))
02499 res = niter_desc.niter;
02500 else
02501 res = chrec_dont_know;
02502
02503 end:
02504 return set_nb_iterations_in_loop (loop, res);
02505 }
02506
02507
02508
02509
02510
02511 static void
02512 number_of_iterations_for_all_loops (VEC(tree,heap) **exit_conditions)
02513 {
02514 unsigned int i;
02515 unsigned nb_chrec_dont_know_loops = 0;
02516 unsigned nb_static_loops = 0;
02517 tree cond;
02518
02519 for (i = 0; VEC_iterate (tree, *exit_conditions, i, cond); i++)
02520 {
02521 tree res = number_of_iterations_in_loop (loop_containing_stmt (cond));
02522 if (chrec_contains_undetermined (res))
02523 nb_chrec_dont_know_loops++;
02524 else
02525 nb_static_loops++;
02526 }
02527
02528 if (dump_file)
02529 {
02530 fprintf (dump_file, "\n(\n");
02531 fprintf (dump_file, "-----------------------------------------\n");
02532 fprintf (dump_file, "%d\tnb_chrec_dont_know_loops\n", nb_chrec_dont_know_loops);
02533 fprintf (dump_file, "%d\tnb_static_loops\n", nb_static_loops);
02534 fprintf (dump_file, "%d\tnb_total_loops\n", current_loops->num);
02535 fprintf (dump_file, "-----------------------------------------\n");
02536 fprintf (dump_file, ")\n\n");
02537
02538 print_loop_ir (dump_file);
02539 }
02540 }
02541
02542
02543
02544
02545
02546 struct chrec_stats
02547 {
02548 unsigned nb_chrecs;
02549 unsigned nb_affine;
02550 unsigned nb_affine_multivar;
02551 unsigned nb_higher_poly;
02552 unsigned nb_chrec_dont_know;
02553 unsigned nb_undetermined;
02554 };
02555
02556
02557
02558 static inline void
02559 reset_chrecs_counters (struct chrec_stats *stats)
02560 {
02561 stats->nb_chrecs = 0;
02562 stats->nb_affine = 0;
02563 stats->nb_affine_multivar = 0;
02564 stats->nb_higher_poly = 0;
02565 stats->nb_chrec_dont_know = 0;
02566 stats->nb_undetermined = 0;
02567 }
02568
02569
02570
02571 static void
02572 dump_chrecs_stats (FILE *file, struct chrec_stats *stats)
02573 {
02574 fprintf (file, "\n(\n");
02575 fprintf (file, "-----------------------------------------\n");
02576 fprintf (file, "%d\taffine univariate chrecs\n", stats->nb_affine);
02577 fprintf (file, "%d\taffine multivariate chrecs\n", stats->nb_affine_multivar);
02578 fprintf (file, "%d\tdegree greater than 2 polynomials\n",
02579 stats->nb_higher_poly);
02580 fprintf (file, "%d\tchrec_dont_know chrecs\n", stats->nb_chrec_dont_know);
02581 fprintf (file, "-----------------------------------------\n");
02582 fprintf (file, "%d\ttotal chrecs\n", stats->nb_chrecs);
02583 fprintf (file, "%d\twith undetermined coefficients\n",
02584 stats->nb_undetermined);
02585 fprintf (file, "-----------------------------------------\n");
02586 fprintf (file, "%d\tchrecs in the scev database\n",
02587 (int) htab_elements (scalar_evolution_info));
02588 fprintf (file, "%d\tsets in the scev database\n", nb_set_scev);
02589 fprintf (file, "%d\tgets in the scev database\n", nb_get_scev);
02590 fprintf (file, "-----------------------------------------\n");
02591 fprintf (file, ")\n\n");
02592 }
02593
02594
02595
02596 static void
02597 gather_chrec_stats (tree chrec, struct chrec_stats *stats)
02598 {
02599 if (dump_file && (dump_flags & TDF_STATS))
02600 {
02601 fprintf (dump_file, "(classify_chrec ");
02602 print_generic_expr (dump_file, chrec, 0);
02603 fprintf (dump_file, "\n");
02604 }
02605
02606 stats->nb_chrecs++;
02607
02608 if (chrec == NULL_TREE)
02609 {
02610 stats->nb_undetermined++;
02611 return;
02612 }
02613
02614 switch (TREE_CODE (chrec))
02615 {
02616 case POLYNOMIAL_CHREC:
02617 if (evolution_function_is_affine_p (chrec))
02618 {
02619 if (dump_file && (dump_flags & TDF_STATS))
02620 fprintf (dump_file, " affine_univariate\n");
02621 stats->nb_affine++;
02622 }
02623 else if (evolution_function_is_affine_multivariate_p (chrec))
02624 {
02625 if (dump_file && (dump_flags & TDF_STATS))
02626 fprintf (dump_file, " affine_multivariate\n");
02627 stats->nb_affine_multivar++;
02628 }
02629 else
02630 {
02631 if (dump_file && (dump_flags & TDF_STATS))
02632 fprintf (dump_file, " higher_degree_polynomial\n");
02633 stats->nb_higher_poly++;
02634 }
02635
02636 break;
02637
02638 default:
02639 break;
02640 }
02641
02642 if (chrec_contains_undetermined (chrec))
02643 {
02644 if (dump_file && (dump_flags & TDF_STATS))
02645 fprintf (dump_file, " undetermined\n");
02646 stats->nb_undetermined++;
02647 }
02648
02649 if (dump_file && (dump_flags & TDF_STATS))
02650 fprintf (dump_file, ")\n");
02651 }
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663 static void
02664 analyze_scalar_evolution_for_all_loop_phi_nodes (VEC(tree,heap) **exit_conditions)
02665 {
02666 unsigned int i;
02667 struct chrec_stats stats;
02668 tree cond;
02669
02670 reset_chrecs_counters (&stats);
02671
02672 for (i = 0; VEC_iterate (tree, *exit_conditions, i, cond); i++)
02673 {
02674 struct loop *loop;
02675 basic_block bb;
02676 tree phi, chrec;
02677
02678 loop = loop_containing_stmt (cond);
02679 bb = loop->header;
02680
02681 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
02682 if (is_gimple_reg (PHI_RESULT (phi)))
02683 {
02684 chrec = instantiate_parameters
02685 (loop,
02686 analyze_scalar_evolution (loop, PHI_RESULT (phi)));
02687
02688 if (dump_file && (dump_flags & TDF_STATS))
02689 gather_chrec_stats (chrec, &stats);
02690 }
02691 }
02692
02693 if (dump_file && (dump_flags & TDF_STATS))
02694 dump_chrecs_stats (dump_file, &stats);
02695 }
02696
02697
02698
02699
02700 static int
02701 gather_stats_on_scev_database_1 (void **slot, void *stats)
02702 {
02703 struct scev_info_str *entry = (struct scev_info_str *) *slot;
02704
02705 gather_chrec_stats (entry->chrec, (struct chrec_stats *) stats);
02706
02707 return 1;
02708 }
02709
02710
02711
02712 void
02713 gather_stats_on_scev_database (void)
02714 {
02715 struct chrec_stats stats;
02716
02717 if (!dump_file)
02718 return;
02719
02720 reset_chrecs_counters (&stats);
02721
02722 htab_traverse (scalar_evolution_info, gather_stats_on_scev_database_1,
02723 &stats);
02724
02725 dump_chrecs_stats (dump_file, &stats);
02726 }
02727
02728
02729
02730
02731
02732 static void
02733 initialize_scalar_evolutions_analyzer (void)
02734 {
02735
02736 if (chrec_dont_know == NULL_TREE)
02737 {
02738 chrec_not_analyzed_yet = NULL_TREE;
02739 chrec_dont_know = make_node (SCEV_NOT_KNOWN);
02740 chrec_known = make_node (SCEV_KNOWN);
02741 TREE_TYPE (chrec_dont_know) = void_type_node;
02742 TREE_TYPE (chrec_known) = void_type_node;
02743 }
02744 }
02745
02746
02747
02748 void
02749 scev_initialize (struct loops *loops)
02750 {
02751 unsigned i;
02752 current_loops = loops;
02753
02754 scalar_evolution_info = htab_create (100, hash_scev_info,
02755 eq_scev_info, del_scev_info);
02756 already_instantiated = BITMAP_ALLOC (NULL);
02757
02758 initialize_scalar_evolutions_analyzer ();
02759
02760 for (i = 1; i < loops->num; i++)
02761 if (loops->parray[i])
02762 loops->parray[i]->nb_iterations = NULL_TREE;
02763 }
02764
02765
02766
02767 void
02768 scev_reset (void)
02769 {
02770 unsigned i;
02771 struct loop *loop;
02772
02773 if (!scalar_evolution_info || !current_loops)
02774 return;
02775
02776 htab_empty (scalar_evolution_info);
02777 for (i = 1; i < current_loops->num; i++)
02778 {
02779 loop = current_loops->parray[i];
02780 if (loop)
02781 loop->nb_iterations = NULL_TREE;
02782 }
02783 }
02784
02785
02786
02787
02788
02789
02790
02791 bool
02792 simple_iv (struct loop *loop, tree stmt, tree op, affine_iv *iv,
02793 bool allow_nonconstant_step)
02794 {
02795 basic_block bb = bb_for_stmt (stmt);
02796 tree type, ev;
02797 bool folded_casts;
02798
02799 iv->base = NULL_TREE;
02800 iv->step = NULL_TREE;
02801 iv->no_overflow = false;
02802
02803 type = TREE_TYPE (op);
02804 if (TREE_CODE (type) != INTEGER_TYPE
02805 && TREE_CODE (type) != POINTER_TYPE)
02806 return false;
02807
02808 ev = analyze_scalar_evolution_in_loop (loop, bb->loop_father, op,
02809 &folded_casts);
02810 if (chrec_contains_undetermined (ev))
02811 return false;
02812
02813 if (tree_does_not_contain_chrecs (ev)
02814 && !chrec_contains_symbols_defined_in_loop (ev, loop->num))
02815 {
02816 iv->base = ev;
02817 iv->no_overflow = true;
02818 return true;
02819 }
02820
02821 if (TREE_CODE (ev) != POLYNOMIAL_CHREC
02822 || CHREC_VARIABLE (ev) != (unsigned) loop->num)
02823 return false;
02824
02825 iv->step = CHREC_RIGHT (ev);
02826 if (allow_nonconstant_step)
02827 {
02828 if (tree_contains_chrecs (iv->step, NULL)
02829 || chrec_contains_symbols_defined_in_loop (iv->step, loop->num))
02830 return false;
02831 }
02832 else if (TREE_CODE (iv->step) != INTEGER_CST)
02833 return false;
02834
02835 iv->base = CHREC_LEFT (ev);
02836 if (tree_contains_chrecs (iv->base, NULL)
02837 || chrec_contains_symbols_defined_in_loop (iv->base, loop->num))
02838 return false;
02839
02840 iv->no_overflow = !folded_casts && TYPE_OVERFLOW_UNDEFINED (type);
02841
02842 return true;
02843 }
02844
02845
02846
02847 void
02848 scev_analysis (void)
02849 {
02850 VEC(tree,heap) *exit_conditions;
02851
02852 exit_conditions = VEC_alloc (tree, heap, 37);
02853 select_loops_exit_conditions (current_loops, &exit_conditions);
02854
02855 if (dump_file && (dump_flags & TDF_STATS))
02856 analyze_scalar_evolution_for_all_loop_phi_nodes (&exit_conditions);
02857
02858 number_of_iterations_for_all_loops (&exit_conditions);
02859 VEC_free (tree, heap, exit_conditions);
02860 }
02861
02862
02863
02864 void
02865 scev_finalize (void)
02866 {
02867 htab_delete (scalar_evolution_info);
02868 BITMAP_FREE (already_instantiated);
02869 }
02870
02871
02872
02873 static bool
02874 expression_expensive_p (tree expr)
02875 {
02876 return force_expr_to_var_cost (expr) >= target_spill_cost;
02877 }
02878
02879
02880
02881
02882
02883
02884
02885
02886 unsigned int
02887 scev_const_prop (void)
02888 {
02889 basic_block bb;
02890 tree name, phi, next_phi, type, ev;
02891 struct loop *loop, *ex_loop;
02892 bitmap ssa_names_to_remove = NULL;
02893 unsigned i;
02894
02895 if (!current_loops)
02896 return 0;
02897
02898 FOR_EACH_BB (bb)
02899 {
02900 loop = bb->loop_father;
02901
02902 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
02903 {
02904 name = PHI_RESULT (phi);
02905
02906 if (!is_gimple_reg (name))
02907 continue;
02908
02909 type = TREE_TYPE (name);
02910
02911 if (!POINTER_TYPE_P (type)
02912 && !INTEGRAL_TYPE_P (type))
02913 continue;
02914
02915 ev = resolve_mixers (loop, analyze_scalar_evolution (loop, name));
02916 if (!is_gimple_min_invariant (ev)
02917 || !may_propagate_copy (name, ev))
02918 continue;
02919
02920
02921 if (name != ev)
02922 replace_uses_by (name, ev);
02923
02924 if (!ssa_names_to_remove)
02925 ssa_names_to_remove = BITMAP_ALLOC (NULL);
02926 bitmap_set_bit (ssa_names_to_remove, SSA_NAME_VERSION (name));
02927 }
02928 }
02929
02930
02931
02932 if (ssa_names_to_remove)
02933 {
02934 bitmap_iterator bi;
02935 unsigned i;
02936
02937 EXECUTE_IF_SET_IN_BITMAP (ssa_names_to_remove, 0, i, bi)
02938 {
02939 name = ssa_name (i);
02940 phi = SSA_NAME_DEF_STMT (name);
02941
02942 gcc_assert (TREE_CODE (phi) == PHI_NODE);
02943 remove_phi_node (phi, NULL);
02944 }
02945
02946 BITMAP_FREE (ssa_names_to_remove);
02947 scev_reset ();
02948 }
02949
02950
02951 for (i = current_loops->num - 1; i > 0; i--)
02952 {
02953 edge exit;
02954 tree def, rslt, ass, niter;
02955 block_stmt_iterator bsi;
02956
02957 loop = current_loops->parray[i];
02958 if (!loop)
02959 continue;
02960
02961
02962
02963 exit = loop->single_exit;
02964 if (!exit)
02965 continue;
02966
02967 niter = number_of_iterations_in_loop (loop);
02968 if (niter == chrec_dont_know
02969
02970
02971 || expression_expensive_p (niter))
02972 continue;
02973
02974
02975 if (!single_pred_p (exit->dest))
02976 split_loop_exit_edge (exit);
02977 tree_block_label (exit->dest);
02978 bsi = bsi_after_labels (exit->dest);
02979
02980 ex_loop = superloop_at_depth (loop, exit->dest->loop_father->depth + 1);
02981
02982 for (phi = phi_nodes (exit->dest); phi; phi = next_phi)
02983 {
02984 next_phi = PHI_CHAIN (phi);
02985 rslt = PHI_RESULT (phi);
02986 def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
02987 if (!is_gimple_reg (def))
02988 continue;
02989
02990 if (!POINTER_TYPE_P (TREE_TYPE (def))
02991 && !INTEGRAL_TYPE_P (TREE_TYPE (def)))
02992 continue;
02993
02994 def = analyze_scalar_evolution_in_loop (ex_loop, loop, def, NULL);
02995 def = compute_overall_effect_of_inner_loop (ex_loop, def);
02996 if (!tree_does_not_contain_chrecs (def)
02997 || chrec_contains_symbols_defined_in_loop (def, ex_loop->num)
02998
02999
03000
03001 || contains_abnormal_ssa_name_p (def))
03002 continue;
03003
03004
03005
03006 def = unshare_expr (def);
03007 SET_PHI_RESULT (phi, NULL_TREE);
03008 remove_phi_node (phi, NULL_TREE);
03009
03010 ass = build2 (MODIFY_EXPR, void_type_node, rslt, NULL_TREE);
03011 SSA_NAME_DEF_STMT (rslt) = ass;
03012 {
03013 block_stmt_iterator dest = bsi;
03014 bsi_insert_before (&dest, ass, BSI_NEW_STMT);
03015 def = force_gimple_operand_bsi (&dest, def, false, NULL_TREE);
03016 }
03017 TREE_OPERAND (ass, 1) = def;
03018 update_stmt (ass);
03019 }
03020 }
03021 return 0;
03022 }