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 #include "config.h"
00078 #include "system.h"
00079 #include "coretypes.h"
00080 #include "tm.h"
00081 #include "errors.h"
00082 #include "ggc.h"
00083 #include "tree.h"
00084
00085
00086 #include "rtl.h"
00087 #include "basic-block.h"
00088 #include "diagnostic.h"
00089 #include "tree-flow.h"
00090 #include "tree-dump.h"
00091 #include "timevar.h"
00092 #include "cfgloop.h"
00093 #include "tree-chrec.h"
00094 #include "tree-data-ref.h"
00095 #include "tree-scalar-evolution.h"
00096 #include "tree-pass.h"
00097
00098
00099
00100
00101
00102
00103
00104
00105 bool
00106 array_base_name_differ_p (struct data_reference *a,
00107 struct data_reference *b,
00108 bool *differ_p)
00109 {
00110 tree base_a = DR_BASE_NAME (a);
00111 tree base_b = DR_BASE_NAME (b);
00112 tree ta, tb;
00113
00114 if (!base_a || !base_b)
00115 return false;
00116
00117 ta = TREE_TYPE (base_a);
00118 tb = TREE_TYPE (base_b);
00119
00120
00121
00122 if (base_a == base_b)
00123 {
00124 *differ_p = false;
00125 return true;
00126 }
00127
00128
00129
00130 if (TREE_CODE (base_a) == INDIRECT_REF && TREE_CODE (base_b) == INDIRECT_REF
00131 && TREE_OPERAND (base_a, 0) == TREE_OPERAND (base_b, 0))
00132 {
00133 *differ_p = false;
00134 return true;
00135 }
00136
00137
00138 if (TREE_CODE (base_a) == COMPONENT_REF && TREE_CODE (base_b) == COMPONENT_REF
00139 && TREE_OPERAND (base_a, 0) == TREE_OPERAND (base_b, 0)
00140 && TREE_OPERAND (base_a, 1) == TREE_OPERAND (base_b, 1))
00141 {
00142 *differ_p = false;
00143 return true;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 if (TREE_CODE (base_a) == VAR_DECL && TREE_CODE (base_b) == VAR_DECL)
00155 {
00156 *differ_p = true;
00157 return true;
00158 }
00159
00160
00161
00162 if (TREE_CODE (base_a) == COMPONENT_REF && TREE_CODE (base_b) == COMPONENT_REF
00163 && ((TREE_CODE (TREE_OPERAND (base_a, 0)) == VAR_DECL
00164 && TREE_CODE (TREE_OPERAND (base_b, 0)) == VAR_DECL
00165 && TREE_OPERAND (base_a, 0) != TREE_OPERAND (base_b, 0))
00166 || (TREE_CODE (TREE_TYPE (TREE_OPERAND (base_a, 0))) == RECORD_TYPE
00167 && TREE_CODE (TREE_TYPE (TREE_OPERAND (base_b, 0))) == RECORD_TYPE
00168 && TREE_OPERAND (base_a, 1) != TREE_OPERAND (base_b, 1))))
00169 {
00170 *differ_p = true;
00171 return true;
00172 }
00173
00174
00175 if ((TREE_CODE (base_a) == VAR_DECL
00176 && (TREE_CODE (base_b) == COMPONENT_REF
00177 && TREE_CODE (TREE_OPERAND (base_b, 0)) == VAR_DECL))
00178 || (TREE_CODE (base_b) == VAR_DECL
00179 && (TREE_CODE (base_a) == COMPONENT_REF
00180 && TREE_CODE (TREE_OPERAND (base_a, 0)) == VAR_DECL)))
00181 {
00182 *differ_p = true;
00183 return true;
00184 }
00185
00186 return false;
00187 }
00188
00189
00190
00191 static inline bool
00192 tree_fold_divides_p (tree type,
00193 tree a,
00194 tree b)
00195 {
00196
00197 return integer_zerop
00198 (fold (build (MINUS_EXPR, type, a, tree_fold_gcd (a, b))));
00199 }
00200
00201
00202
00203
00204 static int
00205 gcd (int a, int b)
00206 {
00207
00208 int x, y, z;
00209
00210 x = abs (a);
00211 y = abs (b);
00212
00213 while (x>0)
00214 {
00215 z = y % x;
00216 y = x;
00217 x = z;
00218 }
00219
00220 return (y);
00221 }
00222
00223
00224
00225 static inline bool
00226 int_divides_p (int a, int b)
00227 {
00228 return ((b % a) == 0);
00229 }
00230
00231
00232
00233
00234
00235 void
00236 dump_data_references (FILE *file,
00237 varray_type datarefs)
00238 {
00239 unsigned int i;
00240
00241 for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
00242 dump_data_reference (file, VARRAY_GENERIC_PTR (datarefs, i));
00243 }
00244
00245
00246
00247 void
00248 dump_data_dependence_relations (FILE *file,
00249 varray_type ddr)
00250 {
00251 unsigned int i;
00252
00253 for (i = 0; i < VARRAY_ACTIVE_SIZE (ddr); i++)
00254 dump_data_dependence_relation (file, VARRAY_GENERIC_PTR (ddr, i));
00255 }
00256
00257
00258
00259 void
00260 dump_data_reference (FILE *outf,
00261 struct data_reference *dr)
00262 {
00263 unsigned int i;
00264
00265 fprintf (outf, "(Data Ref: \n stmt: ");
00266 print_generic_stmt (outf, DR_STMT (dr), 0);
00267 fprintf (outf, " ref: ");
00268 print_generic_stmt (outf, DR_REF (dr), 0);
00269 fprintf (outf, " base_name: ");
00270 print_generic_stmt (outf, DR_BASE_NAME (dr), 0);
00271
00272 for (i = 0; i < DR_NUM_DIMENSIONS (dr); i++)
00273 {
00274 fprintf (outf, " Access function %d: ", i);
00275 print_generic_stmt (outf, DR_ACCESS_FN (dr, i), 0);
00276 }
00277 fprintf (outf, ")\n");
00278 }
00279
00280
00281
00282 void
00283 dump_subscript (FILE *outf, struct subscript *subscript)
00284 {
00285 tree chrec = SUB_CONFLICTS_IN_A (subscript);
00286
00287 fprintf (outf, "\n (subscript \n");
00288 fprintf (outf, " iterations_that_access_an_element_twice_in_A: ");
00289 print_generic_stmt (outf, chrec, 0);
00290 if (chrec == chrec_known)
00291 fprintf (outf, " (no dependence)\n");
00292 else if (chrec_contains_undetermined (chrec))
00293 fprintf (outf, " (don't know)\n");
00294 else
00295 {
00296 tree last_iteration = SUB_LAST_CONFLICT (subscript);
00297 fprintf (outf, " last_conflict: ");
00298 print_generic_stmt (outf, last_iteration, 0);
00299 }
00300
00301 chrec = SUB_CONFLICTS_IN_B (subscript);
00302 fprintf (outf, " iterations_that_access_an_element_twice_in_B: ");
00303 print_generic_stmt (outf, chrec, 0);
00304 if (chrec == chrec_known)
00305 fprintf (outf, " (no dependence)\n");
00306 else if (chrec_contains_undetermined (chrec))
00307 fprintf (outf, " (don't know)\n");
00308 else
00309 {
00310 tree last_iteration = SUB_LAST_CONFLICT (subscript);
00311 fprintf (outf, " last_conflict: ");
00312 print_generic_stmt (outf, last_iteration, 0);
00313 }
00314
00315 fprintf (outf, " (Subscript distance: ");
00316 print_generic_stmt (outf, SUB_DISTANCE (subscript), 0);
00317 fprintf (outf, " )\n");
00318 fprintf (outf, " )\n");
00319 }
00320
00321
00322
00323 void
00324 dump_data_dependence_relation (FILE *outf,
00325 struct data_dependence_relation *ddr)
00326 {
00327 struct data_reference *dra, *drb;
00328
00329 dra = DDR_A (ddr);
00330 drb = DDR_B (ddr);
00331 fprintf (outf, "(Data Dep: \n");
00332 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
00333 fprintf (outf, " (don't know)\n");
00334
00335 else if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
00336 fprintf (outf, " (no dependence)\n");
00337
00338 else if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
00339 {
00340 unsigned int i;
00341 for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
00342 {
00343 fprintf (outf, " access_fn_A: ");
00344 print_generic_stmt (outf, DR_ACCESS_FN (dra, i), 0);
00345 fprintf (outf, " access_fn_B: ");
00346 print_generic_stmt (outf, DR_ACCESS_FN (drb, i), 0);
00347 dump_subscript (outf, DDR_SUBSCRIPT (ddr, i));
00348 }
00349 if (DDR_DIST_VECT (ddr))
00350 {
00351 fprintf (outf, " distance_vect: ");
00352 print_lambda_vector (outf, DDR_DIST_VECT (ddr), DDR_SIZE_VECT (ddr));
00353 }
00354 if (DDR_DIR_VECT (ddr))
00355 {
00356 fprintf (outf, " direction_vect: ");
00357 print_lambda_vector (outf, DDR_DIR_VECT (ddr), DDR_SIZE_VECT (ddr));
00358 }
00359 }
00360
00361 fprintf (outf, ")\n");
00362 }
00363
00364
00365
00366
00367
00368 void
00369 dump_data_dependence_direction (FILE *file,
00370 enum data_dependence_direction dir)
00371 {
00372 switch (dir)
00373 {
00374 case dir_positive:
00375 fprintf (file, "+");
00376 break;
00377
00378 case dir_negative:
00379 fprintf (file, "-");
00380 break;
00381
00382 case dir_equal:
00383 fprintf (file, "=");
00384 break;
00385
00386 case dir_positive_or_negative:
00387 fprintf (file, "+-");
00388 break;
00389
00390 case dir_positive_or_equal:
00391 fprintf (file, "+=");
00392 break;
00393
00394 case dir_negative_or_equal:
00395 fprintf (file, "-=");
00396 break;
00397
00398 case dir_star:
00399 fprintf (file, "*");
00400 break;
00401
00402 default:
00403 break;
00404 }
00405 }
00406
00407
00408
00409
00410
00411
00412 void
00413 dump_dist_dir_vectors (FILE *file, varray_type ddrs)
00414 {
00415 unsigned int i;
00416
00417 for (i = 0; i < VARRAY_ACTIVE_SIZE (ddrs); i++)
00418 {
00419 struct data_dependence_relation *ddr =
00420 (struct data_dependence_relation *)
00421 VARRAY_GENERIC_PTR (ddrs, i);
00422 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE
00423 && DDR_AFFINE_P (ddr))
00424 {
00425 fprintf (file, "DISTANCE_V (");
00426 print_lambda_vector (file, DDR_DIST_VECT (ddr), DDR_SIZE_VECT (ddr));
00427 fprintf (file, ")\n");
00428 fprintf (file, "DIRECTION_V (");
00429 print_lambda_vector (file, DDR_DIR_VECT (ddr), DDR_SIZE_VECT (ddr));
00430 fprintf (file, ")\n");
00431 }
00432 }
00433 fprintf (file, "\n\n");
00434 }
00435
00436
00437
00438 void
00439 dump_ddrs (FILE *file, varray_type ddrs)
00440 {
00441 unsigned int i;
00442
00443 for (i = 0; i < VARRAY_ACTIVE_SIZE (ddrs); i++)
00444 {
00445 struct data_dependence_relation *ddr =
00446 (struct data_dependence_relation *)
00447 VARRAY_GENERIC_PTR (ddrs, i);
00448 dump_data_dependence_relation (file, ddr);
00449 }
00450 fprintf (file, "\n\n");
00451 }
00452
00453
00454
00455
00456
00457
00458 static void
00459 compute_estimated_nb_iterations (struct loop *loop)
00460 {
00461 tree estimation;
00462 struct nb_iter_bound *bound, *next;
00463
00464 for (bound = loop->bounds; bound; bound = next)
00465 {
00466 next = bound->next;
00467 estimation = bound->bound;
00468
00469 if (TREE_CODE (estimation) != INTEGER_CST)
00470 continue;
00471
00472 if (loop->estimated_nb_iterations)
00473 {
00474
00475 if (tree_int_cst_lt (estimation, loop->estimated_nb_iterations))
00476 loop->estimated_nb_iterations = estimation;
00477 }
00478 else
00479 loop->estimated_nb_iterations = estimation;
00480 }
00481 }
00482
00483
00484
00485
00486 static void
00487 estimate_niter_from_size_of_data (struct loop *loop,
00488 tree opnd0,
00489 tree access_fn,
00490 tree stmt)
00491 {
00492 tree estimation;
00493 tree array_size, data_size, element_size;
00494 tree init, step;
00495
00496 init = initial_condition (access_fn);
00497 step = evolution_part_in_loop_num (access_fn, loop->num);
00498
00499 array_size = TYPE_SIZE (TREE_TYPE (opnd0));
00500 element_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (opnd0)));
00501 if (array_size == NULL_TREE
00502 || TREE_CODE (array_size) != INTEGER_CST
00503 || TREE_CODE (element_size) != INTEGER_CST)
00504 return;
00505
00506 data_size = fold (build2 (EXACT_DIV_EXPR, integer_type_node,
00507 array_size, element_size));
00508
00509 if (init != NULL_TREE
00510 && step != NULL_TREE
00511 && TREE_CODE (init) == INTEGER_CST
00512 && TREE_CODE (step) == INTEGER_CST)
00513 {
00514 estimation = fold (build2 (CEIL_DIV_EXPR, integer_type_node,
00515 fold (build2 (MINUS_EXPR, integer_type_node,
00516 data_size, init)), step));
00517
00518 record_estimate (loop, estimation, boolean_true_node, stmt);
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527
00528 static tree
00529 analyze_array_indexes (struct loop *loop,
00530 varray_type *access_fns,
00531 tree ref, tree stmt)
00532 {
00533 tree opnd0, opnd1;
00534 tree access_fn;
00535
00536 opnd0 = TREE_OPERAND (ref, 0);
00537 opnd1 = TREE_OPERAND (ref, 1);
00538
00539
00540
00541
00542
00543 access_fn = instantiate_parameters
00544 (loop, analyze_scalar_evolution (loop, opnd1));
00545
00546 if (loop->estimated_nb_iterations == NULL_TREE)
00547 estimate_niter_from_size_of_data (loop, opnd0, access_fn, stmt);
00548
00549 VARRAY_PUSH_TREE (*access_fns, access_fn);
00550
00551
00552 if (TREE_CODE (opnd0) == ARRAY_REF)
00553 return analyze_array_indexes (loop, access_fns, opnd0, stmt);
00554
00555
00556 else
00557 return opnd0;
00558 }
00559
00560
00561
00562
00563
00564
00565 struct data_reference *
00566 analyze_array (tree stmt, tree ref, bool is_read)
00567 {
00568 struct data_reference *res;
00569
00570 if (dump_file && (dump_flags & TDF_DETAILS))
00571 {
00572 fprintf (dump_file, "(analyze_array \n");
00573 fprintf (dump_file, " (ref = ");
00574 print_generic_stmt (dump_file, ref, 0);
00575 fprintf (dump_file, ")\n");
00576 }
00577
00578 res = xmalloc (sizeof (struct data_reference));
00579
00580 DR_STMT (res) = stmt;
00581 DR_REF (res) = ref;
00582 VARRAY_TREE_INIT (DR_ACCESS_FNS (res), 3, "access_fns");
00583 DR_BASE_NAME (res) = analyze_array_indexes
00584 (loop_containing_stmt (stmt), &(DR_ACCESS_FNS (res)), ref, stmt);
00585 DR_IS_READ (res) = is_read;
00586
00587 if (dump_file && (dump_flags & TDF_DETAILS))
00588 fprintf (dump_file, ")\n");
00589
00590 return res;
00591 }
00592
00593
00594
00595
00596 struct data_reference *
00597 init_data_ref (tree stmt,
00598 tree ref,
00599 tree base,
00600 tree access_fn,
00601 bool is_read)
00602 {
00603 struct data_reference *res;
00604
00605 if (dump_file && (dump_flags & TDF_DETAILS))
00606 {
00607 fprintf (dump_file, "(init_data_ref \n");
00608 fprintf (dump_file, " (ref = ");
00609 print_generic_stmt (dump_file, ref, 0);
00610 fprintf (dump_file, ")\n");
00611 }
00612
00613 res = xmalloc (sizeof (struct data_reference));
00614
00615 DR_STMT (res) = stmt;
00616 DR_REF (res) = ref;
00617 VARRAY_TREE_INIT (DR_ACCESS_FNS (res), 5, "access_fns");
00618 DR_BASE_NAME (res) = base;
00619 VARRAY_PUSH_TREE (DR_ACCESS_FNS (res), access_fn);
00620 DR_IS_READ (res) = is_read;
00621
00622 if (dump_file && (dump_flags & TDF_DETAILS))
00623 fprintf (dump_file, ")\n");
00624
00625 return res;
00626 }
00627
00628
00629
00630
00631
00632
00633 static bool
00634 all_chrecs_equal_p (tree chrec)
00635 {
00636 int j;
00637
00638 for (j = 0; j < TREE_VEC_LENGTH (chrec) - 1; j++)
00639 {
00640 tree chrec_j = TREE_VEC_ELT (chrec, j);
00641 tree chrec_j_1 = TREE_VEC_ELT (chrec, j + 1);
00642 if (!integer_zerop
00643 (chrec_fold_minus
00644 (integer_type_node, chrec_j, chrec_j_1)))
00645 return false;
00646 }
00647 return true;
00648 }
00649
00650
00651
00652
00653 static void
00654 compute_subscript_distance (struct data_dependence_relation *ddr)
00655 {
00656 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
00657 {
00658 unsigned int i;
00659
00660 for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
00661 {
00662 tree conflicts_a, conflicts_b, difference;
00663 struct subscript *subscript;
00664
00665 subscript = DDR_SUBSCRIPT (ddr, i);
00666 conflicts_a = SUB_CONFLICTS_IN_A (subscript);
00667 conflicts_b = SUB_CONFLICTS_IN_B (subscript);
00668
00669 if (TREE_CODE (conflicts_a) == TREE_VEC)
00670 {
00671 if (!all_chrecs_equal_p (conflicts_a))
00672 {
00673 SUB_DISTANCE (subscript) = chrec_dont_know;
00674 return;
00675 }
00676 else
00677 conflicts_a = TREE_VEC_ELT (conflicts_a, 0);
00678 }
00679
00680 if (TREE_CODE (conflicts_b) == TREE_VEC)
00681 {
00682 if (!all_chrecs_equal_p (conflicts_b))
00683 {
00684 SUB_DISTANCE (subscript) = chrec_dont_know;
00685 return;
00686 }
00687 else
00688 conflicts_b = TREE_VEC_ELT (conflicts_b, 0);
00689 }
00690
00691 difference = chrec_fold_minus
00692 (integer_type_node, conflicts_b, conflicts_a);
00693
00694 if (evolution_function_is_constant_p (difference))
00695 SUB_DISTANCE (subscript) = difference;
00696
00697 else
00698 SUB_DISTANCE (subscript) = chrec_dont_know;
00699 }
00700 }
00701 }
00702
00703
00704
00705 struct data_dependence_relation *
00706 initialize_data_dependence_relation (struct data_reference *a,
00707 struct data_reference *b)
00708 {
00709 struct data_dependence_relation *res;
00710 bool differ_p;
00711
00712 res = xmalloc (sizeof (struct data_dependence_relation));
00713 DDR_A (res) = a;
00714 DDR_B (res) = b;
00715
00716 if (a == NULL || b == NULL
00717 || DR_BASE_NAME (a) == NULL_TREE
00718 || DR_BASE_NAME (b) == NULL_TREE)
00719 DDR_ARE_DEPENDENT (res) = chrec_dont_know;
00720
00721
00722
00723 else if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)
00724 || (array_base_name_differ_p (a, b, &differ_p) && differ_p))
00725 DDR_ARE_DEPENDENT (res) = chrec_known;
00726
00727 else
00728 {
00729 unsigned int i;
00730 DDR_AFFINE_P (res) = true;
00731 DDR_ARE_DEPENDENT (res) = NULL_TREE;
00732 DDR_SUBSCRIPTS_VECTOR_INIT (res, DR_NUM_DIMENSIONS (a));
00733 DDR_SIZE_VECT (res) = 0;
00734 DDR_DIST_VECT (res) = NULL;
00735 DDR_DIR_VECT (res) = NULL;
00736
00737 for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
00738 {
00739 struct subscript *subscript;
00740
00741 subscript = xmalloc (sizeof (struct subscript));
00742 SUB_CONFLICTS_IN_A (subscript) = chrec_dont_know;
00743 SUB_CONFLICTS_IN_B (subscript) = chrec_dont_know;
00744 SUB_LAST_CONFLICT (subscript) = chrec_dont_know;
00745 SUB_DISTANCE (subscript) = chrec_dont_know;
00746 VARRAY_PUSH_GENERIC_PTR (DDR_SUBSCRIPTS (res), subscript);
00747 }
00748 }
00749
00750 return res;
00751 }
00752
00753
00754
00755
00756 static inline void
00757 finalize_ddr_dependent (struct data_dependence_relation *ddr,
00758 tree chrec)
00759 {
00760 if (dump_file && (dump_flags & TDF_DETAILS))
00761 {
00762 fprintf (dump_file, "(dependence classified: ");
00763 print_generic_expr (dump_file, chrec, 0);
00764 fprintf (dump_file, ")\n");
00765 }
00766
00767 DDR_ARE_DEPENDENT (ddr) = chrec;
00768 varray_clear (DDR_SUBSCRIPTS (ddr));
00769 }
00770
00771
00772
00773
00774 static inline void
00775 non_affine_dependence_relation (struct data_dependence_relation *ddr)
00776 {
00777 if (dump_file && (dump_flags & TDF_DETAILS))
00778 fprintf (dump_file, "(Dependence relation cannot be represented by distance vector.) \n");
00779
00780 DDR_AFFINE_P (ddr) = false;
00781 }
00782
00783
00784
00785
00786
00787
00788
00789
00790 static inline bool
00791 ziv_subscript_p (tree chrec_a,
00792 tree chrec_b)
00793 {
00794 return (evolution_function_is_constant_p (chrec_a)
00795 && evolution_function_is_constant_p (chrec_b));
00796 }
00797
00798
00799
00800
00801 static bool
00802 siv_subscript_p (tree chrec_a,
00803 tree chrec_b)
00804 {
00805 if ((evolution_function_is_constant_p (chrec_a)
00806 && evolution_function_is_univariate_p (chrec_b))
00807 || (evolution_function_is_constant_p (chrec_b)
00808 && evolution_function_is_univariate_p (chrec_a)))
00809 return true;
00810
00811 if (evolution_function_is_univariate_p (chrec_a)
00812 && evolution_function_is_univariate_p (chrec_b))
00813 {
00814 switch (TREE_CODE (chrec_a))
00815 {
00816 case POLYNOMIAL_CHREC:
00817 switch (TREE_CODE (chrec_b))
00818 {
00819 case POLYNOMIAL_CHREC:
00820 if (CHREC_VARIABLE (chrec_a) != CHREC_VARIABLE (chrec_b))
00821 return false;
00822
00823 default:
00824 return true;
00825 }
00826
00827 default:
00828 return true;
00829 }
00830 }
00831
00832 return false;
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842 static void
00843 analyze_ziv_subscript (tree chrec_a,
00844 tree chrec_b,
00845 tree *overlaps_a,
00846 tree *overlaps_b,
00847 tree *last_conflicts)
00848 {
00849 tree difference;
00850
00851 if (dump_file && (dump_flags & TDF_DETAILS))
00852 fprintf (dump_file, "(analyze_ziv_subscript \n");
00853
00854 difference = chrec_fold_minus (integer_type_node, chrec_a, chrec_b);
00855
00856 switch (TREE_CODE (difference))
00857 {
00858 case INTEGER_CST:
00859 if (integer_zerop (difference))
00860 {
00861
00862
00863 *overlaps_a = integer_zero_node;
00864 *overlaps_b = integer_zero_node;
00865 *last_conflicts = chrec_dont_know;
00866 }
00867 else
00868 {
00869
00870 *overlaps_a = chrec_known;
00871 *overlaps_b = chrec_known;
00872 *last_conflicts = integer_zero_node;
00873 }
00874 break;
00875
00876 default:
00877
00878
00879 *overlaps_a = chrec_dont_know;
00880 *overlaps_b = chrec_dont_know;
00881 *last_conflicts = chrec_dont_know;
00882 break;
00883 }
00884
00885 if (dump_file && (dump_flags & TDF_DETAILS))
00886 fprintf (dump_file, ")\n");
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 static void
00898 analyze_siv_subscript_cst_affine (tree chrec_a,
00899 tree chrec_b,
00900 tree *overlaps_a,
00901 tree *overlaps_b,
00902 tree *last_conflicts)
00903 {
00904 bool value0, value1, value2;
00905 tree difference = chrec_fold_minus
00906 (integer_type_node, CHREC_LEFT (chrec_b), chrec_a);
00907
00908 if (!chrec_is_positive (initial_condition (difference), &value0))
00909 {
00910 *overlaps_a = chrec_dont_know;
00911 *overlaps_b = chrec_dont_know;
00912 *last_conflicts = chrec_dont_know;
00913 return;
00914 }
00915 else
00916 {
00917 if (value0 == false)
00918 {
00919 if (!chrec_is_positive (CHREC_RIGHT (chrec_b), &value1))
00920 {
00921 *overlaps_a = chrec_dont_know;
00922 *overlaps_b = chrec_dont_know;
00923 *last_conflicts = chrec_dont_know;
00924 return;
00925 }
00926 else
00927 {
00928 if (value1 == true)
00929 {
00930
00931
00932
00933
00934
00935 if (tree_fold_divides_p
00936 (integer_type_node, CHREC_RIGHT (chrec_b), difference))
00937 {
00938 *overlaps_a = integer_zero_node;
00939 *overlaps_b = fold
00940 (build (EXACT_DIV_EXPR, integer_type_node,
00941 fold (build1 (ABS_EXPR, integer_type_node, difference)),
00942 CHREC_RIGHT (chrec_b)));
00943 *last_conflicts = integer_one_node;
00944 return;
00945 }
00946
00947
00948
00949 else
00950 {
00951 *overlaps_a = chrec_known;
00952 *overlaps_b = chrec_known;
00953 *last_conflicts = integer_zero_node;
00954 return;
00955 }
00956 }
00957
00958 else
00959 {
00960
00961
00962
00963
00964
00965 *overlaps_a = chrec_known;
00966 *overlaps_b = chrec_known;
00967 *last_conflicts = integer_zero_node;
00968 return;
00969 }
00970 }
00971 }
00972 else
00973 {
00974 if (!chrec_is_positive (CHREC_RIGHT (chrec_b), &value2))
00975 {
00976 *overlaps_a = chrec_dont_know;
00977 *overlaps_b = chrec_dont_know;
00978 *last_conflicts = chrec_dont_know;
00979 return;
00980 }
00981 else
00982 {
00983 if (value2 == false)
00984 {
00985
00986
00987
00988
00989 if (tree_fold_divides_p
00990 (integer_type_node, CHREC_RIGHT (chrec_b), difference))
00991 {
00992 *overlaps_a = integer_zero_node;
00993 *overlaps_b = fold
00994 (build (EXACT_DIV_EXPR, integer_type_node, difference,
00995 CHREC_RIGHT (chrec_b)));
00996 *last_conflicts = integer_one_node;
00997 return;
00998 }
00999
01000
01001
01002 else
01003 {
01004 *overlaps_a = chrec_known;
01005 *overlaps_b = chrec_known;
01006 *last_conflicts = integer_zero_node;
01007 return;
01008 }
01009 }
01010 else
01011 {
01012
01013
01014
01015
01016
01017 *overlaps_a = chrec_known;
01018 *overlaps_b = chrec_known;
01019 *last_conflicts = integer_zero_node;
01020 return;
01021 }
01022 }
01023 }
01024 }
01025 }
01026
01027
01028
01029
01030 static int
01031 initialize_matrix_A (lambda_matrix A, tree chrec, unsigned index, int mult)
01032 {
01033 gcc_assert (chrec);
01034
01035 if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
01036 return int_cst_value (chrec);
01037
01038 A[index][0] = mult * int_cst_value (CHREC_RIGHT (chrec));
01039 return initialize_matrix_A (A, CHREC_LEFT (chrec), index + 1, mult);
01040 }
01041
01042 #define FLOOR_DIV(x,y) ((x) / (y))
01043
01044
01045
01046
01047
01048
01049
01050
01051 static void
01052 compute_overlap_steps_for_affine_univar (int niter, int step_a, int step_b,
01053 tree *overlaps_a, tree *overlaps_b,
01054 tree *last_conflicts, int dim)
01055 {
01056 if (((step_a > 0 && step_b > 0)
01057 || (step_a < 0 && step_b < 0)))
01058 {
01059 int step_overlaps_a, step_overlaps_b;
01060 int gcd_steps_a_b, last_conflict, tau2;
01061
01062 gcd_steps_a_b = gcd (step_a, step_b);
01063 step_overlaps_a = step_b / gcd_steps_a_b;
01064 step_overlaps_b = step_a / gcd_steps_a_b;
01065
01066 tau2 = FLOOR_DIV (niter, step_overlaps_a);
01067 tau2 = MIN (tau2, FLOOR_DIV (niter, step_overlaps_b));
01068 last_conflict = tau2;
01069
01070 *overlaps_a = build_polynomial_chrec
01071 (dim, integer_zero_node,
01072 build_int_cst (NULL_TREE, step_overlaps_a));
01073 *overlaps_b = build_polynomial_chrec
01074 (dim, integer_zero_node,
01075 build_int_cst (NULL_TREE, step_overlaps_b));
01076 *last_conflicts = build_int_cst (NULL_TREE, last_conflict);
01077 }
01078
01079 else
01080 {
01081 *overlaps_a = integer_zero_node;
01082 *overlaps_b = integer_zero_node;
01083 *last_conflicts = integer_zero_node;
01084 }
01085 }
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103 static void
01104 compute_overlap_steps_for_affine_1_2 (tree chrec_a, tree chrec_b,
01105 tree *overlaps_a, tree *overlaps_b,
01106 tree *last_conflicts)
01107 {
01108 bool xz_p, yz_p, xyz_p;
01109 int step_x, step_y, step_z;
01110 int niter_x, niter_y, niter_z, niter;
01111 tree numiter_x, numiter_y, numiter_z;
01112 tree overlaps_a_xz, overlaps_b_xz, last_conflicts_xz;
01113 tree overlaps_a_yz, overlaps_b_yz, last_conflicts_yz;
01114 tree overlaps_a_xyz, overlaps_b_xyz, last_conflicts_xyz;
01115
01116 step_x = int_cst_value (CHREC_RIGHT (CHREC_LEFT (chrec_a)));
01117 step_y = int_cst_value (CHREC_RIGHT (chrec_a));
01118 step_z = int_cst_value (CHREC_RIGHT (chrec_b));
01119
01120 numiter_x = number_of_iterations_in_loop
01121 (current_loops->parray[CHREC_VARIABLE (CHREC_LEFT (chrec_a))]);
01122 numiter_y = number_of_iterations_in_loop
01123 (current_loops->parray[CHREC_VARIABLE (chrec_a)]);
01124 numiter_z = number_of_iterations_in_loop
01125 (current_loops->parray[CHREC_VARIABLE (chrec_b)]);
01126
01127 if (TREE_CODE (numiter_x) != INTEGER_CST)
01128 numiter_x = current_loops->parray[CHREC_VARIABLE (CHREC_LEFT (chrec_a))]
01129 ->estimated_nb_iterations;
01130 if (TREE_CODE (numiter_y) != INTEGER_CST)
01131 numiter_y = current_loops->parray[CHREC_VARIABLE (chrec_a)]
01132 ->estimated_nb_iterations;
01133 if (TREE_CODE (numiter_z) != INTEGER_CST)
01134 numiter_z = current_loops->parray[CHREC_VARIABLE (chrec_b)]
01135 ->estimated_nb_iterations;
01136
01137 if (numiter_x == NULL_TREE || numiter_y == NULL_TREE
01138 || numiter_z == NULL_TREE)
01139 {
01140 *overlaps_a = chrec_dont_know;
01141 *overlaps_b = chrec_dont_know;
01142 *last_conflicts = chrec_dont_know;
01143 return;
01144 }
01145
01146 niter_x = int_cst_value (numiter_x);
01147 niter_y = int_cst_value (numiter_y);
01148 niter_z = int_cst_value (numiter_z);
01149
01150 niter = MIN (niter_x, niter_z);
01151 compute_overlap_steps_for_affine_univar (niter, step_x, step_z,
01152 &overlaps_a_xz,
01153 &overlaps_b_xz,
01154 &last_conflicts_xz, 1);
01155 niter = MIN (niter_y, niter_z);
01156 compute_overlap_steps_for_affine_univar (niter, step_y, step_z,
01157 &overlaps_a_yz,
01158 &overlaps_b_yz,
01159 &last_conflicts_yz, 2);
01160 niter = MIN (niter_x, niter_z);
01161 niter = MIN (niter_y, niter);
01162 compute_overlap_steps_for_affine_univar (niter, step_x + step_y, step_z,
01163 &overlaps_a_xyz,
01164 &overlaps_b_xyz,
01165 &last_conflicts_xyz, 3);
01166
01167 xz_p = !integer_zerop (last_conflicts_xz);
01168 yz_p = !integer_zerop (last_conflicts_yz);
01169 xyz_p = !integer_zerop (last_conflicts_xyz);
01170
01171 if (xz_p || yz_p || xyz_p)
01172 {
01173 *overlaps_a = make_tree_vec (2);
01174 TREE_VEC_ELT (*overlaps_a, 0) = integer_zero_node;
01175 TREE_VEC_ELT (*overlaps_a, 1) = integer_zero_node;
01176 *overlaps_b = integer_zero_node;
01177 if (xz_p)
01178 {
01179 TREE_VEC_ELT (*overlaps_a, 0) =
01180 chrec_fold_plus (integer_type_node, TREE_VEC_ELT (*overlaps_a, 0),
01181 overlaps_a_xz);
01182 *overlaps_b =
01183 chrec_fold_plus (integer_type_node, *overlaps_b, overlaps_b_xz);
01184 *last_conflicts = last_conflicts_xz;
01185 }
01186 if (yz_p)
01187 {
01188 TREE_VEC_ELT (*overlaps_a, 1) =
01189 chrec_fold_plus (integer_type_node, TREE_VEC_ELT (*overlaps_a, 1),
01190 overlaps_a_yz);
01191 *overlaps_b =
01192 chrec_fold_plus (integer_type_node, *overlaps_b, overlaps_b_yz);
01193 *last_conflicts = last_conflicts_yz;
01194 }
01195 if (xyz_p)
01196 {
01197 TREE_VEC_ELT (*overlaps_a, 0) =
01198 chrec_fold_plus (integer_type_node, TREE_VEC_ELT (*overlaps_a, 0),
01199 overlaps_a_xyz);
01200 TREE_VEC_ELT (*overlaps_a, 1) =
01201 chrec_fold_plus (integer_type_node, TREE_VEC_ELT (*overlaps_a, 1),
01202 overlaps_a_xyz);
01203 *overlaps_b =
01204 chrec_fold_plus (integer_type_node, *overlaps_b, overlaps_b_xyz);
01205 *last_conflicts = last_conflicts_xyz;
01206 }
01207 }
01208 else
01209 {
01210 *overlaps_a = integer_zero_node;
01211 *overlaps_b = integer_zero_node;
01212 *last_conflicts = integer_zero_node;
01213 }
01214 }
01215
01216
01217
01218
01219
01220 static void
01221 analyze_subscript_affine_affine (tree chrec_a,
01222 tree chrec_b,
01223 tree *overlaps_a,
01224 tree *overlaps_b,
01225 tree *last_conflicts)
01226 {
01227 unsigned nb_vars_a, nb_vars_b, dim;
01228 int init_a, init_b, gamma, gcd_alpha_beta;
01229 int tau1, tau2;
01230 lambda_matrix A, U, S;
01231
01232 if (dump_file && (dump_flags & TDF_DETAILS))
01233 fprintf (dump_file, "(analyze_subscript_affine_affine \n");
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247 nb_vars_a = nb_vars_in_chrec (chrec_a);
01248 nb_vars_b = nb_vars_in_chrec (chrec_b);
01249
01250 dim = nb_vars_a + nb_vars_b;
01251 U = lambda_matrix_new (dim, dim);
01252 A = lambda_matrix_new (dim, 1);
01253 S = lambda_matrix_new (dim, 1);
01254
01255 init_a = initialize_matrix_A (A, chrec_a, 0, 1);
01256 init_b = initialize_matrix_A (A, chrec_b, nb_vars_a, -1);
01257 gamma = init_b - init_a;
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267 if (gamma == 0)
01268 {
01269 if (nb_vars_a == 1 && nb_vars_b == 1)
01270 {
01271 int step_a, step_b;
01272 int niter, niter_a, niter_b;
01273 tree numiter_a, numiter_b;
01274
01275 numiter_a = number_of_iterations_in_loop
01276 (current_loops->parray[CHREC_VARIABLE (chrec_a)]);
01277 numiter_b = number_of_iterations_in_loop
01278 (current_loops->parray[CHREC_VARIABLE (chrec_b)]);
01279
01280 if (TREE_CODE (numiter_a) != INTEGER_CST)
01281 numiter_a = current_loops->parray[CHREC_VARIABLE (chrec_a)]
01282 ->estimated_nb_iterations;
01283 if (TREE_CODE (numiter_b) != INTEGER_CST)
01284 numiter_b = current_loops->parray[CHREC_VARIABLE (chrec_b)]
01285 ->estimated_nb_iterations;
01286 if (numiter_a == NULL_TREE || numiter_b == NULL_TREE)
01287 {
01288 *overlaps_a = chrec_dont_know;
01289 *overlaps_b = chrec_dont_know;
01290 *last_conflicts = chrec_dont_know;
01291 return;
01292 }
01293
01294 niter_a = int_cst_value (numiter_a);
01295 niter_b = int_cst_value (numiter_b);
01296 niter = MIN (niter_a, niter_b);
01297
01298 step_a = int_cst_value (CHREC_RIGHT (chrec_a));
01299 step_b = int_cst_value (CHREC_RIGHT (chrec_b));
01300
01301 compute_overlap_steps_for_affine_univar (niter, step_a, step_b,
01302 overlaps_a, overlaps_b,
01303 last_conflicts, 1);
01304 }
01305
01306 else if (nb_vars_a == 2 && nb_vars_b == 1)
01307 compute_overlap_steps_for_affine_1_2
01308 (chrec_a, chrec_b, overlaps_a, overlaps_b, last_conflicts);
01309
01310 else if (nb_vars_a == 1 && nb_vars_b == 2)
01311 compute_overlap_steps_for_affine_1_2
01312 (chrec_b, chrec_a, overlaps_b, overlaps_a, last_conflicts);
01313
01314 else
01315 {
01316 *overlaps_a = chrec_dont_know;
01317 *overlaps_b = chrec_dont_know;
01318 *last_conflicts = chrec_dont_know;
01319 }
01320 return;
01321 }
01322
01323
01324 lambda_matrix_right_hermite (A, dim, 1, S, U);
01325
01326 if (S[0][0] < 0)
01327 {
01328 S[0][0] *= -1;
01329 lambda_matrix_row_negate (U, dim, 0);
01330 }
01331 gcd_alpha_beta = S[0][0];
01332
01333
01334 if (!int_divides_p (gcd_alpha_beta, gamma))
01335 {
01336
01337
01338 *overlaps_a = chrec_known;
01339 *overlaps_b = chrec_known;
01340 *last_conflicts = integer_zero_node;
01341 }
01342
01343
01344 else if (nb_vars_a == 1 && nb_vars_b == 1)
01345 {
01346
01347 if (((A[0][0] > 0 && -A[1][0] > 0)
01348 || (A[0][0] < 0 && -A[1][0] < 0)))
01349 {
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367 int i0, j0, i1, j1;
01368
01369
01370
01371
01372 int x0, y0;
01373 int niter, niter_a, niter_b;
01374 tree numiter_a, numiter_b;
01375
01376 numiter_a = number_of_iterations_in_loop
01377 (current_loops->parray[CHREC_VARIABLE (chrec_a)]);
01378 numiter_b = number_of_iterations_in_loop
01379 (current_loops->parray[CHREC_VARIABLE (chrec_b)]);
01380
01381 if (TREE_CODE (numiter_a) != INTEGER_CST)
01382 numiter_a = current_loops->parray[CHREC_VARIABLE (chrec_a)]
01383 ->estimated_nb_iterations;
01384 if (TREE_CODE (numiter_b) != INTEGER_CST)
01385 numiter_b = current_loops->parray[CHREC_VARIABLE (chrec_b)]
01386 ->estimated_nb_iterations;
01387 if (numiter_a == NULL_TREE || numiter_b == NULL_TREE)
01388 {
01389 *overlaps_a = chrec_dont_know;
01390 *overlaps_b = chrec_dont_know;
01391 *last_conflicts = chrec_dont_know;
01392 return;
01393 }
01394
01395 niter_a = int_cst_value (numiter_a);
01396 niter_b = int_cst_value (numiter_b);
01397 niter = MIN (niter_a, niter_b);
01398
01399 i0 = U[0][0] * gamma / gcd_alpha_beta;
01400 j0 = U[0][1] * gamma / gcd_alpha_beta;
01401 i1 = U[1][0];
01402 j1 = U[1][1];
01403
01404 if ((i1 == 0 && i0 < 0)
01405 || (j1 == 0 && j0 < 0))
01406 {
01407
01408
01409
01410
01411 *overlaps_a = chrec_known;
01412 *overlaps_b = chrec_known;
01413 *last_conflicts = integer_zero_node;
01414 }
01415
01416 else
01417 {
01418 if (i1 > 0)
01419 {
01420 tau1 = CEIL (-i0, i1);
01421 tau2 = FLOOR_DIV (niter - i0, i1);
01422
01423 if (j1 > 0)
01424 {
01425 int last_conflict, min_multiple;
01426 tau1 = MAX (tau1, CEIL (-j0, j1));
01427 tau2 = MIN (tau2, FLOOR_DIV (niter - j0, j1));
01428
01429 x0 = i1 * tau1 + i0;
01430 y0 = j1 * tau1 + j0;
01431
01432
01433
01434
01435
01436 min_multiple = MIN (x0 / i1, y0 / j1);
01437 x0 -= i1 * min_multiple;
01438 y0 -= j1 * min_multiple;
01439
01440 tau1 = (x0 - i0)/i1;
01441 last_conflict = tau2 - tau1;
01442
01443 *overlaps_a = build_polynomial_chrec
01444 (1,
01445 build_int_cst (NULL_TREE, x0),
01446 build_int_cst (NULL_TREE, i1));
01447 *overlaps_b = build_polynomial_chrec
01448 (1,
01449 build_int_cst (NULL_TREE, y0),
01450 build_int_cst (NULL_TREE, j1));
01451 *last_conflicts = build_int_cst (NULL_TREE, last_conflict);
01452 }
01453 else
01454 {
01455
01456
01457 *overlaps_a = chrec_dont_know;
01458 *overlaps_b = chrec_dont_know;
01459 *last_conflicts = chrec_dont_know;
01460 }
01461 }
01462
01463 else
01464 {
01465
01466
01467 *overlaps_a = chrec_dont_know;
01468 *overlaps_b = chrec_dont_know;
01469 *last_conflicts = chrec_dont_know;
01470 }
01471 }
01472 }
01473 else
01474 {
01475 *overlaps_a = chrec_dont_know;
01476 *overlaps_b = chrec_dont_know;
01477 *last_conflicts = chrec_dont_know;
01478 }
01479 }
01480
01481 else
01482 {
01483 *overlaps_a = chrec_dont_know;
01484 *overlaps_b = chrec_dont_know;
01485 *last_conflicts = chrec_dont_know;
01486 }
01487
01488
01489 if (dump_file && (dump_flags & TDF_DETAILS))
01490 {
01491 fprintf (dump_file, " (overlaps_a = ");
01492 print_generic_expr (dump_file, *overlaps_a, 0);
01493 fprintf (dump_file, ")\n (overlaps_b = ");
01494 print_generic_expr (dump_file, *overlaps_b, 0);
01495 fprintf (dump_file, ")\n");
01496 }
01497
01498 if (dump_file && (dump_flags & TDF_DETAILS))
01499 fprintf (dump_file, ")\n");
01500 }
01501
01502
01503
01504
01505
01506
01507
01508
01509 static void
01510 analyze_siv_subscript (tree chrec_a,
01511 tree chrec_b,
01512 tree *overlaps_a,
01513 tree *overlaps_b,
01514 tree *last_conflicts)
01515 {
01516 if (dump_file && (dump_flags & TDF_DETAILS))
01517 fprintf (dump_file, "(analyze_siv_subscript \n");
01518
01519 if (evolution_function_is_constant_p (chrec_a)
01520 && evolution_function_is_affine_p (chrec_b))
01521 analyze_siv_subscript_cst_affine (chrec_a, chrec_b,
01522 overlaps_a, overlaps_b, last_conflicts);
01523
01524 else if (evolution_function_is_affine_p (chrec_a)
01525 && evolution_function_is_constant_p (chrec_b))
01526 analyze_siv_subscript_cst_affine (chrec_b, chrec_a,
01527 overlaps_b, overlaps_a, last_conflicts);
01528
01529 else if (evolution_function_is_affine_p (chrec_a)
01530 && evolution_function_is_affine_p (chrec_b))
01531 analyze_subscript_affine_affine (chrec_a, chrec_b,
01532 overlaps_a, overlaps_b, last_conflicts);
01533 else
01534 {
01535 *overlaps_a = chrec_dont_know;
01536 *overlaps_b = chrec_dont_know;
01537 *last_conflicts = chrec_dont_know;
01538 }
01539
01540 if (dump_file && (dump_flags & TDF_DETAILS))
01541 fprintf (dump_file, ")\n");
01542 }
01543
01544
01545
01546
01547 static bool
01548 chrec_steps_divide_constant_p (tree chrec,
01549 tree cst)
01550 {
01551 switch (TREE_CODE (chrec))
01552 {
01553 case POLYNOMIAL_CHREC:
01554 return (tree_fold_divides_p (integer_type_node, CHREC_RIGHT (chrec), cst)
01555 && chrec_steps_divide_constant_p (CHREC_LEFT (chrec), cst));
01556
01557 default:
01558
01559 return true;
01560 }
01561 }
01562
01563
01564
01565
01566
01567
01568
01569
01570 static void
01571 analyze_miv_subscript (tree chrec_a,
01572 tree chrec_b,
01573 tree *overlaps_a,
01574 tree *overlaps_b,
01575 tree *last_conflicts)
01576 {
01577
01578
01579
01580
01581
01582
01583
01584
01585 tree difference;
01586
01587 if (dump_file && (dump_flags & TDF_DETAILS))
01588 fprintf (dump_file, "(analyze_miv_subscript \n");
01589
01590 difference = chrec_fold_minus (integer_type_node, chrec_a, chrec_b);
01591
01592 if (chrec_zerop (difference))
01593 {
01594
01595
01596 *overlaps_a = integer_zero_node;
01597 *overlaps_b = integer_zero_node;
01598 *last_conflicts = number_of_iterations_in_loop
01599 (current_loops->parray[CHREC_VARIABLE (chrec_a)]);
01600 }
01601
01602 else if (evolution_function_is_constant_p (difference)
01603
01604
01605 && !chrec_steps_divide_constant_p (chrec_a, difference))
01606 {
01607
01608
01609
01610
01611
01612 *overlaps_a = chrec_known;
01613 *overlaps_b = chrec_known;
01614 *last_conflicts = integer_zero_node;
01615 }
01616
01617 else if (evolution_function_is_affine_multivariate_p (chrec_a)
01618 && evolution_function_is_affine_multivariate_p (chrec_b))
01619 {
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 analyze_subscript_affine_affine (chrec_a, chrec_b,
01635 overlaps_a, overlaps_b, last_conflicts);
01636 }
01637
01638 else
01639 {
01640
01641 *overlaps_a = chrec_dont_know;
01642 *overlaps_b = chrec_dont_know;
01643 *last_conflicts = chrec_dont_know;
01644 }
01645
01646 if (dump_file && (dump_flags & TDF_DETAILS))
01647 fprintf (dump_file, ")\n");
01648 }
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 static void
01661 analyze_overlapping_iterations (tree chrec_a,
01662 tree chrec_b,
01663 tree *overlap_iterations_a,
01664 tree *overlap_iterations_b,
01665 tree *last_conflicts)
01666 {
01667 if (dump_file && (dump_flags & TDF_DETAILS))
01668 {
01669 fprintf (dump_file, "(analyze_overlapping_iterations \n");
01670 fprintf (dump_file, " (chrec_a = ");
01671 print_generic_expr (dump_file, chrec_a, 0);
01672 fprintf (dump_file, ")\n chrec_b = ");
01673 print_generic_expr (dump_file, chrec_b, 0);
01674 fprintf (dump_file, ")\n");
01675 }
01676
01677 if (chrec_a == NULL_TREE
01678 || chrec_b == NULL_TREE
01679 || chrec_contains_undetermined (chrec_a)
01680 || chrec_contains_undetermined (chrec_b)
01681 || chrec_contains_symbols (chrec_a)
01682 || chrec_contains_symbols (chrec_b))
01683 {
01684 *overlap_iterations_a = chrec_dont_know;
01685 *overlap_iterations_b = chrec_dont_know;
01686 }
01687
01688 else if (ziv_subscript_p (chrec_a, chrec_b))
01689 analyze_ziv_subscript (chrec_a, chrec_b,
01690 overlap_iterations_a, overlap_iterations_b,
01691 last_conflicts);
01692
01693 else if (siv_subscript_p (chrec_a, chrec_b))
01694 analyze_siv_subscript (chrec_a, chrec_b,
01695 overlap_iterations_a, overlap_iterations_b,
01696 last_conflicts);
01697
01698 else
01699 analyze_miv_subscript (chrec_a, chrec_b,
01700 overlap_iterations_a, overlap_iterations_b,
01701 last_conflicts);
01702
01703 if (dump_file && (dump_flags & TDF_DETAILS))
01704 {
01705 fprintf (dump_file, " (overlap_iterations_a = ");
01706 print_generic_expr (dump_file, *overlap_iterations_a, 0);
01707 fprintf (dump_file, ")\n (overlap_iterations_b = ");
01708 print_generic_expr (dump_file, *overlap_iterations_b, 0);
01709 fprintf (dump_file, ")\n");
01710 }
01711 }
01712
01713
01714
01715
01716
01717
01718
01719 static void
01720 subscript_dependence_tester (struct data_dependence_relation *ddr)
01721 {
01722 unsigned int i;
01723 struct data_reference *dra = DDR_A (ddr);
01724 struct data_reference *drb = DDR_B (ddr);
01725 tree last_conflicts;
01726
01727 if (dump_file && (dump_flags & TDF_DETAILS))
01728 fprintf (dump_file, "(subscript_dependence_tester \n");
01729
01730 for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
01731 {
01732 tree overlaps_a, overlaps_b;
01733 struct subscript *subscript = DDR_SUBSCRIPT (ddr, i);
01734
01735 analyze_overlapping_iterations (DR_ACCESS_FN (dra, i),
01736 DR_ACCESS_FN (drb, i),
01737 &overlaps_a, &overlaps_b,
01738 &last_conflicts);
01739
01740 if (chrec_contains_undetermined (overlaps_a)
01741 || chrec_contains_undetermined (overlaps_b))
01742 {
01743 finalize_ddr_dependent (ddr, chrec_dont_know);
01744 break;
01745 }
01746
01747 else if (overlaps_a == chrec_known
01748 || overlaps_b == chrec_known)
01749 {
01750 finalize_ddr_dependent (ddr, chrec_known);
01751 break;
01752 }
01753
01754 else
01755 {
01756 SUB_CONFLICTS_IN_A (subscript) = overlaps_a;
01757 SUB_CONFLICTS_IN_B (subscript) = overlaps_b;
01758 SUB_LAST_CONFLICT (subscript) = last_conflicts;
01759 }
01760 }
01761
01762 if (dump_file && (dump_flags & TDF_DETAILS))
01763 fprintf (dump_file, ")\n");
01764 }
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776 static bool
01777 build_classic_dist_vector (struct data_dependence_relation *ddr,
01778 int nb_loops, int first_loop_depth)
01779 {
01780 unsigned i;
01781 lambda_vector dist_v, init_v;
01782
01783 dist_v = lambda_vector_new (nb_loops);
01784 init_v = lambda_vector_new (nb_loops);
01785 lambda_vector_clear (dist_v, nb_loops);
01786 lambda_vector_clear (init_v, nb_loops);
01787
01788 if (DDR_ARE_DEPENDENT (ddr) != NULL_TREE)
01789 return true;
01790
01791 for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
01792 {
01793 tree access_fn_a, access_fn_b;
01794 struct subscript *subscript = DDR_SUBSCRIPT (ddr, i);
01795
01796 if (chrec_contains_undetermined (SUB_DISTANCE (subscript)))
01797 {
01798 non_affine_dependence_relation (ddr);
01799 return true;
01800 }
01801
01802 access_fn_a = DR_ACCESS_FN (DDR_A (ddr), i);
01803 access_fn_b = DR_ACCESS_FN (DDR_B (ddr), i);
01804
01805 if (TREE_CODE (access_fn_a) == POLYNOMIAL_CHREC
01806 && TREE_CODE (access_fn_b) == POLYNOMIAL_CHREC)
01807 {
01808 int dist, loop_nb, loop_depth;
01809 int loop_nb_a = CHREC_VARIABLE (access_fn_a);
01810 int loop_nb_b = CHREC_VARIABLE (access_fn_b);
01811 struct loop *loop_a = current_loops->parray[loop_nb_a];
01812 struct loop *loop_b = current_loops->parray[loop_nb_b];
01813
01814
01815
01816
01817
01818 if (loop_a->depth < first_loop_depth
01819 || loop_b->depth < first_loop_depth)
01820 return false;
01821
01822 if (loop_nb_a != loop_nb_b
01823 && !flow_loop_nested_p (loop_a, loop_b)
01824 && !flow_loop_nested_p (loop_b, loop_a))
01825 {
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837 non_affine_dependence_relation (ddr);
01838 return true;
01839 }
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849 loop_nb = loop_nb_a < loop_nb_b ? loop_nb_a : loop_nb_b;
01850 loop_depth = current_loops->parray[loop_nb]->depth - first_loop_depth;
01851
01852
01853
01854
01855 gcc_assert (loop_depth >= 0);
01856 gcc_assert (loop_depth < nb_loops);
01857 if (chrec_contains_undetermined (SUB_DISTANCE (subscript)))
01858 {
01859 non_affine_dependence_relation (ddr);
01860 return true;
01861 }
01862
01863 dist = int_cst_value (SUB_DISTANCE (subscript));
01864
01865
01866
01867
01868
01869
01870
01871 if (init_v[loop_depth] != 0
01872 && dist_v[loop_depth] != dist)
01873 {
01874 finalize_ddr_dependent (ddr, chrec_known);
01875 return true;
01876 }
01877
01878 dist_v[loop_depth] = dist;
01879 init_v[loop_depth] = 1;
01880 }
01881 }
01882
01883
01884
01885
01886
01887
01888
01889
01890 {
01891 struct loop *lca, *loop_a, *loop_b;
01892 struct data_reference *a = DDR_A (ddr);
01893 struct data_reference *b = DDR_B (ddr);
01894 int lca_depth;
01895 loop_a = loop_containing_stmt (DR_STMT (a));
01896 loop_b = loop_containing_stmt (DR_STMT (b));
01897
01898
01899 lca = find_common_loop (loop_a, loop_b);
01900
01901 lca_depth = lca->depth;
01902 lca_depth -= first_loop_depth;
01903 gcc_assert (lca_depth >= 0);
01904 gcc_assert (lca_depth < nb_loops);
01905
01906
01907
01908 if (lca != loop_a
01909 && lca != loop_b
01910 && init_v[lca_depth] == 0)
01911 dist_v[lca_depth] = 1;
01912
01913 lca = lca->outer;
01914
01915 if (lca)
01916 {
01917 lca_depth = lca->depth - first_loop_depth;
01918 while (lca->depth != 0)
01919 {
01920
01921
01922 if (lca_depth < 0)
01923 break;
01924
01925 gcc_assert (lca_depth < nb_loops);
01926
01927 if (init_v[lca_depth] == 0)
01928 dist_v[lca_depth] = 1;
01929 lca = lca->outer;
01930 lca_depth = lca->depth - first_loop_depth;
01931
01932 }
01933 }
01934 }
01935
01936 DDR_DIST_VECT (ddr) = dist_v;
01937 DDR_SIZE_VECT (ddr) = nb_loops;
01938 return true;
01939 }
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951 static bool
01952 build_classic_dir_vector (struct data_dependence_relation *ddr,
01953 int nb_loops, int first_loop_depth)
01954 {
01955 unsigned i;
01956 lambda_vector dir_v, init_v;
01957
01958 dir_v = lambda_vector_new (nb_loops);
01959 init_v = lambda_vector_new (nb_loops);
01960 lambda_vector_clear (dir_v, nb_loops);
01961 lambda_vector_clear (init_v, nb_loops);
01962
01963 if (DDR_ARE_DEPENDENT (ddr) != NULL_TREE)
01964 return true;
01965
01966 for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
01967 {
01968 tree access_fn_a, access_fn_b;
01969 struct subscript *subscript = DDR_SUBSCRIPT (ddr, i);
01970
01971 if (chrec_contains_undetermined (SUB_DISTANCE (subscript)))
01972 {
01973 non_affine_dependence_relation (ddr);
01974 return true;
01975 }
01976
01977 access_fn_a = DR_ACCESS_FN (DDR_A (ddr), i);
01978 access_fn_b = DR_ACCESS_FN (DDR_B (ddr), i);
01979 if (TREE_CODE (access_fn_a) == POLYNOMIAL_CHREC
01980 && TREE_CODE (access_fn_b) == POLYNOMIAL_CHREC)
01981 {
01982 int dist, loop_nb, loop_depth;
01983 enum data_dependence_direction dir = dir_star;
01984 int loop_nb_a = CHREC_VARIABLE (access_fn_a);
01985 int loop_nb_b = CHREC_VARIABLE (access_fn_b);
01986 struct loop *loop_a = current_loops->parray[loop_nb_a];
01987 struct loop *loop_b = current_loops->parray[loop_nb_b];
01988
01989
01990
01991
01992
01993 if (loop_a->depth < first_loop_depth
01994 || loop_b->depth < first_loop_depth)
01995 return false;
01996
01997 if (loop_nb_a != loop_nb_b
01998 && !flow_loop_nested_p (loop_a, loop_b)
01999 && !flow_loop_nested_p (loop_b, loop_a))
02000 {
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012 non_affine_dependence_relation (ddr);
02013 return true;
02014 }
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024 loop_nb = loop_nb_a < loop_nb_b ? loop_nb_a : loop_nb_b;
02025 loop_depth = current_loops->parray[loop_nb]->depth - first_loop_depth;
02026
02027
02028
02029
02030 gcc_assert (loop_depth >= 0);
02031 gcc_assert (loop_depth < nb_loops);
02032
02033 if (chrec_contains_undetermined (SUB_DISTANCE (subscript)))
02034 {
02035 non_affine_dependence_relation (ddr);
02036 return true;
02037 }
02038
02039 dist = int_cst_value (SUB_DISTANCE (subscript));
02040
02041 if (dist == 0)
02042 dir = dir_equal;
02043 else if (dist > 0)
02044 dir = dir_positive;
02045 else if (dist < 0)
02046 dir = dir_negative;
02047
02048
02049
02050
02051
02052
02053
02054 if (init_v[loop_depth] != 0
02055 && dir != dir_star
02056 && (enum data_dependence_direction) dir_v[loop_depth] != dir
02057 && (enum data_dependence_direction) dir_v[loop_depth] != dir_star)
02058 {
02059 finalize_ddr_dependent (ddr, chrec_known);
02060 return true;
02061 }
02062
02063 dir_v[loop_depth] = dir;
02064 init_v[loop_depth] = 1;
02065 }
02066 }
02067
02068
02069
02070
02071
02072
02073
02074
02075 {
02076 struct loop *lca, *loop_a, *loop_b;
02077 struct data_reference *a = DDR_A (ddr);
02078 struct data_reference *b = DDR_B (ddr);
02079 int lca_depth;
02080 loop_a = loop_containing_stmt (DR_STMT (a));
02081 loop_b = loop_containing_stmt (DR_STMT (b));
02082
02083
02084 lca = find_common_loop (loop_a, loop_b);
02085 lca_depth = lca->depth - first_loop_depth;
02086
02087 gcc_assert (lca_depth >= 0);
02088 gcc_assert (lca_depth < nb_loops);
02089
02090
02091
02092 if (lca != loop_a
02093 && lca != loop_b
02094 && init_v[lca_depth] == 0)
02095 dir_v[lca_depth] = dir_positive;
02096
02097 lca = lca->outer;
02098 if (lca)
02099 {
02100 lca_depth = lca->depth - first_loop_depth;
02101 while (lca->depth != 0)
02102 {
02103
02104
02105 if (lca_depth < 0)
02106 break;
02107
02108 gcc_assert (lca_depth < nb_loops);
02109
02110 if (init_v[lca_depth] == 0)
02111 dir_v[lca_depth] = dir_positive;
02112 lca = lca->outer;
02113 lca_depth = lca->depth - first_loop_depth;
02114
02115 }
02116 }
02117 }
02118
02119 DDR_DIR_VECT (ddr) = dir_v;
02120 DDR_SIZE_VECT (ddr) = nb_loops;
02121 return true;
02122 }
02123
02124
02125
02126
02127 static bool
02128 access_functions_are_affine_or_constant_p (struct data_reference *a)
02129 {
02130 unsigned int i;
02131 varray_type fns = DR_ACCESS_FNS (a);
02132
02133 for (i = 0; i < VARRAY_ACTIVE_SIZE (fns); i++)
02134 if (!evolution_function_is_constant_p (VARRAY_TREE (fns, i))
02135 && !evolution_function_is_affine_multivariate_p (VARRAY_TREE (fns, i)))
02136 return false;
02137
02138 return true;
02139 }
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 void
02151 compute_affine_dependence (struct data_dependence_relation *ddr)
02152 {
02153 struct data_reference *dra = DDR_A (ddr);
02154 struct data_reference *drb = DDR_B (ddr);
02155
02156 if (dump_file && (dump_flags & TDF_DETAILS))
02157 {
02158 fprintf (dump_file, "(compute_affine_dependence\n");
02159 fprintf (dump_file, " (stmt_a = \n");
02160 print_generic_expr (dump_file, DR_STMT (dra), 0);
02161 fprintf (dump_file, ")\n (stmt_b = \n");
02162 print_generic_expr (dump_file, DR_STMT (drb), 0);
02163 fprintf (dump_file, ")\n");
02164 }
02165
02166
02167 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
02168 {
02169 if (access_functions_are_affine_or_constant_p (dra)
02170 && access_functions_are_affine_or_constant_p (drb))
02171 subscript_dependence_tester (ddr);
02172
02173
02174
02175
02176 else
02177 finalize_ddr_dependent (ddr, chrec_dont_know);
02178 }
02179
02180 if (dump_file && (dump_flags & TDF_DETAILS))
02181 fprintf (dump_file, ")\n");
02182 }
02183
02184
02185
02186
02187
02188
02189
02190 static void
02191 compute_all_dependences (varray_type datarefs,
02192 varray_type *dependence_relations)
02193 {
02194 unsigned int i, j, N;
02195
02196 N = VARRAY_ACTIVE_SIZE (datarefs);
02197
02198 for (i = 0; i < N; i++)
02199 for (j = i; j < N; j++)
02200 {
02201 struct data_reference *a, *b;
02202 struct data_dependence_relation *ddr;
02203
02204 a = VARRAY_GENERIC_PTR (datarefs, i);
02205 b = VARRAY_GENERIC_PTR (datarefs, j);
02206 ddr = initialize_data_dependence_relation (a, b);
02207
02208 VARRAY_PUSH_GENERIC_PTR (*dependence_relations, ddr);
02209 compute_affine_dependence (ddr);
02210 compute_subscript_distance (ddr);
02211 }
02212 }
02213
02214
02215
02216
02217
02218
02219
02220
02221 tree
02222 find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
02223 {
02224 bool dont_know_node_not_inserted = true;
02225 basic_block bb, *bbs;
02226 unsigned int i;
02227 block_stmt_iterator bsi;
02228
02229 bbs = get_loop_body (loop);
02230
02231 for (i = 0; i < loop->num_nodes; i++)
02232 {
02233 bb = bbs[i];
02234
02235 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
02236 {
02237 tree stmt = bsi_stmt (bsi);
02238 stmt_ann_t ann = stmt_ann (stmt);
02239
02240 if (TREE_CODE (stmt) != MODIFY_EXPR)
02241 continue;
02242
02243 if (!VUSE_OPS (ann)
02244 && !V_MUST_DEF_OPS (ann)
02245 && !V_MAY_DEF_OPS (ann))
02246 continue;
02247
02248
02249
02250 if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF)
02251 VARRAY_PUSH_GENERIC_PTR
02252 (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 0),
02253 false));
02254
02255 else if (TREE_CODE (TREE_OPERAND (stmt, 1)) == ARRAY_REF)
02256 VARRAY_PUSH_GENERIC_PTR
02257 (*datarefs, analyze_array (stmt, TREE_OPERAND (stmt, 1),
02258 true));
02259 else
02260 {
02261 if (dont_know_node_not_inserted)
02262 {
02263 struct data_reference *res;
02264 res = xmalloc (sizeof (struct data_reference));
02265 DR_STMT (res) = NULL_TREE;
02266 DR_REF (res) = NULL_TREE;
02267 DR_ACCESS_FNS (res) = NULL;
02268 DR_BASE_NAME (res) = NULL;
02269 DR_IS_READ (res) = false;
02270 VARRAY_PUSH_GENERIC_PTR (*datarefs, res);
02271 dont_know_node_not_inserted = false;
02272 }
02273 }
02274
02275
02276 if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0
02277 || NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
02278 bb->loop_father->parallel_p = false;
02279 }
02280
02281 if (bb->loop_father->estimated_nb_iterations == NULL_TREE)
02282 compute_estimated_nb_iterations (bb->loop_father);
02283 }
02284
02285 free (bbs);
02286
02287 return dont_know_node_not_inserted ? NULL_TREE : chrec_dont_know;
02288 }
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298 void
02299 compute_data_dependences_for_loop (unsigned nb_loops,
02300 struct loop *loop,
02301 varray_type *datarefs,
02302 varray_type *dependence_relations)
02303 {
02304 unsigned int i;
02305 varray_type allrelations;
02306
02307
02308
02309 if (find_data_references_in_loop (loop, datarefs) == chrec_dont_know)
02310 {
02311 struct data_dependence_relation *ddr;
02312
02313
02314
02315 ddr = initialize_data_dependence_relation (NULL, NULL);
02316 VARRAY_PUSH_GENERIC_PTR (*dependence_relations, ddr);
02317 build_classic_dist_vector (ddr, nb_loops, loop->depth);
02318 build_classic_dir_vector (ddr, nb_loops, loop->depth);
02319 return;
02320 }
02321
02322 VARRAY_GENERIC_PTR_INIT (allrelations, 1, "Data dependence relations");
02323 compute_all_dependences (*datarefs, &allrelations);
02324
02325 for (i = 0; i < VARRAY_ACTIVE_SIZE (allrelations); i++)
02326 {
02327 struct data_dependence_relation *ddr;
02328 ddr = VARRAY_GENERIC_PTR (allrelations, i);
02329 if (build_classic_dist_vector (ddr, nb_loops, loop->depth))
02330 {
02331 VARRAY_PUSH_GENERIC_PTR (*dependence_relations, ddr);
02332 build_classic_dir_vector (ddr, nb_loops, loop->depth);
02333 }
02334 }
02335 }
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359 void
02360 analyze_all_data_dependences (struct loops *loops)
02361 {
02362 unsigned int i;
02363 varray_type datarefs;
02364 varray_type dependence_relations;
02365 int nb_data_refs = 10;
02366
02367 VARRAY_GENERIC_PTR_INIT (datarefs, nb_data_refs, "datarefs");
02368 VARRAY_GENERIC_PTR_INIT (dependence_relations,
02369 nb_data_refs * nb_data_refs,
02370 "dependence_relations");
02371
02372
02373 compute_data_dependences_for_loop (loops->num, loops->parray[0],
02374 &datarefs, &dependence_relations);
02375
02376 if (dump_file)
02377 {
02378 dump_data_dependence_relations (dump_file, dependence_relations);
02379 fprintf (dump_file, "\n\n");
02380
02381 if (dump_flags & TDF_DETAILS)
02382 dump_dist_dir_vectors (dump_file, dependence_relations);
02383
02384 if (dump_flags & TDF_STATS)
02385 {
02386 unsigned nb_top_relations = 0;
02387 unsigned nb_bot_relations = 0;
02388 unsigned nb_basename_differ = 0;
02389 unsigned nb_chrec_relations = 0;
02390
02391 for (i = 0; i < VARRAY_ACTIVE_SIZE (dependence_relations); i++)
02392 {
02393 struct data_dependence_relation *ddr;
02394 ddr = VARRAY_GENERIC_PTR (dependence_relations, i);
02395
02396 if (chrec_contains_undetermined (DDR_ARE_DEPENDENT (ddr)))
02397 nb_top_relations++;
02398
02399 else if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
02400 {
02401 struct data_reference *a = DDR_A (ddr);
02402 struct data_reference *b = DDR_B (ddr);
02403 bool differ_p;
02404
02405 if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)
02406 || (array_base_name_differ_p (a, b, &differ_p) && differ_p))
02407 nb_basename_differ++;
02408 else
02409 nb_bot_relations++;
02410 }
02411
02412 else
02413 nb_chrec_relations++;
02414 }
02415
02416 gather_stats_on_scev_database ();
02417 }
02418 }
02419
02420 free_dependence_relations (dependence_relations);
02421 free_data_refs (datarefs);
02422 }
02423
02424
02425
02426 void
02427 free_dependence_relation (struct data_dependence_relation *ddr)
02428 {
02429 if (ddr == NULL)
02430 return;
02431
02432 if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE && DDR_SUBSCRIPTS (ddr))
02433 varray_clear (DDR_SUBSCRIPTS (ddr));
02434 free (ddr);
02435 }
02436
02437
02438
02439
02440 void
02441 free_dependence_relations (varray_type dependence_relations)
02442 {
02443 unsigned int i;
02444 if (dependence_relations == NULL)
02445 return;
02446
02447 for (i = 0; i < VARRAY_ACTIVE_SIZE (dependence_relations); i++)
02448 free_dependence_relation (VARRAY_GENERIC_PTR (dependence_relations, i));
02449 varray_clear (dependence_relations);
02450 }
02451
02452
02453
02454 void
02455 free_data_refs (varray_type datarefs)
02456 {
02457 unsigned int i;
02458
02459 if (datarefs == NULL)
02460 return;
02461
02462 for (i = 0; i < VARRAY_ACTIVE_SIZE (datarefs); i++)
02463 {
02464 struct data_reference *dr = (struct data_reference *)
02465 VARRAY_GENERIC_PTR (datarefs, i);
02466 if (dr)
02467 {
02468 if (DR_ACCESS_FNS (dr))
02469 varray_clear (DR_ACCESS_FNS (dr));
02470 free (dr);
02471 }
02472 }
02473 varray_clear (datarefs);
02474 }
02475