1 /* Analyze loop dependencies
2 Copyright (C) 2000, 2002 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 Practical Dependence Testing, Goff, Kennedy, Tseng, PLDI, 1991
23 High Performance Compilers for Parallel Computing, Wolfe
37 #define MAX_SUBSCRIPTS 13
40 We perform the following steps:
42 Build the data structures def_use_chain, loop_chain, and induction_chain.
44 Determine if a loop index is a normalized induction variable.
45 A loop is currently considered to be a for loop having an index set to an
46 initial value, conditional check of the index, and increment/decrement of
49 Determine the distance and direction vectors. Both are two dimensioned
50 arrays where the first dimension represents a loop and the second
51 dimension represents a subscript. Dependencies are actually per loop, not
52 per subscript. So for:
53 for (i = 0; i < 10; i++)
54 for (j = 0; j < 10; j++)
55 array [i][j] = array[i][j-1]
56 We find the dependencies: loop1/sub_i, loop1/sub_j, loop2/sub_i, loop2/sub_j
57 and then intersect loop1/sub_i V loop2/sub_i and loop1/sub_i V loop2/sub_j
58 We determine the type of dependence, which determines which test we use.
59 We then try to refine the type of dependence we have and add the
60 dependence to the dep_chain
63 enum dependence_type
{dt_flow
, dt_anti
, dt_output
, dt_none
};
65 static const char *const dependence_string
[] = {"flow", "anti", "output", "none"};
67 enum direction_type
{lt
, le
, eq
, gt
, ge
, star
, independent
, undef
};
69 static const char *const direction_string
[] = {"<", "<=", "=", ">", ">=", "*",
70 "INDEPENDENT", "UNDEFINED"};
72 enum def_use_type
{def
, use
, init_def_use
};
74 enum du_status_type
{seen
, unseen
};
76 enum loop_status_type
{normal
, unnormal
};
78 enum complexity_type
{ziv
, strong_siv
, weak_siv
, weak_zero_siv
,
79 weak_crossing_siv
, miv
};
81 /* Given a def/use one can chase the next chain to follow the def/use
82 for that variable. Alternately one can sequentially follow each
83 element of def_use_chain. */
85 typedef struct def_use
GTY(())
89 /* loop containing this def/use */
96 enum def_use_type type
;
98 enum du_status_type status
;
99 /* next def/use for this same name */
100 struct def_use
*next
;
101 /* dependencies for this def */
102 struct dependence
*dep
;
105 /* Given a loop* one can chase the next_nest chain to follow the nested
106 loops for that loop. Alternately one can sequentially follow each
107 element of loop_chain and check outer_loop to get all loops
108 contained within a certain loop. */
110 typedef struct loop
GTY(())
112 /* outermost loop containing this loop */
115 tree containing_loop
;
116 /* nest level for this loop */
118 /* can loop be normalized? */
119 enum loop_status_type status
;
120 /* loop* for loop contained in this loop */
121 struct loop
*next_nest
;
122 /* induction variables for this loop. Currently only the index variable. */
123 struct induction
*ind
;
126 /* Pointed to by loop. One per induction variable. */
128 typedef struct induction
GTY(())
131 const char *variable
;
132 /* increment. Currently only +1 or -1 */
138 /* next induction variable for this loop. Currently null. */
139 struct induction
*next
;
142 /* Pointed to by def/use. One per dependence. */
144 typedef struct dependence
GTY(())
148 enum dependence_type dependence
;
149 enum direction_type direction
[MAX_SUBSCRIPTS
];
150 int distance
[MAX_SUBSCRIPTS
];
151 struct dependence
*next
;
154 /* subscripts are represented by an array of these. Each reflects one
155 X * i + Y term, where X and Y are constants. */
157 typedef struct subscript
159 /* ordinal subscript number */
166 const char *variable
;
167 /* next subscript term. Currently null. */
168 struct subscript
*next
;
171 /* Remember the destination the front end encountered. */
173 static tree dest_to_remember
;
175 /* Chain for def_use */
176 static GTY ((param_is (def_use
))) varray_type def_use_chain
;
178 /* Chain for dependence */
179 static GTY ((param_is (dependence
))) varray_type dep_chain
;
182 static GTY ((param_is (loop
))) varray_type loop_chain
;
184 /* Chain for induction */
185 static GTY ((param_is (induction
))) varray_type induction_chain
;
187 void init_dependence_analysis
PARAMS ((tree
));
188 static void build_def_use
PARAMS ((tree
, enum def_use_type
));
189 static loop
* add_loop
PARAMS ((tree
, tree
, int));
190 static int find_induction_variable
PARAMS ((tree
, tree
, tree
, loop
*));
191 static int get_low_bound
PARAMS ((tree
, const char*));
192 static int have_induction_variable
PARAMS ((tree
, const char*));
193 static void link_loops
PARAMS ((void));
194 static void get_node_dependence
PARAMS ((void));
195 static void check_node_dependence
PARAMS ((def_use
*));
196 static int get_coefficients
PARAMS ((def_use
*, subscript
[]));
197 static int get_one_coefficient
PARAMS ((tree
, subscript
*, def_use
*, enum tree_code
*));
198 static void normalize_coefficients
PARAMS ((subscript
[], loop
*, int));
199 static void classify_dependence
PARAMS ((subscript
[], subscript
[],
200 enum complexity_type
[], int*, int));
201 static void ziv_test
PARAMS ((subscript
[], subscript
[],
202 enum direction_type
[][MAX_SUBSCRIPTS
],
203 int[][MAX_SUBSCRIPTS
], loop
*, int));
204 static void siv_test
PARAMS ((subscript
[], subscript
[],
205 enum direction_type
[][MAX_SUBSCRIPTS
],
206 int[][MAX_SUBSCRIPTS
], loop
*, int));
207 static int check_subscript_induction
PARAMS ((subscript
*, subscript
*, loop
*));
208 static void gcd_test
PARAMS ((subscript
[], subscript
[], enum
209 direction_type
[][MAX_SUBSCRIPTS
],
210 int[][MAX_SUBSCRIPTS
], loop
*, int));
211 static int find_gcd
PARAMS ((int, int));
212 static void merge_dependencies
PARAMS ((enum direction_type
[][MAX_SUBSCRIPTS
],
213 int[][MAX_SUBSCRIPTS
], int, int));
214 static void dump_array_ref
PARAMS ((tree
));
216 static void dump_one_node
PARAMS ((def_use
*, varray_type
*));
217 static void dump_node_dependence
PARAMS ((void));
219 int search_dependence
PARAMS ((tree
));
220 void remember_dest_for_dependence
PARAMS ((tree
));
221 int have_dependence_p
PARAMS ((rtx
, rtx
, enum direction_type
[], int[]));
222 void end_dependence_analysis
PARAMS ((void));
224 /* Build dependence chain 'dep_chain', which is used by have_dependence_p,
225 for the function given by EXP. */
228 init_dependence_analysis (exp
)
231 VARRAY_GENERIC_PTR_INIT (def_use_chain
, 50, "def_use_chain");
232 VARRAY_GENERIC_PTR_INIT (dep_chain
, 50, "dep_chain");
233 VARRAY_GENERIC_PTR_INIT (loop_chain
, 50, "loop_chain");
234 VARRAY_GENERIC_PTR_INIT (induction_chain
, 50, "induction_chain");
236 build_def_use (exp
, init_def_use
);
240 get_node_dependence ();
242 /* dump_node_dependence (&def_use_chain);*/
249 /* Build ARRAY_REF def/use info 'def_use_chain' starting at EXP which is a def
253 build_def_use (exp
, du_type
)
255 enum def_use_type du_type
;
257 static tree outer_loop
;
259 static tree current_loop
;
261 static loop
*loop_def
;
266 if (du_type
== init_def_use
)
274 switch (TREE_CODE (node
))
277 node
= TREE_OPERAND (node
, 0);
280 build_def_use (TREE_VALUE (node
), 0);
281 node
= TREE_CHAIN (node
);
284 node
= TREE_CHAIN (node
);
287 if (! nloop
) outer_loop
= node
;
290 loop_def
= add_loop (node
, outer_loop
, nloop
);
291 if (find_induction_variable (TREE_OPERAND (node
, 0),
292 TREE_OPERAND (node
, 1),
293 TREE_OPERAND (node
, 2), loop_def
)
295 loop_def
->status
= unnormal
;
297 build_def_use (TREE_OPERAND (node
, 3), 0);
300 node
= TREE_CHAIN (node
);
303 /* Is an induction variable modified? */
305 && TREE_CODE (TREE_OPERAND (node
, 0)) == VAR_DECL
306 && have_induction_variable
307 (loop_def
->outer_loop
,
308 IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (node
, 0)))) >= 0)
309 loop_def
->status
= unnormal
;
311 if (TREE_CODE (TREE_OPERAND (node
, 0)) == ARRAY_REF
312 || TREE_CODE (TREE_OPERAND (node
, 0)) == INDIRECT_REF
)
313 build_def_use (TREE_OPERAND (node
, 0), def
);
315 build_def_use (TREE_OPERAND (node
, 1), use
);
316 node
= TREE_CHAIN (node
);
319 if (! TREE_OPERAND (node
, 1)
320 || TREE_CODE (TREE_OPERAND (node
, 1)) != ARRAY_REF
)
325 node
= TREE_OPERAND (node
, 1);
330 char null_string
= '\0';
332 VARRAY_PUSH_GENERIC_PTR (def_use_chain
,
333 ggc_alloc (sizeof (def_use
)));
334 du_ptr
= VARRAY_GENERIC_PTR (def_use_chain
, du_idx
++);
335 du_ptr
->type
= du_type
;
336 du_ptr
->status
= unseen
;
337 du_ptr
->outer_loop
= outer_loop
;
338 du_ptr
->containing_loop
= current_loop
;
339 du_ptr
->expression
= node
;
340 du_ptr
->variable
= &null_string
;
343 for (array_ref
= node
;
344 TREE_CODE (array_ref
) == ARRAY_REF
;
345 array_ref
= TREE_OPERAND (array_ref
, 0))
348 if (TREE_CODE (array_ref
) == COMPONENT_REF
)
350 array_ref
= TREE_OPERAND (array_ref
, 1);
351 if (! (TREE_CODE (array_ref
) == FIELD_DECL
352 && TREE_CODE (TREE_TYPE (array_ref
)) == ARRAY_TYPE
))
361 && strcmp (IDENTIFIER_POINTER (DECL_NAME (array_ref
)),
362 ((def_use
*) (VARRAY_GENERIC_PTR
363 (def_use_chain
, i
)))->variable
);
369 for (tmp_duc
= ((def_use
*) (VARRAY_GENERIC_PTR (def_use_chain
, i
)));
371 tmp_duc
= ((def_use
*)tmp_duc
->next
));
372 tmp_duc
->next
= du_ptr
;
374 else du_ptr
->next
= 0;
375 du_ptr
->variable
= IDENTIFIER_POINTER (DECL_NAME (array_ref
));
382 node
= TREE_CHAIN (node
);
386 if (TREE_CODE (TREE_OPERAND (node
, 0)) == MODIFY_EXPR
)
387 build_def_use (TREE_OPERAND (node
, 0), def
);
388 node
= TREE_CHAIN (node
);
392 if (TREE_CODE_CLASS (TREE_CODE (node
)) == '2')
394 build_def_use (TREE_OPERAND (node
, 0), use
);
395 build_def_use (TREE_OPERAND (node
, 1), use
);
396 node
= TREE_CHAIN (node
);
403 /* Add a loop to 'loop_chain' corresponding to for loop LOOP_NODE at depth
404 NLOOP, whose outermost loop is OUTER_LOOP */
407 add_loop (loop_node
, outer_loop
, nloop
)
414 VARRAY_PUSH_GENERIC_PTR (loop_chain
, ggc_alloc (sizeof (loop
)));
415 loop_ptr
= VARRAY_TOP (loop_chain
, generic
);
416 loop_ptr
->outer_loop
= outer_loop
;
417 loop_ptr
->containing_loop
= loop_node
;
418 loop_ptr
->depth
= nloop
;
419 loop_ptr
->status
= normal
;
420 loop_ptr
->next_nest
= 0;
425 /* Update LOOP_DEF if for loop's COND_NODE and INCR_NODE define an index that
426 is a normalized induction variable. */
429 find_induction_variable (init_node
, cond_node
, incr_node
, loop_def
)
436 enum tree_code incr_code
;
439 if (! init_node
|| ! incr_node
|| ! cond_node
)
441 /* Allow for ',' operator in increment expression of FOR */
444 while (TREE_CODE (incr
) == COMPOUND_EXPR
)
446 incr_code
= TREE_CODE (TREE_OPERAND (incr
, 0));
447 if (incr_code
== PREDECREMENT_EXPR
|| incr_code
== POSTDECREMENT_EXPR
448 || incr_code
== PREINCREMENT_EXPR
|| incr_code
== POSTINCREMENT_EXPR
)
450 incr_node
= TREE_OPERAND (incr
, 0);
453 incr_code
= TREE_CODE (TREE_OPERAND (incr
, 1));
454 if (incr_code
== PREDECREMENT_EXPR
|| incr_code
== POSTDECREMENT_EXPR
455 || incr_code
== PREINCREMENT_EXPR
|| incr_code
== POSTINCREMENT_EXPR
)
457 incr_node
= TREE_OPERAND (incr
, 1);
460 incr
= TREE_OPERAND (incr
, 1);
463 /* Allow index condition to be part of logical expression */
464 cond_node
= TREE_VALUE (cond_node
);
467 #define INDEX_LIMIT_CHECK(NODE) \
468 (TREE_CODE_CLASS (TREE_CODE (NODE)) == '<') \
469 && (TREE_CODE (TREE_OPERAND (NODE, 0)) == VAR_DECL \
470 && (IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (NODE, 0))) \
471 == IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (incr_node, 0))))) \
474 while (TREE_CODE (incr
) == TRUTH_ANDIF_EXPR
475 || TREE_CODE (incr
) == TRUTH_ORIF_EXPR
)
477 if (INDEX_LIMIT_CHECK (TREE_OPERAND (incr
, 0)))
479 cond_node
= TREE_OPERAND (incr
, 0);
482 if (INDEX_LIMIT_CHECK (TREE_OPERAND (incr
, 1)))
484 cond_node
= TREE_OPERAND (incr
, 1);
487 incr
= TREE_OPERAND (incr
, 0);
490 incr_code
= TREE_CODE (incr_node
);
491 if ((incr_code
== PREDECREMENT_EXPR
|| incr_code
== POSTDECREMENT_EXPR
492 || incr_code
== PREINCREMENT_EXPR
|| incr_code
== POSTINCREMENT_EXPR
)
493 && TREE_CODE_CLASS (TREE_CODE (cond_node
)) == '<')
495 if (!INDEX_LIMIT_CHECK (cond_node
))
498 VARRAY_PUSH_GENERIC_PTR (induction_chain
,
499 ggc_alloc (sizeof (induction
)));
500 ind_ptr
= VARRAY_TOP (induction_chain
, generic
);
501 loop_def
->ind
= ind_ptr
;
502 ind_ptr
->variable
= IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND
504 ind_ptr
->increment
= TREE_INT_CST_LOW (TREE_OPERAND (incr_node
, 1));
505 if (TREE_CODE (incr_node
) == PREDECREMENT_EXPR
506 || TREE_CODE (incr_node
) == POSTDECREMENT_EXPR
)
507 ind_ptr
->increment
= -ind_ptr
->increment
;
509 ind_ptr
->low_bound
= get_low_bound (init_node
, ind_ptr
->variable
);
510 if (TREE_CODE (TREE_OPERAND (cond_node
, 0)) == VAR_DECL
511 && IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (cond_node
, 0)))
512 == ind_ptr
->variable
)
514 if (TREE_CODE (TREE_OPERAND (cond_node
, 1)) == INTEGER_CST
)
515 ind_ptr
->high_bound
=
516 TREE_INT_CST_LOW (TREE_OPERAND (cond_node
, 1));
518 ind_ptr
->high_bound
= ind_ptr
->increment
< 0 ? INT_MIN
: INT_MAX
;
520 else if (TREE_CODE (TREE_OPERAND (cond_node
, 1)) == VAR_DECL
521 && IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (cond_node
, 1)))
522 == ind_ptr
->variable
)
524 if (TREE_CODE (TREE_OPERAND (cond_node
, 0)) == INTEGER_CST
)
525 ind_ptr
->high_bound
=
526 TREE_INT_CST_LOW (TREE_OPERAND (cond_node
, 0));
528 ind_ptr
->high_bound
= ind_ptr
->increment
< 0 ? INT_MIN
: INT_MAX
;
536 /* Return the low bound for induction VARIABLE in NODE */
539 get_low_bound (node
, variable
)
541 const char *variable
;
544 if (TREE_CODE (node
) == SCOPE_STMT
)
545 node
= TREE_CHAIN (node
);
550 while (TREE_CODE (node
) == COMPOUND_EXPR
)
552 if (TREE_CODE (TREE_OPERAND (node
, 0)) == MODIFY_EXPR
553 && (TREE_CODE (TREE_OPERAND (node
, 0)) == VAR_DECL
554 && IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (node
, 0)))
559 if (TREE_CODE (node
) == EXPR_STMT
)
560 node
= TREE_OPERAND (node
, 0);
561 if (TREE_CODE (node
) == MODIFY_EXPR
562 && (TREE_CODE (TREE_OPERAND (node
, 0)) == VAR_DECL
563 && IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (node
, 0)))
566 return TREE_INT_CST_LOW (TREE_OPERAND (node
, 1));
572 /* Return the ordinal subscript position for IND_VAR if it is an induction
573 variable contained in OUTER_LOOP, otherwise return -1. */
576 have_induction_variable (outer_loop
, ind_var
)
582 unsigned int ind_idx
= 0;
583 unsigned int loop_idx
= 0;
585 for (loop_ptr
= VARRAY_GENERIC_PTR (loop_chain
, loop_idx
);
586 loop_ptr
&& loop_idx
< VARRAY_SIZE (loop_chain
);
587 loop_ptr
= VARRAY_GENERIC_PTR (loop_chain
, ++loop_idx
))
588 if (loop_ptr
->outer_loop
== outer_loop
)
589 for (ind_ptr
= loop_ptr
->ind
;
590 ind_ptr
&& ind_idx
< VARRAY_SIZE (induction_chain
);
591 ind_ptr
= ind_ptr
->next
)
593 if (! strcmp (ind_ptr
->variable
, ind_var
))
599 /* Chain the nodes of 'loop_chain'. */
604 unsigned int loop_idx
= 0;
605 loop
*loop_ptr
, *prev_loop_ptr
= 0;
607 prev_loop_ptr
= VARRAY_GENERIC_PTR (loop_chain
, loop_idx
);
608 for (loop_ptr
= VARRAY_GENERIC_PTR (loop_chain
, ++loop_idx
);
609 loop_ptr
&& loop_idx
< VARRAY_SIZE (loop_chain
);
610 loop_ptr
= VARRAY_GENERIC_PTR (loop_chain
, ++loop_idx
))
612 if (prev_loop_ptr
->outer_loop
== loop_ptr
->outer_loop
)
614 if (prev_loop_ptr
->depth
== loop_ptr
->depth
- 1)
615 prev_loop_ptr
->next_nest
= loop_ptr
;
616 prev_loop_ptr
= loop_ptr
;
621 /* Check the dependence for each member of 'def_use_chain'. */
624 get_node_dependence ()
630 for (du_ptr
= VARRAY_GENERIC_PTR (def_use_chain
, du_idx
);
631 du_ptr
&& du_idx
< VARRAY_SIZE (def_use_chain
);
632 du_ptr
= VARRAY_GENERIC_PTR (def_use_chain
, du_idx
++))
634 if (du_ptr
->status
== unseen
)
635 check_node_dependence (du_ptr
);
639 /* Check the dependence for definition DU. */
642 check_node_dependence (du
)
645 def_use
*def_ptr
, *use_ptr
;
646 dependence
*dep_ptr
, *dep_list
;
647 subscript icoefficients
[MAX_SUBSCRIPTS
];
648 subscript ocoefficients
[MAX_SUBSCRIPTS
];
649 loop
*loop_ptr
, *ck_loop_ptr
;
650 unsigned int loop_idx
= 0;
651 int distance
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
];
655 enum direction_type direction
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
];
656 enum complexity_type complexity
[MAX_SUBSCRIPTS
];
660 for (j
= 1 ; j
< MAX_SUBSCRIPTS
; j
++)
662 direction
[j
][0] = undef
;
666 for (def_ptr
= du
; def_ptr
; def_ptr
= def_ptr
->next
)
668 if (def_ptr
->type
!= def
)
670 subscript_count
= get_coefficients (def_ptr
, ocoefficients
);
671 if (subscript_count
< 0)
675 for (loop_ptr
= VARRAY_GENERIC_PTR (loop_chain
, loop_idx
);
676 loop_ptr
&& loop_idx
< VARRAY_SIZE (loop_chain
);
677 loop_ptr
= VARRAY_GENERIC_PTR (loop_chain
, ++loop_idx
))
679 if (loop_ptr
->outer_loop
== def_ptr
->outer_loop
)
684 for (ck_loop_ptr
= loop_ptr
;
685 ck_loop_ptr
&& loop_idx
< VARRAY_SIZE (loop_chain
);
686 ck_loop_ptr
= VARRAY_GENERIC_PTR (loop_chain
, ++loop_idx
))
688 if (ck_loop_ptr
->outer_loop
== def_ptr
->outer_loop
689 && ck_loop_ptr
->status
== unnormal
)
695 normalize_coefficients (ocoefficients
, loop_ptr
, subscript_count
);
697 for (use_ptr
= du
; use_ptr
; use_ptr
= use_ptr
->next
)
699 if (def_ptr
== use_ptr
700 || def_ptr
->outer_loop
!= use_ptr
->outer_loop
)
702 def_ptr
->status
= seen
;
703 use_ptr
->status
= seen
;
704 subscript_count
= get_coefficients (use_ptr
, icoefficients
);
705 normalize_coefficients (icoefficients
, loop_ptr
, subscript_count
);
706 classify_dependence (icoefficients
, ocoefficients
, complexity
,
707 &separability
, subscript_count
);
709 for (i
= 1, ck_loop_ptr
= loop_ptr
; ck_loop_ptr
; i
++)
711 for (j
= 1; j
<= subscript_count
; j
++)
713 direction
[i
][j
] = star
;
714 distance
[i
][j
] = INT_MAX
;
715 if (separability
&& complexity
[j
] == ziv
)
716 ziv_test (icoefficients
, ocoefficients
, direction
, distance
,
718 else if (separability
719 && (complexity
[j
] == strong_siv
720 || complexity
[j
] == weak_zero_siv
721 || complexity
[j
] == weak_crossing_siv
))
722 siv_test (icoefficients
, ocoefficients
, direction
, distance
,
725 gcd_test (icoefficients
, ocoefficients
, direction
, distance
,
727 /* ?? Add other tests: single variable exact test, banerjee */
730 ck_loop_ptr
= ck_loop_ptr
->next_nest
;
733 merge_dependencies (direction
, distance
, i
- 1, j
- 1);
736 for (j
= 1; j
<= i
- 1; j
++)
738 if (direction
[j
][0] != independent
)
741 if (! have_dependence
)
744 VARRAY_PUSH_GENERIC_PTR (dep_chain
, ggc_alloc (sizeof (dependence
)));
745 dep_ptr
= VARRAY_TOP (dep_chain
, generic
);
746 dep_ptr
->source
= use_ptr
->expression
;
747 dep_ptr
->destination
= def_ptr
->expression
;
750 if (def_ptr
< use_ptr
&& use_ptr
->type
== use
)
751 dep_ptr
->dependence
= dt_flow
;
752 else if (def_ptr
> use_ptr
&& use_ptr
->type
== use
)
753 dep_ptr
->dependence
= dt_anti
;
754 else dep_ptr
->dependence
= dt_output
;
756 for (j
= 1 ; j
<= i
- 1 ; j
++)
758 if (direction
[j
][0] == gt
)
760 dep_ptr
->dependence
= dt_anti
;
761 direction
[j
][0] = lt
;
762 distance
[j
][0] = -distance
[j
][0];
765 else if (direction
[j
][0] == lt
)
767 dep_ptr
->dependence
= dt_flow
;
771 for (j
= 1 ; j
< MAX_SUBSCRIPTS
; j
++)
773 dep_ptr
->direction
[j
] = direction
[j
][0];
774 dep_ptr
->distance
[j
] = distance
[j
][0];
777 for (dep_list
= def_ptr
->dep
;
778 dep_list
&& dep_list
->next
;
779 dep_list
= dep_list
->next
)
784 /* Dummy for rtl interface */
785 dependence
*dep_root_ptr
;
787 VARRAY_PUSH_GENERIC_PTR (dep_chain
,
788 ggc_alloc (sizeof (dependence
)));
789 dep_root_ptr
= VARRAY_TOP (dep_chain
, generic
);
790 dep_root_ptr
->source
= 0;
791 dep_root_ptr
->destination
= def_ptr
->expression
;
792 dep_root_ptr
->dependence
= dt_none
;
793 dep_root_ptr
->next
= dep_ptr
;
794 def_ptr
->dep
= dep_ptr
;
797 dep_list
->next
= dep_ptr
;
802 /* Get the COEFFICIENTS and offset for def/use DU. */
805 get_coefficients (du
, coefficients
)
807 subscript coefficients
[MAX_SUBSCRIPTS
];
815 for (array_ref
= du
->expression
;
816 TREE_CODE (array_ref
) == ARRAY_REF
;
817 array_ref
= TREE_OPERAND (array_ref
, 0))
822 for (i
= 0; i
< MAX_SUBSCRIPTS
; i
++)
824 coefficients
[i
].position
= 0;
825 coefficients
[i
].coefficient
= INT_MIN
;
826 coefficients
[i
].offset
= INT_MIN
;
827 coefficients
[i
].variable
= 0;
828 coefficients
[i
].next
= 0;
831 for (array_ref
= du
->expression
;
832 TREE_CODE (array_ref
) == ARRAY_REF
;
833 array_ref
= TREE_OPERAND (array_ref
, 0))
835 if (TREE_CODE (TREE_OPERAND (array_ref
, 1)) == INTEGER_CST
)
836 coefficients
[idx
].offset
= TREE_INT_CST_LOW (TREE_OPERAND (array_ref
, 1));
838 if (get_one_coefficient (TREE_OPERAND (array_ref
, 1),
839 &coefficients
[idx
], du
, 0) < 0)
846 /* Get the COEFFICIENTS and offset for NODE having TYPE and defined in DU. */
849 get_one_coefficient (node
, coefficients
, du
, type
)
851 subscript
*coefficients
;
853 enum tree_code
*type
;
855 enum tree_code tree_op
, tree_op_code
;
858 tree_op
= TREE_CODE (node
);
862 if (tree_op
== VAR_DECL
)
864 index
= have_induction_variable (du
->outer_loop
,
865 IDENTIFIER_POINTER (DECL_NAME (node
)));
868 coefficients
->position
= index
;
869 coefficients
->variable
= IDENTIFIER_POINTER (DECL_NAME (node
));
870 coefficients
->coefficient
= 1;
871 if (coefficients
->offset
== INT_MIN
)
872 coefficients
->offset
= 0;
876 else if (tree_op
== INTEGER_CST
)
878 return TREE_INT_CST_LOW (node
);
880 else if (tree_op
== NON_LVALUE_EXPR
)
882 return get_one_coefficient (TREE_OPERAND (node
, 0), coefficients
, du
,
885 else if (tree_op
== PLUS_EXPR
)
887 value
= get_one_coefficient (TREE_OPERAND (node
, 0), coefficients
, du
,
889 if (tree_op_code
== INTEGER_CST
)
890 coefficients
->offset
= value
;
892 value
= get_one_coefficient (TREE_OPERAND (node
, 1), coefficients
, du
,
894 if (tree_op_code
== INTEGER_CST
)
895 coefficients
->offset
= value
;
899 else if (tree_op
== MINUS_EXPR
)
901 value
= get_one_coefficient (TREE_OPERAND (node
, 0), coefficients
, du
,
903 if (tree_op_code
== INTEGER_CST
)
904 coefficients
->offset
= value
;
906 value
= get_one_coefficient (TREE_OPERAND (node
, 1), coefficients
, du
,
908 if (tree_op_code
== INTEGER_CST
)
909 coefficients
->offset
= -value
;
913 else if (tree_op
== MULT_EXPR
)
915 int value0
, value1
, value0_is_idx
= 0, value1_is_idx
= 0;
917 value0
= get_one_coefficient (TREE_OPERAND (node
, 0), coefficients
, du
,
919 if (tree_op_code
== VAR_DECL
)
922 value1
= get_one_coefficient (TREE_OPERAND (node
, 1), coefficients
, du
,
924 if (tree_op_code
== VAR_DECL
)
928 coefficients
->coefficient
= value1
;
929 else if (value1_is_idx
)
930 coefficients
->coefficient
= value0
;
935 /* Adjust the COEFFICIENTS as if loop LOOP_PTR were normalized to start at 0. */
938 normalize_coefficients (coefficients
, loop_ptr
, count
)
939 subscript coefficients
[MAX_SUBSCRIPTS
];
947 for (i
= 1; i
<= count
; i
++)
949 for (ck_loop_ptr
= loop_ptr
; ck_loop_ptr
;
950 ck_loop_ptr
= ck_loop_ptr
->next_nest
)
951 for (ind_ptr
= ck_loop_ptr
->ind
; ind_ptr
; ind_ptr
= ind_ptr
->next
)
953 if (coefficients
[i
].variable
== ind_ptr
->variable
)
955 if (ind_ptr
->low_bound
< ind_ptr
->high_bound
)
956 coefficients
[i
].offset
+= coefficients
[i
].coefficient
957 * ind_ptr
->low_bound
;
958 else if (ind_ptr
->high_bound
!= INT_MIN
)
960 coefficients
[i
].offset
= coefficients
[i
].coefficient
961 * ind_ptr
->high_bound
;
962 coefficients
[i
].coefficient
= coefficients
[i
].coefficient
971 /* Determine the COMPLEXITY and SEPARABILITY for COUNT subscripts of
972 inputs ICOEFFICIENTS and outputs OCOEFFICIENTS */
975 classify_dependence (icoefficients
, ocoefficients
, complexity
, separability
,
977 subscript icoefficients
[MAX_SUBSCRIPTS
];
978 subscript ocoefficients
[MAX_SUBSCRIPTS
];
979 enum complexity_type complexity
[MAX_SUBSCRIPTS
];
983 const char *iiv_used
[MAX_SUBSCRIPTS
];
984 const char *oiv_used
[MAX_SUBSCRIPTS
];
985 int ocoeff
[MAX_SUBSCRIPTS
];
986 int icoeff
[MAX_SUBSCRIPTS
];
989 memset (iiv_used
, 0, sizeof (tree
) * MAX_SUBSCRIPTS
);
990 memset (oiv_used
, 0, sizeof (tree
) * MAX_SUBSCRIPTS
);
991 memset (icoeff
, 0, sizeof (int) * MAX_SUBSCRIPTS
);
992 memset (ocoeff
, 0, sizeof (int) * MAX_SUBSCRIPTS
);
993 for (idx
= 1; idx
<= count
; idx
++)
995 if (icoefficients
[idx
].variable
!= 0)
999 iiv_used
[idx
] = icoefficients
[idx
].variable
;
1000 icoeff
[idx
] = icoefficients
[idx
].coefficient
;
1003 if (ocoefficients
[idx
].variable
!= 0)
1005 if (! oiv_used
[idx
])
1007 oiv_used
[idx
] = ocoefficients
[idx
].variable
;
1008 ocoeff
[idx
] = ocoefficients
[idx
].coefficient
;
1013 for (idx
= 1; idx
<= count
; idx
++)
1015 if (iiv_used
[idx
] == 0 && oiv_used
[idx
] == 0)
1016 complexity
[idx
] = ziv
;
1017 else if (iiv_used
[idx
] == oiv_used
[idx
])
1019 if (icoeff
[idx
] == ocoeff
[idx
])
1020 complexity
[idx
] = strong_siv
;
1021 else if (icoeff
[idx
] == -1 * ocoeff
[idx
])
1022 complexity
[idx
] = weak_crossing_siv
;
1024 complexity
[idx
] = weak_siv
;
1026 else if (icoeff
[idx
] == 0 || ocoeff
[idx
] == 0)
1027 complexity
[idx
] = weak_zero_siv
;
1028 else complexity
[idx
] = miv
;
1032 for (idx
= 1; idx
<= count
; idx
++)
1034 for (cidx
= 1; cidx
<= count
; cidx
++)
1037 && iiv_used
[idx
] && oiv_used
[cidx
]
1038 && iiv_used
[idx
] == oiv_used
[cidx
])
1044 /* Determine the DIRECTION and DISTANCE dependency for subscript SUB of
1045 inputs ICOEFFICIENTS and outputs OCOEFFICIENTS of loop LOOP_PTR using
1046 the zero induction variable test */
1049 ziv_test (icoefficients
, ocoefficients
, direction
, distance
, loop_ptr
, sub
)
1050 subscript icoefficients
[MAX_SUBSCRIPTS
];
1051 subscript ocoefficients
[MAX_SUBSCRIPTS
];
1052 enum direction_type direction
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
];
1053 int distance
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
] ATTRIBUTE_UNUSED
;
1057 if (ocoefficients
[sub
].offset
!=
1058 icoefficients
[sub
].offset
)
1059 direction
[loop_ptr
->depth
][sub
] = independent
;
1062 /* Determine the DIRECTION and DISTANCE dependency for subscript SUB of
1063 inputs ICOEFFICIENTS and outputs OCOEFFICIENTS of loop LOOP_PTR using
1064 the single induction variable test */
1067 siv_test (icoefficients
, ocoefficients
, direction
, distance
, loop_ptr
, sub
)
1068 subscript icoefficients
[MAX_SUBSCRIPTS
];
1069 subscript ocoefficients
[MAX_SUBSCRIPTS
];
1070 enum direction_type direction
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
];
1071 int distance
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
];
1079 if (! check_subscript_induction (&icoefficients
[sub
], &ocoefficients
[sub
],
1083 coef_diff
= icoefficients
[sub
].offset
- ocoefficients
[sub
].offset
;
1084 /* strong_siv requires equal coefficients. weak_crossing_siv requires
1085 coefficients to have equal absolute value. weak_zero_siv uses the
1086 nonzero coefficient. */
1088 if (ocoefficients
[sub
].coefficient
== INT_MIN
)
1089 coef
= icoefficients
[sub
].coefficient
;
1090 else if (icoefficients
[sub
].coefficient
== INT_MIN
)
1091 coef
= ocoefficients
[sub
].coefficient
;
1092 else if (ocoefficients
[sub
].coefficient
==
1093 -1 * icoefficients
[sub
].coefficient
)
1094 coef
= 2 * abs (ocoefficients
[sub
].coefficient
);
1096 coef
= icoefficients
[sub
].coefficient
;
1098 gcd
= -coef_diff
/ coef
;
1099 if (gcd
* coef
!= -coef_diff
)
1101 direction
[loop_ptr
->depth
][sub
] = independent
;
1105 distance
[loop_ptr
->depth
][sub
] = gcd
;
1107 direction
[loop_ptr
->depth
][sub
] = gt
;
1109 direction
[loop_ptr
->depth
][sub
] = lt
;
1111 direction
[loop_ptr
->depth
][sub
] = eq
;
1115 /* Return 1 if an induction variable of LOOP_PTR is used by either
1116 input ICOEFFICIENT or output OCOEFFICIENT */
1119 check_subscript_induction (icoefficient
, ocoefficient
, loop_ptr
)
1120 subscript
*icoefficient
;
1121 subscript
*ocoefficient
;
1125 int sub_ind_input
= 0;
1126 int sub_ind_output
= 0;
1128 for (ind_ptr
= loop_ptr
->ind
; ind_ptr
; ind_ptr
= ind_ptr
->next
)
1130 if (icoefficient
->variable
== ind_ptr
->variable
)
1132 if (ocoefficient
->variable
== ind_ptr
->variable
)
1135 if (sub_ind_input
|| sub_ind_output
)
1141 #define abs(N) ((N) < 0 ? -(N) : (N))
1143 /* Determine the DIRECTION and DISTANCE dependency for subscript SUB of
1144 inputs ICOEFFICIENTS and outputs OCOEFFICIENTS of loop LOOP_PTR using
1145 the greatest common denominator test */
1148 gcd_test (icoefficients
, ocoefficients
, direction
, distance
, loop_ptr
, sub
)
1149 subscript icoefficients
[MAX_SUBSCRIPTS
];
1150 subscript ocoefficients
[MAX_SUBSCRIPTS
];
1151 enum direction_type direction
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
];
1152 int distance
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
] ATTRIBUTE_UNUSED
;
1159 if (! check_subscript_induction (&icoefficients
[sub
], &ocoefficients
[sub
],
1163 g
= find_gcd (icoefficients
[sub
].coefficient
,
1164 ocoefficients
[sub
].coefficient
);
1167 coef_diff
= icoefficients
[sub
].offset
- ocoefficients
[sub
].offset
;
1169 if (gg
* g
!= coef_diff
)
1171 direction
[loop_ptr
->depth
][sub
] = independent
;
1174 /* ?? gcd does not yield direction and distance. Wolfe's direction
1175 vector hierarchy can be used to give this. */
1178 /* Find the gcd of X and Y using Euclid's algorithm */
1210 /* Merge SUBSCRIPT_COUNT DIRECTIONs and DISTANCEs for LOOP_COUNT loops.
1211 We use a predefined array to handle the direction merge.
1212 The distance merge makes use of the fact that distances default to
1213 INT_MAX. Distances are '&' together. Watch out for a negative distance.
1217 merge_dependencies (direction
, distance
, loop_count
, subscript_count
)
1218 enum direction_type direction
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
];
1219 int distance
[MAX_SUBSCRIPTS
][MAX_SUBSCRIPTS
];
1221 int subscript_count
;
1226 static const enum direction_type direction_merge
[8][8] =
1227 {{lt
, le
, le
, star
, star
, lt
, independent
, lt
},
1228 {le
, le
, le
, star
, star
, le
, independent
, le
},
1229 {le
, le
, eq
, ge
, ge
, eq
, independent
, eq
},
1230 {star
, star
, ge
, gt
, ge
, gt
, independent
, ge
},
1231 {star
, star
, ge
, ge
, ge
, ge
, independent
, ge
},
1232 {lt
, le
, eq
, gt
, ge
, star
, independent
, star
},
1233 {independent
, independent
, independent
, independent
, independent
},
1234 {independent
, independent
, independent
}
1237 for (i
= 1; i
<= loop_count
; i
++)
1239 distance
[i
][0] = INT_MAX
;
1240 direction
[i
][0] = star
;
1242 for (j
= 1; j
<= subscript_count
; j
++)
1244 if (distance
[i
][j
] < 0)
1246 distance
[i
][0] = distance
[i
][0] & abs (distance
[i
][j
]);
1250 distance
[i
][0] = distance
[i
][0] & distance
[i
][j
];
1251 direction
[i
][0] = direction_merge
[(int)direction
[i
][0]]
1252 [(int)direction
[i
][j
]];
1254 distance
[i
][0] = sign
* distance
[i
][0];
1258 /* Dump ARRAY_REF NODE. */
1261 dump_array_ref (node
)
1264 enum tree_code tree_op
= TREE_CODE (node
);
1266 if (tree_op
== VAR_DECL
)
1268 printf ("%s", IDENTIFIER_POINTER (DECL_NAME (node
)));
1270 else if (tree_op
== INTEGER_CST
)
1272 printf ("%d", (int)TREE_INT_CST_LOW (node
));
1274 else if (tree_op
== PLUS_EXPR
)
1276 dump_array_ref (TREE_OPERAND (node
, 0));
1278 dump_array_ref (TREE_OPERAND (node
, 1));
1280 else if (tree_op
== MINUS_EXPR
)
1282 dump_array_ref (TREE_OPERAND (node
, 0));
1284 dump_array_ref (TREE_OPERAND (node
, 1));
1286 else if (tree_op
== MULT_EXPR
)
1288 dump_array_ref (TREE_OPERAND (node
, 0));
1290 dump_array_ref (TREE_OPERAND (node
, 1));
1294 /* Dump def/use DU. */
1298 dump_one_node (du
, seen
)
1303 dependence
*dep_ptr
;
1306 for (du_ptr
= du
; du_ptr
; du_ptr
= du_ptr
->next
)
1308 printf ("%s ", du_ptr
->variable
);
1309 for (array_ref
= du_ptr
->expression
;
1310 TREE_CODE (array_ref
) == ARRAY_REF
;
1311 array_ref
= TREE_OPERAND (array_ref
, 0))
1314 dump_array_ref (TREE_OPERAND (array_ref
, 1));
1318 printf (" Outer Loop %x Containing Loop %x Expression %x %s\n",
1319 (int)du_ptr
->outer_loop
,
1320 (int)du_ptr
->containing_loop
,
1321 (int)du_ptr
->expression
, du_ptr
->type
== def
? "Def" : "Use");
1322 VARRAY_PUSH_GENERIC_PTR (*seen
, du_ptr
);
1324 for (dep_ptr
= du_ptr
->dep
; dep_ptr
; dep_ptr
= dep_ptr
->next
)
1327 printf ("%s Dependence with %x ",
1328 dependence_string
[(int)dep_ptr
->dependence
],
1329 (int)dep_ptr
->source
);
1330 printf ("Dir/Dist ");
1331 for (i
= 1 ; i
< MAX_SUBSCRIPTS
; i
++)
1332 if (dep_ptr
->direction
[i
] != undef
)
1333 printf ("[%d] %s/%d ", i
,
1334 direction_string
[(int)dep_ptr
->direction
[i
]],
1335 dep_ptr
->distance
[i
]);
1341 /* Dump dependence info. */
1344 dump_node_dependence (void)
1347 unsigned int du_idx
, seen_idx
, i
;
1350 VARRAY_GENERIC_PTR_INIT (seen
, 20, "seen");
1353 for (du_ptr
= VARRAY_GENERIC_PTR (def_use_chain
, du_idx
);
1354 du_idx
< VARRAY_SIZE (def_use_chain
);
1355 du_ptr
= VARRAY_GENERIC_PTR (def_use_chain
, du_idx
++))
1357 for (i
= 0; i
< VARRAY_SIZE (seen
) && VARRAY_GENERIC_PTR (seen
, i
)
1359 if (i
>= VARRAY_SIZE (seen
))
1360 dump_one_node (du_ptr
, &seen
);
1365 /* Return the index into 'dep_chain' if there is a dependency for destination
1366 dest_to_remember (set by remember_dest_for_dependence) and source node.
1367 Called by the front end, which adds the index onto a MEM rtx. */
1370 search_dependence (node
)
1373 dependence
*dep_ptr
;
1379 if (TREE_CODE (node
) == INDIRECT_REF
&& TREE_OPERAND (node
, 1)
1380 && TREE_CODE (TREE_OPERAND (node
, 1)) == ARRAY_REF
)
1381 node
= TREE_OPERAND (node
, 1);
1383 for (dep_ptr
= VARRAY_GENERIC_PTR (dep_chain
, 0);
1384 dep_ptr
; dep_ptr
= VARRAY_GENERIC_PTR (dep_chain
, dep_idx
++))
1386 if ((node
== dep_ptr
->source
1387 && dest_to_remember
== dep_ptr
->destination
)
1388 || (! dep_ptr
->source
&& node
== dep_ptr
->destination
))
1396 /* Remember a destination NODE for search_dependence. */
1399 remember_dest_for_dependence (node
)
1404 if (TREE_CODE (node
) == INDIRECT_REF
&& TREE_OPERAND (node
, 1)
1405 && TREE_CODE (TREE_OPERAND (node
, 1)) == ARRAY_REF
)
1406 node
= TREE_OPERAND (node
, 1);
1407 dest_to_remember
= node
;
1411 #ifndef MEM_DEPENDENCY
1412 #define MEM_DEPENDENCY(RTX) XCWINT (RTX, 2, MEM)
1415 /* Return 1 along with the dependence DIRECTION and DISTANCE if there is a
1416 dependence from dest_rtx to src_rtx. */
1419 have_dependence_p (dest_rtx
, src_rtx
, direction
, distance
)
1422 enum direction_type direction
[MAX_SUBSCRIPTS
];
1423 int distance
[MAX_SUBSCRIPTS
];
1425 int dest_idx
= 0, src_idx
= 0;
1427 dependence
*dep_ptr
;
1429 if (GET_CODE (SET_DEST (PATTERN (dest_rtx
))) == MEM
)
1431 dest
= SET_DEST (PATTERN (dest_rtx
));
1432 dest_idx
= MEM_DEPENDENCY (dest
) - 1;
1434 if (GET_CODE (SET_SRC (PATTERN (src_rtx
))) == MEM
)
1436 src
= SET_SRC (PATTERN (src_rtx
));
1437 src_idx
= MEM_DEPENDENCY (src
) - 1;
1439 if (dest_idx
>= 0 || src_idx
>= 0)
1442 for (dep_ptr
= VARRAY_GENERIC_PTR (dep_chain
, -dest_idx
);
1443 dep_ptr
; dep_ptr
= dep_ptr
->next
)
1445 if (dep_ptr
== VARRAY_GENERIC_PTR (dep_chain
, -src_idx
))
1447 direction
= (enum direction_type
*) &dep_ptr
->direction
;
1448 distance
= (int*) &dep_ptr
->distance
;
1455 /* Cleanup when dependency analysis is complete. */
1458 end_dependence_analysis ()
1463 #include "gt-dependence.h"