PIPS
sc_new_loop_bound.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sc_new_loop_bound.c 1671 2019-06-26 19:14:11Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28 
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include "linear_assert.h"
32 
33 #include "boolean.h"
34 #include "arithmetique.h"
35 #include "vecteur.h"
36 #include "contrainte.h"
37 #include "sc.h"
38 
39 /* Psysteme new_loop_bound(Psysteme scn, Pbase base_index)
40  * computation of the new iteration space (given the loop bounds)
41  * in the new basis G
42  *
43  * scn is destroyed
44  *
45  * if the list of indexes is empty, the system is assumed to
46  * be a list of constraints that have to be verified for the set
47  * of solutions not to be empty, so scn is returned.
48  *
49  * Reference about the algorithm PPoPP'91
50  */
52 (Psysteme scn,
53  Pbase base_index)
54 {
55  Psysteme
56  result = NULL,
57  condition = NULL,
58  enumeration = NULL;
59 
60  algorithm_row_echelon_generic(scn, base_index,
61  &condition, &enumeration, false);
62 
63  sc_rm(scn);
64  scn = NULL;
65  result = sc_fusion(condition, enumeration);
66 
67  return result;
68 }
69 
70 /* Psysteme get_other_constraints(psyst, vars)
71  * Psysteme *psyst;
72  * Pbase vars;
73  *
74  * IN: vars
75  * IN/OUT: psyst
76  * OUT: returned system
77  *
78  * returns the constraints that do not contain any of the variables listed
79  * in Pbase vars, which are removed from the original Psysteme *psyst.
80  * if the original system is undefined, the same thing is returned.
81  *
82  * (c) FC 16/05/94
83  */
85  Psysteme *psyst;
86  Pbase vars;
87 {
89  egothers = (Pcontrainte) NULL,
90  inothers = (Pcontrainte) NULL,
91  egsyst = (Pcontrainte) NULL,
92  insyst = (Pcontrainte) NULL;
93 
94  assert(!SC_UNDEFINED_P(*psyst));
95 
96  if (sc_empty_p(*psyst))
97  return(sc_empty(base_difference(sc_base(*psyst), vars)));
98  /* else
99  */
100  Pcontrainte_separate_on_vars(sc_egalites(*psyst),
101  vars, &egsyst, &egothers);
102  Pcontrainte_separate_on_vars(sc_inegalites(*psyst),
103  vars, &insyst, &inothers);
104 
105  /* result in built and syst is modified.
106  */
107  *psyst = (sc_rm(*psyst), sc_make(egsyst, insyst));
108  return sc_make(egothers, inothers);
109 }
110 
111 /*----------------------------------------------------------
112  *
113  * ALGORITHM ROW ECHELON from Ancourt and Irigoin, PPoPP'91
114  *
115  * The algorithm is slightly different:
116  *
117  * conditions are taken out of the system built.
118  *
119  * void algorithm_row_echelon(syst, scans, pcondition, penumeration)
120  * Psysteme syst;
121  * Pbase scans;
122  * Psysteme *pcondition, *penumeration;
123  *
124  * IN: syst, scans
125  * OUT: pcondition, penumeration
126  *
127  * (c) FC 16/05/94
128  */
129 
130 /* each variable should be at least within one <= and one >=;
131  * scn IS NOT modified.
132  */
133 void
135  Psysteme scn, /* initial system, which is not touched. */
136  Pbase base_index, /* enumeration variables, from outer to inner. */
137  Psysteme *pcondition, /* returned condition (what remains from scn). */
138  Psysteme *penumeration, /* returned enumeration system. */
139  bool redundancy /* whether to allow outwards redundancy. */)
140 {
141  int i, dimension = vect_size(base_index);
142  Psysteme ps_interm, ps_project, ps_tmp;
143  Pbase reverse_base;
144  Pvecteur pb;
145  Pcontrainte ineq = NULL,
146  *c = (Pcontrainte*) malloc(sizeof(Pcontrainte)*(dimension+1));
147 
148  if (VECTEUR_NUL_P(base_index))
149  {
150  *penumeration = sc_rn(NULL);
151  *pcondition = sc_dup(scn);
152  return;
153  }
154 
155  // check base consistency
156  assert(vect_in_basis_p(base_index, scn->base));
157 
158  ps_project = sc_dup(scn);
159  sc_transform_eg_in_ineg(ps_project);
160  ps_project = sc_sort_constraints(ps_project, base_index);
161  ps_project = sc_elim_redond(ps_project);
162 
163  if (SC_UNDEFINED_P(ps_project))
164  ps_project = sc_empty(base_difference(sc_base(scn), base_index));
165 
166  if (sc_empty_p(ps_project))
167  {
168  *penumeration = sc_empty(base_index);
169  *pcondition = ps_project;
170  return;
171  }
172 
173  reverse_base = base_reversal(base_index);
174 
175  for (pb=reverse_base, i=dimension;
176  !VECTEUR_NUL_P(pb);
177  pb=pb->succ, i--)
178  {
179  c[i] = contrainte_dup_extract(sc_inegalites(ps_project), pb->var);
180 
181  ps_project = sc_projection(ps_project, pb->var);
182  vect_erase_var(&sc_base(ps_project), pb->var);
183  ps_project->dimension--;
184  ps_project = sc_triang_elim_redund(ps_project, base_index);
185  }
186 
187  if (ps_project==NULL || sc_empty_p(ps_project))
188  {
189  *penumeration = sc_empty(base_index);
190  *pcondition = ps_project;
191  return;
192  }
193 
194  c[0] = contrainte_dup_extract(sc_inegalites(ps_project), NULL);
195  sc_rm(ps_project);
196 
197  for (i=0; i<dimension+1; i++)
198  ineq = contrainte_append(c[i], ineq);
199 
200  ps_interm = sc_make(NULL, ineq);
201 
202  /* returns a a la Omega system, with no innerward redundancy.
203  * in fact this is just a quick approximation of that property.
204  * the way the system is computed may keep some outerward redundancies,
205  * because a constraint may be redundant with some not yet computed
206  * projection...
207  */
208  if (redundancy)
209  {
210  *pcondition = get_other_constraints(&ps_interm, base_index);
211  sc_transform_ineg_in_eg(*pcondition);
212  *penumeration = ps_interm;
213 
214  return;
215  }
216 
217  /* ELSE remove redundancy in the system...
218  *
219  * include the original system again, to recover simple
220  * constraints that may have been removed.
221  * May not be interesting...
222  */
223  ps_tmp = sc_dup(scn);
224  sc_transform_eg_in_ineg(ps_tmp);
225  //assert(sc_consistent_p(ps_tmp));
226  //assert(sc_consistent_p(ps_interm));
227  // sc_fusion() is declared obsolete: sc_append() and
228  // sc_intersection() are suggested as replacements
229  //ps_interm = sc_fusion(ps_interm, ps_tmp);
230  ps_interm = sc_append(ps_interm, ps_tmp);
231  //assert(sc_consistent_p(ps_interm));
232  ps_interm = sc_triang_elim_redund(ps_interm, base_index);
233 
234  *pcondition = get_other_constraints(&ps_interm, base_index);
235  sc_transform_ineg_in_eg(*pcondition);
236  *penumeration = ps_interm;
237 
238  base_rm(reverse_base), free(c);
239 
240  /* what is returned must be ok.
241  */
242  assert(!SC_UNDEFINED_P(*pcondition) && !SC_UNDEFINED_P(*penumeration));
243 }
244 
245 /* see comments above.
246  */
247 void
249  Psysteme scn,
250  Pbase base_index,
251  Psysteme *pcondition,
252  Psysteme *penumeration)
253 {
255  (scn, base_index, pcondition, penumeration, false);
256 }
257 
259 {
260  return;
261 }
262 
263 
264 /*----------------------------------------------------------
265  *
266  * ALGORITHM TILING from Ancourt and Irigoin, PPoPP'91
267  *
268  * The algorithm is slightly different:
269  *
270  * constraints may appear thru the projections that do not contain the
271  * desired loop variables. These constraints are taken out of the
272  * systems. The inner ones are reinjected to help for the outer loop, and
273  * those of the outer loop are stored as conditions to be checked before
274  * the loop nest. The intuition is that if these constraints are violated,
275  * the polyhedron is empty, and the loop nest *must* be avoided.
276  *
277  * Corinne ANCOURT, Fabien COELHO, Apr 1 94.
278  *
279  * - may be improved by recognizing equalities?
280  * then deducable variables could be rebuilt.
281  * - there should be no equalities on the scanners...
282  *
283  * void algorithm_tiling(syst, outer, inner,
284  * pcondition, ptile_enum, piter_enum)
285  * Psysteme syst;
286  * Pbase outer, inner;
287  * Psysteme *pcondition, *ptile_enum, *piter_enum;
288  *
289  * IN: syst, outer, inner
290  * OUT: pcondition, ptile_enum, piter_enum
291  */
293 (Psysteme syst,
294  Pbase outer,
295  Pbase inner,
296  Psysteme *pcondition,
297  Psysteme *ptile_enum,
298  Psysteme *piter_enum)
299 {
300  Psysteme sc = SC_UNDEFINED, transfer = SC_UNDEFINED;
301  Pbase b = BASE_NULLE;
302 
303  /* tiles iterations enumeration row echelon
304  */
305  algorithm_row_echelon_generic(syst, inner, &transfer, piter_enum, true);
306 
307  if (sc_empty_p(transfer))
308  {
309  sc_rm(transfer), sc_rm(*piter_enum),
310  *piter_enum = sc_empty(BASE_NULLE),
311  *ptile_enum = sc_empty(BASE_NULLE),
312  *pcondition = sc_empty(BASE_NULLE);
313  return;
314  }
315 
316  /* project variables
317  */
318  for(b=inner, sc=sc_safe_intersection(sc_rn(BASE_NULLE), syst, transfer);
319  b!=BASE_NULLE;
320  sc=sc_projection(sc, var_of(b)), b=b->succ);
321 
322  sc_rm(transfer);
323  sc_nredund(&sc);
324 
325  /* tiles enumeration row echelon
326  */
327  algorithm_row_echelon_generic(sc, outer, pcondition, ptile_enum, true);
328 
329  if (sc_empty_p(*pcondition))
330  {
331  sc_rm(*piter_enum), sc_rm(*ptile_enum),
332  *piter_enum = sc_empty(BASE_NULLE),
333  *ptile_enum = sc_empty(BASE_NULLE);
334  return;
335  }
336 
337  /* clean bases
338  */
339  sc_base(*ptile_enum)=(base_rm(sc_base(*ptile_enum)), BASE_NULLE),
340  sc_creer_base(*ptile_enum);
341 
342  sc_base(*piter_enum)=(base_rm(sc_base(*piter_enum)), BASE_NULLE),
343  sc_creer_base(*piter_enum);
344 }
345 
346 /* that is all
347  */
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
Pbase base_difference(Pbase b1, Pbase b2)
Pbase base_difference(Pbase b1, Pbase b2): allocate b; b = b1 - b2 – with the set meaning return b;.
Definition: base.c:621
bool vect_in_basis_p(Pvecteur v, Pbase b)
Pvecteur vect_in_basis_p(Pvecteur v, Pbase b): check that all coordinates in v are in b,...
Definition: base.c:342
Pbase base_reversal(Pbase b_in)
Pbase base_reversal(Pbase b_in): produces a basis b_out, having the same basis vectors as b_in,...
Definition: base.c:221
struct Scontrainte * Pcontrainte
Pcontrainte contrainte_append(Pcontrainte c1, Pcontrainte c2)
Pcontrainte contrainte_append(c1, c2) Pcontrainte c1, c2;.
Definition: binaires.c:267
Pcontrainte contrainte_dup_extract(Pcontrainte, Variable)
Pcontrainte contrainte_dup_extract(c, var) Pcontrainte c; Variable var;.
Definition: unaires.c:215
void Pcontrainte_separate_on_vars(Pcontrainte, Pbase, Pcontrainte *, Pcontrainte *)
void Pcontrainte_separate_on_vars(initial, vars, pwith, pwithout) Pcontrainte initial; Pbase vars; Pc...
Definition: unaires.c:140
void * malloc(YYSIZE_T)
void free(void *)
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define assert(ex)
Definition: newgen_assert.h:41
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg)
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg): allocation et initialisation d'un systeme d'equ...
Definition: sc.c:78
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319
Psysteme sc_rn(Pbase b)
Psysteme sc_rn(Pbase b): build a Psysteme without constraints to define R^n, where n is b's dimension...
Definition: sc_alloc.c:336
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
Psysteme sc_append(Psysteme s1, Psysteme s2)
Psysteme sc_append(Psysteme s1, Psysteme s2): calcul de l'intersection des polyedres definis par s1 e...
Psysteme sc_safe_intersection(Psysteme s1, Psysteme s2, Psysteme s3)
Psysteme sc_safe_intersection(Psysteme s1, Psysteme s2, Psysteme s3) input : output : calcul d'un sys...
Psysteme sc_fusion(Psysteme s1, Psysteme s2)
package sc
void sc_set_row_echelon_redundancy(bool b __attribute__((unused)))
void algorithm_tiling(Psysteme syst, Pbase outer, Pbase inner, Psysteme *pcondition, Psysteme *ptile_enum, Psysteme *piter_enum)
Psysteme new_loop_bound(Psysteme scn, Pbase base_index)
Psysteme new_loop_bound(Psysteme scn, Pbase base_index) computation of the new iteration space (given...
void algorithm_row_echelon_generic(Psysteme scn, Pbase base_index, Psysteme *pcondition, Psysteme *penumeration, bool redundancy)
each variable should be at least within one <= and one >=; scn IS NOT modified.
Psysteme get_other_constraints(Psysteme *psyst, Pbase vars)
Psysteme get_other_constraints(psyst, vars) Psysteme *psyst; Pbase vars;.
void algorithm_row_echelon(Psysteme scn, Pbase base_index, Psysteme *pcondition, Psysteme *penumeration)
see comments above.
void sc_transform_ineg_in_eg(Psysteme sc)
Transform the two constraints A.x <= b and -A.x <= -b of system sc into an equality A....
void sc_transform_eg_in_ineg(Psysteme sc)
Package sc.
Psysteme sc_sort_constraints(Psysteme ps, Pbase base_index)
Psysteme sc_triang_elim_redund(Psysteme ps, Pbase base_index)
sort contrainte c, base b, relatively to sort_base, as defined by the switches.
Pbase base
Definition: sc-local.h:75
int dimension
Definition: sc-local.h:74
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Variable var
Definition: vecteur-local.h:90
struct Svecteur * succ
Definition: vecteur-local.h:92
#define VECTEUR_NUL_P(v)
#define base_rm(b)
#define var_of(varval)
#define BASE_NULLE
MACROS SUR LES BASES.
void vect_erase_var(Pvecteur *ppv, Variable v)
void vect_erase_var(Pvecteur * ppv, Variable v): projection du vecteur *ppv selon la direction v (i....
Definition: unaires.c:106