Makefile.in (tree-ssa-loop-niter.o): Depends on tree-data-ref.h.
2004-10-11 Sebastian Pop <pop@cri.ensmp.fr> * Makefile.in (tree-ssa-loop-niter.o): Depends on tree-data-ref.h. * cfgloop.c (initialize_loops_parallel_p): New. (flow_loops_find): Initialize the parallel_p field to true for all the loops. * tree-ssa-loop-niter.c: Include "tree-data-ref.h". (estimate_numbers_of_iterations_loop): Infers the loop bounds from the size of the data accessed in the loop. (struct nb_iter_bound): Moved... * cfgloop.h (struct nb_iter_bound): ... here. (estimated_nb_iterations, parallel_p): New fields in struct loop. (record_estimate): Declare extern here. * tree-chrec.c: Fix comments. (nb_vars_in_chrec): New function. * tree-chrec.h (nb_vars_in_chrec): Declared here. * tree-data-ref.c: Don't include lambda.h, that is already included in tree-data-ref.h. (tree_fold_divides_p): Don't check for integer_onep. (tree_fold_bezout): Removed. (gcd): New static duplicated function. (int_divides_p, dump_subscript): New. (dump_data_dependence_relation): Use dump_subscript. (dump_dist_dir_vectors, dump_ddrs, compute_estimated_nb_iterations, estimate_niter_from_size_of_data): New. (analyze_array_indexes, analyze_array): Call estimate_niter_from_size_of_data during the detection of array references. Pass in a pointer to the statement that contains the array reference. (all_chrecs_equal_p): New. (compute_distance_vector): Renamed compute_subscript_distance. Deal with multivariate conflict functions. (initialize_data_dependence_relation): Initialize DDR_AFFINE_P, DDR_SIZE_VECT, DDR_DIST_VECT, and DDR_DIR_VECT. (non_affine_dependence_relation): New. (analyze_ziv_subscript, analyze_siv_subscript_cst_affine, analyze_siv_subscript, analyze_miv_subscript, analyze_overlapping_iterations, subscript_dependence_tester): Initialize and return last_conflicts function. (initialize_matrix_A, FLOOR, compute_overlap_steps_for_affine_univar, compute_overlap_steps_for_affine_1_2): New. (analyze_siv_subscript_affine_cst): Removed. (analyze_subscript_affine_affine): Disprove dependences based on the iteration domains. Solve the univariate dependence case as before, but use lambda_matrix_right_hermite instead of tree_fold_bezout. Implement the multivariate case of 2 versus 1 variables. (build_classic_dist_vector, build_classic_dir_vector): Implement some unhandled cases. (find_data_references_in_loop): Compute and initialize loop->estimated_nb_iterations and loop->parallel_p. (analyze_all_data_dependences): Modify the debug dump order. * tree-data-ref.h (SUB_LAST_CONFLICT_IN_A, SUB_LAST_CONFLICT_IN_B, subscript->last_conflict_in_a, subscript->last_conflict_in_b): Removed. (SUB_LAST_CONFLICT, subscript->last_conflict, data_dependence_relation->affine_p, data_dependence_relation->size_vect, DDR_AFFINE_P, DDR_SIZE_VECT): New. (find_data_references_in_loop, initialize_data_dependence_relation, dump_subscript, dump_ddrs, dump_dist_dir_vectors): Declared here. From-SVN: r88965
This commit is contained in:
parent
06c3418c6c
commit
86df10e35e
9 changed files with 1035 additions and 457 deletions
|
@ -1,3 +1,62 @@
|
|||
2004-10-11 Sebastian Pop <pop@cri.ensmp.fr>
|
||||
|
||||
* Makefile.in (tree-ssa-loop-niter.o): Depends on tree-data-ref.h.
|
||||
* cfgloop.c (initialize_loops_parallel_p): New.
|
||||
(flow_loops_find): Initialize the parallel_p field to true for all
|
||||
the loops.
|
||||
* tree-ssa-loop-niter.c: Include "tree-data-ref.h".
|
||||
(estimate_numbers_of_iterations_loop): Infers the loop bounds from
|
||||
the size of the data accessed in the loop.
|
||||
(struct nb_iter_bound): Moved...
|
||||
* cfgloop.h (struct nb_iter_bound): ... here.
|
||||
(estimated_nb_iterations, parallel_p): New fields in struct loop.
|
||||
(record_estimate): Declare extern here.
|
||||
* tree-chrec.c: Fix comments.
|
||||
(nb_vars_in_chrec): New function.
|
||||
* tree-chrec.h (nb_vars_in_chrec): Declared here.
|
||||
* tree-data-ref.c: Don't include lambda.h, that is already included
|
||||
in tree-data-ref.h.
|
||||
(tree_fold_divides_p): Don't check for integer_onep.
|
||||
(tree_fold_bezout): Removed.
|
||||
(gcd): New static duplicated function.
|
||||
(int_divides_p, dump_subscript): New.
|
||||
(dump_data_dependence_relation): Use dump_subscript.
|
||||
(dump_dist_dir_vectors, dump_ddrs, compute_estimated_nb_iterations,
|
||||
estimate_niter_from_size_of_data): New.
|
||||
(analyze_array_indexes, analyze_array): Call
|
||||
estimate_niter_from_size_of_data during the detection of array
|
||||
references. Pass in a pointer to the statement that contains the
|
||||
array reference.
|
||||
(all_chrecs_equal_p): New.
|
||||
(compute_distance_vector): Renamed compute_subscript_distance.
|
||||
Deal with multivariate conflict functions.
|
||||
(initialize_data_dependence_relation): Initialize DDR_AFFINE_P,
|
||||
DDR_SIZE_VECT, DDR_DIST_VECT, and DDR_DIR_VECT.
|
||||
(non_affine_dependence_relation): New.
|
||||
(analyze_ziv_subscript, analyze_siv_subscript_cst_affine,
|
||||
analyze_siv_subscript, analyze_miv_subscript,
|
||||
analyze_overlapping_iterations, subscript_dependence_tester):
|
||||
Initialize and return last_conflicts function.
|
||||
(initialize_matrix_A, FLOOR, compute_overlap_steps_for_affine_univar,
|
||||
compute_overlap_steps_for_affine_1_2): New.
|
||||
(analyze_siv_subscript_affine_cst): Removed.
|
||||
(analyze_subscript_affine_affine): Disprove dependences based on the
|
||||
iteration domains. Solve the univariate dependence case as before,
|
||||
but use lambda_matrix_right_hermite instead of tree_fold_bezout.
|
||||
Implement the multivariate case of 2 versus 1 variables.
|
||||
(build_classic_dist_vector, build_classic_dir_vector): Implement some
|
||||
unhandled cases.
|
||||
(find_data_references_in_loop): Compute and initialize
|
||||
loop->estimated_nb_iterations and loop->parallel_p.
|
||||
(analyze_all_data_dependences): Modify the debug dump order.
|
||||
* tree-data-ref.h (SUB_LAST_CONFLICT_IN_A, SUB_LAST_CONFLICT_IN_B,
|
||||
subscript->last_conflict_in_a, subscript->last_conflict_in_b): Removed.
|
||||
(SUB_LAST_CONFLICT, subscript->last_conflict,
|
||||
data_dependence_relation->affine_p, data_dependence_relation->size_vect,
|
||||
DDR_AFFINE_P, DDR_SIZE_VECT): New.
|
||||
(find_data_references_in_loop, initialize_data_dependence_relation,
|
||||
dump_subscript, dump_ddrs, dump_dist_dir_vectors): Declared here.
|
||||
|
||||
2004-10-12 Kelley Cook <kcook@gcc.gnu.org>
|
||||
|
||||
* configure: Regenerate.
|
||||
|
|
|
@ -1706,7 +1706,7 @@ tree-ssa-loop-unswitch.o : tree-ssa-loop-unswitch.c $(TREE_FLOW_H) $(CONFIG_H) \
|
|||
tree-ssa-loop-niter.o : tree-ssa-loop-niter.c $(TREE_FLOW_H) $(CONFIG_H) \
|
||||
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) cfgloop.h $(PARAMS_H) tree-inline.h \
|
||||
output.h diagnostic.h $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H) \
|
||||
tree-pass.h $(SCEV_H)
|
||||
tree-pass.h $(SCEV_H) tree-data-ref.h
|
||||
tree-ssa-loop-ivcanon.o : tree-ssa-loop-ivcanon.c $(TREE_FLOW_H) $(CONFIG_H) \
|
||||
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) tree-inline.h \
|
||||
output.h diagnostic.h $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H) \
|
||||
|
|
|
@ -780,6 +780,20 @@ canonicalize_loop_headers (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Initialize all the parallel_p fields of the loops structure to true. */
|
||||
|
||||
static void
|
||||
initialize_loops_parallel_p (struct loops *loops)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < loops->num; i++)
|
||||
{
|
||||
struct loop *loop = loops->parray[i];
|
||||
loop->parallel_p = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find all the natural loops in the function and save in LOOPS structure and
|
||||
recalculate loop_depth information in basic block structures. FLAGS
|
||||
controls which loop information is collected. Return the number of natural
|
||||
|
@ -945,6 +959,7 @@ flow_loops_find (struct loops *loops, int flags)
|
|||
flow_loop_scan (loops->parray[i], flags);
|
||||
|
||||
loops->num = num_loops;
|
||||
initialize_loops_parallel_p (loops);
|
||||
}
|
||||
|
||||
sbitmap_free (headers);
|
||||
|
|
|
@ -43,6 +43,20 @@ struct lpt_decision
|
|||
unsigned times;
|
||||
};
|
||||
|
||||
/* The structure describing a bound on number of iterations of a loop. */
|
||||
|
||||
struct nb_iter_bound
|
||||
{
|
||||
tree bound; /* The expression whose value is an upper bound on the
|
||||
number of executions of anything after ... */
|
||||
tree at_stmt; /* ... this statement during one execution of loop. */
|
||||
tree additional; /* A conjunction of conditions the operands of BOUND
|
||||
satisfy. The additional information about the value
|
||||
of the bound may be derived from it. */
|
||||
struct nb_iter_bound *next;
|
||||
/* The next bound in a list. */
|
||||
};
|
||||
|
||||
/* Structure to hold information for each natural loop. */
|
||||
struct loop
|
||||
{
|
||||
|
@ -173,12 +187,22 @@ struct loop
|
|||
information in this field. */
|
||||
tree nb_iterations;
|
||||
|
||||
/* An INTEGER_CST estimation of the number of iterations. NULL_TREE
|
||||
if there is no estimation. */
|
||||
tree estimated_nb_iterations;
|
||||
|
||||
/* Upper bound on number of iterations of a loop. */
|
||||
struct nb_iter_bound *bounds;
|
||||
|
||||
/* If not NULL, loop has just single exit edge stored here (edges to the
|
||||
EXIT_BLOCK_PTR do not count. */
|
||||
edge single_exit;
|
||||
|
||||
/* True when the loop does not carry data dependences, and
|
||||
consequently the iterations can be executed in any order. False
|
||||
when the loop carries data dependences, or when the property is
|
||||
not decidable. */
|
||||
bool parallel_p;
|
||||
};
|
||||
|
||||
/* Flags for state of loop structure. */
|
||||
|
@ -462,6 +486,7 @@ enum
|
|||
extern void unroll_and_peel_loops (struct loops *, int);
|
||||
extern void doloop_optimize_loops (struct loops *);
|
||||
extern void move_loop_invariants (struct loops *);
|
||||
extern void record_estimate (struct loop *, tree, tree, tree);
|
||||
|
||||
/* Old loop optimizer interface. */
|
||||
|
||||
|
|
|
@ -636,7 +636,7 @@ chrec_component_in_loop_num (tree chrec,
|
|||
}
|
||||
|
||||
/* Returns the evolution part in LOOP_NUM. Example: the call
|
||||
evolution_part_in_loop_num (1, {{0, +, 1}_1, +, 2}_1) returns
|
||||
evolution_part_in_loop_num ({{0, +, 1}_1, +, 2}_1, 1) returns
|
||||
{1, +, 2}_1 */
|
||||
|
||||
tree
|
||||
|
@ -647,7 +647,7 @@ evolution_part_in_loop_num (tree chrec,
|
|||
}
|
||||
|
||||
/* Returns the initial condition in LOOP_NUM. Example: the call
|
||||
initial_condition_in_loop_num ({{0, +, 1}_1, +, 2}_2, 1) returns
|
||||
initial_condition_in_loop_num ({{0, +, 1}_1, +, 2}_2, 2) returns
|
||||
{0, +, 1}_1 */
|
||||
|
||||
tree
|
||||
|
@ -932,6 +932,26 @@ evolution_function_is_univariate_p (tree chrec)
|
|||
}
|
||||
}
|
||||
|
||||
/* Returns the number of variables of CHREC. Example: the call
|
||||
nb_vars_in_chrec ({{0, +, 1}_5, +, 2}_6) returns 2. */
|
||||
|
||||
unsigned
|
||||
nb_vars_in_chrec (tree chrec)
|
||||
{
|
||||
if (chrec == NULL_TREE)
|
||||
return 0;
|
||||
|
||||
switch (TREE_CODE (chrec))
|
||||
{
|
||||
case POLYNOMIAL_CHREC:
|
||||
return 1 + nb_vars_in_chrec
|
||||
(initial_condition_in_loop_num (chrec, CHREC_VARIABLE (chrec)));
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Convert the initial condition of chrec to type. */
|
||||
|
|
|
@ -91,6 +91,7 @@ extern bool chrec_contains_undetermined (tree);
|
|||
extern bool tree_contains_chrecs (tree);
|
||||
extern bool evolution_function_is_affine_multivariate_p (tree);
|
||||
extern bool evolution_function_is_univariate_p (tree);
|
||||
extern unsigned nb_vars_in_chrec (tree);
|
||||
|
||||
|
||||
|
||||
|
|
1311
gcc/tree-data-ref.c
1311
gcc/tree-data-ref.c
File diff suppressed because it is too large
Load diff
|
@ -79,10 +79,9 @@ struct subscript
|
|||
tree conflicting_iterations_in_a;
|
||||
tree conflicting_iterations_in_b;
|
||||
|
||||
/* These fields store the information about the iteration domain
|
||||
/* This field stores the information about the iteration domain
|
||||
validity of the dependence relation. */
|
||||
tree last_conflict_in_a;
|
||||
tree last_conflict_in_b;
|
||||
tree last_conflict;
|
||||
|
||||
/* Distance from the iteration that access a conflicting element in
|
||||
A to the iteration that access this same conflicting element in
|
||||
|
@ -93,8 +92,7 @@ struct subscript
|
|||
|
||||
#define SUB_CONFLICTS_IN_A(SUB) SUB->conflicting_iterations_in_a
|
||||
#define SUB_CONFLICTS_IN_B(SUB) SUB->conflicting_iterations_in_b
|
||||
#define SUB_LAST_CONFLICT_IN_A(SUB) SUB->last_conflict_in_a
|
||||
#define SUB_LAST_CONFLICT_IN_B(SUB) SUB->last_conflict_in_b
|
||||
#define SUB_LAST_CONFLICT(SUB) SUB->last_conflict
|
||||
#define SUB_DISTANCE(SUB) SUB->distance
|
||||
|
||||
/* A data_dependence_relation represents a relation between two
|
||||
|
@ -106,6 +104,10 @@ struct data_dependence_relation
|
|||
struct data_reference *a;
|
||||
struct data_reference *b;
|
||||
|
||||
/* When the dependence relation is affine, it can be represented by
|
||||
a distance vector. */
|
||||
bool affine_p;
|
||||
|
||||
/* A "yes/no/maybe" field for the dependence relation:
|
||||
|
||||
- when "ARE_DEPENDENT == NULL_TREE", there exist a dependence
|
||||
|
@ -124,6 +126,9 @@ struct data_dependence_relation
|
|||
the data_dependence_relation. */
|
||||
varray_type subscripts;
|
||||
|
||||
/* The size of the direction/distance vectors. */
|
||||
int size_vect;
|
||||
|
||||
/* The classic direction vector. */
|
||||
lambda_vector dir_vect;
|
||||
|
||||
|
@ -133,26 +138,32 @@ struct data_dependence_relation
|
|||
|
||||
#define DDR_A(DDR) DDR->a
|
||||
#define DDR_B(DDR) DDR->b
|
||||
#define DDR_AFFINE_P(DDR) DDR->affine_p
|
||||
#define DDR_ARE_DEPENDENT(DDR) DDR->are_dependent
|
||||
#define DDR_SUBSCRIPTS(DDR) DDR->subscripts
|
||||
#define DDR_SUBSCRIPTS_VECTOR_INIT(DDR, N) \
|
||||
VARRAY_GENERIC_PTR_INIT (DDR_SUBSCRIPTS (DDR), N, "subscripts_vector");
|
||||
#define DDR_SUBSCRIPT(DDR, I) VARRAY_GENERIC_PTR (DDR_SUBSCRIPTS (DDR), I)
|
||||
#define DDR_NUM_SUBSCRIPTS(DDR) VARRAY_ACTIVE_SIZE (DDR_SUBSCRIPTS (DDR))
|
||||
#define DDR_SIZE_VECT(DDR) DDR->size_vect
|
||||
#define DDR_DIR_VECT(DDR) DDR->dir_vect
|
||||
#define DDR_DIST_VECT(DDR) DDR->dist_vect
|
||||
|
||||
|
||||
|
||||
struct data_dependence_relation *initialize_data_dependence_relation
|
||||
extern tree find_data_references_in_loop (struct loop *, varray_type *);
|
||||
extern struct data_dependence_relation *initialize_data_dependence_relation
|
||||
(struct data_reference *, struct data_reference *);
|
||||
void compute_affine_dependence (struct data_dependence_relation *);
|
||||
extern void compute_affine_dependence (struct data_dependence_relation *);
|
||||
extern void analyze_all_data_dependences (struct loops *);
|
||||
extern void compute_data_dependences_for_loop (unsigned, struct loop *,
|
||||
varray_type *, varray_type *);
|
||||
extern struct data_reference * init_data_ref (tree, tree, tree, tree, bool);
|
||||
extern struct data_reference *analyze_array (tree, tree, bool);
|
||||
|
||||
extern void dump_subscript (FILE *, struct subscript *);
|
||||
extern void dump_ddrs (FILE *, varray_type);
|
||||
extern void dump_dist_dir_vectors (FILE *, varray_type);
|
||||
extern void dump_data_reference (FILE *, struct data_reference *);
|
||||
extern void dump_data_references (FILE *, varray_type);
|
||||
extern void dump_data_dependence_relation (FILE *,
|
||||
|
@ -161,11 +172,12 @@ extern void dump_data_dependence_relations (FILE *, varray_type);
|
|||
extern void dump_data_dependence_direction (FILE *,
|
||||
enum data_dependence_direction);
|
||||
extern bool array_base_name_differ_p (struct data_reference *,
|
||||
struct data_reference *, bool *p);
|
||||
struct data_reference *, bool *);
|
||||
extern void free_dependence_relation (struct data_dependence_relation *);
|
||||
extern void free_dependence_relations (varray_type);
|
||||
extern void free_data_refs (varray_type);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* GCC_TREE_DATA_REF_H */
|
||||
|
|
|
@ -36,6 +36,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "ggc.h"
|
||||
#include "tree-chrec.h"
|
||||
#include "tree-scalar-evolution.h"
|
||||
#include "tree-data-ref.h"
|
||||
#include "params.h"
|
||||
#include "flags.h"
|
||||
#include "tree-inline.h"
|
||||
|
@ -943,24 +944,10 @@ find_loop_niter_by_eval (struct loop *loop, edge *exit)
|
|||
|
||||
*/
|
||||
|
||||
/* The structure describing a bound on number of iterations of a loop. */
|
||||
|
||||
struct nb_iter_bound
|
||||
{
|
||||
tree bound; /* The expression whose value is an upper bound on the
|
||||
number of executions of anything after ... */
|
||||
tree at_stmt; /* ... this statement during one execution of loop. */
|
||||
tree additional; /* A conjunction of conditions the operands of BOUND
|
||||
satisfy. The additional information about the value
|
||||
of the bound may be derived from it. */
|
||||
struct nb_iter_bound *next;
|
||||
/* The next bound in a list. */
|
||||
};
|
||||
|
||||
/* Records that AT_STMT is executed at most BOUND times in LOOP. The
|
||||
additional condition ADDITIONAL is recorded with the bound. */
|
||||
|
||||
static void
|
||||
void
|
||||
record_estimate (struct loop *loop, tree bound, tree additional, tree at_stmt)
|
||||
{
|
||||
struct nb_iter_bound *elt = xmalloc (sizeof (struct nb_iter_bound));
|
||||
|
@ -1010,8 +997,14 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
|
|||
}
|
||||
free (exits);
|
||||
|
||||
/* TODO Here we could use other possibilities, like bounds of arrays accessed
|
||||
in the loop. */
|
||||
/* Analyzes the bounds of arrays accessed in the loop. */
|
||||
if (loop->estimated_nb_iterations == NULL_TREE)
|
||||
{
|
||||
varray_type datarefs;
|
||||
VARRAY_GENERIC_PTR_INIT (datarefs, 3, "datarefs");
|
||||
find_data_references_in_loop (loop, &datarefs);
|
||||
free_data_refs (datarefs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Records estimates on numbers of iterations of LOOPS. */
|
||||
|
|
Loading…
Add table
Reference in a new issue