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 "errors.h"
00239 #include "ggc.h"
00240 #include "tree.h"
00241 #include "real.h"
00242
00243
00244 #include "rtl.h"
00245 #include "basic-block.h"
00246 #include "diagnostic.h"
00247 #include "tree-flow.h"
00248 #include "tree-dump.h"
00249 #include "timevar.h"
00250 #include "cfgloop.h"
00251 #include "tree-chrec.h"
00252 #include "tree-scalar-evolution.h"
00253 #include "tree-pass.h"
00254 #include "flags.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 = xmalloc (sizeof (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 = e1;
00320 const struct scev_info_str *elt2 = 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 = *slot;
00350
00351 return &res->chrec;
00352 }
00353
00354
00355
00356 tree
00357 count_ev_in_wider_type (tree type, tree chrec)
00358 {
00359 tree base, step;
00360 struct loop *loop;
00361
00362 if (!evolution_function_is_affine_p (chrec))
00363 return fold_convert (type, chrec);
00364
00365 base = CHREC_LEFT (chrec);
00366 step = CHREC_RIGHT (chrec);
00367 loop = current_loops->parray[CHREC_VARIABLE (chrec)];
00368
00369
00370
00371
00372 step = can_count_iv_in_wider_type (loop, type, base, step, NULL_TREE);
00373 if (!step)
00374 return fold_convert (type, chrec);
00375 base = chrec_convert (type, base);
00376
00377 return build_polynomial_chrec (CHREC_VARIABLE (chrec),
00378 base, step);
00379 }
00380
00381
00382
00383
00384 bool
00385 chrec_contains_symbols_defined_in_loop (tree chrec, unsigned loop_nb)
00386 {
00387 if (chrec == NULL_TREE)
00388 return false;
00389
00390 if (TREE_INVARIANT (chrec))
00391 return false;
00392
00393 if (TREE_CODE (chrec) == VAR_DECL
00394 || TREE_CODE (chrec) == PARM_DECL
00395 || TREE_CODE (chrec) == FUNCTION_DECL
00396 || TREE_CODE (chrec) == LABEL_DECL
00397 || TREE_CODE (chrec) == RESULT_DECL
00398 || TREE_CODE (chrec) == FIELD_DECL)
00399 return true;
00400
00401 if (TREE_CODE (chrec) == SSA_NAME)
00402 {
00403 tree def = SSA_NAME_DEF_STMT (chrec);
00404 struct loop *def_loop = loop_containing_stmt (def);
00405 struct loop *loop = current_loops->parray[loop_nb];
00406
00407 if (def_loop == NULL)
00408 return false;
00409
00410 if (loop == def_loop || flow_loop_nested_p (loop, def_loop))
00411 return true;
00412
00413 return false;
00414 }
00415
00416 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
00417 {
00418 case 3:
00419 if (chrec_contains_symbols_defined_in_loop (TREE_OPERAND (chrec, 2),
00420 loop_nb))
00421 return true;
00422
00423 case 2:
00424 if (chrec_contains_symbols_defined_in_loop (TREE_OPERAND (chrec, 1),
00425 loop_nb))
00426 return true;
00427
00428 case 1:
00429 if (chrec_contains_symbols_defined_in_loop (TREE_OPERAND (chrec, 0),
00430 loop_nb))
00431 return true;
00432
00433 default:
00434 return false;
00435 }
00436 }
00437
00438
00439
00440 static bool
00441 loop_phi_node_p (tree phi)
00442 {
00443
00444
00445
00446
00447 return loop_containing_stmt (phi)->header == bb_for_stmt (phi);
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 static tree
00486 compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
00487 {
00488 bool val = false;
00489
00490 if (evolution_fn == chrec_dont_know)
00491 return chrec_dont_know;
00492
00493 else if (TREE_CODE (evolution_fn) == POLYNOMIAL_CHREC)
00494 {
00495 if (CHREC_VARIABLE (evolution_fn) >= (unsigned) loop->num)
00496 {
00497 struct loop *inner_loop =
00498 current_loops->parray[CHREC_VARIABLE (evolution_fn)];
00499 tree nb_iter = number_of_iterations_in_loop (inner_loop);
00500
00501 if (nb_iter == chrec_dont_know)
00502 return chrec_dont_know;
00503 else
00504 {
00505 tree res;
00506
00507
00508
00509 nb_iter = chrec_fold_minus (chrec_type (nb_iter),
00510 nb_iter,
00511 build_int_cst_type (chrec_type (nb_iter), 1));
00512
00513
00514
00515 res = chrec_apply (inner_loop->num, evolution_fn, nb_iter);
00516
00517
00518 return compute_overall_effect_of_inner_loop (loop, res);
00519 }
00520 }
00521 else
00522 return evolution_fn;
00523 }
00524
00525
00526 else if (no_evolution_in_loop_p (evolution_fn, loop->num, &val) && val)
00527 return evolution_fn;
00528
00529 else
00530 return chrec_dont_know;
00531 }
00532
00533
00534
00535
00536
00537 bool
00538 chrec_is_positive (tree chrec, bool *value)
00539 {
00540 bool value0, value1;
00541 bool value2;
00542 tree end_value;
00543 tree nb_iter;
00544
00545 switch (TREE_CODE (chrec))
00546 {
00547 case POLYNOMIAL_CHREC:
00548 if (!chrec_is_positive (CHREC_LEFT (chrec), &value0)
00549 || !chrec_is_positive (CHREC_RIGHT (chrec), &value1))
00550 return false;
00551
00552
00553 if (value0 == value1)
00554 {
00555 *value = value0;
00556 return true;
00557 }
00558
00559
00560
00561
00562
00563 if (!evolution_function_is_affine_p (chrec))
00564 return false;
00565
00566 nb_iter = number_of_iterations_in_loop
00567 (current_loops->parray[CHREC_VARIABLE (chrec)]);
00568
00569 if (chrec_contains_undetermined (nb_iter))
00570 return false;
00571
00572 nb_iter = chrec_fold_minus
00573 (chrec_type (nb_iter), nb_iter,
00574 build_int_cst (chrec_type (nb_iter), 1));
00575
00576 #if 0
00577
00578
00579 if (after_exit)
00580 nb_iter = chrec_fold_minus
00581 (chrec_type (nb_iter), nb_iter,
00582 build_int_cst (chrec_type (nb_iter), 1));
00583 #endif
00584
00585 end_value = chrec_apply (CHREC_VARIABLE (chrec), chrec, nb_iter);
00586
00587 if (!chrec_is_positive (end_value, &value2))
00588 return false;
00589
00590 *value = value0;
00591 return value0 == value1;
00592
00593 case INTEGER_CST:
00594 *value = (tree_int_cst_sgn (chrec) == 1);
00595 return true;
00596
00597 default:
00598 return false;
00599 }
00600 }
00601
00602
00603
00604 static void
00605 set_scalar_evolution (tree scalar, tree chrec)
00606 {
00607 tree *scalar_info;
00608
00609 if (TREE_CODE (scalar) != SSA_NAME)
00610 return;
00611
00612 scalar_info = find_var_scev_info (scalar);
00613
00614 if (dump_file)
00615 {
00616 if (dump_flags & TDF_DETAILS)
00617 {
00618 fprintf (dump_file, "(set_scalar_evolution \n");
00619 fprintf (dump_file, " (scalar = ");
00620 print_generic_expr (dump_file, scalar, 0);
00621 fprintf (dump_file, ")\n (scalar_evolution = ");
00622 print_generic_expr (dump_file, chrec, 0);
00623 fprintf (dump_file, "))\n");
00624 }
00625 if (dump_flags & TDF_STATS)
00626 nb_set_scev++;
00627 }
00628
00629 *scalar_info = chrec;
00630 }
00631
00632
00633
00634 static tree
00635 get_scalar_evolution (tree scalar)
00636 {
00637 tree res;
00638
00639 if (dump_file)
00640 {
00641 if (dump_flags & TDF_DETAILS)
00642 {
00643 fprintf (dump_file, "(get_scalar_evolution \n");
00644 fprintf (dump_file, " (scalar = ");
00645 print_generic_expr (dump_file, scalar, 0);
00646 fprintf (dump_file, ")\n");
00647 }
00648 if (dump_flags & TDF_STATS)
00649 nb_get_scev++;
00650 }
00651
00652 switch (TREE_CODE (scalar))
00653 {
00654 case SSA_NAME:
00655 res = *find_var_scev_info (scalar);
00656 break;
00657
00658 case REAL_CST:
00659 case INTEGER_CST:
00660 res = scalar;
00661 break;
00662
00663 default:
00664 res = chrec_not_analyzed_yet;
00665 break;
00666 }
00667
00668 if (dump_file && (dump_flags & TDF_DETAILS))
00669 {
00670 fprintf (dump_file, " (scalar_evolution = ");
00671 print_generic_expr (dump_file, res, 0);
00672 fprintf (dump_file, "))\n");
00673 }
00674
00675 return res;
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 static tree
00689 add_to_evolution_1 (unsigned loop_nb,
00690 tree chrec_before,
00691 tree to_add)
00692 {
00693 switch (TREE_CODE (chrec_before))
00694 {
00695 case POLYNOMIAL_CHREC:
00696 if (CHREC_VARIABLE (chrec_before) <= loop_nb)
00697 {
00698 unsigned var;
00699 tree left, right;
00700 tree type = chrec_type (chrec_before);
00701
00702
00703 if (CHREC_VARIABLE (chrec_before) < loop_nb)
00704 {
00705 var = loop_nb;
00706 left = chrec_before;
00707 right = build_int_cst (type, 0);
00708 }
00709 else
00710 {
00711 var = CHREC_VARIABLE (chrec_before);
00712 left = CHREC_LEFT (chrec_before);
00713 right = CHREC_RIGHT (chrec_before);
00714 }
00715
00716 return build_polynomial_chrec
00717 (var, left, chrec_fold_plus (type, right, to_add));
00718 }
00719 else
00720
00721 return build_polynomial_chrec
00722 (CHREC_VARIABLE (chrec_before),
00723 add_to_evolution_1 (loop_nb, CHREC_LEFT (chrec_before), to_add),
00724 CHREC_RIGHT (chrec_before));
00725
00726 default:
00727
00728 if (chrec_before == chrec_dont_know)
00729 return chrec_dont_know;
00730 return build_polynomial_chrec (loop_nb, chrec_before, to_add);
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
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868 static tree
00869 add_to_evolution (unsigned loop_nb,
00870 tree chrec_before,
00871 enum tree_code code,
00872 tree to_add)
00873 {
00874 tree type = chrec_type (to_add);
00875 tree res = NULL_TREE;
00876
00877 if (to_add == NULL_TREE)
00878 return chrec_before;
00879
00880
00881
00882 if (TREE_CODE (to_add) == POLYNOMIAL_CHREC)
00883
00884 return chrec_dont_know;
00885
00886 if (dump_file && (dump_flags & TDF_DETAILS))
00887 {
00888 fprintf (dump_file, "(add_to_evolution \n");
00889 fprintf (dump_file, " (loop_nb = %d)\n", loop_nb);
00890 fprintf (dump_file, " (chrec_before = ");
00891 print_generic_expr (dump_file, chrec_before, 0);
00892 fprintf (dump_file, ")\n (to_add = ");
00893 print_generic_expr (dump_file, to_add, 0);
00894 fprintf (dump_file, ")\n");
00895 }
00896
00897 if (code == MINUS_EXPR)
00898 to_add = chrec_fold_multiply (type, to_add, SCALAR_FLOAT_TYPE_P (type)
00899 ? build_real (type, dconstm1)
00900 : build_int_cst_type (type, -1));
00901
00902 res = add_to_evolution_1 (loop_nb, chrec_before, to_add);
00903
00904 if (dump_file && (dump_flags & TDF_DETAILS))
00905 {
00906 fprintf (dump_file, " (res = ");
00907 print_generic_expr (dump_file, res, 0);
00908 fprintf (dump_file, "))\n");
00909 }
00910
00911 return res;
00912 }
00913
00914
00915
00916 static inline tree
00917 set_nb_iterations_in_loop (struct loop *loop,
00918 tree res)
00919 {
00920 res = chrec_fold_plus (chrec_type (res), res,
00921 build_int_cst_type (chrec_type (res), 1));
00922
00923
00924
00925
00926
00927 if ((TREE_CODE (res) == INTEGER_CST && TREE_INT_CST_LOW (res) == 0)
00928 || TREE_OVERFLOW (res))
00929 res = chrec_dont_know;
00930
00931 if (dump_file && (dump_flags & TDF_DETAILS))
00932 {
00933 fprintf (dump_file, " (set_nb_iterations_in_loop = ");
00934 print_generic_expr (dump_file, res, 0);
00935 fprintf (dump_file, "))\n");
00936 }
00937
00938 loop->nb_iterations = res;
00939 return res;
00940 }
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 static bool
00952 analyzable_condition (tree expr)
00953 {
00954 tree condition;
00955
00956 if (TREE_CODE (expr) != COND_EXPR)
00957 return false;
00958
00959 condition = TREE_OPERAND (expr, 0);
00960
00961 switch (TREE_CODE (condition))
00962 {
00963 case SSA_NAME:
00964 return true;
00965
00966 case LT_EXPR:
00967 case LE_EXPR:
00968 case GT_EXPR:
00969 case GE_EXPR:
00970 case EQ_EXPR:
00971 case NE_EXPR:
00972 return true;
00973
00974 default:
00975 return false;
00976 }
00977
00978 return false;
00979 }
00980
00981
00982
00983
00984
00985 tree
00986 get_loop_exit_condition (struct loop *loop)
00987 {
00988 tree res = NULL_TREE;
00989 edge exit_edge = loop->single_exit;
00990
00991
00992 if (dump_file && (dump_flags & TDF_DETAILS))
00993 fprintf (dump_file, "(get_loop_exit_condition \n ");
00994
00995 if (exit_edge)
00996 {
00997 tree expr;
00998
00999 expr = last_stmt (exit_edge->src);
01000 if (analyzable_condition (expr))
01001 res = expr;
01002 }
01003
01004 if (dump_file && (dump_flags & TDF_DETAILS))
01005 {
01006 print_generic_expr (dump_file, res, 0);
01007 fprintf (dump_file, ")\n");
01008 }
01009
01010 return res;
01011 }
01012
01013
01014
01015 static void
01016 get_exit_conditions_rec (struct loop *loop,
01017 varray_type *exit_conditions)
01018 {
01019 if (!loop)
01020 return;
01021
01022
01023 get_exit_conditions_rec (loop->inner, exit_conditions);
01024 get_exit_conditions_rec (loop->next, exit_conditions);
01025
01026 if (loop->single_exit)
01027 {
01028 tree loop_condition = get_loop_exit_condition (loop);
01029
01030 if (loop_condition)
01031 VARRAY_PUSH_TREE (*exit_conditions, loop_condition);
01032 }
01033 }
01034
01035
01036
01037
01038 static void
01039 select_loops_exit_conditions (struct loops *loops,
01040 varray_type *exit_conditions)
01041 {
01042 struct loop *function_body = loops->parray[0];
01043
01044 get_exit_conditions_rec (function_body->inner, exit_conditions);
01045 }
01046
01047
01048
01049
01050 static bool follow_ssa_edge (struct loop *loop, tree, tree, tree *);
01051
01052
01053
01054
01055 static bool
01056 follow_ssa_edge_in_rhs (struct loop *loop,
01057 tree rhs,
01058 tree halting_phi,
01059 tree *evolution_of_loop)
01060 {
01061 bool res = false;
01062 tree rhs0, rhs1;
01063 tree type_rhs = TREE_TYPE (rhs);
01064
01065
01066
01067
01068
01069
01070
01071
01072 switch (TREE_CODE (rhs))
01073 {
01074 case NOP_EXPR:
01075
01076 res = follow_ssa_edge_in_rhs (loop, TREE_OPERAND (rhs, 0), halting_phi,
01077 evolution_of_loop);
01078 *evolution_of_loop = chrec_convert (TREE_TYPE (rhs), *evolution_of_loop);
01079 break;
01080
01081 case INTEGER_CST:
01082
01083 res = false;
01084 break;
01085
01086 case SSA_NAME:
01087
01088 res = follow_ssa_edge
01089 (loop, SSA_NAME_DEF_STMT (rhs), halting_phi, evolution_of_loop);
01090 break;
01091
01092 case PLUS_EXPR:
01093
01094 rhs0 = TREE_OPERAND (rhs, 0);
01095 rhs1 = TREE_OPERAND (rhs, 1);
01096 STRIP_TYPE_NOPS (rhs0);
01097 STRIP_TYPE_NOPS (rhs1);
01098
01099 if (TREE_CODE (rhs0) == SSA_NAME)
01100 {
01101 if (TREE_CODE (rhs1) == SSA_NAME)
01102 {
01103
01104
01105 res = follow_ssa_edge
01106 (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
01107 evolution_of_loop);
01108
01109 if (res)
01110 *evolution_of_loop = add_to_evolution
01111 (loop->num,
01112 chrec_convert (type_rhs, *evolution_of_loop),
01113 PLUS_EXPR, rhs1);
01114
01115 else
01116 {
01117 res = follow_ssa_edge
01118 (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
01119 evolution_of_loop);
01120
01121 if (res)
01122 *evolution_of_loop = add_to_evolution
01123 (loop->num,
01124 chrec_convert (type_rhs, *evolution_of_loop),
01125 PLUS_EXPR, rhs0);
01126 }
01127 }
01128
01129 else
01130 {
01131
01132
01133 res = follow_ssa_edge
01134 (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
01135 evolution_of_loop);
01136 if (res)
01137 *evolution_of_loop = add_to_evolution
01138 (loop->num, chrec_convert (type_rhs, *evolution_of_loop),
01139 PLUS_EXPR, rhs1);
01140 }
01141 }
01142
01143 else if (TREE_CODE (rhs1) == SSA_NAME)
01144 {
01145
01146
01147 res = follow_ssa_edge
01148 (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
01149 evolution_of_loop);
01150 if (res)
01151 *evolution_of_loop = add_to_evolution
01152 (loop->num, chrec_convert (type_rhs, *evolution_of_loop),
01153 PLUS_EXPR, rhs0);
01154 }
01155
01156 else
01157
01158
01159
01160 res = false;
01161
01162 break;
01163
01164 case MINUS_EXPR:
01165
01166 rhs0 = TREE_OPERAND (rhs, 0);
01167 rhs1 = TREE_OPERAND (rhs, 1);
01168 STRIP_TYPE_NOPS (rhs0);
01169 STRIP_TYPE_NOPS (rhs1);
01170
01171 if (TREE_CODE (rhs0) == SSA_NAME)
01172 {
01173
01174
01175 res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
01176 evolution_of_loop);
01177 if (res)
01178 *evolution_of_loop = add_to_evolution
01179 (loop->num, chrec_convert (type_rhs, *evolution_of_loop),
01180 MINUS_EXPR, rhs1);
01181 }
01182 else
01183
01184
01185
01186 res = false;
01187
01188 break;
01189
01190 case MULT_EXPR:
01191
01192 rhs0 = TREE_OPERAND (rhs, 0);
01193 rhs1 = TREE_OPERAND (rhs, 1);
01194 STRIP_TYPE_NOPS (rhs0);
01195 STRIP_TYPE_NOPS (rhs1);
01196
01197 if (TREE_CODE (rhs0) == SSA_NAME)
01198 {
01199 if (TREE_CODE (rhs1) == SSA_NAME)
01200 {
01201
01202
01203 res = follow_ssa_edge
01204 (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
01205 evolution_of_loop);
01206
01207 if (res)
01208 *evolution_of_loop = chrec_dont_know;
01209
01210 else
01211 {
01212 res = follow_ssa_edge
01213 (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
01214 evolution_of_loop);
01215
01216 if (res)
01217 *evolution_of_loop = chrec_dont_know;
01218 }
01219 }
01220
01221 else
01222 {
01223
01224
01225 res = follow_ssa_edge
01226 (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
01227 evolution_of_loop);
01228 if (res)
01229 *evolution_of_loop = chrec_dont_know;
01230 }
01231 }
01232
01233 else if (TREE_CODE (rhs1) == SSA_NAME)
01234 {
01235
01236
01237 res = follow_ssa_edge
01238 (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
01239 evolution_of_loop);
01240 if (res)
01241 *evolution_of_loop = chrec_dont_know;
01242 }
01243
01244 else
01245
01246
01247
01248 res = false;
01249
01250 break;
01251
01252 default:
01253 res = false;
01254 break;
01255 }
01256
01257 return res;
01258 }
01259
01260
01261
01262 static bool
01263 backedge_phi_arg_p (tree phi, int i)
01264 {
01265 edge e = PHI_ARG_EDGE (phi, i);
01266
01267
01268
01269
01270 if (e->flags & EDGE_IRREDUCIBLE_LOOP)
01271 return true;
01272
01273 return false;
01274 }
01275
01276
01277
01278
01279
01280 static inline bool
01281 follow_ssa_edge_in_condition_phi_branch (int i,
01282 struct loop *loop,
01283 tree condition_phi,
01284 tree halting_phi,
01285 tree *evolution_of_branch,
01286 tree init_cond)
01287 {
01288 tree branch = PHI_ARG_DEF (condition_phi, i);
01289 *evolution_of_branch = chrec_dont_know;
01290
01291
01292
01293 if (backedge_phi_arg_p (condition_phi, i))
01294 return false;
01295
01296 if (TREE_CODE (branch) == SSA_NAME)
01297 {
01298 *evolution_of_branch = init_cond;
01299 return follow_ssa_edge (loop, SSA_NAME_DEF_STMT (branch), halting_phi,
01300 evolution_of_branch);
01301 }
01302
01303
01304
01305
01306
01307
01308
01309
01310 return false;
01311 }
01312
01313
01314
01315
01316 static bool
01317 follow_ssa_edge_in_condition_phi (struct loop *loop,
01318 tree condition_phi,
01319 tree halting_phi,
01320 tree *evolution_of_loop)
01321 {
01322 int i;
01323 tree init = *evolution_of_loop;
01324 tree evolution_of_branch;
01325
01326 if (!follow_ssa_edge_in_condition_phi_branch (0, loop, condition_phi,
01327 halting_phi,
01328 &evolution_of_branch,
01329 init))
01330 return false;
01331 *evolution_of_loop = evolution_of_branch;
01332
01333 for (i = 1; i < PHI_NUM_ARGS (condition_phi); i++)
01334 {
01335
01336
01337 if (*evolution_of_loop == chrec_dont_know)
01338 return true;
01339
01340 if (!follow_ssa_edge_in_condition_phi_branch (i, loop, condition_phi,
01341 halting_phi,
01342 &evolution_of_branch,
01343 init))
01344 return false;
01345
01346 *evolution_of_loop = chrec_merge (*evolution_of_loop,
01347 evolution_of_branch);
01348 }
01349
01350 return true;
01351 }
01352
01353
01354
01355
01356
01357
01358 static bool
01359 follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
01360 tree loop_phi_node,
01361 tree halting_phi,
01362 tree *evolution_of_loop)
01363 {
01364 struct loop *loop = loop_containing_stmt (loop_phi_node);
01365 tree ev = analyze_scalar_evolution (loop, PHI_RESULT (loop_phi_node));
01366
01367
01368
01369 if (ev == PHI_RESULT (loop_phi_node))
01370 {
01371 bool res = false;
01372 int i;
01373
01374 for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
01375 {
01376 tree arg = PHI_ARG_DEF (loop_phi_node, i);
01377 basic_block bb;
01378
01379
01380 bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
01381 if (!flow_bb_inside_loop_p (loop, bb))
01382 res = res || follow_ssa_edge_in_rhs (outer_loop, arg, halting_phi,
01383 evolution_of_loop);
01384 }
01385
01386
01387 if (res == true)
01388 *evolution_of_loop = chrec_dont_know;
01389
01390 return res;
01391 }
01392
01393
01394 ev = compute_overall_effect_of_inner_loop (loop, ev);
01395 return follow_ssa_edge_in_rhs (outer_loop, ev, halting_phi,
01396 evolution_of_loop);
01397 }
01398
01399
01400
01401
01402 static bool
01403 follow_ssa_edge (struct loop *loop,
01404 tree def,
01405 tree halting_phi,
01406 tree *evolution_of_loop)
01407 {
01408 struct loop *def_loop;
01409
01410 if (TREE_CODE (def) == NOP_EXPR)
01411 return false;
01412
01413 def_loop = loop_containing_stmt (def);
01414
01415 switch (TREE_CODE (def))
01416 {
01417 case PHI_NODE:
01418 if (!loop_phi_node_p (def))
01419
01420
01421
01422
01423 return follow_ssa_edge_in_condition_phi
01424 (loop, def, halting_phi, evolution_of_loop);
01425
01426
01427
01428
01429 if (def == halting_phi)
01430 return true;
01431
01432
01433
01434
01435 if (def_loop == loop)
01436 return false;
01437
01438
01439 if (flow_loop_nested_p (loop, def_loop))
01440 return follow_ssa_edge_inner_loop_phi
01441 (loop, def, halting_phi, evolution_of_loop);
01442
01443
01444 return false;
01445
01446 case MODIFY_EXPR:
01447 return follow_ssa_edge_in_rhs (loop,
01448 TREE_OPERAND (def, 1),
01449 halting_phi,
01450 evolution_of_loop);
01451
01452 default:
01453
01454
01455
01456 return false;
01457 }
01458 }
01459
01460
01461
01462
01463
01464
01465 static tree
01466 analyze_evolution_in_loop (tree loop_phi_node,
01467 tree init_cond)
01468 {
01469 int i;
01470 tree evolution_function = chrec_not_analyzed_yet;
01471 struct loop *loop = loop_containing_stmt (loop_phi_node);
01472 basic_block bb;
01473
01474 if (dump_file && (dump_flags & TDF_DETAILS))
01475 {
01476 fprintf (dump_file, "(analyze_evolution_in_loop \n");
01477 fprintf (dump_file, " (loop_phi_node = ");
01478 print_generic_expr (dump_file, loop_phi_node, 0);
01479 fprintf (dump_file, ")\n");
01480 }
01481
01482 for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
01483 {
01484 tree arg = PHI_ARG_DEF (loop_phi_node, i);
01485 tree ssa_chain, ev_fn;
01486 bool res;
01487
01488
01489 bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
01490 if (!flow_bb_inside_loop_p (loop, bb))
01491 continue;
01492
01493 if (TREE_CODE (arg) == SSA_NAME)
01494 {
01495 ssa_chain = SSA_NAME_DEF_STMT (arg);
01496
01497
01498 ev_fn = init_cond;
01499 res = follow_ssa_edge (loop, ssa_chain, loop_phi_node, &ev_fn);
01500 }
01501 else
01502 res = false;
01503
01504
01505
01506
01507
01508
01509
01510 if (!res)
01511 ev_fn = chrec_dont_know;
01512
01513
01514
01515 evolution_function = chrec_merge (evolution_function, ev_fn);
01516 }
01517
01518 if (dump_file && (dump_flags & TDF_DETAILS))
01519 {
01520 fprintf (dump_file, " (evolution_function = ");
01521 print_generic_expr (dump_file, evolution_function, 0);
01522 fprintf (dump_file, "))\n");
01523 }
01524
01525 return evolution_function;
01526 }
01527
01528
01529
01530
01531
01532
01533
01534
01535 static tree
01536 analyze_initial_condition (tree loop_phi_node)
01537 {
01538 int i;
01539 tree init_cond = chrec_not_analyzed_yet;
01540 struct loop *loop = bb_for_stmt (loop_phi_node)->loop_father;
01541
01542 if (dump_file && (dump_flags & TDF_DETAILS))
01543 {
01544 fprintf (dump_file, "(analyze_initial_condition \n");
01545 fprintf (dump_file, " (loop_phi_node = \n");
01546 print_generic_expr (dump_file, loop_phi_node, 0);
01547 fprintf (dump_file, ")\n");
01548 }
01549
01550 for (i = 0; i < PHI_NUM_ARGS (loop_phi_node); i++)
01551 {
01552 tree branch = PHI_ARG_DEF (loop_phi_node, i);
01553 basic_block bb = PHI_ARG_EDGE (loop_phi_node, i)->src;
01554
01555
01556
01557 if (flow_bb_inside_loop_p (loop, bb))
01558 continue;
01559
01560 if (init_cond == chrec_not_analyzed_yet)
01561 {
01562 init_cond = branch;
01563 continue;
01564 }
01565
01566 if (TREE_CODE (branch) == SSA_NAME)
01567 {
01568 init_cond = chrec_dont_know;
01569 break;
01570 }
01571
01572 init_cond = chrec_merge (init_cond, branch);
01573 }
01574
01575
01576 if (init_cond == chrec_not_analyzed_yet)
01577 init_cond = chrec_dont_know;
01578
01579 if (dump_file && (dump_flags & TDF_DETAILS))
01580 {
01581 fprintf (dump_file, " (init_cond = ");
01582 print_generic_expr (dump_file, init_cond, 0);
01583 fprintf (dump_file, "))\n");
01584 }
01585
01586 return init_cond;
01587 }
01588
01589
01590
01591 static tree
01592 interpret_loop_phi (struct loop *loop, tree loop_phi_node)
01593 {
01594 tree res;
01595 struct loop *phi_loop = loop_containing_stmt (loop_phi_node);
01596 tree init_cond;
01597
01598 if (phi_loop != loop)
01599 {
01600 struct loop *subloop;
01601 tree evolution_fn = analyze_scalar_evolution
01602 (phi_loop, PHI_RESULT (loop_phi_node));
01603
01604
01605 subloop = superloop_at_depth (phi_loop, loop->depth + 1);
01606
01607
01608 res = compute_overall_effect_of_inner_loop (subloop, evolution_fn);
01609 return res;
01610 }
01611
01612
01613 init_cond = analyze_initial_condition (loop_phi_node);
01614 res = analyze_evolution_in_loop (loop_phi_node, init_cond);
01615
01616 return res;
01617 }
01618
01619
01620
01621
01622
01623 static tree
01624 interpret_condition_phi (struct loop *loop, tree condition_phi)
01625 {
01626 int i;
01627 tree res = chrec_not_analyzed_yet;
01628
01629 for (i = 0; i < PHI_NUM_ARGS (condition_phi); i++)
01630 {
01631 tree branch_chrec;
01632
01633 if (backedge_phi_arg_p (condition_phi, i))
01634 {
01635 res = chrec_dont_know;
01636 break;
01637 }
01638
01639 branch_chrec = analyze_scalar_evolution
01640 (loop, PHI_ARG_DEF (condition_phi, i));
01641
01642 res = chrec_merge (res, branch_chrec);
01643 }
01644
01645 return res;
01646 }
01647
01648
01649
01650
01651
01652
01653
01654
01655 static tree
01656 interpret_rhs_modify_expr (struct loop *loop,
01657 tree opnd1, tree type)
01658 {
01659 tree res, opnd10, opnd11, chrec10, chrec11;
01660
01661 if (is_gimple_min_invariant (opnd1))
01662 return chrec_convert (type, opnd1);
01663
01664 switch (TREE_CODE (opnd1))
01665 {
01666 case PLUS_EXPR:
01667 opnd10 = TREE_OPERAND (opnd1, 0);
01668 opnd11 = TREE_OPERAND (opnd1, 1);
01669 chrec10 = analyze_scalar_evolution (loop, opnd10);
01670 chrec11 = analyze_scalar_evolution (loop, opnd11);
01671 chrec10 = chrec_convert (type, chrec10);
01672 chrec11 = chrec_convert (type, chrec11);
01673 res = chrec_fold_plus (type, chrec10, chrec11);
01674 break;
01675
01676 case MINUS_EXPR:
01677 opnd10 = TREE_OPERAND (opnd1, 0);
01678 opnd11 = TREE_OPERAND (opnd1, 1);
01679 chrec10 = analyze_scalar_evolution (loop, opnd10);
01680 chrec11 = analyze_scalar_evolution (loop, opnd11);
01681 chrec10 = chrec_convert (type, chrec10);
01682 chrec11 = chrec_convert (type, chrec11);
01683 res = chrec_fold_minus (type, chrec10, chrec11);
01684 break;
01685
01686 case NEGATE_EXPR:
01687 opnd10 = TREE_OPERAND (opnd1, 0);
01688 chrec10 = analyze_scalar_evolution (loop, opnd10);
01689 chrec10 = chrec_convert (type, chrec10);
01690 res = chrec_fold_minus (type, build_int_cst (type, 0), chrec10);
01691 break;
01692
01693 case MULT_EXPR:
01694 opnd10 = TREE_OPERAND (opnd1, 0);
01695 opnd11 = TREE_OPERAND (opnd1, 1);
01696 chrec10 = analyze_scalar_evolution (loop, opnd10);
01697 chrec11 = analyze_scalar_evolution (loop, opnd11);
01698 chrec10 = chrec_convert (type, chrec10);
01699 chrec11 = chrec_convert (type, chrec11);
01700 res = chrec_fold_multiply (type, chrec10, chrec11);
01701 break;
01702
01703 case SSA_NAME:
01704 res = chrec_convert (type, analyze_scalar_evolution (loop, opnd1));
01705 break;
01706
01707 case NOP_EXPR:
01708 case CONVERT_EXPR:
01709 opnd10 = TREE_OPERAND (opnd1, 0);
01710 chrec10 = analyze_scalar_evolution (loop, opnd10);
01711 res = chrec_convert (type, chrec10);
01712 break;
01713
01714 default:
01715 res = chrec_dont_know;
01716 break;
01717 }
01718
01719 return res;
01720 }
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733 static tree
01734 compute_scalar_evolution_in_loop (struct loop *wrto_loop,
01735 struct loop *def_loop,
01736 tree ev)
01737 {
01738 tree res;
01739 if (def_loop == wrto_loop)
01740 return ev;
01741
01742 def_loop = superloop_at_depth (def_loop, wrto_loop->depth + 1);
01743 res = compute_overall_effect_of_inner_loop (def_loop, ev);
01744
01745 return analyze_scalar_evolution_1 (wrto_loop, res, chrec_not_analyzed_yet);
01746 }
01747
01748
01749
01750 static tree
01751 analyze_scalar_evolution_1 (struct loop *loop, tree var, tree res)
01752 {
01753 tree def, type = TREE_TYPE (var);
01754 basic_block bb;
01755 struct loop *def_loop;
01756
01757 if (loop == NULL)
01758 return chrec_dont_know;
01759
01760 if (TREE_CODE (var) != SSA_NAME)
01761 return interpret_rhs_modify_expr (loop, var, type);
01762
01763 def = SSA_NAME_DEF_STMT (var);
01764 bb = bb_for_stmt (def);
01765 def_loop = bb ? bb->loop_father : NULL;
01766
01767 if (bb == NULL
01768 || !flow_bb_inside_loop_p (loop, bb))
01769 {
01770
01771 res = var;
01772 goto set_and_end;
01773 }
01774
01775 if (res != chrec_not_analyzed_yet)
01776 {
01777 if (loop != bb->loop_father)
01778 res = compute_scalar_evolution_in_loop
01779 (find_common_loop (loop, bb->loop_father), bb->loop_father, res);
01780
01781 goto set_and_end;
01782 }
01783
01784 if (loop != def_loop)
01785 {
01786 res = analyze_scalar_evolution_1 (def_loop, var, chrec_not_analyzed_yet);
01787 res = compute_scalar_evolution_in_loop (loop, def_loop, res);
01788
01789 goto set_and_end;
01790 }
01791
01792 switch (TREE_CODE (def))
01793 {
01794 case MODIFY_EXPR:
01795 res = interpret_rhs_modify_expr (loop, TREE_OPERAND (def, 1), type);
01796 break;
01797
01798 case PHI_NODE:
01799 if (loop_phi_node_p (def))
01800 res = interpret_loop_phi (loop, def);
01801 else
01802 res = interpret_condition_phi (loop, def);
01803 break;
01804
01805 default:
01806 res = chrec_dont_know;
01807 break;
01808 }
01809
01810 set_and_end:
01811
01812
01813 if (res == chrec_dont_know)
01814 res = var;
01815
01816 if (loop == def_loop)
01817 set_scalar_evolution (var, res);
01818
01819 return res;
01820 }
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838 tree
01839 analyze_scalar_evolution (struct loop *loop, tree var)
01840 {
01841 tree res;
01842
01843 if (dump_file && (dump_flags & TDF_DETAILS))
01844 {
01845 fprintf (dump_file, "(analyze_scalar_evolution \n");
01846 fprintf (dump_file, " (loop_nb = %d)\n", loop->num);
01847 fprintf (dump_file, " (scalar = ");
01848 print_generic_expr (dump_file, var, 0);
01849 fprintf (dump_file, ")\n");
01850 }
01851
01852 res = analyze_scalar_evolution_1 (loop, var, get_scalar_evolution (var));
01853
01854 if (TREE_CODE (var) == SSA_NAME && res == chrec_dont_know)
01855 res = var;
01856
01857 if (dump_file && (dump_flags & TDF_DETAILS))
01858 fprintf (dump_file, ")\n");
01859
01860 return res;
01861 }
01862
01863
01864
01865
01866
01867 static tree
01868 analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop,
01869 tree version)
01870 {
01871 bool val = false;
01872 tree ev = version;
01873
01874 while (1)
01875 {
01876 ev = analyze_scalar_evolution (use_loop, ev);
01877 ev = resolve_mixers (use_loop, ev);
01878
01879 if (use_loop == wrto_loop)
01880 return ev;
01881
01882
01883
01884
01885 if (!no_evolution_in_loop_p (ev, use_loop->num, &val)
01886 || !val)
01887 return chrec_dont_know;
01888
01889 use_loop = use_loop->outer;
01890 }
01891 }
01892
01893
01894
01895 static tree
01896 get_instantiated_value (htab_t cache, tree version)
01897 {
01898 struct scev_info_str *info, pattern;
01899
01900 pattern.var = version;
01901 info = htab_find (cache, &pattern);
01902
01903 if (info)
01904 return info->chrec;
01905 else
01906 return NULL_TREE;
01907 }
01908
01909
01910
01911 static void
01912 set_instantiated_value (htab_t cache, tree version, tree val)
01913 {
01914 struct scev_info_str *info, pattern;
01915 PTR *slot;
01916
01917 pattern.var = version;
01918 slot = htab_find_slot (cache, &pattern, INSERT);
01919
01920 if (*slot)
01921 info = *slot;
01922 else
01923 info = *slot = new_scev_info_str (version);
01924 info->chrec = val;
01925 }
01926
01927
01928
01929
01930
01931
01932
01933 static tree
01934 instantiate_parameters_1 (struct loop *loop, tree chrec,
01935 bool allow_superloop_chrecs,
01936 htab_t cache)
01937 {
01938 tree res, op0, op1, op2;
01939 basic_block def_bb;
01940 struct loop *def_loop;
01941
01942 if (chrec == NULL_TREE
01943 || automatically_generated_chrec_p (chrec))
01944 return chrec;
01945
01946 if (is_gimple_min_invariant (chrec))
01947 return chrec;
01948
01949 switch (TREE_CODE (chrec))
01950 {
01951 case SSA_NAME:
01952 def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (chrec));
01953
01954
01955
01956 if (!def_bb
01957 || (!allow_superloop_chrecs
01958 && !flow_bb_inside_loop_p (loop, def_bb)))
01959 return chrec;
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970 res = get_instantiated_value (cache, chrec);
01971 if (res)
01972 return res;
01973
01974
01975
01976
01977
01978 res = !flow_bb_inside_loop_p (loop, def_bb) ? chrec : chrec_dont_know;
01979 set_instantiated_value (cache, chrec, res);
01980
01981
01982
01983
01984
01985
01986 if (bitmap_bit_p (already_instantiated, SSA_NAME_VERSION (chrec)))
01987 return res;
01988
01989 def_loop = find_common_loop (loop, def_bb->loop_father);
01990
01991
01992
01993 bitmap_set_bit (already_instantiated, SSA_NAME_VERSION (chrec));
01994 res = analyze_scalar_evolution (def_loop, chrec);
01995 if (res != chrec_dont_know)
01996 res = instantiate_parameters_1 (loop, res, allow_superloop_chrecs,
01997 cache);
01998 bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec));
01999
02000
02001 set_instantiated_value (cache, chrec, res);
02002 return res;
02003
02004 case POLYNOMIAL_CHREC:
02005 op0 = instantiate_parameters_1 (loop, CHREC_LEFT (chrec),
02006 allow_superloop_chrecs, cache);
02007 if (op0 == chrec_dont_know)
02008 return chrec_dont_know;
02009
02010 op1 = instantiate_parameters_1 (loop, CHREC_RIGHT (chrec),
02011 allow_superloop_chrecs, cache);
02012 if (op1 == chrec_dont_know)
02013 return chrec_dont_know;
02014
02015 if (CHREC_LEFT (chrec) != op0
02016 || CHREC_RIGHT (chrec) != op1)
02017 chrec = build_polynomial_chrec (CHREC_VARIABLE (chrec), op0, op1);
02018 return chrec;
02019
02020 case PLUS_EXPR:
02021 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02022 allow_superloop_chrecs, cache);
02023 if (op0 == chrec_dont_know)
02024 return chrec_dont_know;
02025
02026 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02027 allow_superloop_chrecs, cache);
02028 if (op1 == chrec_dont_know)
02029 return chrec_dont_know;
02030
02031 if (TREE_OPERAND (chrec, 0) != op0
02032 || TREE_OPERAND (chrec, 1) != op1)
02033 chrec = chrec_fold_plus (TREE_TYPE (chrec), op0, op1);
02034 return chrec;
02035
02036 case MINUS_EXPR:
02037 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02038 allow_superloop_chrecs, cache);
02039 if (op0 == chrec_dont_know)
02040 return chrec_dont_know;
02041
02042 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02043 allow_superloop_chrecs, cache);
02044 if (op1 == chrec_dont_know)
02045 return chrec_dont_know;
02046
02047 if (TREE_OPERAND (chrec, 0) != op0
02048 || TREE_OPERAND (chrec, 1) != op1)
02049 chrec = chrec_fold_minus (TREE_TYPE (chrec), op0, op1);
02050 return chrec;
02051
02052 case MULT_EXPR:
02053 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02054 allow_superloop_chrecs, cache);
02055 if (op0 == chrec_dont_know)
02056 return chrec_dont_know;
02057
02058 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02059 allow_superloop_chrecs, cache);
02060 if (op1 == chrec_dont_know)
02061 return chrec_dont_know;
02062
02063 if (TREE_OPERAND (chrec, 0) != op0
02064 || TREE_OPERAND (chrec, 1) != op1)
02065 chrec = chrec_fold_multiply (TREE_TYPE (chrec), op0, op1);
02066 return chrec;
02067
02068 case NOP_EXPR:
02069 case CONVERT_EXPR:
02070 case NON_LVALUE_EXPR:
02071 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02072 allow_superloop_chrecs, cache);
02073 if (op0 == chrec_dont_know)
02074 return chrec_dont_know;
02075
02076 if (op0 == TREE_OPERAND (chrec, 0))
02077 return chrec;
02078
02079 return chrec_convert (TREE_TYPE (chrec), op0);
02080
02081 case SCEV_NOT_KNOWN:
02082 return chrec_dont_know;
02083
02084 case SCEV_KNOWN:
02085 return chrec_known;
02086
02087 default:
02088 break;
02089 }
02090
02091 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
02092 {
02093 case 3:
02094 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02095 allow_superloop_chrecs, cache);
02096 if (op0 == chrec_dont_know)
02097 return chrec_dont_know;
02098
02099 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02100 allow_superloop_chrecs, cache);
02101 if (op1 == chrec_dont_know)
02102 return chrec_dont_know;
02103
02104 op2 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 2),
02105 allow_superloop_chrecs, cache);
02106 if (op2 == chrec_dont_know)
02107 return chrec_dont_know;
02108
02109 if (op0 == TREE_OPERAND (chrec, 0)
02110 && op1 == TREE_OPERAND (chrec, 1)
02111 && op2 == TREE_OPERAND (chrec, 2))
02112 return chrec;
02113
02114 return fold (build (TREE_CODE (chrec),
02115 TREE_TYPE (chrec), op0, op1, op2));
02116
02117 case 2:
02118 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02119 allow_superloop_chrecs, cache);
02120 if (op0 == chrec_dont_know)
02121 return chrec_dont_know;
02122
02123 op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
02124 allow_superloop_chrecs, cache);
02125 if (op1 == chrec_dont_know)
02126 return chrec_dont_know;
02127
02128 if (op0 == TREE_OPERAND (chrec, 0)
02129 && op1 == TREE_OPERAND (chrec, 1))
02130 return chrec;
02131 return fold (build (TREE_CODE (chrec), TREE_TYPE (chrec), op0, op1));
02132
02133 case 1:
02134 op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
02135 allow_superloop_chrecs, cache);
02136 if (op0 == chrec_dont_know)
02137 return chrec_dont_know;
02138 if (op0 == TREE_OPERAND (chrec, 0))
02139 return chrec;
02140 return fold (build1 (TREE_CODE (chrec), TREE_TYPE (chrec), op0));
02141
02142 case 0:
02143 return chrec;
02144
02145 default:
02146 break;
02147 }
02148
02149
02150 return chrec_dont_know;
02151 }
02152
02153
02154
02155
02156
02157 tree
02158 instantiate_parameters (struct loop *loop,
02159 tree chrec)
02160 {
02161 tree res;
02162 htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
02163
02164 if (dump_file && (dump_flags & TDF_DETAILS))
02165 {
02166 fprintf (dump_file, "(instantiate_parameters \n");
02167 fprintf (dump_file, " (loop_nb = %d)\n", loop->num);
02168 fprintf (dump_file, " (chrec = ");
02169 print_generic_expr (dump_file, chrec, 0);
02170 fprintf (dump_file, ")\n");
02171 }
02172
02173 res = instantiate_parameters_1 (loop, chrec, true, cache);
02174
02175 if (dump_file && (dump_flags & TDF_DETAILS))
02176 {
02177 fprintf (dump_file, " (res = ");
02178 print_generic_expr (dump_file, res, 0);
02179 fprintf (dump_file, "))\n");
02180 }
02181
02182 htab_delete (cache);
02183
02184 return res;
02185 }
02186
02187
02188
02189
02190 static tree
02191 resolve_mixers (struct loop *loop, tree chrec)
02192 {
02193 htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
02194 tree ret = instantiate_parameters_1 (loop, chrec, false, cache);
02195 htab_delete (cache);
02196 return ret;
02197 }
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219 tree
02220 number_of_iterations_in_loop (struct loop *loop)
02221 {
02222 tree res, type;
02223 edge exit;
02224 struct tree_niter_desc niter_desc;
02225
02226
02227
02228 res = loop->nb_iterations;
02229 if (res)
02230 return res;
02231 res = chrec_dont_know;
02232
02233 if (dump_file && (dump_flags & TDF_DETAILS))
02234 fprintf (dump_file, "(number_of_iterations_in_loop\n");
02235
02236 exit = loop->single_exit;
02237 if (!exit)
02238 goto end;
02239
02240 if (!number_of_iterations_exit (loop, exit, &niter_desc))
02241 goto end;
02242
02243 type = TREE_TYPE (niter_desc.niter);
02244 if (integer_nonzerop (niter_desc.may_be_zero))
02245 res = build_int_cst (type, 0);
02246 else if (integer_zerop (niter_desc.may_be_zero))
02247 res = niter_desc.niter;
02248 else
02249 res = chrec_dont_know;
02250
02251 end:
02252 return set_nb_iterations_in_loop (loop, res);
02253 }
02254
02255
02256
02257
02258
02259 static void
02260 number_of_iterations_for_all_loops (varray_type exit_conditions)
02261 {
02262 unsigned int i;
02263 unsigned nb_chrec_dont_know_loops = 0;
02264 unsigned nb_static_loops = 0;
02265
02266 for (i = 0; i < VARRAY_ACTIVE_SIZE (exit_conditions); i++)
02267 {
02268 tree res = number_of_iterations_in_loop
02269 (loop_containing_stmt (VARRAY_TREE (exit_conditions, i)));
02270 if (chrec_contains_undetermined (res))
02271 nb_chrec_dont_know_loops++;
02272 else
02273 nb_static_loops++;
02274 }
02275
02276 if (dump_file)
02277 {
02278 fprintf (dump_file, "\n(\n");
02279 fprintf (dump_file, "-----------------------------------------\n");
02280 fprintf (dump_file, "%d\tnb_chrec_dont_know_loops\n", nb_chrec_dont_know_loops);
02281 fprintf (dump_file, "%d\tnb_static_loops\n", nb_static_loops);
02282 fprintf (dump_file, "%d\tnb_total_loops\n", current_loops->num);
02283 fprintf (dump_file, "-----------------------------------------\n");
02284 fprintf (dump_file, ")\n\n");
02285
02286 print_loop_ir (dump_file);
02287 }
02288 }
02289
02290
02291
02292
02293
02294 struct chrec_stats
02295 {
02296 unsigned nb_chrecs;
02297 unsigned nb_affine;
02298 unsigned nb_affine_multivar;
02299 unsigned nb_higher_poly;
02300 unsigned nb_chrec_dont_know;
02301 unsigned nb_undetermined;
02302 };
02303
02304
02305
02306 static inline void
02307 reset_chrecs_counters (struct chrec_stats *stats)
02308 {
02309 stats->nb_chrecs = 0;
02310 stats->nb_affine = 0;
02311 stats->nb_affine_multivar = 0;
02312 stats->nb_higher_poly = 0;
02313 stats->nb_chrec_dont_know = 0;
02314 stats->nb_undetermined = 0;
02315 }
02316
02317
02318
02319 static void
02320 dump_chrecs_stats (FILE *file, struct chrec_stats *stats)
02321 {
02322 fprintf (file, "\n(\n");
02323 fprintf (file, "-----------------------------------------\n");
02324 fprintf (file, "%d\taffine univariate chrecs\n", stats->nb_affine);
02325 fprintf (file, "%d\taffine multivariate chrecs\n", stats->nb_affine_multivar);
02326 fprintf (file, "%d\tdegree greater than 2 polynomials\n",
02327 stats->nb_higher_poly);
02328 fprintf (file, "%d\tchrec_dont_know chrecs\n", stats->nb_chrec_dont_know);
02329 fprintf (file, "-----------------------------------------\n");
02330 fprintf (file, "%d\ttotal chrecs\n", stats->nb_chrecs);
02331 fprintf (file, "%d\twith undetermined coefficients\n",
02332 stats->nb_undetermined);
02333 fprintf (file, "-----------------------------------------\n");
02334 fprintf (file, "%d\tchrecs in the scev database\n",
02335 (int) htab_elements (scalar_evolution_info));
02336 fprintf (file, "%d\tsets in the scev database\n", nb_set_scev);
02337 fprintf (file, "%d\tgets in the scev database\n", nb_get_scev);
02338 fprintf (file, "-----------------------------------------\n");
02339 fprintf (file, ")\n\n");
02340 }
02341
02342
02343
02344 static void
02345 gather_chrec_stats (tree chrec, struct chrec_stats *stats)
02346 {
02347 if (dump_file && (dump_flags & TDF_STATS))
02348 {
02349 fprintf (dump_file, "(classify_chrec ");
02350 print_generic_expr (dump_file, chrec, 0);
02351 fprintf (dump_file, "\n");
02352 }
02353
02354 stats->nb_chrecs++;
02355
02356 if (chrec == NULL_TREE)
02357 {
02358 stats->nb_undetermined++;
02359 return;
02360 }
02361
02362 switch (TREE_CODE (chrec))
02363 {
02364 case POLYNOMIAL_CHREC:
02365 if (evolution_function_is_affine_p (chrec))
02366 {
02367 if (dump_file && (dump_flags & TDF_STATS))
02368 fprintf (dump_file, " affine_univariate\n");
02369 stats->nb_affine++;
02370 }
02371 else if (evolution_function_is_affine_multivariate_p (chrec))
02372 {
02373 if (dump_file && (dump_flags & TDF_STATS))
02374 fprintf (dump_file, " affine_multivariate\n");
02375 stats->nb_affine_multivar++;
02376 }
02377 else
02378 {
02379 if (dump_file && (dump_flags & TDF_STATS))
02380 fprintf (dump_file, " higher_degree_polynomial\n");
02381 stats->nb_higher_poly++;
02382 }
02383
02384 break;
02385
02386 default:
02387 break;
02388 }
02389
02390 if (chrec_contains_undetermined (chrec))
02391 {
02392 if (dump_file && (dump_flags & TDF_STATS))
02393 fprintf (dump_file, " undetermined\n");
02394 stats->nb_undetermined++;
02395 }
02396
02397 if (dump_file && (dump_flags & TDF_STATS))
02398 fprintf (dump_file, ")\n");
02399 }
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411 static void
02412 analyze_scalar_evolution_for_all_loop_phi_nodes (varray_type exit_conditions)
02413 {
02414 unsigned int i;
02415 struct chrec_stats stats;
02416
02417 reset_chrecs_counters (&stats);
02418
02419 for (i = 0; i < VARRAY_ACTIVE_SIZE (exit_conditions); i++)
02420 {
02421 struct loop *loop;
02422 basic_block bb;
02423 tree phi, chrec;
02424
02425 loop = loop_containing_stmt (VARRAY_TREE (exit_conditions, i));
02426 bb = loop->header;
02427
02428 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
02429 if (is_gimple_reg (PHI_RESULT (phi)))
02430 {
02431 chrec = instantiate_parameters
02432 (loop,
02433 analyze_scalar_evolution (loop, PHI_RESULT (phi)));
02434
02435 if (dump_file && (dump_flags & TDF_STATS))
02436 gather_chrec_stats (chrec, &stats);
02437 }
02438 }
02439
02440 if (dump_file && (dump_flags & TDF_STATS))
02441 dump_chrecs_stats (dump_file, &stats);
02442 }
02443
02444
02445
02446
02447 static int
02448 gather_stats_on_scev_database_1 (void **slot, void *stats)
02449 {
02450 struct scev_info_str *entry = *slot;
02451
02452 gather_chrec_stats (entry->chrec, stats);
02453
02454 return 1;
02455 }
02456
02457
02458
02459 void
02460 gather_stats_on_scev_database (void)
02461 {
02462 struct chrec_stats stats;
02463
02464 if (!dump_file)
02465 return;
02466
02467 reset_chrecs_counters (&stats);
02468
02469 htab_traverse (scalar_evolution_info, gather_stats_on_scev_database_1,
02470 &stats);
02471
02472 dump_chrecs_stats (dump_file, &stats);
02473 }
02474
02475
02476
02477
02478
02479 static void
02480 initialize_scalar_evolutions_analyzer (void)
02481 {
02482
02483 if (chrec_dont_know == NULL_TREE)
02484 {
02485 chrec_not_analyzed_yet = NULL_TREE;
02486 chrec_dont_know = make_node (SCEV_NOT_KNOWN);
02487 chrec_known = make_node (SCEV_KNOWN);
02488 TREE_TYPE (chrec_dont_know) = NULL_TREE;
02489 TREE_TYPE (chrec_known) = NULL_TREE;
02490 }
02491 }
02492
02493
02494
02495 void
02496 scev_initialize (struct loops *loops)
02497 {
02498 unsigned i;
02499 current_loops = loops;
02500
02501 scalar_evolution_info = htab_create (100, hash_scev_info,
02502 eq_scev_info, del_scev_info);
02503 already_instantiated = BITMAP_ALLOC (NULL);
02504
02505 initialize_scalar_evolutions_analyzer ();
02506
02507 for (i = 1; i < loops->num; i++)
02508 if (loops->parray[i])
02509 loops->parray[i]->nb_iterations = NULL_TREE;
02510 }
02511
02512
02513
02514 void
02515 scev_reset (void)
02516 {
02517 unsigned i;
02518 struct loop *loop;
02519
02520 if (!scalar_evolution_info || !current_loops)
02521 return;
02522
02523 htab_empty (scalar_evolution_info);
02524 for (i = 1; i < current_loops->num; i++)
02525 {
02526 loop = current_loops->parray[i];
02527 if (loop)
02528 loop->nb_iterations = NULL_TREE;
02529 }
02530 }
02531
02532
02533
02534
02535 bool
02536 simple_iv (struct loop *loop, tree stmt, tree op, tree *base, tree *step)
02537 {
02538 basic_block bb = bb_for_stmt (stmt);
02539 tree type, ev;
02540
02541 *base = NULL_TREE;
02542 *step = NULL_TREE;
02543
02544 type = TREE_TYPE (op);
02545 if (TREE_CODE (type) != INTEGER_TYPE
02546 && TREE_CODE (type) != POINTER_TYPE)
02547 return false;
02548
02549 ev = analyze_scalar_evolution_in_loop (loop, bb->loop_father, op);
02550 if (chrec_contains_undetermined (ev))
02551 return false;
02552
02553 if (tree_does_not_contain_chrecs (ev)
02554 && !chrec_contains_symbols_defined_in_loop (ev, loop->num))
02555 {
02556 *base = ev;
02557 return true;
02558 }
02559
02560 if (TREE_CODE (ev) != POLYNOMIAL_CHREC
02561 || CHREC_VARIABLE (ev) != (unsigned) loop->num)
02562 return false;
02563
02564 *step = CHREC_RIGHT (ev);
02565 if (TREE_CODE (*step) != INTEGER_CST)
02566 return false;
02567 *base = CHREC_LEFT (ev);
02568 if (tree_contains_chrecs (*base, NULL)
02569 || chrec_contains_symbols_defined_in_loop (*base, loop->num))
02570 return false;
02571
02572 return true;
02573 }
02574
02575
02576
02577 void
02578 scev_analysis (void)
02579 {
02580 varray_type exit_conditions;
02581
02582 VARRAY_GENERIC_PTR_INIT (exit_conditions, 37, "exit_conditions");
02583 select_loops_exit_conditions (current_loops, &exit_conditions);
02584
02585 if (dump_file && (dump_flags & TDF_STATS))
02586 analyze_scalar_evolution_for_all_loop_phi_nodes (exit_conditions);
02587
02588 number_of_iterations_for_all_loops (exit_conditions);
02589 VARRAY_CLEAR (exit_conditions);
02590 }
02591
02592
02593
02594 void
02595 scev_finalize (void)
02596 {
02597 htab_delete (scalar_evolution_info);
02598 BITMAP_FREE (already_instantiated);
02599 }
02600