]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-data-ref.h
backport: As described in http://gcc.gnu.org/ml/gcc/2012-08/msg00015.html...
[thirdparty/gcc.git] / gcc / tree-data-ref.h
CommitLineData
b8698a0f 1/* Data references and dependences detectors.
e08120b1 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
96867bbd 3 Free Software Foundation, Inc.
0ff4040e 4 Contributed by Sebastian Pop <pop@cri.ensmp.fr>
56cf8686
SP
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
56cf8686
SP
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
56cf8686
SP
21
22#ifndef GCC_TREE_DATA_REF_H
23#define GCC_TREE_DATA_REF_H
24
3a796c6f 25#include "graphds.h"
3d8864c0 26#include "omega.h"
dea61d92 27#include "tree-chrec.h"
36d59cf7 28
98b44b0e 29/*
3cb960c7
ZD
30 innermost_loop_behavior describes the evolution of the address of the memory
31 reference in the innermost enclosing loop. The address is expressed as
32 BASE + STEP * # of iteration, and base is further decomposed as the base
33 pointer (BASE_ADDRESS), loop invariant offset (OFFSET) and
b8698a0f
L
34 constant offset (INIT). Examples, in loop nest
35
3cb960c7
ZD
36 for (i = 0; i < 100; i++)
37 for (j = 3; j < 100; j++)
98b44b0e 38
86a07404 39 Example 1 Example 2
3cb960c7 40 data-ref a[j].b[i][j] *(p + x + 16B + 4B * j)
b8698a0f 41
dea61d92 42
3cb960c7
ZD
43 innermost_loop_behavior
44 base_address &a p
45 offset i * D_i x
46 init 3 * D_j + offsetof (b) 28
86a07404 47 step D_j 4
86a07404 48
98b44b0e 49 */
3cb960c7 50struct innermost_loop_behavior
86a07404
IR
51{
52 tree base_address;
53 tree offset;
54 tree init;
55 tree step;
3cb960c7
ZD
56
57 /* Alignment information. ALIGNED_TO is set to the largest power of two
58 that divides OFFSET. */
59 tree aligned_to;
86a07404
IR
60};
61
3cb960c7 62/* Describes the evolutions of indices of the memory reference. The indices
c4ddde1b
RG
63 are indices of the ARRAY_REFs, indexes in artificial dimensions
64 added for member selection of records and the operands of MEM_REFs.
65 BASE_OBJECT is the part of the reference that is loop-invariant
66 (note that this reference does not have to cover the whole object
67 being accessed, in which case UNCONSTRAINED_BASE is set; hence it is
68 not recommended to use BASE_OBJECT in any code generation).
69 For the examples above,
70
71 base_object: a *(p + x + 4B * j_0)
3cb960c7 72 indices: {j_0, +, 1}_2 {16, +, 4}_2
c4ddde1b 73 4
3cb960c7
ZD
74 {i_0, +, 1}_1
75 {j_0, +, 1}_2
76*/
77
78struct indices
86a07404
IR
79{
80 /* The object. */
81 tree base_object;
b8698a0f 82
3cb960c7 83 /* A list of chrecs. Access functions of the indices. */
86a07404 84 VEC(tree,heap) *access_fns;
c4ddde1b
RG
85
86 /* Whether BASE_OBJECT is an access representing the whole object
87 or whether the access could not be constrained. */
88 bool unconstrained_base;
86a07404
IR
89};
90
3cb960c7
ZD
91struct dr_alias
92{
93 /* The alias information that should be used for new pointers to this
c4ddde1b 94 location. */
3cb960c7 95 struct ptr_info_def *ptr_info;
86a07404
IR
96};
97
b305e3da
SP
98/* An integer vector. A vector formally consists of an element of a vector
99 space. A vector space is a set that is closed under vector addition
100 and scalar multiplication. In this vector space, an element is a list of
101 integers. */
102typedef int *lambda_vector;
103DEF_VEC_P(lambda_vector);
104DEF_VEC_ALLOC_P(lambda_vector,heap);
105DEF_VEC_ALLOC_P(lambda_vector,gc);
106
107/* An integer matrix. A matrix consists of m vectors of length n (IE
108 all vectors are the same length). */
109typedef lambda_vector *lambda_matrix;
110
9f275479
JS
111/* Each vector of the access matrix represents a linear access
112 function for a subscript. First elements correspond to the
113 leftmost indices, ie. for a[i][j] the first vector corresponds to
114 the subscript in "i". The elements of a vector are relative to
115 the loop nests in which the data reference is considered,
116 i.e. the vector is relative to the SCoP that provides the context
117 in which this data reference occurs.
118
119 For example, in
120
121 | loop_1
122 | loop_2
123 | a[i+3][2*j+n-1]
124
b8698a0f 125 if "i" varies in loop_1 and "j" varies in loop_2, the access
9f275479
JS
126 matrix with respect to the loop nest {loop_1, loop_2} is:
127
128 | loop_1 loop_2 param_n cst
129 | 1 0 0 3
130 | 0 2 1 -1
131
132 whereas the access matrix with respect to loop_2 considers "i" as
133 a parameter:
134
135 | loop_2 param_i param_n cst
136 | 0 1 0 3
137 | 2 0 1 -1
138*/
139struct access_matrix
140{
36174c82 141 VEC (loop_p, heap) *loop_nest;
9f275479
JS
142 int nb_induction_vars;
143 VEC (tree, heap) *parameters;
96867bbd 144 VEC (lambda_vector, gc) *matrix;
9f275479
JS
145};
146
36174c82 147#define AM_LOOP_NEST(M) (M)->loop_nest
9f275479
JS
148#define AM_NB_INDUCTION_VARS(M) (M)->nb_induction_vars
149#define AM_PARAMETERS(M) (M)->parameters
150#define AM_MATRIX(M) (M)->matrix
151#define AM_NB_PARAMETERS(M) (VEC_length (tree, AM_PARAMETERS(M)))
152#define AM_CONST_COLUMN_INDEX(M) (AM_NB_INDUCTION_VARS (M) + AM_NB_PARAMETERS (M))
153#define AM_NB_COLUMNS(M) (AM_NB_INDUCTION_VARS (M) + AM_NB_PARAMETERS (M) + 1)
154#define AM_GET_SUBSCRIPT_ACCESS_VECTOR(M, I) VEC_index (lambda_vector, AM_MATRIX (M), I)
155#define AM_GET_ACCESS_MATRIX_ELEMENT(M, I, J) AM_GET_SUBSCRIPT_ACCESS_VECTOR (M, I)[J]
156
157/* Return the column in the access matrix of LOOP_NUM. */
158
159static inline int
160am_vector_index_for_loop (struct access_matrix *access_matrix, int loop_num)
161{
36174c82
SP
162 int i;
163 loop_p l;
164
165 for (i = 0; VEC_iterate (loop_p, AM_LOOP_NEST (access_matrix), i, l); i++)
166 if (l->num == loop_num)
167 return i;
168
169 gcc_unreachable();
9f275479
JS
170}
171
36d59cf7 172struct data_reference
56cf8686 173{
56cf8686 174 /* A pointer to the statement that contains this DR. */
726a989a 175 gimple stmt;
b8698a0f 176
3cb960c7 177 /* A pointer to the memory reference. */
56cf8686
SP
178 tree ref;
179
56cf8686 180 /* Auxiliary info specific to a pass. */
5417e022 181 void *aux;
56cf8686
SP
182
183 /* True when the data reference is in RHS of a stmt. */
184 bool is_read;
185
3cb960c7
ZD
186 /* Behavior of the memory reference in the innermost loop. */
187 struct innermost_loop_behavior innermost;
86a07404 188
f8bf9252 189 /* Subscripts of this data reference. */
3cb960c7 190 struct indices indices;
86a07404 191
3cb960c7
ZD
192 /* Alias information for the data reference. */
193 struct dr_alias alias;
56cf8686 194
9f275479
JS
195 /* Matrix representation for the data access functions. */
196 struct access_matrix *access_matrix;
197};
ebf78a47 198
86a07404
IR
199#define DR_STMT(DR) (DR)->stmt
200#define DR_REF(DR) (DR)->ref
3cb960c7 201#define DR_BASE_OBJECT(DR) (DR)->indices.base_object
c4ddde1b 202#define DR_UNCONSTRAINED_BASE(DR) (DR)->indices.unconstrained_base
3cb960c7 203#define DR_ACCESS_FNS(DR) (DR)->indices.access_fns
86a07404 204#define DR_ACCESS_FN(DR, I) VEC_index (tree, DR_ACCESS_FNS (DR), I)
b8698a0f 205#define DR_NUM_DIMENSIONS(DR) VEC_length (tree, DR_ACCESS_FNS (DR))
86a07404 206#define DR_IS_READ(DR) (DR)->is_read
b0af49c4 207#define DR_IS_WRITE(DR) (!DR_IS_READ (DR))
3cb960c7
ZD
208#define DR_BASE_ADDRESS(DR) (DR)->innermost.base_address
209#define DR_OFFSET(DR) (DR)->innermost.offset
210#define DR_INIT(DR) (DR)->innermost.init
211#define DR_STEP(DR) (DR)->innermost.step
3cb960c7 212#define DR_PTR_INFO(DR) (DR)->alias.ptr_info
3cb960c7 213#define DR_ALIGNED_TO(DR) (DR)->innermost.aligned_to
9f275479
JS
214#define DR_ACCESS_MATRIX(DR) (DR)->access_matrix
215
216typedef struct data_reference *data_reference_p;
217DEF_VEC_P(data_reference_p);
218DEF_VEC_ALLOC_P (data_reference_p, heap);
56cf8686
SP
219
220enum data_dependence_direction {
b8698a0f
L
221 dir_positive,
222 dir_negative,
223 dir_equal,
56cf8686
SP
224 dir_positive_or_negative,
225 dir_positive_or_equal,
226 dir_negative_or_equal,
227 dir_star,
228 dir_independent
229};
230
d93817c4
ZD
231/* The description of the grid of iterations that overlap. At most
232 two loops are considered at the same time just now, hence at most
233 two functions are needed. For each of the functions, we store
234 the vector of coefficients, f[0] + x * f[1] + y * f[2] + ...,
235 where x, y, ... are variables. */
236
237#define MAX_DIM 2
238
239/* Special values of N. */
240#define NO_DEPENDENCE 0
241#define NOT_KNOWN (MAX_DIM + 1)
242#define CF_NONTRIVIAL_P(CF) ((CF)->n != NO_DEPENDENCE && (CF)->n != NOT_KNOWN)
243#define CF_NOT_KNOWN_P(CF) ((CF)->n == NOT_KNOWN)
244#define CF_NO_DEPENDENCE_P(CF) ((CF)->n == NO_DEPENDENCE)
245
246typedef VEC (tree, heap) *affine_fn;
247
248typedef struct
249{
250 unsigned n;
251 affine_fn fns[MAX_DIM];
252} conflict_function;
253
56cf8686
SP
254/* What is a subscript? Given two array accesses a subscript is the
255 tuple composed of the access functions for a given dimension.
256 Example: Given A[f1][f2][f3] and B[g1][g2][g3], there are three
257 subscripts: (f1, g1), (f2, g2), (f3, g3). These three subscripts
258 are stored in the data_dependence_relation structure under the form
259 of an array of subscripts. */
260
36d59cf7 261struct subscript
56cf8686
SP
262{
263 /* A description of the iterations for which the elements are
264 accessed twice. */
d93817c4
ZD
265 conflict_function *conflicting_iterations_in_a;
266 conflict_function *conflicting_iterations_in_b;
b8698a0f 267
86df10e3 268 /* This field stores the information about the iteration domain
56cf8686 269 validity of the dependence relation. */
86df10e3 270 tree last_conflict;
b8698a0f 271
56cf8686
SP
272 /* Distance from the iteration that access a conflicting element in
273 A to the iteration that access this same conflicting element in
89dbed81 274 B. The distance is a tree scalar expression, i.e. a constant or a
56cf8686
SP
275 symbolic expression, but certainly not a chrec function. */
276 tree distance;
56cf8686
SP
277};
278
ebf78a47
SP
279typedef struct subscript *subscript_p;
280DEF_VEC_P(subscript_p);
281DEF_VEC_ALLOC_P (subscript_p, heap);
282
56cf8686
SP
283#define SUB_CONFLICTS_IN_A(SUB) SUB->conflicting_iterations_in_a
284#define SUB_CONFLICTS_IN_B(SUB) SUB->conflicting_iterations_in_b
86df10e3 285#define SUB_LAST_CONFLICT(SUB) SUB->last_conflict
56cf8686 286#define SUB_DISTANCE(SUB) SUB->distance
56cf8686
SP
287
288/* A data_dependence_relation represents a relation between two
289 data_references A and B. */
290
36d59cf7 291struct data_dependence_relation
56cf8686 292{
b8698a0f 293
56cf8686
SP
294 struct data_reference *a;
295 struct data_reference *b;
296
297 /* A "yes/no/maybe" field for the dependence relation:
b8698a0f 298
56cf8686
SP
299 - when "ARE_DEPENDENT == NULL_TREE", there exist a dependence
300 relation between A and B, and the description of this relation
301 is given in the SUBSCRIPTS array,
b8698a0f 302
56cf8686
SP
303 - when "ARE_DEPENDENT == chrec_known", there is no dependence and
304 SUBSCRIPTS is empty,
b8698a0f 305
56cf8686
SP
306 - when "ARE_DEPENDENT == chrec_dont_know", there may be a dependence,
307 but the analyzer cannot be more specific. */
308 tree are_dependent;
b8698a0f 309
56cf8686
SP
310 /* For each subscript in the dependence test, there is an element in
311 this array. This is the attribute that labels the edge A->B of
312 the data_dependence_relation. */
ebf78a47 313 VEC (subscript_p, heap) *subscripts;
36d59cf7 314
ba42e045
SP
315 /* The analyzed loop nest. */
316 VEC (loop_p, heap) *loop_nest;
86df10e3 317
36d59cf7 318 /* The classic direction vector. */
ebf78a47 319 VEC (lambda_vector, heap) *dir_vects;
36d59cf7
DB
320
321 /* The classic distance vector. */
ebf78a47 322 VEC (lambda_vector, heap) *dist_vects;
71d5b5e1 323
8f5929e1
JJ
324 /* An index in loop_nest for the innermost loop that varies for
325 this data dependence relation. */
326 unsigned inner_loop;
327
71d5b5e1
SP
328 /* Is the dependence reversed with respect to the lexicographic order? */
329 bool reversed_p;
8f5929e1
JJ
330
331 /* When the dependence relation is affine, it can be represented by
332 a distance vector. */
333 bool affine_p;
334
335 /* Set to true when the dependence relation is on the same data
336 access. */
337 bool self_reference_p;
56cf8686
SP
338};
339
0ff4040e
SP
340typedef struct data_dependence_relation *ddr_p;
341DEF_VEC_P(ddr_p);
342DEF_VEC_ALLOC_P(ddr_p,heap);
343
56cf8686
SP
344#define DDR_A(DDR) DDR->a
345#define DDR_B(DDR) DDR->b
86df10e3 346#define DDR_AFFINE_P(DDR) DDR->affine_p
56cf8686
SP
347#define DDR_ARE_DEPENDENT(DDR) DDR->are_dependent
348#define DDR_SUBSCRIPTS(DDR) DDR->subscripts
ebf78a47
SP
349#define DDR_SUBSCRIPT(DDR, I) VEC_index (subscript_p, DDR_SUBSCRIPTS (DDR), I)
350#define DDR_NUM_SUBSCRIPTS(DDR) VEC_length (subscript_p, DDR_SUBSCRIPTS (DDR))
ba42e045
SP
351
352#define DDR_LOOP_NEST(DDR) DDR->loop_nest
353/* The size of the direction/distance vectors: the number of loops in
354 the loop nest. */
355#define DDR_NB_LOOPS(DDR) (VEC_length (loop_p, DDR_LOOP_NEST (DDR)))
3d8864c0 356#define DDR_INNER_LOOP(DDR) DDR->inner_loop
b3924be9 357#define DDR_SELF_REFERENCE(DDR) DDR->self_reference_p
304afda6
SP
358
359#define DDR_DIST_VECTS(DDR) ((DDR)->dist_vects)
360#define DDR_DIR_VECTS(DDR) ((DDR)->dir_vects)
361#define DDR_NUM_DIST_VECTS(DDR) \
362 (VEC_length (lambda_vector, DDR_DIST_VECTS (DDR)))
363#define DDR_NUM_DIR_VECTS(DDR) \
364 (VEC_length (lambda_vector, DDR_DIR_VECTS (DDR)))
365#define DDR_DIR_VECT(DDR, I) \
366 VEC_index (lambda_vector, DDR_DIR_VECTS (DDR), I)
367#define DDR_DIST_VECT(DDR, I) \
368 VEC_index (lambda_vector, DDR_DIST_VECTS (DDR), I)
71d5b5e1 369#define DDR_REVERSED_P(DDR) DDR->reversed_p
56cf8686
SP
370
371\f
4e4452b6 372bool dr_analyze_innermost (struct data_reference *, struct loop *);
9f275479 373extern bool compute_data_dependences_for_loop (struct loop *, bool,
01be8516 374 VEC (loop_p, heap) **,
e14b10df
SP
375 VEC (data_reference_p, heap) **,
376 VEC (ddr_p, heap) **);
a70d6342
IR
377extern bool compute_data_dependences_for_bb (basic_block, bool,
378 VEC (data_reference_p, heap) **,
379 VEC (ddr_p, heap) **);
aeb83f09 380extern void debug_ddrs (VEC (ddr_p, heap) *);
56cf8686 381extern void dump_data_reference (FILE *, struct data_reference *);
a37d995a 382extern void debug_data_reference (struct data_reference *);
a37d995a 383extern void debug_data_references (VEC (data_reference_p, heap) *);
ba42e045 384extern void debug_data_dependence_relation (struct data_dependence_relation *);
ebf78a47 385extern void dump_data_dependence_relations (FILE *, VEC (ddr_p, heap) *);
dea61d92 386extern void debug_data_dependence_relations (VEC (ddr_p, heap) *);
36d59cf7 387extern void free_dependence_relation (struct data_dependence_relation *);
ebf78a47 388extern void free_dependence_relations (VEC (ddr_p, heap) *);
dea61d92 389extern void free_data_ref (data_reference_p);
ebf78a47 390extern void free_data_refs (VEC (data_reference_p, heap) *);
f8bf9252
SP
391extern bool find_data_references_in_stmt (struct loop *, gimple,
392 VEC (data_reference_p, heap) **);
5c640e29 393extern bool graphite_find_data_references_in_stmt (loop_p, loop_p, gimple,
ed91d661 394 VEC (data_reference_p, heap) **);
5c640e29 395struct data_reference *create_data_ref (loop_p, loop_p, tree, gimple, bool);
f8bf9252 396extern bool find_loop_nest (struct loop *, VEC (loop_p, heap) **);
aec7ae7d
JJ
397extern struct data_dependence_relation *initialize_data_dependence_relation
398 (struct data_reference *, struct data_reference *, VEC (loop_p, heap) *);
399extern void compute_self_dependence (struct data_dependence_relation *);
3881dee9 400extern bool compute_all_dependences (VEC (data_reference_p, heap) *,
f8bf9252
SP
401 VEC (ddr_p, heap) **, VEC (loop_p, heap) *,
402 bool);
bfe068c3
IR
403extern tree find_data_references_in_bb (struct loop *, basic_block,
404 VEC (data_reference_p, heap) **);
f8bf9252 405
f8bf9252 406extern bool dr_may_alias_p (const struct data_reference *,
02f5d6c5 407 const struct data_reference *, bool);
bfe068c3
IR
408extern bool dr_equal_offsets_p (struct data_reference *,
409 struct data_reference *);
ebf78a47 410
e1fd038a
SP
411
412/* Return true when the base objects of data references A and B are
413 the same memory object. */
414
415static inline bool
416same_data_refs_base_objects (data_reference_p a, data_reference_p b)
417{
418 return DR_NUM_DIMENSIONS (a) == DR_NUM_DIMENSIONS (b)
419 && operand_equal_p (DR_BASE_OBJECT (a), DR_BASE_OBJECT (b), 0);
420}
421
422/* Return true when the data references A and B are accessing the same
423 memory object with the same access functions. */
424
425static inline bool
426same_data_refs (data_reference_p a, data_reference_p b)
427{
428 unsigned int i;
429
430 /* The references are exactly the same. */
431 if (operand_equal_p (DR_REF (a), DR_REF (b), 0))
432 return true;
433
434 if (!same_data_refs_base_objects (a, b))
435 return false;
436
437 for (i = 0; i < DR_NUM_DIMENSIONS (a); i++)
438 if (!eq_evolutions_p (DR_ACCESS_FN (a, i), DR_ACCESS_FN (b, i)))
439 return false;
440
441 return true;
442}
443
dea61d92
SP
444/* Return true when the DDR contains two data references that have the
445 same access functions. */
446
447static inline bool
448same_access_functions (const struct data_dependence_relation *ddr)
449{
450 unsigned i;
451
452 for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
453 if (!eq_evolutions_p (DR_ACCESS_FN (DDR_A (ddr), i),
454 DR_ACCESS_FN (DDR_B (ddr), i)))
455 return false;
456
457 return true;
458}
459
460/* Return true when DDR is an anti-dependence relation. */
461
462static inline bool
463ddr_is_anti_dependent (ddr_p ddr)
464{
465 return (DDR_ARE_DEPENDENT (ddr) == NULL_TREE
466 && DR_IS_READ (DDR_A (ddr))
b0af49c4 467 && DR_IS_WRITE (DDR_B (ddr))
dea61d92
SP
468 && !same_access_functions (ddr));
469}
470
471/* Return true when DEPENDENCE_RELATIONS contains an anti-dependence. */
472
473static inline bool
474ddrs_have_anti_deps (VEC (ddr_p, heap) *dependence_relations)
475{
476 unsigned i;
477 ddr_p ddr;
478
479 for (i = 0; VEC_iterate (ddr_p, dependence_relations, i, ddr); i++)
480 if (ddr_is_anti_dependent (ddr))
481 return true;
482
483 return false;
484}
485
b305e3da
SP
486/* Returns the dependence level for a vector DIST of size LENGTH.
487 LEVEL = 0 means a lexicographic dependence, i.e. a dependence due
488 to the sequence of statements, not carried by any loop. */
489
490static inline unsigned
491dependence_level (lambda_vector dist_vect, int length)
492{
493 int i;
494
495 for (i = 0; i < length; i++)
496 if (dist_vect[i] != 0)
497 return i + 1;
498
499 return 0;
500}
501
dea61d92
SP
502/* Return the dependence level for the DDR relation. */
503
504static inline unsigned
505ddr_dependence_level (ddr_p ddr)
506{
507 unsigned vector;
508 unsigned level = 0;
509
510 if (DDR_DIST_VECTS (ddr))
511 level = dependence_level (DDR_DIST_VECT (ddr, 0), DDR_NB_LOOPS (ddr));
512
513 for (vector = 1; vector < DDR_NUM_DIST_VECTS (ddr); vector++)
514 level = MIN (level, dependence_level (DDR_DIST_VECT (ddr, vector),
515 DDR_NB_LOOPS (ddr)));
516 return level;
517}
518
3a796c6f
SP
519\f
520
dea61d92 521/* A Reduced Dependence Graph (RDG) vertex representing a statement. */
3a796c6f
SP
522typedef struct rdg_vertex
523{
524 /* The statement represented by this vertex. */
726a989a 525 gimple stmt;
dea61d92 526
1fa0c180
RG
527 /* Vector of data-references in this statement. */
528 VEC(data_reference_p, heap) *datarefs;
529
dea61d92
SP
530 /* True when the statement contains a write to memory. */
531 bool has_mem_write;
532
533 /* True when the statement contains a read from memory. */
534 bool has_mem_reads;
3a796c6f
SP
535} *rdg_vertex_p;
536
dea61d92 537#define RDGV_STMT(V) ((struct rdg_vertex *) ((V)->data))->stmt
1fa0c180 538#define RDGV_DATAREFS(V) ((struct rdg_vertex *) ((V)->data))->datarefs
dea61d92
SP
539#define RDGV_HAS_MEM_WRITE(V) ((struct rdg_vertex *) ((V)->data))->has_mem_write
540#define RDGV_HAS_MEM_READS(V) ((struct rdg_vertex *) ((V)->data))->has_mem_reads
541#define RDG_STMT(RDG, I) RDGV_STMT (&(RDG->vertices[I]))
1fa0c180 542#define RDG_DATAREFS(RDG, I) RDGV_DATAREFS (&(RDG->vertices[I]))
dea61d92
SP
543#define RDG_MEM_WRITE_STMT(RDG, I) RDGV_HAS_MEM_WRITE (&(RDG->vertices[I]))
544#define RDG_MEM_READS_STMT(RDG, I) RDGV_HAS_MEM_READS (&(RDG->vertices[I]))
545
dea61d92 546void debug_rdg_vertex (struct graph *, int);
dea61d92
SP
547void debug_rdg_component (struct graph *, int);
548void dump_rdg (FILE *, struct graph *);
549void debug_rdg (struct graph *);
726a989a 550int rdg_vertex_for_stmt (struct graph *, gimple);
3a796c6f
SP
551
552/* Data dependence type. */
553
b8698a0f 554enum rdg_dep_type
3a796c6f
SP
555{
556 /* Read After Write (RAW). */
557 flow_dd = 'f',
b8698a0f 558
3a796c6f
SP
559 /* Write After Read (WAR). */
560 anti_dd = 'a',
b8698a0f 561
3a796c6f 562 /* Write After Write (WAW). */
b8698a0f
L
563 output_dd = 'o',
564
3a796c6f 565 /* Read After Read (RAR). */
b8698a0f 566 input_dd = 'i'
3a796c6f
SP
567};
568
569/* Dependence information attached to an edge of the RDG. */
570
b8698a0f 571typedef struct rdg_edge
3a796c6f
SP
572{
573 /* Type of the dependence. */
574 enum rdg_dep_type type;
dea61d92 575
f8bf9252
SP
576 /* Levels of the dependence: the depth of the loops that carry the
577 dependence. */
dea61d92 578 unsigned level;
f8bf9252
SP
579
580 /* Dependence relation between data dependences, NULL when one of
581 the vertices is a scalar. */
582 ddr_p relation;
3a796c6f
SP
583} *rdg_edge_p;
584
585#define RDGE_TYPE(E) ((struct rdg_edge *) ((E)->data))->type
dea61d92 586#define RDGE_LEVEL(E) ((struct rdg_edge *) ((E)->data))->level
f8bf9252 587#define RDGE_RELATION(E) ((struct rdg_edge *) ((E)->data))->relation
3a796c6f 588
01be8516
SP
589struct graph *build_rdg (struct loop *,
590 VEC (loop_p, heap) **,
591 VEC (ddr_p, heap) **,
592 VEC (data_reference_p, heap) **);
f8bf9252 593struct graph *build_empty_rdg (int);
dea61d92 594void free_rdg (struct graph *);
3a796c6f 595
ba42e045
SP
596/* Return the index of the variable VAR in the LOOP_NEST array. */
597
598static inline int
599index_in_loop_nest (int var, VEC (loop_p, heap) *loop_nest)
600{
601 struct loop *loopi;
602 int var_index;
603
604 for (var_index = 0; VEC_iterate (loop_p, loop_nest, var_index, loopi);
605 var_index++)
606 if (loopi->num == var)
607 break;
608
609 return var_index;
610}
611
dea61d92 612bool rdg_defs_used_in_other_loops_p (struct graph *, int);
dea61d92 613
be6b029b
RG
614/* Returns true when the data reference DR the form "A[i] = ..."
615 with a stride equal to its unit type size. */
5e37ea0e
SP
616
617static inline bool
d0582dc1 618adjacent_dr_p (struct data_reference *dr)
5e37ea0e 619{
be6b029b
RG
620 /* If this is a bitfield store bail out. */
621 if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF
622 && DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1)))
623 return false;
624
625 if (!DR_STEP (dr)
626 || TREE_CODE (DR_STEP (dr)) != INTEGER_CST)
627 return false;
628
629 return tree_int_cst_equal (fold_unary (ABS_EXPR, TREE_TYPE (DR_STEP (dr)),
630 DR_STEP (dr)),
631 TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr))));
5e37ea0e
SP
632}
633
f8bf9252 634/* In tree-data-ref.c */
468c2ac0
DN
635void split_constant_offset (tree , tree *, tree *);
636
f8bf9252
SP
637/* Strongly connected components of the reduced data dependence graph. */
638
639typedef struct rdg_component
640{
641 int num;
642 VEC (int, heap) *vertices;
643} *rdgc;
644
645DEF_VEC_P (rdgc);
646DEF_VEC_ALLOC_P (rdgc, heap);
647
648DEF_VEC_P (bitmap);
649DEF_VEC_ALLOC_P (bitmap, heap);
650
b305e3da
SP
651/* Compute the greatest common divisor of a VECTOR of SIZE numbers. */
652
653static inline int
654lambda_vector_gcd (lambda_vector vector, int size)
655{
656 int i;
657 int gcd1 = 0;
658
659 if (size > 0)
660 {
661 gcd1 = vector[0];
662 for (i = 1; i < size; i++)
663 gcd1 = gcd (gcd1, vector[i]);
664 }
665 return gcd1;
666}
667
668/* Allocate a new vector of given SIZE. */
669
670static inline lambda_vector
671lambda_vector_new (int size)
672{
673 return (lambda_vector) ggc_alloc_cleared_atomic (sizeof (int) * size);
674}
675
676/* Clear out vector VEC1 of length SIZE. */
677
678static inline void
679lambda_vector_clear (lambda_vector vec1, int size)
680{
681 memset (vec1, 0, size * sizeof (*vec1));
682}
683
684/* Returns true when the vector V is lexicographically positive, in
685 other words, when the first nonzero element is positive. */
686
687static inline bool
688lambda_vector_lexico_pos (lambda_vector v,
689 unsigned n)
690{
691 unsigned i;
692 for (i = 0; i < n; i++)
693 {
694 if (v[i] == 0)
695 continue;
696 if (v[i] < 0)
697 return false;
698 if (v[i] > 0)
699 return true;
700 }
701 return true;
702}
703
704/* Return true if vector VEC1 of length SIZE is the zero vector. */
705
706static inline bool
707lambda_vector_zerop (lambda_vector vec1, int size)
708{
709 int i;
710 for (i = 0; i < size; i++)
711 if (vec1[i] != 0)
712 return false;
713 return true;
714}
715
716/* Allocate a matrix of M rows x N cols. */
717
718static inline lambda_matrix
719lambda_matrix_new (int m, int n, struct obstack *lambda_obstack)
720{
721 lambda_matrix mat;
722 int i;
723
724 mat = (lambda_matrix) obstack_alloc (lambda_obstack,
725 sizeof (lambda_vector *) * m);
726
727 for (i = 0; i < m; i++)
728 mat[i] = lambda_vector_new (n);
729
730 return mat;
731}
732
56cf8686 733#endif /* GCC_TREE_DATA_REF_H */