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 #include "config.h"
00027 #include "system.h"
00028
00029 #include "rtl.h"
00030 #include "expr.h"
00031 #include "tree.h"
00032 #include "c-common.h"
00033 #include "flags.h"
00034 #include "varray.h"
00035
00036 #define MAX_SUBSCRIPTS 13
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 enum dependence_type {dt_flow, dt_anti, dt_output, dt_none};
00063 #if 0
00064 static const char *const dependence_string [] = {"flow", "anti", "output", "none"};
00065 #endif
00066 enum direction_type {lt, le, eq, gt, ge, star, independent, undef};
00067 #if 0
00068 static const char *const direction_string [] = {"<", "<=", "=", ">", ">=", "*",
00069 "INDEPENDENT", "UNDEFINED"};
00070 #endif
00071 enum def_use_type {def, use, init_def_use};
00072
00073 enum du_status_type {seen, unseen};
00074
00075 enum loop_status_type {normal, unnormal};
00076
00077 enum complexity_type {ziv, strong_siv, weak_siv, weak_zero_siv,
00078 weak_crossing_siv, miv};
00079
00080
00081
00082
00083
00084 typedef struct def_use
00085 {
00086
00087 tree outer_loop;
00088
00089 tree containing_loop;
00090
00091 tree expression;
00092
00093 const char *variable;
00094
00095 enum def_use_type type;
00096
00097 enum du_status_type status;
00098
00099 struct def_use *next;
00100
00101 struct dependence *dep;
00102 } def_use;
00103
00104
00105
00106
00107
00108
00109 typedef struct loop
00110 {
00111
00112 tree outer_loop;
00113
00114 tree containing_loop;
00115
00116 int depth;
00117
00118 enum loop_status_type status;
00119
00120 struct loop *next_nest;
00121
00122 struct induction *ind;
00123 } loop;
00124
00125
00126
00127 typedef struct induction
00128 {
00129
00130 const char *variable;
00131
00132 int increment;
00133
00134 int low_bound;
00135
00136 int high_bound;
00137
00138 struct induction *next;
00139 } induction;
00140
00141
00142
00143 typedef struct dependence
00144 {
00145 tree source;
00146 tree destination;
00147 enum dependence_type dependence;
00148 enum direction_type direction[MAX_SUBSCRIPTS];
00149 int distance[MAX_SUBSCRIPTS];
00150 struct dependence *next;
00151 } dependence;
00152
00153
00154
00155
00156 typedef struct subscript
00157 {
00158
00159 int position;
00160
00161 int coefficient;
00162
00163 int offset;
00164
00165 const char *variable;
00166
00167 struct subscript *next;
00168 } subscript;
00169
00170
00171
00172 static tree dest_to_remember;
00173
00174
00175 static varray_type def_use_chain;
00176
00177
00178 static varray_type dep_chain;
00179
00180
00181 static varray_type loop_chain;
00182
00183
00184 static varray_type induction_chain;
00185
00186 void init_dependence_analysis PARAMS ((tree));
00187 static void build_def_use PARAMS ((tree, enum def_use_type));
00188 static loop* add_loop PARAMS ((tree, tree, int));
00189 static int find_induction_variable PARAMS ((tree, tree, tree, loop*));
00190 static int get_low_bound PARAMS ((tree, const char*));
00191 static int have_induction_variable PARAMS ((tree, const char*));
00192 static void link_loops PARAMS ((void));
00193 static void get_node_dependence PARAMS ((void));
00194 static void check_node_dependence PARAMS ((def_use*));
00195 static int get_coefficients PARAMS ((def_use*, subscript[]));
00196 static int get_one_coefficient PARAMS ((tree, subscript*, def_use*, enum tree_code*));
00197 static void normalize_coefficients PARAMS ((subscript[], loop*, int));
00198 static void classify_dependence PARAMS ((subscript[], subscript[],
00199 enum complexity_type[], int*, int));
00200 static void ziv_test PARAMS ((subscript[], subscript[],
00201 enum direction_type[][MAX_SUBSCRIPTS],
00202 int[][MAX_SUBSCRIPTS], loop*, int));
00203 static void siv_test PARAMS ((subscript[], subscript[],
00204 enum direction_type[][MAX_SUBSCRIPTS],
00205 int[][MAX_SUBSCRIPTS], loop*, int));
00206 static int check_subscript_induction PARAMS ((subscript*, subscript*, loop*));
00207 static void gcd_test PARAMS ((subscript[], subscript[], enum
00208 direction_type[][MAX_SUBSCRIPTS],
00209 int[][MAX_SUBSCRIPTS], loop*, int));
00210 static int find_gcd PARAMS ((int, int));
00211 static void merge_dependencies PARAMS ((enum direction_type[][MAX_SUBSCRIPTS],
00212 int[][MAX_SUBSCRIPTS], int, int));
00213 static void dump_array_ref PARAMS ((tree));
00214 #if 0
00215 static void dump_one_node PARAMS ((def_use*, varray_type*));
00216 static void dump_node_dependence PARAMS ((void));
00217 #endif
00218 int search_dependence PARAMS ((tree));
00219 void remember_dest_for_dependence PARAMS ((tree));
00220 int have_dependence_p PARAMS ((rtx, rtx, enum direction_type[], int[]));
00221 void end_dependence_analysis PARAMS ((void));
00222
00223
00224
00225
00226 void
00227 init_dependence_analysis (exp)
00228 tree exp;
00229 {
00230 def_use *du_ptr;
00231
00232 VARRAY_GENERIC_PTR_INIT (def_use_chain, 50, "def_use_chain");
00233 VARRAY_GENERIC_PTR_INIT (dep_chain, 50, "dep_chain");
00234 VARRAY_GENERIC_PTR_INIT (loop_chain, 50, "loop_chain");
00235 VARRAY_GENERIC_PTR_INIT (induction_chain, 50, "induction_chain");
00236
00237 build_def_use (exp, init_def_use);
00238
00239 link_loops ();
00240
00241 get_node_dependence ();
00242
00243
00244
00245 for (du_ptr = VARRAY_TOP (def_use_chain, generic);
00246 VARRAY_POP (def_use_chain);
00247 du_ptr = VARRAY_TOP (def_use_chain, generic))
00248 {
00249 free (du_ptr);
00250 }
00251
00252 VARRAY_FREE (def_use_chain);
00253 VARRAY_FREE (loop_chain);
00254 VARRAY_FREE (induction_chain);
00255 }
00256
00257
00258
00259
00260 static void
00261 build_def_use (exp, du_type)
00262 tree exp;
00263 enum def_use_type du_type;
00264 {
00265 static tree outer_loop;
00266 static int nloop;
00267 static tree current_loop;
00268 static int du_idx;
00269 static loop *loop_def;
00270 tree node = exp;
00271 tree array_ref;
00272 def_use *du_ptr;
00273
00274 if (du_type == init_def_use)
00275 {
00276 outer_loop = 0;
00277 nloop = 0;
00278 du_idx = 0;
00279 }
00280
00281 while (node)
00282 switch (TREE_CODE (node))
00283 {
00284 case COMPOUND_STMT:
00285 node = TREE_OPERAND (node, 0);
00286 break;
00287 case TREE_LIST:
00288 build_def_use (TREE_VALUE (node), 0);
00289 node = TREE_CHAIN (node);
00290 break;
00291 case CALL_EXPR:
00292 node = TREE_CHAIN (node);
00293 break;
00294 case FOR_STMT:
00295 if (! nloop) outer_loop = node;
00296 nloop++;
00297 current_loop = node;
00298 loop_def = add_loop (node, outer_loop, nloop);
00299 if (find_induction_variable (TREE_OPERAND (node, 0),
00300 TREE_OPERAND (node, 1),
00301 TREE_OPERAND (node, 2), loop_def)
00302 == 0)
00303 loop_def->status = unnormal;
00304
00305 build_def_use (TREE_OPERAND (node, 3), 0);
00306 nloop--;
00307 current_loop = 0;
00308 node = TREE_CHAIN (node);
00309 break;
00310 case MODIFY_EXPR:
00311
00312 if (loop_def
00313 && TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL
00314 && have_induction_variable
00315 (loop_def->outer_loop,
00316 IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (node, 0)))) >= 0)
00317 loop_def->status = unnormal;
00318
00319 if (TREE_CODE (TREE_OPERAND (node, 0)) == ARRAY_REF
00320 || TREE_CODE (TREE_OPERAND (node, 0)) == INDIRECT_REF)
00321 build_def_use (TREE_OPERAND (node, 0), def);
00322
00323 build_def_use (TREE_OPERAND (node, 1), use);
00324 node = TREE_CHAIN (node);
00325 break;
00326 case INDIRECT_REF:
00327 if (! TREE_OPERAND (node, 1)
00328 || TREE_CODE (TREE_OPERAND (node, 1)) != ARRAY_REF)
00329 {
00330 node = 0;
00331 break;
00332 }
00333 node = TREE_OPERAND (node, 1);
00334 case ARRAY_REF:
00335 if (nloop)
00336 {
00337 int i;
00338 char null_string = '\0';
00339
00340 VARRAY_PUSH_GENERIC_PTR (def_use_chain, xmalloc (sizeof (def_use)));
00341 du_ptr = VARRAY_GENERIC_PTR (def_use_chain, du_idx++);
00342 du_ptr->type = du_type;
00343 du_ptr->status = unseen;
00344 du_ptr->outer_loop = outer_loop;
00345 du_ptr->containing_loop = current_loop;
00346 du_ptr->expression = node;
00347 du_ptr->variable = &null_string;
00348 du_ptr->next = 0;
00349 du_ptr->dep = 0;
00350 for (array_ref = node;
00351 TREE_CODE (array_ref) == ARRAY_REF;
00352 array_ref = TREE_OPERAND (array_ref, 0))
00353 ;
00354
00355 if (TREE_CODE (array_ref) == COMPONENT_REF)
00356 {
00357 array_ref = TREE_OPERAND (array_ref, 1);
00358 if (! (TREE_CODE (array_ref) == FIELD_DECL
00359 && TREE_CODE (TREE_TYPE (array_ref)) == ARRAY_TYPE))
00360 {
00361 node = 0;
00362 break;
00363 }
00364 }
00365
00366 for (i = 0;
00367 i < du_idx
00368 && strcmp (IDENTIFIER_POINTER (DECL_NAME (array_ref)),
00369 ((def_use*) (VARRAY_GENERIC_PTR
00370 (def_use_chain, i)))->variable);
00371 i++)
00372 ;
00373 if (i != du_idx)
00374 {
00375 def_use *tmp_duc;
00376 for (tmp_duc = ((def_use*) (VARRAY_GENERIC_PTR (def_use_chain, i)));
00377 tmp_duc->next;
00378 tmp_duc = ((def_use*)tmp_duc->next));
00379 tmp_duc->next = du_ptr;
00380 }
00381 else du_ptr->next = 0;
00382 du_ptr->variable = IDENTIFIER_POINTER (DECL_NAME (array_ref));
00383 }
00384 node = 0;
00385 break;
00386
00387 case SCOPE_STMT:
00388 case DECL_STMT:
00389 node = TREE_CHAIN (node);
00390 break;
00391
00392 case EXPR_STMT:
00393 if (TREE_CODE (TREE_OPERAND (node, 0)) == MODIFY_EXPR)
00394 build_def_use (TREE_OPERAND (node, 0), def);
00395 node = TREE_CHAIN (node);
00396 break;
00397
00398 default:
00399 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
00400 {
00401 build_def_use (TREE_OPERAND (node, 0), use);
00402 build_def_use (TREE_OPERAND (node, 1), use);
00403 node = TREE_CHAIN (node);
00404 }
00405 else
00406 node = 0;
00407 }
00408 }
00409
00410
00411
00412
00413 static loop*
00414 add_loop (loop_node, outer_loop, nloop)
00415 tree loop_node;
00416 tree outer_loop;
00417 int nloop;
00418 {
00419 loop *loop_ptr;
00420
00421 VARRAY_PUSH_GENERIC_PTR (loop_chain, xmalloc (sizeof (loop)));
00422 loop_ptr = VARRAY_TOP (loop_chain, generic);
00423 loop_ptr->outer_loop = outer_loop;
00424 loop_ptr->containing_loop = loop_node;
00425 loop_ptr->depth = nloop;
00426 loop_ptr->status = normal;
00427 loop_ptr->next_nest = 0;
00428 loop_ptr->ind = 0;
00429 return loop_ptr;
00430 }
00431
00432
00433
00434
00435 static int
00436 find_induction_variable (init_node, cond_node, incr_node, loop_def)
00437 tree init_node;
00438 tree cond_node;
00439 tree incr_node;
00440 loop *loop_def;
00441 {
00442 induction *ind_ptr;
00443 enum tree_code incr_code;
00444 tree incr;
00445
00446 if (! init_node || ! incr_node || ! cond_node)
00447 return 0;
00448
00449
00450 incr = incr_node;
00451 while (TREE_CODE (incr) == COMPOUND_EXPR)
00452 {
00453 incr_code = TREE_CODE (TREE_OPERAND (incr, 0));
00454 if (incr_code == PREDECREMENT_EXPR || incr_code == POSTDECREMENT_EXPR
00455 || incr_code == PREINCREMENT_EXPR || incr_code == POSTINCREMENT_EXPR)
00456 {
00457 incr_node = TREE_OPERAND (incr, 0);
00458 break;
00459 }
00460 incr_code = TREE_CODE (TREE_OPERAND (incr, 1));
00461 if (incr_code == PREDECREMENT_EXPR || incr_code == POSTDECREMENT_EXPR
00462 || incr_code == PREINCREMENT_EXPR || incr_code == POSTINCREMENT_EXPR)
00463 {
00464 incr_node = TREE_OPERAND (incr, 1);
00465 break;
00466 }
00467 incr = TREE_OPERAND (incr, 1);
00468 }
00469
00470
00471 cond_node = TREE_VALUE (cond_node);
00472 incr = cond_node;
00473
00474 #define INDEX_LIMIT_CHECK(NODE) \
00475 (TREE_CODE_CLASS (TREE_CODE (NODE)) == '<') \
00476 && (TREE_CODE (TREE_OPERAND (NODE, 0)) == VAR_DECL \
00477 && (IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (NODE, 0))) \
00478 == IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (incr_node, 0))))) \
00479 ? 1 : 0
00480
00481 while (TREE_CODE (incr) == TRUTH_ANDIF_EXPR
00482 || TREE_CODE (incr) == TRUTH_ORIF_EXPR)
00483 {
00484 if (INDEX_LIMIT_CHECK (TREE_OPERAND (incr, 0)))
00485 {
00486 cond_node = TREE_OPERAND (incr, 0);
00487 break;
00488 }
00489 if (INDEX_LIMIT_CHECK (TREE_OPERAND (incr, 1)))
00490 {
00491 cond_node = TREE_OPERAND (incr, 1);
00492 break;
00493 }
00494 incr = TREE_OPERAND (incr, 0);
00495 }
00496
00497 incr_code = TREE_CODE (incr_node);
00498 if ((incr_code == PREDECREMENT_EXPR || incr_code == POSTDECREMENT_EXPR
00499 || incr_code == PREINCREMENT_EXPR || incr_code == POSTINCREMENT_EXPR)
00500 && TREE_CODE_CLASS (TREE_CODE (cond_node)) == '<')
00501 {
00502 if (!INDEX_LIMIT_CHECK (cond_node))
00503 return 0;
00504
00505 VARRAY_PUSH_GENERIC_PTR (induction_chain, xmalloc (sizeof (induction)));
00506 ind_ptr = VARRAY_TOP (induction_chain, generic);
00507 loop_def->ind = ind_ptr;
00508 ind_ptr->variable = IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND
00509 (incr_node, 0)));
00510 ind_ptr->increment = TREE_INT_CST_LOW (TREE_OPERAND (incr_node, 1));
00511 if (TREE_CODE (incr_node) == PREDECREMENT_EXPR
00512 || TREE_CODE (incr_node) == POSTDECREMENT_EXPR)
00513 ind_ptr->increment = -ind_ptr->increment;
00514
00515 ind_ptr->low_bound = get_low_bound (init_node, ind_ptr->variable);
00516 if (TREE_CODE (TREE_OPERAND (cond_node, 0)) == VAR_DECL
00517 && IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (cond_node, 0)))
00518 == ind_ptr->variable)
00519 {
00520 if (TREE_CODE (TREE_OPERAND (cond_node, 1)) == INTEGER_CST)
00521 ind_ptr->high_bound =
00522 TREE_INT_CST_LOW (TREE_OPERAND (cond_node, 1));
00523 else
00524 ind_ptr->high_bound = ind_ptr->increment < 0 ? INT_MIN : INT_MAX;
00525 }
00526 else if (TREE_CODE (TREE_OPERAND (cond_node, 1)) == VAR_DECL
00527 && IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (cond_node, 1)))
00528 == ind_ptr->variable)
00529 {
00530 if (TREE_CODE (TREE_OPERAND (cond_node, 0)) == INTEGER_CST)
00531 ind_ptr->high_bound =
00532 TREE_INT_CST_LOW (TREE_OPERAND (cond_node, 0));
00533 else
00534 ind_ptr->high_bound = ind_ptr->increment < 0 ? INT_MIN : INT_MAX;
00535 }
00536 ind_ptr->next = 0;
00537 return 1;
00538 }
00539 return 0;
00540 }
00541
00542
00543
00544 static int
00545 get_low_bound (node, variable)
00546 tree node;
00547 const char *variable;
00548 {
00549
00550 if (TREE_CODE (node) == SCOPE_STMT)
00551 node = TREE_CHAIN (node);
00552
00553 if (! node)
00554 return INT_MIN;
00555
00556 while (TREE_CODE (node) == COMPOUND_EXPR)
00557 {
00558 if (TREE_CODE (TREE_OPERAND (node, 0)) == MODIFY_EXPR
00559 && (TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL
00560 && IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (node, 0)))
00561 == variable))
00562 break;
00563 }
00564
00565 if (TREE_CODE (node) == EXPR_STMT)
00566 node = TREE_OPERAND (node, 0);
00567 if (TREE_CODE (node) == MODIFY_EXPR
00568 && (TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL
00569 && IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (node, 0)))
00570 == variable))
00571 {
00572 return TREE_INT_CST_LOW (TREE_OPERAND (node, 1));
00573 }
00574 return INT_MIN;
00575 }
00576
00577
00578
00579
00580
00581 static int
00582 have_induction_variable (outer_loop, ind_var)
00583 tree outer_loop;
00584 const char *ind_var;
00585 {
00586 induction *ind_ptr;
00587 loop *loop_ptr;
00588 unsigned int ind_idx = 0;
00589 unsigned int loop_idx = 0;
00590
00591 for (loop_ptr = VARRAY_GENERIC_PTR (loop_chain, loop_idx);
00592 loop_ptr && loop_idx < VARRAY_SIZE (loop_chain);
00593 loop_ptr = VARRAY_GENERIC_PTR (loop_chain, ++loop_idx))
00594 if (loop_ptr->outer_loop == outer_loop)
00595 for (ind_ptr = loop_ptr->ind;
00596 ind_ptr && ind_idx < VARRAY_SIZE (induction_chain);
00597 ind_ptr = ind_ptr->next)
00598 {
00599 if (! strcmp (ind_ptr->variable, ind_var))
00600 return loop_idx + 1;
00601 }
00602 return -1;
00603 }
00604
00605
00606
00607 static void
00608 link_loops ()
00609 {
00610 unsigned int loop_idx = 0;
00611 loop *loop_ptr, *prev_loop_ptr = 0;
00612
00613 prev_loop_ptr = VARRAY_GENERIC_PTR (loop_chain, loop_idx);
00614 for (loop_ptr = VARRAY_GENERIC_PTR (loop_chain, ++loop_idx);
00615 loop_ptr && loop_idx < VARRAY_SIZE (loop_chain);
00616 loop_ptr = VARRAY_GENERIC_PTR (loop_chain, ++loop_idx))
00617 {
00618 if (prev_loop_ptr->outer_loop == loop_ptr->outer_loop)
00619 {
00620 if (prev_loop_ptr->depth == loop_ptr->depth - 1)
00621 prev_loop_ptr->next_nest = loop_ptr;
00622 prev_loop_ptr = loop_ptr;
00623 }
00624 }
00625 }
00626
00627
00628
00629 static void
00630 get_node_dependence ()
00631 {
00632 unsigned int du_idx;
00633 def_use *du_ptr;
00634
00635 du_idx = 0;
00636 for (du_ptr = VARRAY_GENERIC_PTR (def_use_chain, du_idx);
00637 du_ptr && du_idx < VARRAY_SIZE (def_use_chain);
00638 du_ptr = VARRAY_GENERIC_PTR (def_use_chain, du_idx++))
00639 {
00640 if (du_ptr->status == unseen)
00641 check_node_dependence (du_ptr);
00642 }
00643 }
00644
00645
00646
00647 static void
00648 check_node_dependence (du)
00649 def_use *du;
00650 {
00651 def_use *def_ptr, *use_ptr;
00652 dependence *dep_ptr, *dep_list;
00653 subscript icoefficients[MAX_SUBSCRIPTS];
00654 subscript ocoefficients[MAX_SUBSCRIPTS];
00655 loop *loop_ptr, *ck_loop_ptr;
00656 unsigned int loop_idx = 0;
00657 int distance[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS];
00658 int i, j;
00659 int subscript_count;
00660 int unnormal_loop;
00661 enum direction_type direction[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS];
00662 enum complexity_type complexity[MAX_SUBSCRIPTS];
00663 int separability;
00664 int have_dependence;
00665
00666 for (j = 1 ; j < MAX_SUBSCRIPTS; j++)
00667 {
00668 direction[j][0] = undef;
00669 distance[j][0] = 0;
00670 }
00671
00672 for (def_ptr = du; def_ptr; def_ptr = def_ptr->next)
00673 {
00674 if (def_ptr->type != def)
00675 continue;
00676 subscript_count = get_coefficients (def_ptr, ocoefficients);
00677 if (subscript_count < 0)
00678 continue;
00679
00680 loop_idx = 0;
00681 for (loop_ptr = VARRAY_GENERIC_PTR (loop_chain, loop_idx);
00682 loop_ptr && loop_idx < VARRAY_SIZE (loop_chain);
00683 loop_ptr = VARRAY_GENERIC_PTR (loop_chain, ++loop_idx))
00684 {
00685 if (loop_ptr->outer_loop == def_ptr->outer_loop)
00686 break;
00687 }
00688
00689 unnormal_loop = 0;
00690 for (ck_loop_ptr = loop_ptr;
00691 ck_loop_ptr && loop_idx < VARRAY_SIZE (loop_chain);
00692 ck_loop_ptr = VARRAY_GENERIC_PTR (loop_chain, ++loop_idx))
00693 {
00694 if (ck_loop_ptr->outer_loop == def_ptr->outer_loop
00695 && ck_loop_ptr->status == unnormal)
00696 unnormal_loop = 1;
00697 }
00698 if (unnormal_loop)
00699 continue;
00700
00701 normalize_coefficients (ocoefficients, loop_ptr, subscript_count);
00702
00703 for (use_ptr = du; use_ptr; use_ptr = use_ptr->next)
00704 {
00705 if (def_ptr == use_ptr
00706 || def_ptr->outer_loop != use_ptr->outer_loop)
00707 continue;
00708 def_ptr->status = seen;
00709 use_ptr->status = seen;
00710 subscript_count = get_coefficients (use_ptr, icoefficients);
00711 normalize_coefficients (icoefficients, loop_ptr, subscript_count);
00712 classify_dependence (icoefficients, ocoefficients, complexity,
00713 &separability, subscript_count);
00714
00715 for (i = 1, ck_loop_ptr = loop_ptr; ck_loop_ptr; i++)
00716 {
00717 for (j = 1; j <= subscript_count; j++)
00718 {
00719 direction[i][j] = star;
00720 distance[i][j] = INT_MAX;
00721 if (separability && complexity[j] == ziv)
00722 ziv_test (icoefficients, ocoefficients, direction, distance,
00723 ck_loop_ptr, j);
00724 else if (separability
00725 && (complexity[j] == strong_siv
00726 || complexity[j] == weak_zero_siv
00727 || complexity[j] == weak_crossing_siv))
00728 siv_test (icoefficients, ocoefficients, direction, distance,
00729 ck_loop_ptr, j);
00730 else
00731 gcd_test (icoefficients, ocoefficients, direction, distance,
00732 ck_loop_ptr, j);
00733
00734 }
00735
00736 ck_loop_ptr = ck_loop_ptr->next_nest;
00737 }
00738
00739 merge_dependencies (direction, distance, i - 1, j - 1);
00740
00741 have_dependence = 0;
00742 for (j = 1; j <= i - 1; j++)
00743 {
00744 if (direction[j][0] != independent)
00745 have_dependence = 1;
00746 }
00747 if (! have_dependence)
00748 continue;
00749
00750 VARRAY_PUSH_GENERIC_PTR (dep_chain, xmalloc (sizeof (dependence)));
00751 dep_ptr = VARRAY_TOP (dep_chain, generic);
00752 dep_ptr->source = use_ptr->expression;
00753 dep_ptr->destination = def_ptr->expression;
00754 dep_ptr->next = 0;
00755
00756 if (def_ptr < use_ptr && use_ptr->type == use)
00757 dep_ptr->dependence = dt_flow;
00758 else if (def_ptr > use_ptr && use_ptr->type == use)
00759 dep_ptr->dependence = dt_anti;
00760 else dep_ptr->dependence = dt_output;
00761
00762 for (j = 1 ; j <= i - 1 ; j++)
00763 {
00764 if (direction[j][0] == gt)
00765 {
00766 dep_ptr->dependence = dt_anti;
00767 direction[j][0] = lt;
00768 distance[j][0] = -distance[j][0];
00769 break;
00770 }
00771 else if (direction[j][0] == lt)
00772 {
00773 dep_ptr->dependence = dt_flow;
00774 break;
00775 }
00776 }
00777 for (j = 1 ; j < MAX_SUBSCRIPTS ; j++)
00778 {
00779 dep_ptr->direction[j] = direction[j][0];
00780 dep_ptr->distance[j] = distance[j][0];
00781 }
00782
00783 for (dep_list = def_ptr->dep ;
00784 dep_list && dep_list->next ;
00785 dep_list = dep_list->next)
00786 ;
00787
00788 if (! dep_list)
00789 {
00790
00791 dependence *dep_root_ptr;
00792
00793 VARRAY_PUSH_GENERIC_PTR (dep_chain, xmalloc (sizeof (dependence)));
00794 dep_root_ptr = VARRAY_TOP (dep_chain, generic);
00795 dep_root_ptr->source = 0;
00796 dep_root_ptr->destination = def_ptr->expression;
00797 dep_root_ptr->dependence = dt_none;
00798 dep_root_ptr->next = dep_ptr;
00799 def_ptr->dep = dep_ptr;
00800 }
00801 else
00802 dep_list->next = dep_ptr;
00803 }
00804 }
00805 }
00806
00807
00808
00809 static int
00810 get_coefficients (du, coefficients)
00811 def_use *du;
00812 subscript coefficients [MAX_SUBSCRIPTS];
00813 {
00814 int idx = 0;
00815 int array_count;
00816 int i;
00817 tree array_ref;
00818
00819 array_count = 0;
00820 for (array_ref = du->expression;
00821 TREE_CODE (array_ref) == ARRAY_REF;
00822 array_ref = TREE_OPERAND (array_ref, 0))
00823 array_count += 1;
00824
00825 idx = array_count;
00826
00827 for (i = 0; i < MAX_SUBSCRIPTS; i++)
00828 {
00829 coefficients[i].position = 0;
00830 coefficients[i].coefficient = INT_MIN;
00831 coefficients[i].offset = INT_MIN;
00832 coefficients[i].variable = 0;
00833 coefficients[i].next = 0;
00834 }
00835
00836 for (array_ref = du->expression;
00837 TREE_CODE (array_ref) == ARRAY_REF;
00838 array_ref = TREE_OPERAND (array_ref, 0))
00839 {
00840 if (TREE_CODE (TREE_OPERAND (array_ref, 1)) == INTEGER_CST)
00841 coefficients[idx].offset = TREE_INT_CST_LOW (TREE_OPERAND (array_ref, 1));
00842 else
00843 if (get_one_coefficient (TREE_OPERAND (array_ref, 1),
00844 &coefficients[idx], du, 0) < 0)
00845 return -1;
00846 idx = idx - 1;
00847 }
00848 return array_count;
00849 }
00850
00851
00852
00853 static int
00854 get_one_coefficient (node, coefficients, du, type)
00855 tree node;
00856 subscript *coefficients;
00857 def_use *du;
00858 enum tree_code *type;
00859 {
00860 enum tree_code tree_op, tree_op_code;
00861 int index, value;
00862
00863 tree_op = TREE_CODE (node);
00864 if (type)
00865 *type = tree_op;
00866
00867 if (tree_op == VAR_DECL)
00868 {
00869 index = have_induction_variable (du->outer_loop,
00870 IDENTIFIER_POINTER (DECL_NAME (node)));
00871 if (index >= 0)
00872 {
00873 coefficients->position = index;
00874 coefficients->variable = IDENTIFIER_POINTER (DECL_NAME (node));
00875 coefficients->coefficient = 1;
00876 if (coefficients->offset == INT_MIN)
00877 coefficients->offset = 0;
00878 }
00879 return index;
00880 }
00881 else if (tree_op == INTEGER_CST)
00882 {
00883 return TREE_INT_CST_LOW (node);
00884 }
00885 else if (tree_op == NON_LVALUE_EXPR)
00886 {
00887 return get_one_coefficient (TREE_OPERAND (node, 0), coefficients, du,
00888 &tree_op_code);
00889 }
00890 else if (tree_op == PLUS_EXPR)
00891 {
00892 value = get_one_coefficient (TREE_OPERAND (node, 0), coefficients, du,
00893 &tree_op_code);
00894 if (tree_op_code == INTEGER_CST)
00895 coefficients->offset = value;
00896
00897 value = get_one_coefficient (TREE_OPERAND (node, 1), coefficients, du,
00898 &tree_op_code);
00899 if (tree_op_code == INTEGER_CST)
00900 coefficients->offset = value;
00901
00902 return 0;
00903 }
00904 else if (tree_op == MINUS_EXPR)
00905 {
00906 value = get_one_coefficient (TREE_OPERAND (node, 0), coefficients, du,
00907 &tree_op_code);
00908 if (tree_op_code == INTEGER_CST)
00909 coefficients->offset = value;
00910
00911 value = get_one_coefficient (TREE_OPERAND (node, 1), coefficients, du,
00912 &tree_op_code);
00913 if (tree_op_code == INTEGER_CST)
00914 coefficients->offset = -value;
00915
00916 return 0;
00917 }
00918 else if (tree_op == MULT_EXPR)
00919 {
00920 int value0, value1, value0_is_idx = 0, value1_is_idx = 0;
00921
00922 value0 = get_one_coefficient (TREE_OPERAND (node, 0), coefficients, du,
00923 &tree_op_code);
00924 if (tree_op_code == VAR_DECL)
00925 value0_is_idx = 1;
00926
00927 value1 = get_one_coefficient (TREE_OPERAND (node, 1), coefficients, du,
00928 &tree_op_code);
00929 if (tree_op_code == VAR_DECL)
00930 value1_is_idx = 1;
00931
00932 if (value0_is_idx)
00933 coefficients->coefficient = value1;
00934 else if (value1_is_idx)
00935 coefficients->coefficient = value0;
00936 }
00937 return 0;
00938 }
00939
00940
00941
00942 static void
00943 normalize_coefficients (coefficients, loop_ptr, count)
00944 subscript coefficients [MAX_SUBSCRIPTS];
00945 loop *loop_ptr;
00946 int count;
00947 {
00948 induction *ind_ptr;
00949 loop *ck_loop_ptr;
00950 int i;
00951
00952 for (i = 1; i <= count; i++)
00953 {
00954 for (ck_loop_ptr = loop_ptr; ck_loop_ptr;
00955 ck_loop_ptr = ck_loop_ptr->next_nest)
00956 for (ind_ptr = ck_loop_ptr->ind; ind_ptr; ind_ptr = ind_ptr->next)
00957 {
00958 if (coefficients[i].variable == ind_ptr->variable)
00959 {
00960 if (ind_ptr->low_bound < ind_ptr->high_bound)
00961 coefficients[i].offset += coefficients[i].coefficient
00962 * ind_ptr->low_bound;
00963 else if (ind_ptr->high_bound != INT_MIN)
00964 {
00965 coefficients[i].offset = coefficients[i].coefficient
00966 * ind_ptr->high_bound;
00967 coefficients[i].coefficient = coefficients[i].coefficient
00968 * -1;
00969 }
00970 break;
00971 }
00972 }
00973 }
00974 }
00975
00976
00977
00978
00979 static void
00980 classify_dependence (icoefficients, ocoefficients, complexity, separability,
00981 count)
00982 subscript icoefficients [MAX_SUBSCRIPTS];
00983 subscript ocoefficients [MAX_SUBSCRIPTS];
00984 enum complexity_type complexity [MAX_SUBSCRIPTS];
00985 int *separability;
00986 int count;
00987 {
00988 const char *iiv_used [MAX_SUBSCRIPTS];
00989 const char *oiv_used [MAX_SUBSCRIPTS];
00990 int ocoeff [MAX_SUBSCRIPTS];
00991 int icoeff [MAX_SUBSCRIPTS];
00992 int idx, cidx;
00993
00994 memset (iiv_used, 0, sizeof (tree) * MAX_SUBSCRIPTS);
00995 memset (oiv_used, 0, sizeof (tree) * MAX_SUBSCRIPTS);
00996 memset (icoeff, 0, sizeof (int) * MAX_SUBSCRIPTS);
00997 memset (ocoeff, 0, sizeof (int) * MAX_SUBSCRIPTS);
00998 for (idx = 1; idx <= count; idx++)
00999 {
01000 if (icoefficients[idx].variable != 0)
01001 {
01002 if (! iiv_used[idx])
01003 {
01004 iiv_used[idx] = icoefficients[idx].variable;
01005 icoeff[idx] = icoefficients[idx].coefficient;
01006 }
01007 }
01008 if (ocoefficients[idx].variable != 0)
01009 {
01010 if (! oiv_used[idx])
01011 {
01012 oiv_used[idx] = ocoefficients[idx].variable;
01013 ocoeff[idx] = ocoefficients[idx].coefficient;
01014 }
01015 }
01016 }
01017
01018 for (idx = 1; idx <= count; idx++)
01019 {
01020 if (iiv_used[idx] == 0 && oiv_used[idx] == 0)
01021 complexity[idx] = ziv;
01022 else if (iiv_used[idx] == oiv_used[idx])
01023 {
01024 if (icoeff[idx] == ocoeff[idx])
01025 complexity[idx] = strong_siv;
01026 else if (icoeff[idx] == -1 * ocoeff[idx])
01027 complexity[idx] = weak_crossing_siv;
01028 else
01029 complexity[idx] = weak_siv;
01030 }
01031 else if (icoeff[idx] == 0 || ocoeff[idx] == 0)
01032 complexity[idx] = weak_zero_siv;
01033 else complexity[idx] = miv;
01034 }
01035
01036 *separability = 1;
01037 for (idx = 1; idx <= count; idx++)
01038 {
01039 for (cidx = 1; cidx <= count; cidx++)
01040 {
01041 if (idx != cidx
01042 && iiv_used[idx] && oiv_used[cidx]
01043 && iiv_used[idx] == oiv_used[cidx])
01044 *separability = 0;
01045 }
01046 }
01047 }
01048
01049
01050
01051
01052
01053 static void
01054 ziv_test (icoefficients, ocoefficients, direction, distance, loop_ptr, sub)
01055 subscript icoefficients [MAX_SUBSCRIPTS];
01056 subscript ocoefficients [MAX_SUBSCRIPTS];
01057 enum direction_type direction[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS];
01058 int distance[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS] ATTRIBUTE_UNUSED;
01059 loop *loop_ptr;
01060 int sub;
01061 {
01062 if (ocoefficients[sub].offset !=
01063 icoefficients[sub].offset)
01064 direction[loop_ptr->depth][sub] = independent;
01065 }
01066
01067
01068
01069
01070
01071 static void
01072 siv_test (icoefficients, ocoefficients, direction, distance, loop_ptr, sub)
01073 subscript icoefficients [MAX_SUBSCRIPTS];
01074 subscript ocoefficients [MAX_SUBSCRIPTS];
01075 enum direction_type direction[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS];
01076 int distance[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS];
01077 loop *loop_ptr;
01078 int sub;
01079 {
01080 int coef_diff;
01081 int coef;
01082 int gcd;
01083
01084 if (! check_subscript_induction (&icoefficients[sub], &ocoefficients[sub],
01085 loop_ptr))
01086 return;
01087
01088 coef_diff = icoefficients[sub].offset - ocoefficients[sub].offset;
01089
01090
01091
01092
01093 if (ocoefficients[sub].coefficient == INT_MIN)
01094 coef = icoefficients[sub].coefficient;
01095 else if (icoefficients[sub].coefficient == INT_MIN)
01096 coef = ocoefficients[sub].coefficient;
01097 else if (ocoefficients[sub].coefficient ==
01098 -1 * icoefficients[sub].coefficient)
01099 coef = 2 * abs (ocoefficients[sub].coefficient);
01100 else
01101 coef = icoefficients[sub].coefficient;
01102
01103 gcd = -coef_diff / coef;
01104 if (gcd * coef != -coef_diff)
01105 {
01106 direction[loop_ptr->depth][sub] = independent;
01107 }
01108 else
01109 {
01110 distance[loop_ptr->depth][sub] = gcd;
01111 if (gcd < 0)
01112 direction[loop_ptr->depth][sub] = gt;
01113 else if (gcd > 0)
01114 direction[loop_ptr->depth][sub] = lt;
01115 else
01116 direction[loop_ptr->depth][sub] = eq;
01117 }
01118 }
01119
01120
01121
01122
01123 static int
01124 check_subscript_induction (icoefficient, ocoefficient, loop_ptr)
01125 subscript *icoefficient;
01126 subscript *ocoefficient;
01127 loop *loop_ptr;
01128 {
01129 induction *ind_ptr;
01130 int sub_ind_input = 0;
01131 int sub_ind_output = 0;
01132
01133 for (ind_ptr = loop_ptr->ind; ind_ptr; ind_ptr = ind_ptr->next)
01134 {
01135 if (icoefficient->variable == ind_ptr->variable)
01136 sub_ind_input = 1;
01137 if (ocoefficient->variable == ind_ptr->variable)
01138 sub_ind_output = 1;
01139 }
01140 if (sub_ind_input || sub_ind_output)
01141 return 1;
01142 else
01143 return 0;
01144 }
01145
01146 #define abs(N) ((N) < 0 ? -(N) : (N))
01147
01148
01149
01150
01151
01152 static void
01153 gcd_test (icoefficients, ocoefficients, direction, distance, loop_ptr, sub)
01154 subscript icoefficients [MAX_SUBSCRIPTS];
01155 subscript ocoefficients [MAX_SUBSCRIPTS];
01156 enum direction_type direction[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS];
01157 int distance[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS] ATTRIBUTE_UNUSED;
01158 loop *loop_ptr;
01159 int sub;
01160 {
01161 int coef_diff;
01162 int g, gg;
01163
01164 if (! check_subscript_induction (&icoefficients[sub], &ocoefficients[sub],
01165 loop_ptr))
01166 return;
01167
01168 g = find_gcd (icoefficients[sub].coefficient,
01169 ocoefficients[sub].coefficient);
01170 if (g > 1)
01171 {
01172 coef_diff = icoefficients[sub].offset - ocoefficients[sub].offset;
01173 gg = coef_diff / g;
01174 if (gg * g != coef_diff)
01175 {
01176 direction[loop_ptr->depth][sub] = independent;
01177 }
01178 }
01179
01180
01181 }
01182
01183
01184
01185 static int
01186 find_gcd (x, y)
01187 int x,y;
01188 {
01189 int g, g0, g1, r;
01190
01191 if (x == 0)
01192 {
01193 g = abs (x);
01194 }
01195 else if (y == 0)
01196 {
01197 g = abs (y);
01198 }
01199 else
01200 {
01201 g0 = abs (x);
01202 g1 = abs (y);
01203 r = g0 % g1;
01204 while (r != 0)
01205 {
01206 g0 = g1;
01207 g1 = r;
01208 r = g0 % g1;
01209 }
01210 g = g1;
01211 }
01212 return g;
01213 }
01214
01215
01216
01217
01218
01219
01220
01221 static void
01222 merge_dependencies (direction, distance, loop_count, subscript_count)
01223 enum direction_type direction[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS];
01224 int distance[MAX_SUBSCRIPTS][MAX_SUBSCRIPTS];
01225 int loop_count;
01226 int subscript_count;
01227 {
01228 int i, j;
01229 int sign;
01230
01231 static const enum direction_type direction_merge [8][8] =
01232 {{lt, le, le, star, star, lt, independent, lt},
01233 {le, le, le, star, star, le, independent, le},
01234 {le, le, eq, ge, ge, eq, independent, eq},
01235 {star, star, ge, gt, ge, gt, independent, ge},
01236 {star, star, ge, ge, ge, ge, independent, ge},
01237 {lt, le, eq, gt, ge, star, independent, star},
01238 {independent, independent, independent, independent, independent},
01239 {independent, independent, independent}
01240 };
01241
01242 for (i = 1; i <= loop_count; i++)
01243 {
01244 distance[i][0] = INT_MAX;
01245 direction[i][0] = star;
01246 sign = 1;
01247 for (j = 1; j <= subscript_count; j++)
01248 {
01249 if (distance[i][j] < 0)
01250 {
01251 distance[i][0] = distance[i][0] & abs (distance[i][j]);
01252 sign = -1;
01253 }
01254 else
01255 distance[i][0] = distance[i][0] & distance[i][j];
01256 direction[i][0] = direction_merge[(int)direction[i][0]]
01257 [(int)direction[i][j]];
01258 }
01259 distance[i][0] = sign * distance[i][0];
01260 }
01261 }
01262
01263
01264
01265 static void
01266 dump_array_ref (node)
01267 tree node;
01268 {
01269 enum tree_code tree_op = TREE_CODE (node);
01270
01271 if (tree_op == VAR_DECL)
01272 {
01273 printf ("%s", IDENTIFIER_POINTER (DECL_NAME (node)));
01274 }
01275 else if (tree_op == INTEGER_CST)
01276 {
01277 printf ("%d", (int)TREE_INT_CST_LOW (node));
01278 }
01279 else if (tree_op == PLUS_EXPR)
01280 {
01281 dump_array_ref (TREE_OPERAND (node, 0));
01282 printf ("+");
01283 dump_array_ref (TREE_OPERAND (node, 1));
01284 }
01285 else if (tree_op == MINUS_EXPR)
01286 {
01287 dump_array_ref (TREE_OPERAND (node, 0));
01288 printf ("-");
01289 dump_array_ref (TREE_OPERAND (node, 1));
01290 }
01291 else if (tree_op == MULT_EXPR)
01292 {
01293 dump_array_ref (TREE_OPERAND (node, 0));
01294 printf ("*");
01295 dump_array_ref (TREE_OPERAND (node, 1));
01296 }
01297 }
01298
01299
01300
01301 #if 0
01302 static void
01303 dump_one_node (du, seen)
01304 def_use *du;
01305 varray_type *seen;
01306 {
01307 def_use *du_ptr;
01308 dependence *dep_ptr;
01309 tree array_ref;
01310
01311 for (du_ptr = du; du_ptr; du_ptr = du_ptr->next)
01312 {
01313 printf ("%s ", du_ptr->variable);
01314 for (array_ref = du_ptr->expression;
01315 TREE_CODE (array_ref) == ARRAY_REF;
01316 array_ref = TREE_OPERAND (array_ref, 0))
01317 {
01318 printf ("[");
01319 dump_array_ref (TREE_OPERAND (array_ref, 1));
01320 printf ("]");
01321 }
01322
01323 printf (" Outer Loop %x Containing Loop %x Expression %x %s\n",
01324 (int)du_ptr->outer_loop,
01325 (int)du_ptr->containing_loop,
01326 (int)du_ptr->expression, du_ptr->type == def ? "Def" : "Use");
01327 VARRAY_PUSH_GENERIC_PTR (*seen, du_ptr);
01328
01329 for (dep_ptr = du_ptr->dep; dep_ptr; dep_ptr = dep_ptr->next)
01330 {
01331 int i;
01332 printf ("%s Dependence with %x ",
01333 dependence_string[(int)dep_ptr->dependence],
01334 (int)dep_ptr->source);
01335 printf ("Dir/Dist ");
01336 for (i = 1 ; i < MAX_SUBSCRIPTS ; i++)
01337 if (dep_ptr->direction[i] != undef)
01338 printf ("[%d] %s/%d ", i,
01339 direction_string[(int)dep_ptr->direction[i]],
01340 dep_ptr->distance[i]);
01341 printf ("\n");
01342 }
01343 }
01344 }
01345
01346
01347
01348 static void
01349 dump_node_dependence (void)
01350 {
01351 varray_type seen;
01352 unsigned int du_idx, seen_idx, i;
01353 def_use *du_ptr;
01354
01355 VARRAY_GENERIC_PTR_INIT (seen, 20, "seen");
01356 du_idx = 0;
01357 seen_idx = 0;
01358 for (du_ptr = VARRAY_GENERIC_PTR (def_use_chain, du_idx);
01359 du_idx < VARRAY_SIZE (def_use_chain);
01360 du_ptr = VARRAY_GENERIC_PTR (def_use_chain, du_idx++))
01361 {
01362 for (i = 0; i < VARRAY_SIZE (seen) && VARRAY_GENERIC_PTR (seen, i)
01363 != du_ptr ; i++);
01364 if (i >= VARRAY_SIZE (seen))
01365 dump_one_node (du_ptr, &seen);
01366 }
01367 VARRAY_FREE (seen);
01368 }
01369 #endif
01370
01371
01372
01373
01374
01375 int
01376 search_dependence (node)
01377 tree node;
01378 {
01379 dependence *dep_ptr;
01380 int dep_idx = 0;
01381
01382
01383 if (dep_chain)
01384 {
01385 if (TREE_CODE (node) == INDIRECT_REF && TREE_OPERAND (node, 1)
01386 && TREE_CODE (TREE_OPERAND (node, 1)) == ARRAY_REF)
01387 node = TREE_OPERAND (node, 1);
01388
01389 for (dep_ptr = VARRAY_GENERIC_PTR (dep_chain, 0);
01390 dep_ptr; dep_ptr = VARRAY_GENERIC_PTR (dep_chain, dep_idx++))
01391 {
01392 if ((node == dep_ptr->source
01393 && dest_to_remember == dep_ptr->destination)
01394 || (! dep_ptr->source && node == dep_ptr->destination))
01395 return dep_idx + 1;
01396 }
01397 }
01398
01399 return 0;
01400 }
01401
01402
01403
01404 void
01405 remember_dest_for_dependence (node)
01406 tree node;
01407 {
01408 if (node)
01409 {
01410 if (TREE_CODE (node) == INDIRECT_REF && TREE_OPERAND (node, 1)
01411 && TREE_CODE (TREE_OPERAND (node, 1)) == ARRAY_REF)
01412 node = TREE_OPERAND (node, 1);
01413 dest_to_remember = node;
01414 }
01415 }
01416
01417 #ifndef MEM_DEPENDENCY
01418 #define MEM_DEPENDENCY(RTX) XCWINT (RTX, 2, MEM)
01419 #endif
01420
01421
01422
01423
01424 int
01425 have_dependence_p (dest_rtx, src_rtx, direction, distance)
01426 rtx dest_rtx;
01427 rtx src_rtx;
01428 enum direction_type direction[MAX_SUBSCRIPTS];
01429 int distance[MAX_SUBSCRIPTS];
01430 {
01431 int dest_idx = 0, src_idx = 0;
01432 rtx dest, src;
01433 dependence *dep_ptr;
01434
01435 if (GET_CODE (SET_DEST (PATTERN (dest_rtx))) == MEM)
01436 {
01437 dest = SET_DEST (PATTERN (dest_rtx));
01438 dest_idx = MEM_DEPENDENCY (dest) - 1;
01439 }
01440 if (GET_CODE (SET_SRC (PATTERN (src_rtx))) == MEM)
01441 {
01442 src = SET_SRC (PATTERN (src_rtx));
01443 src_idx = MEM_DEPENDENCY (src) - 1;
01444 }
01445 if (dest_idx >= 0 || src_idx >= 0)
01446 return 0;
01447
01448 for (dep_ptr = VARRAY_GENERIC_PTR (dep_chain, -dest_idx);
01449 dep_ptr; dep_ptr = dep_ptr->next)
01450 {
01451 if (dep_ptr == VARRAY_GENERIC_PTR (dep_chain, -src_idx))
01452 {
01453 direction = (enum direction_type*) &dep_ptr->direction;
01454 distance = (int*) &dep_ptr->distance;
01455 return 1;
01456 }
01457 }
01458 return 0;
01459 }
01460
01461
01462
01463 void
01464 end_dependence_analysis ()
01465 {
01466 VARRAY_FREE (dep_chain);
01467 }