1e4b17023SJohn Marino /* Data dependence analysis for Graphite.
2*5ce9237cSJohn Marino Copyright (C) 2009, 2010, 2013 Free Software Foundation, Inc.
3e4b17023SJohn Marino Contributed by Sebastian Pop <sebastian.pop@amd.com> and
4e4b17023SJohn Marino Konrad Trifunovic <konrad.trifunovic@inria.fr>.
5e4b17023SJohn Marino
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11e4b17023SJohn Marino any later version.
12e4b17023SJohn Marino
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16e4b17023SJohn Marino GNU General Public License for more details.
17e4b17023SJohn Marino
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21e4b17023SJohn Marino
22e4b17023SJohn Marino #include "config.h"
23e4b17023SJohn Marino #include "system.h"
24e4b17023SJohn Marino #include "coretypes.h"
25e4b17023SJohn Marino #include "tree-flow.h"
26e4b17023SJohn Marino #include "tree-dump.h"
27e4b17023SJohn Marino #include "cfgloop.h"
28e4b17023SJohn Marino #include "tree-chrec.h"
29e4b17023SJohn Marino #include "tree-data-ref.h"
30e4b17023SJohn Marino #include "tree-scalar-evolution.h"
31e4b17023SJohn Marino #include "sese.h"
32e4b17023SJohn Marino
33e4b17023SJohn Marino #ifdef HAVE_cloog
34e4b17023SJohn Marino #include "ppl_c.h"
35e4b17023SJohn Marino #include "graphite-ppl.h"
36e4b17023SJohn Marino #include "graphite-poly.h"
37e4b17023SJohn Marino #include "graphite-dependences.h"
38e4b17023SJohn Marino #include "graphite-cloog-util.h"
39e4b17023SJohn Marino
40e4b17023SJohn Marino /* Comparison function for poly_ddr hash table. */
41e4b17023SJohn Marino
42e4b17023SJohn Marino int
eq_poly_ddr_p(const void * pddr1,const void * pddr2)43e4b17023SJohn Marino eq_poly_ddr_p (const void *pddr1, const void *pddr2)
44e4b17023SJohn Marino {
45e4b17023SJohn Marino const struct poly_ddr *p1 = (const struct poly_ddr *) pddr1;
46e4b17023SJohn Marino const struct poly_ddr *p2 = (const struct poly_ddr *) pddr2;
47e4b17023SJohn Marino
48e4b17023SJohn Marino return (PDDR_SOURCE (p1) == PDDR_SOURCE (p2)
49e4b17023SJohn Marino && PDDR_SINK (p1) == PDDR_SINK (p2));
50e4b17023SJohn Marino }
51e4b17023SJohn Marino
52e4b17023SJohn Marino /* Hash function for poly_ddr hashtable. */
53e4b17023SJohn Marino
54e4b17023SJohn Marino hashval_t
hash_poly_ddr_p(const void * pddr)55e4b17023SJohn Marino hash_poly_ddr_p (const void *pddr)
56e4b17023SJohn Marino {
57e4b17023SJohn Marino const struct poly_ddr *p = (const struct poly_ddr *) pddr;
58e4b17023SJohn Marino
59*5ce9237cSJohn Marino return (hashval_t) ((intptr_t) PDDR_SOURCE (p) + (intptr_t) PDDR_SINK (p));
60e4b17023SJohn Marino }
61e4b17023SJohn Marino
62e4b17023SJohn Marino /* Returns true when PDDR has no dependence. */
63e4b17023SJohn Marino
64e4b17023SJohn Marino static bool
pddr_is_empty(poly_ddr_p pddr)65e4b17023SJohn Marino pddr_is_empty (poly_ddr_p pddr)
66e4b17023SJohn Marino {
67e4b17023SJohn Marino if (!pddr)
68e4b17023SJohn Marino return true;
69e4b17023SJohn Marino
70e4b17023SJohn Marino gcc_assert (PDDR_KIND (pddr) != unknown_dependence);
71e4b17023SJohn Marino
72e4b17023SJohn Marino return PDDR_KIND (pddr) == no_dependence ? true : false;
73e4b17023SJohn Marino }
74e4b17023SJohn Marino
75e4b17023SJohn Marino /* Prints to FILE the layout of the dependence polyhedron of PDDR:
76e4b17023SJohn Marino
77e4b17023SJohn Marino T1|I1|T2|I2|S1|S2|G
78e4b17023SJohn Marino
79e4b17023SJohn Marino with
80e4b17023SJohn Marino | T1 and T2 the scattering dimensions for PDDR_SOURCE and PDDR_SINK
81e4b17023SJohn Marino | I1 and I2 the iteration domains
82e4b17023SJohn Marino | S1 and S2 the subscripts
83e4b17023SJohn Marino | G the global parameters. */
84e4b17023SJohn Marino
85e4b17023SJohn Marino static void
print_dependence_polyhedron_layout(FILE * file,poly_ddr_p pddr)86e4b17023SJohn Marino print_dependence_polyhedron_layout (FILE *file, poly_ddr_p pddr)
87e4b17023SJohn Marino {
88e4b17023SJohn Marino poly_dr_p pdr1 = PDDR_SOURCE (pddr);
89e4b17023SJohn Marino poly_dr_p pdr2 = PDDR_SINK (pddr);
90e4b17023SJohn Marino poly_bb_p pbb1 = PDR_PBB (pdr1);
91e4b17023SJohn Marino poly_bb_p pbb2 = PDR_PBB (pdr2);
92e4b17023SJohn Marino
93e4b17023SJohn Marino graphite_dim_t i;
94e4b17023SJohn Marino graphite_dim_t tdim1 = PDDR_ORIGINAL_SCATTERING_P (pddr) ?
95e4b17023SJohn Marino pbb_nb_scattering_orig (pbb1) : pbb_nb_scattering_transform (pbb1);
96e4b17023SJohn Marino graphite_dim_t tdim2 = PDDR_ORIGINAL_SCATTERING_P (pddr) ?
97e4b17023SJohn Marino pbb_nb_scattering_orig (pbb2) : pbb_nb_scattering_transform (pbb2);
98e4b17023SJohn Marino graphite_dim_t idim1 = pbb_dim_iter_domain (pbb1);
99e4b17023SJohn Marino graphite_dim_t idim2 = pbb_dim_iter_domain (pbb2);
100e4b17023SJohn Marino graphite_dim_t sdim1 = PDR_NB_SUBSCRIPTS (pdr1) + 1;
101e4b17023SJohn Marino graphite_dim_t sdim2 = PDR_NB_SUBSCRIPTS (pdr2) + 1;
102e4b17023SJohn Marino graphite_dim_t gdim = scop_nb_params (PBB_SCOP (pbb1));
103e4b17023SJohn Marino
104e4b17023SJohn Marino fprintf (file, "# eq");
105e4b17023SJohn Marino
106e4b17023SJohn Marino for (i = 0; i < tdim1; i++)
107e4b17023SJohn Marino fprintf (file, " t1_%d", (int) i);
108e4b17023SJohn Marino for (i = 0; i < idim1; i++)
109e4b17023SJohn Marino fprintf (file, " i1_%d", (int) i);
110e4b17023SJohn Marino for (i = 0; i < tdim2; i++)
111e4b17023SJohn Marino fprintf (file, " t2_%d", (int) i);
112e4b17023SJohn Marino for (i = 0; i < idim2; i++)
113e4b17023SJohn Marino fprintf (file, " i2_%d", (int) i);
114e4b17023SJohn Marino for (i = 0; i < sdim1; i++)
115e4b17023SJohn Marino fprintf (file, " s1_%d", (int) i);
116e4b17023SJohn Marino for (i = 0; i < sdim2; i++)
117e4b17023SJohn Marino fprintf (file, " s2_%d", (int) i);
118e4b17023SJohn Marino for (i = 0; i < gdim; i++)
119e4b17023SJohn Marino fprintf (file, " g_%d", (int) i);
120e4b17023SJohn Marino
121e4b17023SJohn Marino fprintf (file, " cst\n");
122e4b17023SJohn Marino }
123e4b17023SJohn Marino
124e4b17023SJohn Marino /* Prints to FILE the poly_ddr_p PDDR. */
125e4b17023SJohn Marino
126e4b17023SJohn Marino void
print_pddr(FILE * file,poly_ddr_p pddr)127e4b17023SJohn Marino print_pddr (FILE *file, poly_ddr_p pddr)
128e4b17023SJohn Marino {
129e4b17023SJohn Marino fprintf (file, "pddr (kind: ");
130e4b17023SJohn Marino
131e4b17023SJohn Marino if (PDDR_KIND (pddr) == unknown_dependence)
132e4b17023SJohn Marino fprintf (file, "unknown_dependence");
133e4b17023SJohn Marino else if (PDDR_KIND (pddr) == no_dependence)
134e4b17023SJohn Marino fprintf (file, "no_dependence");
135e4b17023SJohn Marino else if (PDDR_KIND (pddr) == has_dependence)
136e4b17023SJohn Marino fprintf (file, "has_dependence");
137e4b17023SJohn Marino
138e4b17023SJohn Marino fprintf (file, "\n source ");
139e4b17023SJohn Marino print_pdr (file, PDDR_SOURCE (pddr), 2);
140e4b17023SJohn Marino
141e4b17023SJohn Marino fprintf (file, "\n sink ");
142e4b17023SJohn Marino print_pdr (file, PDDR_SINK (pddr), 2);
143e4b17023SJohn Marino
144e4b17023SJohn Marino if (PDDR_KIND (pddr) == has_dependence)
145e4b17023SJohn Marino {
146e4b17023SJohn Marino fprintf (file, "\n dependence polyhedron (\n");
147e4b17023SJohn Marino print_dependence_polyhedron_layout (file, pddr);
148e4b17023SJohn Marino ppl_print_powerset_matrix (file, PDDR_DDP (pddr));
149e4b17023SJohn Marino ppl_io_fprint_Pointset_Powerset_C_Polyhedron (file, PDDR_DDP (pddr));
150e4b17023SJohn Marino fprintf (file, ")\n");
151e4b17023SJohn Marino }
152e4b17023SJohn Marino
153e4b17023SJohn Marino fprintf (file, ")\n");
154e4b17023SJohn Marino }
155e4b17023SJohn Marino
156e4b17023SJohn Marino /* Prints to STDERR the poly_ddr_p PDDR. */
157e4b17023SJohn Marino
158e4b17023SJohn Marino DEBUG_FUNCTION void
debug_pddr(poly_ddr_p pddr)159e4b17023SJohn Marino debug_pddr (poly_ddr_p pddr)
160e4b17023SJohn Marino {
161e4b17023SJohn Marino print_pddr (stderr, pddr);
162e4b17023SJohn Marino }
163e4b17023SJohn Marino
164e4b17023SJohn Marino
165e4b17023SJohn Marino /* Remove all the dimensions except alias information at dimension
166e4b17023SJohn Marino ALIAS_DIM. */
167e4b17023SJohn Marino
168e4b17023SJohn Marino static void
build_alias_set_powerset(ppl_Pointset_Powerset_C_Polyhedron_t alias_powerset,ppl_dimension_type alias_dim)169e4b17023SJohn Marino build_alias_set_powerset (ppl_Pointset_Powerset_C_Polyhedron_t alias_powerset,
170e4b17023SJohn Marino ppl_dimension_type alias_dim)
171e4b17023SJohn Marino {
172e4b17023SJohn Marino ppl_dimension_type *ds;
173e4b17023SJohn Marino ppl_dimension_type access_dim;
174e4b17023SJohn Marino unsigned i, pos;
175e4b17023SJohn Marino
176e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_space_dimension (alias_powerset,
177e4b17023SJohn Marino &access_dim);
178e4b17023SJohn Marino ds = XNEWVEC (ppl_dimension_type, access_dim - 1);
179e4b17023SJohn Marino gcc_assert (alias_dim < access_dim);
180e4b17023SJohn Marino
181e4b17023SJohn Marino for (pos = 0, i = 0; i < access_dim; i++)
182e4b17023SJohn Marino if (i != alias_dim)
183e4b17023SJohn Marino ds[pos++] = i;
184e4b17023SJohn Marino
185e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_remove_space_dimensions (alias_powerset,
186e4b17023SJohn Marino ds,
187e4b17023SJohn Marino access_dim - 1);
188e4b17023SJohn Marino free (ds);
189e4b17023SJohn Marino }
190e4b17023SJohn Marino
191e4b17023SJohn Marino /* Return true when PDR1 and PDR2 may alias. */
192e4b17023SJohn Marino
193e4b17023SJohn Marino static bool
poly_drs_may_alias_p(poly_dr_p pdr1,poly_dr_p pdr2)194e4b17023SJohn Marino poly_drs_may_alias_p (poly_dr_p pdr1, poly_dr_p pdr2)
195e4b17023SJohn Marino {
196e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t alias_powerset1, alias_powerset2;
197e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t accesses1 = PDR_ACCESSES (pdr1);
198e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t accesses2 = PDR_ACCESSES (pdr2);
199e4b17023SJohn Marino ppl_dimension_type alias_dim1 = pdr_alias_set_dim (pdr1);
200e4b17023SJohn Marino ppl_dimension_type alias_dim2 = pdr_alias_set_dim (pdr2);
201e4b17023SJohn Marino int empty_p;
202e4b17023SJohn Marino
203e4b17023SJohn Marino ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
204e4b17023SJohn Marino (&alias_powerset1, accesses1);
205e4b17023SJohn Marino ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
206e4b17023SJohn Marino (&alias_powerset2, accesses2);
207e4b17023SJohn Marino
208e4b17023SJohn Marino build_alias_set_powerset (alias_powerset1, alias_dim1);
209e4b17023SJohn Marino build_alias_set_powerset (alias_powerset2, alias_dim2);
210e4b17023SJohn Marino
211e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign
212e4b17023SJohn Marino (alias_powerset1, alias_powerset2);
213e4b17023SJohn Marino
214e4b17023SJohn Marino empty_p = ppl_Pointset_Powerset_C_Polyhedron_is_empty (alias_powerset1);
215e4b17023SJohn Marino
216e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (alias_powerset1);
217e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (alias_powerset2);
218e4b17023SJohn Marino
219e4b17023SJohn Marino return !empty_p;
220e4b17023SJohn Marino }
221e4b17023SJohn Marino
222e4b17023SJohn Marino /* Swap [cut0, ..., cut1] to the end of DR: "a CUT0 b CUT1 c" is
223e4b17023SJohn Marino transformed into "a CUT0 c CUT1' b"
224e4b17023SJohn Marino
225e4b17023SJohn Marino Add NB0 zeros before "a": "00...0 a CUT0 c CUT1' b"
226e4b17023SJohn Marino Add NB1 zeros between "a" and "c": "00...0 a 00...0 c CUT1' b"
227e4b17023SJohn Marino Add DIM - NB0 - NB1 - PDIM zeros between "c" and "b":
228e4b17023SJohn Marino "00...0 a 00...0 c 00...0 b". */
229e4b17023SJohn Marino
230e4b17023SJohn Marino static ppl_Pointset_Powerset_C_Polyhedron_t
map_dr_into_dep_poly(graphite_dim_t dim,ppl_Pointset_Powerset_C_Polyhedron_t dr,graphite_dim_t cut0,graphite_dim_t cut1,graphite_dim_t nb0,graphite_dim_t nb1)231e4b17023SJohn Marino map_dr_into_dep_poly (graphite_dim_t dim,
232e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t dr,
233e4b17023SJohn Marino graphite_dim_t cut0, graphite_dim_t cut1,
234e4b17023SJohn Marino graphite_dim_t nb0, graphite_dim_t nb1)
235e4b17023SJohn Marino {
236e4b17023SJohn Marino ppl_dimension_type pdim;
237e4b17023SJohn Marino ppl_dimension_type *map;
238e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t res;
239e4b17023SJohn Marino ppl_dimension_type i;
240e4b17023SJohn Marino
241e4b17023SJohn Marino ppl_new_Pointset_Powerset_C_Polyhedron_from_Pointset_Powerset_C_Polyhedron
242e4b17023SJohn Marino (&res, dr);
243e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_space_dimension (res, &pdim);
244e4b17023SJohn Marino
245e4b17023SJohn Marino map = (ppl_dimension_type *) XNEWVEC (ppl_dimension_type, pdim);
246e4b17023SJohn Marino
247e4b17023SJohn Marino /* First mapping: move 'g' vector to right position. */
248e4b17023SJohn Marino for (i = 0; i < cut0; i++)
249e4b17023SJohn Marino map[i] = i;
250e4b17023SJohn Marino
251e4b17023SJohn Marino for (i = cut0; i < cut1; i++)
252e4b17023SJohn Marino map[i] = pdim - cut1 + i;
253e4b17023SJohn Marino
254e4b17023SJohn Marino for (i = cut1; i < pdim; i++)
255e4b17023SJohn Marino map[i] = cut0 + i - cut1;
256e4b17023SJohn Marino
257e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_map_space_dimensions (res, map, pdim);
258e4b17023SJohn Marino free (map);
259e4b17023SJohn Marino
260e4b17023SJohn Marino /* After swapping 's' and 'g' vectors, we have to update a new cut. */
261e4b17023SJohn Marino cut1 = pdim - cut1 + cut0;
262e4b17023SJohn Marino
263e4b17023SJohn Marino ppl_insert_dimensions_pointset (res, 0, nb0);
264e4b17023SJohn Marino ppl_insert_dimensions_pointset (res, nb0 + cut0, nb1);
265e4b17023SJohn Marino ppl_insert_dimensions_pointset (res, nb0 + nb1 + cut1,
266e4b17023SJohn Marino dim - nb0 - nb1 - pdim);
267e4b17023SJohn Marino
268e4b17023SJohn Marino return res;
269e4b17023SJohn Marino }
270e4b17023SJohn Marino
271e4b17023SJohn Marino /* Builds subscript equality constraints. */
272e4b17023SJohn Marino
273e4b17023SJohn Marino static ppl_Pointset_Powerset_C_Polyhedron_t
dr_equality_constraints(graphite_dim_t dim,graphite_dim_t pos,graphite_dim_t nb_subscripts)274e4b17023SJohn Marino dr_equality_constraints (graphite_dim_t dim,
275e4b17023SJohn Marino graphite_dim_t pos, graphite_dim_t nb_subscripts)
276e4b17023SJohn Marino {
277e4b17023SJohn Marino ppl_Polyhedron_t eqs;
278e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t res;
279e4b17023SJohn Marino graphite_dim_t i;
280e4b17023SJohn Marino
281e4b17023SJohn Marino ppl_new_C_Polyhedron_from_space_dimension (&eqs, dim, 0);
282e4b17023SJohn Marino
283e4b17023SJohn Marino for (i = 0; i < nb_subscripts; i++)
284e4b17023SJohn Marino {
285e4b17023SJohn Marino ppl_Constraint_t cstr
286e4b17023SJohn Marino = ppl_build_relation (dim, pos + i, pos + i + nb_subscripts,
287e4b17023SJohn Marino 0, PPL_CONSTRAINT_TYPE_EQUAL);
288e4b17023SJohn Marino ppl_Polyhedron_add_constraint (eqs, cstr);
289e4b17023SJohn Marino ppl_delete_Constraint (cstr);
290e4b17023SJohn Marino }
291e4b17023SJohn Marino
292e4b17023SJohn Marino ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&res, eqs);
293e4b17023SJohn Marino ppl_delete_Polyhedron (eqs);
294e4b17023SJohn Marino return res;
295e4b17023SJohn Marino }
296e4b17023SJohn Marino
297e4b17023SJohn Marino /* Builds scheduling inequality constraints: when DIRECTION is
298e4b17023SJohn Marino 1 builds a GE constraint,
299e4b17023SJohn Marino 0 builds an EQ constraint,
300e4b17023SJohn Marino -1 builds a LE constraint.
301e4b17023SJohn Marino DIM is the dimension of the scheduling space.
302e4b17023SJohn Marino POS and POS + OFFSET are the dimensions that are related. */
303e4b17023SJohn Marino
304e4b17023SJohn Marino static ppl_Pointset_Powerset_C_Polyhedron_t
build_pairwise_scheduling(graphite_dim_t dim,graphite_dim_t pos,graphite_dim_t offset,int direction)305e4b17023SJohn Marino build_pairwise_scheduling (graphite_dim_t dim,
306e4b17023SJohn Marino graphite_dim_t pos,
307e4b17023SJohn Marino graphite_dim_t offset,
308e4b17023SJohn Marino int direction)
309e4b17023SJohn Marino {
310e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t res;
311e4b17023SJohn Marino ppl_Polyhedron_t equalities;
312e4b17023SJohn Marino ppl_Constraint_t cstr;
313e4b17023SJohn Marino graphite_dim_t a = pos;
314e4b17023SJohn Marino graphite_dim_t b = pos + offset;
315e4b17023SJohn Marino
316e4b17023SJohn Marino ppl_new_C_Polyhedron_from_space_dimension (&equalities, dim, 0);
317e4b17023SJohn Marino
318e4b17023SJohn Marino switch (direction)
319e4b17023SJohn Marino {
320e4b17023SJohn Marino case 1:
321e4b17023SJohn Marino /* Builds "a + 1 <= b. */
322e4b17023SJohn Marino cstr = ppl_build_relation (dim, a, b, 1,
323e4b17023SJohn Marino PPL_CONSTRAINT_TYPE_LESS_OR_EQUAL);
324e4b17023SJohn Marino break;
325e4b17023SJohn Marino
326e4b17023SJohn Marino case 0:
327e4b17023SJohn Marino /* Builds "a = b. */
328e4b17023SJohn Marino cstr = ppl_build_relation (dim, a, b, 0,
329e4b17023SJohn Marino PPL_CONSTRAINT_TYPE_EQUAL);
330e4b17023SJohn Marino break;
331e4b17023SJohn Marino
332e4b17023SJohn Marino case -1:
333e4b17023SJohn Marino /* Builds "a >= b + 1. */
334e4b17023SJohn Marino cstr = ppl_build_relation (dim, a, b, -1,
335e4b17023SJohn Marino PPL_CONSTRAINT_TYPE_GREATER_OR_EQUAL);
336e4b17023SJohn Marino break;
337e4b17023SJohn Marino
338e4b17023SJohn Marino default:
339e4b17023SJohn Marino gcc_unreachable ();
340e4b17023SJohn Marino }
341e4b17023SJohn Marino
342e4b17023SJohn Marino ppl_Polyhedron_add_constraint (equalities, cstr);
343e4b17023SJohn Marino ppl_delete_Constraint (cstr);
344e4b17023SJohn Marino
345e4b17023SJohn Marino ppl_new_Pointset_Powerset_C_Polyhedron_from_C_Polyhedron (&res, equalities);
346e4b17023SJohn Marino ppl_delete_Polyhedron (equalities);
347e4b17023SJohn Marino return res;
348e4b17023SJohn Marino }
349e4b17023SJohn Marino
350e4b17023SJohn Marino /* Add to a non empty polyhedron BAG the precedence constraints for
351e4b17023SJohn Marino the lexicographical comparison of time vectors in BAG following the
352e4b17023SJohn Marino lexicographical order. DIM is the dimension of the polyhedron BAG.
353e4b17023SJohn Marino TDIM is the number of loops common to the two statements that are
354e4b17023SJohn Marino compared lexicographically, i.e. the number of loops containing
355e4b17023SJohn Marino both statements. OFFSET is the number of dimensions needed to
356e4b17023SJohn Marino represent the first statement, i.e. dimT1 + dimI1 in the layout of
357e4b17023SJohn Marino the BAG polyhedron: T1|I1|T2|I2|S1|S2|G. When DIRECTION is set to
358e4b17023SJohn Marino 1, compute the direct dependence from PDR1 to PDR2, and when
359e4b17023SJohn Marino DIRECTION is -1, compute the reversed dependence relation, from
360e4b17023SJohn Marino PDR2 to PDR1. */
361e4b17023SJohn Marino
362e4b17023SJohn Marino static ppl_Pointset_Powerset_C_Polyhedron_t
build_lexicographical_constraint(ppl_Pointset_Powerset_C_Polyhedron_t bag,graphite_dim_t dim,graphite_dim_t tdim,graphite_dim_t offset,int direction)363e4b17023SJohn Marino build_lexicographical_constraint (ppl_Pointset_Powerset_C_Polyhedron_t bag,
364e4b17023SJohn Marino graphite_dim_t dim,
365e4b17023SJohn Marino graphite_dim_t tdim,
366e4b17023SJohn Marino graphite_dim_t offset,
367e4b17023SJohn Marino int direction)
368e4b17023SJohn Marino {
369e4b17023SJohn Marino graphite_dim_t i;
370e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t res, lex;
371e4b17023SJohn Marino
372e4b17023SJohn Marino ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension (&res, dim, 1);
373e4b17023SJohn Marino
374e4b17023SJohn Marino lex = build_pairwise_scheduling (dim, 0, offset, direction);
375e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (lex, bag);
376e4b17023SJohn Marino
377e4b17023SJohn Marino if (!ppl_powerset_is_empty (lex))
378e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (res, lex);
379e4b17023SJohn Marino
380e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (lex);
381e4b17023SJohn Marino
382e4b17023SJohn Marino for (i = 0; i < tdim - 1; i++)
383e4b17023SJohn Marino {
384e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t sceq;
385e4b17023SJohn Marino
386e4b17023SJohn Marino sceq = build_pairwise_scheduling (dim, i, offset, 0);
387e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (bag, sceq);
388e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (sceq);
389e4b17023SJohn Marino
390e4b17023SJohn Marino if (ppl_powerset_is_empty (bag))
391e4b17023SJohn Marino break;
392e4b17023SJohn Marino
393e4b17023SJohn Marino lex = build_pairwise_scheduling (dim, i + 1, offset, direction);
394e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (lex, bag);
395e4b17023SJohn Marino
396e4b17023SJohn Marino if (!ppl_powerset_is_empty (lex))
397e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_upper_bound_assign (res, lex);
398e4b17023SJohn Marino
399e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (lex);
400e4b17023SJohn Marino }
401e4b17023SJohn Marino
402e4b17023SJohn Marino return res;
403e4b17023SJohn Marino }
404e4b17023SJohn Marino
405e4b17023SJohn Marino /* Build the dependence polyhedron for data references PDR1 and PDR2.
406e4b17023SJohn Marino The layout of the dependence polyhedron is:
407e4b17023SJohn Marino
408e4b17023SJohn Marino T1|I1|T2|I2|S1|S2|G
409e4b17023SJohn Marino
410e4b17023SJohn Marino with
411e4b17023SJohn Marino | T1 and T2 the scattering dimensions for PDR1 and PDR2
412e4b17023SJohn Marino | I1 and I2 the iteration domains
413e4b17023SJohn Marino | S1 and S2 the subscripts
414e4b17023SJohn Marino | G the global parameters.
415e4b17023SJohn Marino
416e4b17023SJohn Marino When DIRECTION is set to 1, compute the direct dependence from PDR1
417e4b17023SJohn Marino to PDR2, and when DIRECTION is -1, compute the reversed dependence
418e4b17023SJohn Marino relation, from PDR2 to PDR1. */
419e4b17023SJohn Marino
420e4b17023SJohn Marino static ppl_Pointset_Powerset_C_Polyhedron_t
dependence_polyhedron(poly_dr_p pdr1,poly_dr_p pdr2,int direction,bool original_scattering_p)421e4b17023SJohn Marino dependence_polyhedron (poly_dr_p pdr1, poly_dr_p pdr2,
422e4b17023SJohn Marino int direction, bool original_scattering_p)
423e4b17023SJohn Marino {
424e4b17023SJohn Marino poly_bb_p pbb1 = PDR_PBB (pdr1);
425e4b17023SJohn Marino poly_bb_p pbb2 = PDR_PBB (pdr2);
426e4b17023SJohn Marino scop_p scop = PBB_SCOP (pbb1);
427e4b17023SJohn Marino graphite_dim_t tdim1 = original_scattering_p ?
428e4b17023SJohn Marino pbb_nb_scattering_orig (pbb1) : pbb_nb_scattering_transform (pbb1);
429e4b17023SJohn Marino graphite_dim_t tdim2 = original_scattering_p ?
430e4b17023SJohn Marino pbb_nb_scattering_orig (pbb2) : pbb_nb_scattering_transform (pbb2);
431e4b17023SJohn Marino graphite_dim_t ddim1 = pbb_dim_iter_domain (pbb1);
432e4b17023SJohn Marino graphite_dim_t ddim2 = pbb_dim_iter_domain (pbb2);
433e4b17023SJohn Marino graphite_dim_t sdim1 = PDR_NB_SUBSCRIPTS (pdr1) + 1;
434e4b17023SJohn Marino graphite_dim_t sdim2 = PDR_NB_SUBSCRIPTS (pdr2) + 1;
435e4b17023SJohn Marino graphite_dim_t gdim = scop_nb_params (scop);
436e4b17023SJohn Marino graphite_dim_t dim1 = pdr_dim (pdr1);
437e4b17023SJohn Marino graphite_dim_t dim2 = pdr_dim (pdr2);
438e4b17023SJohn Marino graphite_dim_t dim = tdim1 + tdim2 + dim1 + dim2 - gdim;
439e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t res;
440e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t idr1, idr2;
441e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t sc1, sc2, dreq;
442e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t lex;
443e4b17023SJohn Marino
444e4b17023SJohn Marino gcc_assert (PBB_SCOP (pbb1) == PBB_SCOP (pbb2));
445e4b17023SJohn Marino
446e4b17023SJohn Marino combine_context_id_scat (&sc1, pbb1, original_scattering_p);
447e4b17023SJohn Marino combine_context_id_scat (&sc2, pbb2, original_scattering_p);
448e4b17023SJohn Marino
449e4b17023SJohn Marino ppl_insert_dimensions_pointset (sc1, tdim1 + ddim1,
450e4b17023SJohn Marino tdim2 + ddim2 + sdim1 + sdim2);
451e4b17023SJohn Marino
452e4b17023SJohn Marino ppl_insert_dimensions_pointset (sc2, 0, tdim1 + ddim1);
453e4b17023SJohn Marino ppl_insert_dimensions_pointset (sc2, tdim1 + ddim1 + tdim2 + ddim2,
454e4b17023SJohn Marino sdim1 + sdim2);
455e4b17023SJohn Marino
456e4b17023SJohn Marino idr1 = map_dr_into_dep_poly (dim, PDR_ACCESSES (pdr1), ddim1, ddim1 + gdim,
457e4b17023SJohn Marino tdim1, tdim2 + ddim2);
458e4b17023SJohn Marino idr2 = map_dr_into_dep_poly (dim, PDR_ACCESSES (pdr2), ddim2, ddim2 + gdim,
459e4b17023SJohn Marino tdim1 + ddim1 + tdim2, sdim1);
460e4b17023SJohn Marino
461e4b17023SJohn Marino /* Now add the subscript equalities. */
462e4b17023SJohn Marino dreq = dr_equality_constraints (dim, tdim1 + ddim1 + tdim2 + ddim2, sdim1);
463e4b17023SJohn Marino
464e4b17023SJohn Marino ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension (&res, dim, 0);
465e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, sc1);
466e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, sc2);
467e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, idr1);
468e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, idr2);
469e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (res, dreq);
470e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (sc1);
471e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (sc2);
472e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (idr1);
473e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (idr2);
474e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (dreq);
475e4b17023SJohn Marino
476e4b17023SJohn Marino if (ppl_powerset_is_empty (res))
477e4b17023SJohn Marino return NULL;
478e4b17023SJohn Marino
479e4b17023SJohn Marino lex = build_lexicographical_constraint (res, dim, MIN (tdim1, tdim2),
480e4b17023SJohn Marino tdim1 + ddim1, direction);
481e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (res);
482e4b17023SJohn Marino
483e4b17023SJohn Marino return lex;
484e4b17023SJohn Marino }
485e4b17023SJohn Marino
486e4b17023SJohn Marino /* Build the dependence polyhedron for data references PDR1 and PDR2.
487e4b17023SJohn Marino If possible use already cached information.
488e4b17023SJohn Marino
489e4b17023SJohn Marino When DIRECTION is set to 1, compute the direct dependence from PDR1
490e4b17023SJohn Marino to PDR2, and when DIRECTION is -1, compute the reversed dependence
491e4b17023SJohn Marino relation, from PDR2 to PDR1. */
492e4b17023SJohn Marino
493e4b17023SJohn Marino static poly_ddr_p
new_poly_ddr(poly_dr_p pdr1,poly_dr_p pdr2,int direction,bool original_scattering_p)494e4b17023SJohn Marino new_poly_ddr (poly_dr_p pdr1, poly_dr_p pdr2,
495e4b17023SJohn Marino int direction, bool original_scattering_p)
496e4b17023SJohn Marino {
497e4b17023SJohn Marino PTR *x = NULL;
498e4b17023SJohn Marino poly_ddr_p res;
499e4b17023SJohn Marino bool may_alias;
500e4b17023SJohn Marino
501e4b17023SJohn Marino /* Return the PDDR from the cache if it already has been computed. */
502e4b17023SJohn Marino if (original_scattering_p)
503e4b17023SJohn Marino {
504e4b17023SJohn Marino struct poly_ddr tmp;
505e4b17023SJohn Marino scop_p scop = PBB_SCOP (PDR_PBB (pdr1));
506e4b17023SJohn Marino
507e4b17023SJohn Marino tmp.source = pdr1;
508e4b17023SJohn Marino tmp.sink = pdr2;
509e4b17023SJohn Marino x = htab_find_slot (SCOP_ORIGINAL_PDDRS (scop),
510e4b17023SJohn Marino &tmp, INSERT);
511e4b17023SJohn Marino
512e4b17023SJohn Marino if (x && *x)
513e4b17023SJohn Marino return (poly_ddr_p) *x;
514e4b17023SJohn Marino }
515e4b17023SJohn Marino
516e4b17023SJohn Marino res = XNEW (struct poly_ddr);
517e4b17023SJohn Marino PDDR_SOURCE (res) = pdr1;
518e4b17023SJohn Marino PDDR_SINK (res) = pdr2;
519e4b17023SJohn Marino PDDR_DDP (res) = NULL;
520e4b17023SJohn Marino PDDR_ORIGINAL_SCATTERING_P (res) = original_scattering_p;
521e4b17023SJohn Marino PDDR_KIND (res) = unknown_dependence;
522e4b17023SJohn Marino
523e4b17023SJohn Marino may_alias = poly_drs_may_alias_p (pdr1, pdr2);
524e4b17023SJohn Marino
525e4b17023SJohn Marino if (!(pdr_read_p (pdr1) && pdr_read_p (pdr2))
526e4b17023SJohn Marino && PDR_BASE_OBJECT_SET (pdr1) != PDR_BASE_OBJECT_SET (pdr2)
527e4b17023SJohn Marino && may_alias)
528e4b17023SJohn Marino PDDR_KIND (res) = unknown_dependence;
529e4b17023SJohn Marino
530e4b17023SJohn Marino else if (!(pdr_read_p (pdr1) && pdr_read_p (pdr2))
531e4b17023SJohn Marino && same_pdr_p (pdr1, pdr2)
532e4b17023SJohn Marino && may_alias)
533e4b17023SJohn Marino {
534e4b17023SJohn Marino PDDR_DDP (res) = dependence_polyhedron (pdr1, pdr2, direction,
535e4b17023SJohn Marino original_scattering_p);
536e4b17023SJohn Marino if (PDDR_DDP (res))
537e4b17023SJohn Marino PDDR_KIND (res) = has_dependence;
538e4b17023SJohn Marino else
539e4b17023SJohn Marino PDDR_KIND (res) = no_dependence;
540e4b17023SJohn Marino }
541e4b17023SJohn Marino else
542e4b17023SJohn Marino PDDR_KIND (res) = no_dependence;
543e4b17023SJohn Marino
544e4b17023SJohn Marino if (original_scattering_p)
545e4b17023SJohn Marino *x = res;
546e4b17023SJohn Marino
547e4b17023SJohn Marino return res;
548e4b17023SJohn Marino }
549e4b17023SJohn Marino
550e4b17023SJohn Marino /* Free the data dependence relation poly_ddr_p P. */
551e4b17023SJohn Marino
552e4b17023SJohn Marino void
free_poly_ddr(void * p)553e4b17023SJohn Marino free_poly_ddr (void *p)
554e4b17023SJohn Marino {
555e4b17023SJohn Marino poly_ddr_p pddr = (poly_ddr_p) p;
556e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (PDDR_DDP (pddr));
557e4b17023SJohn Marino free (pddr);
558e4b17023SJohn Marino }
559e4b17023SJohn Marino
560e4b17023SJohn Marino /* Return true when the data dependence relation between the data
561e4b17023SJohn Marino references PDR1 belonging to PBB1 and PDR2 is part of a
562e4b17023SJohn Marino reduction. */
563e4b17023SJohn Marino
564e4b17023SJohn Marino static inline bool
reduction_dr_1(poly_bb_p pbb1,poly_dr_p pdr1,poly_dr_p pdr2)565e4b17023SJohn Marino reduction_dr_1 (poly_bb_p pbb1, poly_dr_p pdr1, poly_dr_p pdr2)
566e4b17023SJohn Marino {
567e4b17023SJohn Marino int i;
568e4b17023SJohn Marino poly_dr_p pdr;
569e4b17023SJohn Marino
570e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb1), i, pdr)
571e4b17023SJohn Marino if (PDR_TYPE (pdr) == PDR_WRITE
572e4b17023SJohn Marino && same_pdr_p (pdr, pdr1) && same_pdr_p (pdr, pdr2))
573e4b17023SJohn Marino return true;
574e4b17023SJohn Marino
575e4b17023SJohn Marino return false;
576e4b17023SJohn Marino }
577e4b17023SJohn Marino
578e4b17023SJohn Marino /* Return true when the data dependence relation between the data
579e4b17023SJohn Marino references PDR1 belonging to PBB1 and PDR2 belonging to PBB2 is
580e4b17023SJohn Marino part of a reduction. */
581e4b17023SJohn Marino
582e4b17023SJohn Marino static inline bool
reduction_dr_p(poly_dr_p pdr1,poly_dr_p pdr2)583e4b17023SJohn Marino reduction_dr_p (poly_dr_p pdr1, poly_dr_p pdr2)
584e4b17023SJohn Marino {
585e4b17023SJohn Marino poly_bb_p pbb1 = PDR_PBB (pdr1);
586e4b17023SJohn Marino poly_bb_p pbb2 = PDR_PBB (pdr2);
587e4b17023SJohn Marino
588e4b17023SJohn Marino if (PBB_IS_REDUCTION (pbb1))
589e4b17023SJohn Marino return reduction_dr_1 (pbb1, pdr1, pdr2);
590e4b17023SJohn Marino
591e4b17023SJohn Marino if (PBB_IS_REDUCTION (pbb2))
592e4b17023SJohn Marino return reduction_dr_1 (pbb2, pdr2, pdr1);
593e4b17023SJohn Marino
594e4b17023SJohn Marino return false;
595e4b17023SJohn Marino }
596e4b17023SJohn Marino
597e4b17023SJohn Marino /* Returns true when the PBB_TRANSFORMED_SCATTERING functions of PBB1
598e4b17023SJohn Marino and PBB2 respect the data dependences of PBB_ORIGINAL_SCATTERING
599e4b17023SJohn Marino functions. */
600e4b17023SJohn Marino
601e4b17023SJohn Marino static bool
graphite_legal_transform_dr(poly_dr_p pdr1,poly_dr_p pdr2)602e4b17023SJohn Marino graphite_legal_transform_dr (poly_dr_p pdr1, poly_dr_p pdr2)
603e4b17023SJohn Marino {
604e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t po, pt;
605e4b17023SJohn Marino graphite_dim_t ddim1, otdim1, otdim2, ttdim1, ttdim2;
606e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t po_temp;
607e4b17023SJohn Marino ppl_dimension_type pdim;
608e4b17023SJohn Marino bool is_empty_p;
609e4b17023SJohn Marino poly_ddr_p opddr, tpddr;
610e4b17023SJohn Marino poly_bb_p pbb1, pbb2;
611e4b17023SJohn Marino
612e4b17023SJohn Marino if (reduction_dr_p (pdr1, pdr2))
613e4b17023SJohn Marino return true;
614e4b17023SJohn Marino
615e4b17023SJohn Marino /* We build the reverse dependence relation for the transformed
616e4b17023SJohn Marino scattering, such that when we intersect it with the original PO,
617e4b17023SJohn Marino we get an empty intersection when the transform is legal:
618e4b17023SJohn Marino i.e. the transform should reverse no dependences, and so PT, the
619e4b17023SJohn Marino reversed transformed PDDR, should have no constraint from PO. */
620e4b17023SJohn Marino opddr = new_poly_ddr (pdr1, pdr2, 1, true);
621e4b17023SJohn Marino
622e4b17023SJohn Marino if (PDDR_KIND (opddr) == unknown_dependence)
623e4b17023SJohn Marino return false;
624e4b17023SJohn Marino
625e4b17023SJohn Marino /* There are no dependences between PDR1 and PDR2 in the original
626e4b17023SJohn Marino version of the program, or after the transform, so the
627e4b17023SJohn Marino transform is legal. */
628e4b17023SJohn Marino if (pddr_is_empty (opddr))
629e4b17023SJohn Marino return true;
630e4b17023SJohn Marino
631e4b17023SJohn Marino tpddr = new_poly_ddr (pdr1, pdr2, -1, false);
632e4b17023SJohn Marino
633e4b17023SJohn Marino if (PDDR_KIND (tpddr) == unknown_dependence)
634e4b17023SJohn Marino {
635e4b17023SJohn Marino free_poly_ddr (tpddr);
636e4b17023SJohn Marino return false;
637e4b17023SJohn Marino }
638e4b17023SJohn Marino
639e4b17023SJohn Marino if (pddr_is_empty (tpddr))
640e4b17023SJohn Marino {
641e4b17023SJohn Marino free_poly_ddr (tpddr);
642e4b17023SJohn Marino return true;
643e4b17023SJohn Marino }
644e4b17023SJohn Marino
645e4b17023SJohn Marino po = PDDR_DDP (opddr);
646e4b17023SJohn Marino pt = PDDR_DDP (tpddr);
647e4b17023SJohn Marino
648e4b17023SJohn Marino /* Copy PO into PO_TEMP, such that PO is not destroyed. PO is
649e4b17023SJohn Marino stored in a cache and should not be modified or freed. */
650e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_space_dimension (po, &pdim);
651e4b17023SJohn Marino ppl_new_Pointset_Powerset_C_Polyhedron_from_space_dimension (&po_temp,
652e4b17023SJohn Marino pdim, 0);
653e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (po_temp, po);
654e4b17023SJohn Marino
655e4b17023SJohn Marino /* Extend PO and PT to have the same dimensions. */
656e4b17023SJohn Marino pbb1 = PDR_PBB (pdr1);
657e4b17023SJohn Marino pbb2 = PDR_PBB (pdr2);
658e4b17023SJohn Marino ddim1 = pbb_dim_iter_domain (pbb1);
659e4b17023SJohn Marino otdim1 = pbb_nb_scattering_orig (pbb1);
660e4b17023SJohn Marino otdim2 = pbb_nb_scattering_orig (pbb2);
661e4b17023SJohn Marino ttdim1 = pbb_nb_scattering_transform (pbb1);
662e4b17023SJohn Marino ttdim2 = pbb_nb_scattering_transform (pbb2);
663e4b17023SJohn Marino ppl_insert_dimensions_pointset (po_temp, otdim1, ttdim1);
664e4b17023SJohn Marino ppl_insert_dimensions_pointset (po_temp, otdim1 + ttdim1 + ddim1 + otdim2,
665e4b17023SJohn Marino ttdim2);
666e4b17023SJohn Marino ppl_insert_dimensions_pointset (pt, 0, otdim1);
667e4b17023SJohn Marino ppl_insert_dimensions_pointset (pt, otdim1 + ttdim1 + ddim1, otdim2);
668e4b17023SJohn Marino
669e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (po_temp, pt);
670e4b17023SJohn Marino is_empty_p = ppl_powerset_is_empty (po_temp);
671e4b17023SJohn Marino
672e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (po_temp);
673e4b17023SJohn Marino free_poly_ddr (tpddr);
674e4b17023SJohn Marino
675e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
676e4b17023SJohn Marino fprintf (dump_file, "\nloop carries dependency.\n");
677e4b17023SJohn Marino
678e4b17023SJohn Marino return is_empty_p;
679e4b17023SJohn Marino }
680e4b17023SJohn Marino
681e4b17023SJohn Marino /* Return true when the data dependence relation for PBB1 and PBB2 is
682e4b17023SJohn Marino part of a reduction. */
683e4b17023SJohn Marino
684e4b17023SJohn Marino static inline bool
reduction_ddr_p(poly_bb_p pbb1,poly_bb_p pbb2)685e4b17023SJohn Marino reduction_ddr_p (poly_bb_p pbb1, poly_bb_p pbb2)
686e4b17023SJohn Marino {
687e4b17023SJohn Marino return pbb1 == pbb2 && PBB_IS_REDUCTION (pbb1);
688e4b17023SJohn Marino }
689e4b17023SJohn Marino
690e4b17023SJohn Marino /* Iterates over the data references of PBB1 and PBB2 and detect
691e4b17023SJohn Marino whether the transformed schedule is correct. */
692e4b17023SJohn Marino
693e4b17023SJohn Marino static bool
graphite_legal_transform_bb(poly_bb_p pbb1,poly_bb_p pbb2)694e4b17023SJohn Marino graphite_legal_transform_bb (poly_bb_p pbb1, poly_bb_p pbb2)
695e4b17023SJohn Marino {
696e4b17023SJohn Marino int i, j;
697e4b17023SJohn Marino poly_dr_p pdr1, pdr2;
698e4b17023SJohn Marino
699e4b17023SJohn Marino if (!PBB_PDR_DUPLICATES_REMOVED (pbb1))
700e4b17023SJohn Marino pbb_remove_duplicate_pdrs (pbb1);
701e4b17023SJohn Marino
702e4b17023SJohn Marino if (!PBB_PDR_DUPLICATES_REMOVED (pbb2))
703e4b17023SJohn Marino pbb_remove_duplicate_pdrs (pbb2);
704e4b17023SJohn Marino
705e4b17023SJohn Marino if (reduction_ddr_p (pbb1, pbb2))
706e4b17023SJohn Marino return true;
707e4b17023SJohn Marino
708e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb1), i, pdr1)
709e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb2), j, pdr2)
710e4b17023SJohn Marino if (!graphite_legal_transform_dr (pdr1, pdr2))
711e4b17023SJohn Marino return false;
712e4b17023SJohn Marino
713e4b17023SJohn Marino return true;
714e4b17023SJohn Marino }
715e4b17023SJohn Marino
716e4b17023SJohn Marino /* Iterates over the SCOP and detect whether the transformed schedule
717e4b17023SJohn Marino is correct. */
718e4b17023SJohn Marino
719e4b17023SJohn Marino bool
graphite_legal_transform(scop_p scop)720e4b17023SJohn Marino graphite_legal_transform (scop_p scop)
721e4b17023SJohn Marino {
722e4b17023SJohn Marino int i, j;
723e4b17023SJohn Marino poly_bb_p pbb1, pbb2;
724e4b17023SJohn Marino
725e4b17023SJohn Marino timevar_push (TV_GRAPHITE_DATA_DEPS);
726e4b17023SJohn Marino
727e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb1)
728e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), j, pbb2)
729e4b17023SJohn Marino if (!graphite_legal_transform_bb (pbb1, pbb2))
730e4b17023SJohn Marino {
731e4b17023SJohn Marino timevar_pop (TV_GRAPHITE_DATA_DEPS);
732e4b17023SJohn Marino return false;
733e4b17023SJohn Marino }
734e4b17023SJohn Marino
735e4b17023SJohn Marino timevar_pop (TV_GRAPHITE_DATA_DEPS);
736e4b17023SJohn Marino return true;
737e4b17023SJohn Marino }
738e4b17023SJohn Marino
739e4b17023SJohn Marino /* Returns TRUE when the dependence polyhedron between PDR1 and
740e4b17023SJohn Marino PDR2 represents a loop carried dependence at level LEVEL. */
741e4b17023SJohn Marino
742e4b17023SJohn Marino static bool
graphite_carried_dependence_level_k(poly_dr_p pdr1,poly_dr_p pdr2,int level)743e4b17023SJohn Marino graphite_carried_dependence_level_k (poly_dr_p pdr1, poly_dr_p pdr2,
744e4b17023SJohn Marino int level)
745e4b17023SJohn Marino {
746e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t po;
747e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_t eqpp;
748e4b17023SJohn Marino poly_bb_p pbb = PDR_PBB (pdr1);
749e4b17023SJohn Marino graphite_dim_t tdim1 = pbb_nb_scattering_transform (pbb);
750e4b17023SJohn Marino graphite_dim_t ddim1 = pbb_dim_iter_domain (pbb);
751e4b17023SJohn Marino ppl_dimension_type dim;
752e4b17023SJohn Marino bool empty_p;
753e4b17023SJohn Marino poly_ddr_p pddr = new_poly_ddr (pdr1, pdr2, 1, false);
754e4b17023SJohn Marino graphite_dim_t pos;
755e4b17023SJohn Marino
756e4b17023SJohn Marino if (PDDR_KIND (pddr) == unknown_dependence)
757e4b17023SJohn Marino {
758e4b17023SJohn Marino free_poly_ddr (pddr);
759e4b17023SJohn Marino return true;
760e4b17023SJohn Marino }
761e4b17023SJohn Marino
762e4b17023SJohn Marino if (pddr_is_empty (pddr))
763e4b17023SJohn Marino {
764e4b17023SJohn Marino free_poly_ddr (pddr);
765e4b17023SJohn Marino return false;
766e4b17023SJohn Marino }
767e4b17023SJohn Marino
768e4b17023SJohn Marino po = PDDR_DDP (pddr);
769e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_space_dimension (po, &dim);
770e4b17023SJohn Marino pos = psct_dynamic_dim (pbb, level);
771e4b17023SJohn Marino eqpp = build_pairwise_scheduling (dim, pos, tdim1 + ddim1, 1);
772e4b17023SJohn Marino
773e4b17023SJohn Marino ppl_Pointset_Powerset_C_Polyhedron_intersection_assign (eqpp, po);
774e4b17023SJohn Marino empty_p = ppl_powerset_is_empty (eqpp);
775e4b17023SJohn Marino
776e4b17023SJohn Marino ppl_delete_Pointset_Powerset_C_Polyhedron (eqpp);
777e4b17023SJohn Marino free_poly_ddr (pddr);
778e4b17023SJohn Marino
779e4b17023SJohn Marino return !empty_p;
780e4b17023SJohn Marino }
781e4b17023SJohn Marino
782e4b17023SJohn Marino /* Check data dependency between PBB1 and PBB2 at level LEVEL. */
783e4b17023SJohn Marino
784e4b17023SJohn Marino bool
dependency_between_pbbs_p(poly_bb_p pbb1,poly_bb_p pbb2,int level)785e4b17023SJohn Marino dependency_between_pbbs_p (poly_bb_p pbb1, poly_bb_p pbb2, int level)
786e4b17023SJohn Marino {
787e4b17023SJohn Marino int i, j;
788e4b17023SJohn Marino poly_dr_p pdr1, pdr2;
789e4b17023SJohn Marino
790e4b17023SJohn Marino timevar_push (TV_GRAPHITE_DATA_DEPS);
791e4b17023SJohn Marino
792e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb1), i, pdr1)
793e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb2), j, pdr2)
794e4b17023SJohn Marino if (graphite_carried_dependence_level_k (pdr1, pdr2, level))
795e4b17023SJohn Marino {
796e4b17023SJohn Marino timevar_pop (TV_GRAPHITE_DATA_DEPS);
797e4b17023SJohn Marino return true;
798e4b17023SJohn Marino }
799e4b17023SJohn Marino
800e4b17023SJohn Marino timevar_pop (TV_GRAPHITE_DATA_DEPS);
801e4b17023SJohn Marino return false;
802e4b17023SJohn Marino }
803e4b17023SJohn Marino
804e4b17023SJohn Marino /* When ORIG is true, pretty print to FILE all the original data
805e4b17023SJohn Marino dependences of SCoP in DOT format, otherwise print the transformed
806e4b17023SJohn Marino data deps. */
807e4b17023SJohn Marino
808e4b17023SJohn Marino static void
dot_deps_stmt_2(FILE * file,scop_p scop,bool orig)809e4b17023SJohn Marino dot_deps_stmt_2 (FILE *file, scop_p scop, bool orig)
810e4b17023SJohn Marino {
811e4b17023SJohn Marino int i, j, k, l;
812e4b17023SJohn Marino poly_bb_p pbb1, pbb2;
813e4b17023SJohn Marino poly_dr_p pdr1, pdr2;
814e4b17023SJohn Marino
815e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb1)
816e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), j, pbb2)
817e4b17023SJohn Marino {
818e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb1), k, pdr1)
819e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb2), l, pdr2)
820e4b17023SJohn Marino {
821e4b17023SJohn Marino poly_ddr_p pddr = new_poly_ddr (pdr1, pdr2, 1, orig);
822e4b17023SJohn Marino
823e4b17023SJohn Marino if (!pddr_is_empty (pddr))
824e4b17023SJohn Marino {
825e4b17023SJohn Marino fprintf (file, orig ? "OS%d -> OS%d\n" : "TS%d -> TS%d\n",
826e4b17023SJohn Marino pbb_index (pbb1), pbb_index (pbb2));
827e4b17023SJohn Marino
828e4b17023SJohn Marino free_poly_ddr (pddr);
829e4b17023SJohn Marino goto done;
830e4b17023SJohn Marino }
831e4b17023SJohn Marino
832e4b17023SJohn Marino free_poly_ddr (pddr);
833e4b17023SJohn Marino }
834e4b17023SJohn Marino done:;
835e4b17023SJohn Marino }
836e4b17023SJohn Marino }
837e4b17023SJohn Marino
838e4b17023SJohn Marino /* Pretty print to FILE all the data dependences of SCoP in DOT
839e4b17023SJohn Marino format. */
840e4b17023SJohn Marino
841e4b17023SJohn Marino static void
dot_deps_stmt_1(FILE * file,scop_p scop)842e4b17023SJohn Marino dot_deps_stmt_1 (FILE *file, scop_p scop)
843e4b17023SJohn Marino {
844e4b17023SJohn Marino fputs ("digraph all {\n", file);
845e4b17023SJohn Marino
846e4b17023SJohn Marino dot_deps_stmt_2 (file, scop, true);
847e4b17023SJohn Marino dot_deps_stmt_2 (file, scop, false);
848e4b17023SJohn Marino
849e4b17023SJohn Marino fputs ("}\n\n", file);
850e4b17023SJohn Marino }
851e4b17023SJohn Marino
852e4b17023SJohn Marino /* When ORIG is true, pretty print to FILE all the original data
853e4b17023SJohn Marino dependences of SCoP in DOT format, otherwise print the transformed
854e4b17023SJohn Marino data deps. */
855e4b17023SJohn Marino
856e4b17023SJohn Marino static void
dot_deps_2(FILE * file,scop_p scop,bool orig)857e4b17023SJohn Marino dot_deps_2 (FILE *file, scop_p scop, bool orig)
858e4b17023SJohn Marino {
859e4b17023SJohn Marino int i, j, k, l;
860e4b17023SJohn Marino poly_bb_p pbb1, pbb2;
861e4b17023SJohn Marino poly_dr_p pdr1, pdr2;
862e4b17023SJohn Marino
863e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb1)
864e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), j, pbb2)
865e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb1), k, pdr1)
866e4b17023SJohn Marino FOR_EACH_VEC_ELT (poly_dr_p, PBB_DRS (pbb2), l, pdr2)
867e4b17023SJohn Marino {
868e4b17023SJohn Marino poly_ddr_p pddr = new_poly_ddr (pdr1, pdr2, 1, orig);
869e4b17023SJohn Marino
870e4b17023SJohn Marino if (!pddr_is_empty (pddr))
871e4b17023SJohn Marino fprintf (file, orig
872e4b17023SJohn Marino ? "OS%d_D%d -> OS%d_D%d\n" : "TS%d_D%d -> TS%d_D%d\n",
873e4b17023SJohn Marino pbb_index (pbb1), PDR_ID (pdr1),
874e4b17023SJohn Marino pbb_index (pbb2), PDR_ID (pdr2));
875e4b17023SJohn Marino
876e4b17023SJohn Marino free_poly_ddr (pddr);
877e4b17023SJohn Marino }
878e4b17023SJohn Marino }
879e4b17023SJohn Marino
880e4b17023SJohn Marino /* Pretty print to FILE all the data dependences of SCoP in DOT
881e4b17023SJohn Marino format. */
882e4b17023SJohn Marino
883e4b17023SJohn Marino static void
dot_deps_1(FILE * file,scop_p scop)884e4b17023SJohn Marino dot_deps_1 (FILE *file, scop_p scop)
885e4b17023SJohn Marino {
886e4b17023SJohn Marino fputs ("digraph all {\n", file);
887e4b17023SJohn Marino
888e4b17023SJohn Marino dot_deps_2 (file, scop, true);
889e4b17023SJohn Marino dot_deps_2 (file, scop, false);
890e4b17023SJohn Marino
891e4b17023SJohn Marino fputs ("}\n\n", file);
892e4b17023SJohn Marino }
893e4b17023SJohn Marino
894e4b17023SJohn Marino /* Display all the data dependences in SCoP using dotty. */
895e4b17023SJohn Marino
896e4b17023SJohn Marino DEBUG_FUNCTION void
dot_deps(scop_p scop)897e4b17023SJohn Marino dot_deps (scop_p scop)
898e4b17023SJohn Marino {
899e4b17023SJohn Marino /* When debugging, enable the following code. This cannot be used
900e4b17023SJohn Marino in production compilers because it calls "system". */
901e4b17023SJohn Marino #if 0
902e4b17023SJohn Marino FILE *stream = fopen ("/tmp/scopdeps.dot", "w");
903e4b17023SJohn Marino gcc_assert (stream);
904e4b17023SJohn Marino
905e4b17023SJohn Marino dot_deps_1 (stream, scop);
906e4b17023SJohn Marino fclose (stream);
907e4b17023SJohn Marino
908e4b17023SJohn Marino system ("dotty /tmp/scopdeps.dot &");
909e4b17023SJohn Marino #else
910e4b17023SJohn Marino dot_deps_1 (stderr, scop);
911e4b17023SJohn Marino #endif
912e4b17023SJohn Marino }
913e4b17023SJohn Marino
914e4b17023SJohn Marino /* Display all the statement dependences in SCoP using dotty. */
915e4b17023SJohn Marino
916e4b17023SJohn Marino DEBUG_FUNCTION void
dot_deps_stmt(scop_p scop)917e4b17023SJohn Marino dot_deps_stmt (scop_p scop)
918e4b17023SJohn Marino {
919e4b17023SJohn Marino /* When debugging, enable the following code. This cannot be used
920e4b17023SJohn Marino in production compilers because it calls "system". */
921e4b17023SJohn Marino #if 0
922e4b17023SJohn Marino FILE *stream = fopen ("/tmp/scopdeps.dot", "w");
923e4b17023SJohn Marino gcc_assert (stream);
924e4b17023SJohn Marino
925e4b17023SJohn Marino dot_deps_stmt_1 (stream, scop);
926e4b17023SJohn Marino fclose (stream);
927e4b17023SJohn Marino
928e4b17023SJohn Marino system ("dotty /tmp/scopdeps.dot &");
929e4b17023SJohn Marino #else
930e4b17023SJohn Marino dot_deps_stmt_1 (stderr, scop);
931e4b17023SJohn Marino #endif
932e4b17023SJohn Marino }
933e4b17023SJohn Marino
934e4b17023SJohn Marino #endif
935