xref: /dflybsd-src/contrib/gcc-4.7/gcc/graphite-dependences.c (revision 81fc95a5293ee307c688a350a3feb4734aaddbb4)
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