PIPS
adg_predicate.c
Go to the documentation of this file.
1 /*
2 
3  $Id: adg_predicate.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS 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 General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* Name : adg_utils.c
28  * Package : array_dfg
29  * Author : Arnauld LESERVOT
30  * Date : 93/06/27
31  * Modified :
32  * Documents: "Le Calcul de l'Array Data Flow Graph dans PIPS
33  * Partie II : Implantation dans PIPS" A. LESERVOT
34  * "Dataflow Analysis of Array and Scalar References" P. FEAUTRIER
35  * Comments :
36  */
37 
38 #define GRAPH_IS_DG
39 #include "local.h"
40 
41 /* External variables */
42 extern int Gcount_re;
43 
44 /*=======================================================================*/
45 /* PREDICATE FUNCTIONS */
46 /*=======================================================================*/
47 
48 /*=======================================================================*/
49 /* predicate adg_get_predicate_of_loops( list loops ) AL 15/07/93
50  * Input : a list of loops.
51  * Output : a predicate which represents a conjonction of all
52  * conditions on each loop's indexes.
53  * COMMON use.
54  */
56 list loops;
57 {
58  predicate ret_pred = predicate_undefined;
59  Psysteme new_sc = NULL;
60  Pvecteur pv = NULL;
61 
62  debug(9, "adg_get_predicate_of_loops", "begin\n");
63  new_sc = sc_new();
64  for(; !ENDP( loops ); POP( loops )) {
65  loop l = NULL;
66  range ran = NULL;
67  expression low = NULL, upp = NULL;
68  Pvecteur pvi = NULL;
69 
70  l = LOOP(CAR( loops ));
71  pvi = vect_new( (Variable) loop_index( l ), VALUE_ONE);
72  ran = loop_range( l );
73  low = range_lower( ran );
74  upp = range_upper( ran );
75  pv = vect_substract( EXPRESSION_PVECTEUR(low), pvi );
76  sc_add_inegalite( new_sc, contrainte_make(pv) );
77  pv = vect_substract( pvi, EXPRESSION_PVECTEUR(upp) );
78  sc_add_inegalite( new_sc, contrainte_make(pv) );
79  }
80 
81  if ((new_sc->nb_ineq != 0) || (new_sc->nb_eq != 0)) {
82  new_sc->base = NULL;
83  sc_creer_base(new_sc);
84  ret_pred = make_predicate(new_sc);
85  }
86 
87  if ((get_debug_level() >= 9) && (ret_pred != predicate_undefined))
88  adg_fprint_psysteme(stderr, (Psysteme) predicate_system(ret_pred) );
89  debug(9, "adg_get_predicate_of_loops", "end\n");
90  return( ret_pred );
91 }
92 
93 
94 /*=======================================================================*/
95 /* list adg_predicate_list_dup( (list) ps_l ) AL 13/07/93
96  * Duplicates a list of Predicates.
97  * Was used to simulate union. dj_ functions should be used now.
98  */
100 list ps_l;
101 {
102  list ret_list = NIL;
103 
104  debug(9, "adg_predicate_list_dup", "begin \n");
105  for(; !ENDP( ps_l ); POP( ps_l )) {
106  Psysteme sc = NULL, new_sc = NULL;
107 
108  sc = (Psysteme) predicate_system( PREDICATE(CAR( ps_l )) );
109  new_sc = sc_dup( sc );
110  ADD_ELEMENT_TO_LIST(ret_list,PREDICATE,make_predicate(new_sc));
111  }
112 
113  debug(9, "adg_predicate_list_dup", "end \n");
114  return( ret_list );
115 }
116 
117 /*=======================================================================*/
118 /* list adg_make_disjunctions( (list) ps_l1, (list) ps_l2 ) AL 13/07/93
119  * Takes in two list of Predicate and returns a list of Predicates.
120  * Was used to simulate union. dj_ functions should be used now.
121  */
123 list ps_l1, ps_l2;
124 {
125  list ps_list = NIL, psl1 = NULL, psl2 = NULL, l1 = NULL, l2 = NULL;
126 
127  debug(9, "adg_make_disjunctions", "begin \n");
128  psl1 = adg_predicate_list_dup( ps_l1 );
129  psl2 = adg_predicate_list_dup( ps_l2 );
130  if (psl1 == NIL) RETURN(9, "adg_make_disjunctions", psl2);
131  if (psl2 == NIL) RETURN(9, "adg_make_disjunctions", psl1);
132 
133  for( l1 = psl1; !ENDP(l1); POP( l1 )) {
134  Psysteme p1 = NULL;
135 
136  p1 = (Psysteme) predicate_system(PREDICATE(CAR( l1 )));
137  for (l2 = psl2; !ENDP(l2); POP( l2 )) {
138  Psysteme p2 = NULL;
139  predicate pred = NULL;
140 
141  p2 = (Psysteme) predicate_system(PREDICATE(CAR( l2 )));
142  pred = make_predicate( sc_append( sc_dup(p2), p1 ) );
143  ADD_ELEMENT_TO_LIST( ps_list, PREDICATE, pred );
144  }
145  }
146 
147  debug(9, "adg_make_disjunctions", "end \n");
148  return( ps_list );
149 }
150 
151 /*=======================================================================*/
152 /* list adg_get_conjonctions( (expression) ndf_exp ) AL 13/07/93
153  * Returns a list of Predicates made of conjonctions,
154  * from an ndf expression.
155  * Was used to simulate union. dj_ functions should be used now.
156  */
158 expression ndf_exp;
159 {
160  syntax syn = NULL;
161  list ps_list = NIL, psl1 = NIL, psl2 = NIL;
162  list args = NIL;
163  call c = NULL;
164 
165  pips_debug(9, "exp : %s\n",
166  expression_to_string( ndf_exp )) );
167  syn = expression_syntax( ndf_exp );
168  if (!syntax_call_p( syn )) RETURN(9, "adg_get_conjonctions", ps_list );
169 
170  c = syntax_call( syn );
171  args = call_arguments( c );
172  if (ENTITY_OR_P(call_function( c ))) {
173  psl1 = adg_get_conjonctions(EXPRESSION(CAR( args )));
174  psl2 = adg_get_conjonctions(EXPRESSION(CAR(CDR( args ))));
175  ps_list = gen_nconc( ps_list, psl1 );
176  ps_list = gen_nconc( ps_list, psl2 );
177  }
178  else if (ENTITY_AND_P( call_function(c) )) {
179  Psysteme ps1, ps2;
180  /* We are in a conjonction form case */
181  psl1 = adg_get_conjonctions( EXPRESSION(CAR( args )) );
182  ps1 = (Psysteme) predicate_system(PREDICATE(CAR( psl1 )));
183  psl2 = adg_get_conjonctions( EXPRESSION(CAR(CDR( args ))) );
184  ps2 = (Psysteme) predicate_system(PREDICATE(CAR( psl2 )));
185  ps1 = sc_append( ps1, ps2 );
187  }
188  else if (ENTITY_GREATER_OR_EQUAL_P( call_function(c) )) {
189  normalized nexp;
190  expression e;
191  Psysteme new_sc = NULL;
192 
193  new_sc = sc_new();
194  e = EXPRESSION(CAR( args ));
195  nexp = NORMALIZE_EXPRESSION(e);
196  if(expression_to_int(EXPRESSION(CAR(CDR( args )))) != 0)
197  RETURN(9, "adg_get_conjonctions", ps_list);
198 
199  if( normalized_linear_p(nexp) ) {
200  Pvecteur new_vec = (Pvecteur) normalized_linear(nexp);
201  vect_chg_sgn( new_vec );
202  sc_add_inegalite(new_sc, contrainte_make(new_vec));
203  }
204  else {
205  fprintf(stderr, "\nNon linear expression :");
206  fprintf(stderr, " %s\n", expression_to_string(ndf_exp));
207  }
208  sc_creer_base( new_sc );
210  }
211  else
212  pips_internal_error("Expression : %s is not in a normal disjunctive form !",
213  expression_to_string( ndf_exp ) );
214 
215  debug(9, "adg_get_conjonctions", "end \n");
216  return( ps_list );
217 }
218 
219 /*=======================================================================*/
220 /* list adg_get_disjunctions( (list) exp_l ) AL 13/07/93
221  * exp_l is a list of normal disjunctive form expressions.
222  * It returns a list of Predicates. These Predicates, put together
223  * in a disjunctive form have the same bool value as a system
224  * of incoming expressions.
225  */
227 list exp_l;
228 {
229  list ps_list = NIL;
230 
231  debug( 7, "adg_get_disjunctions", "begin \n" );
232  for(; !ENDP( exp_l ); POP( exp_l )) {
233  expression exp = NULL;
234  list ps_l = NIL;
235 
236  exp = EXPRESSION(CAR( exp_l ));
237  ps_l = adg_get_conjonctions( exp );
238  ps_list = adg_make_disjunctions( ps_list, ps_l );
239  }
240 
241  if (get_debug_level()>8) adg_fprint_predicate_list( stderr, ps_list );
242  debug( 7, "adg_get_disjunctions", "end \n" );
243  return( ps_list );
244 }
245 
246 
247 /*=========================================================================*/
248 /* this is Alexis's function adg_expressions_to_predicate (see mapping) */
249 /* predicate adg_expressions_to_predicate(list exp_l): returns the predicate
250  * that has the inequalities given as expressions in "exp_l". For example:
251  * if A is an expresion of "exp_l" then we'll have the inequality A <= 0 in the
252  * predicate.
253  *
254  * If an expression is not linear, we warn the user.
255  *
256  * Note: if "exp_l" is empty then we return an undefined predicate.
257  */
259 list exp_l;
260 {
261  predicate new_pred = NULL;
262  Psysteme new_sc = NULL;
263 
264  debug(9, "my_adg_expressions_to_predicate", "begin \n");
265  if(exp_l == NIL) RETURN(9, "my_adg_expressions_to_predicate",predicate_undefined );
266 
267  new_sc = sc_new();
268  for(; !ENDP(exp_l) ; POP( exp_l) ) {
269  expression exp = EXPRESSION(CAR( exp_l ));
270  normalized nexp = NULL;
271 
273  nexp = NORMALIZE_EXPRESSION(exp);
274  if( normalized_linear_p(nexp) ) {
275  Pvecteur new_vec = (Pvecteur) normalized_linear(nexp);
276  sc_add_inegalite(new_sc, contrainte_make(new_vec));
277  }
278  else {
279  fprintf(stderr, "\nNon linear expression :");
280  fprintf(stderr, " %s\n", expression_to_string(exp));
281  }
282  }
283 
284  sc_creer_base(new_sc);
285  new_pred = make_predicate(new_sc);
286 
287  if ((get_debug_level() >= 9) && (new_pred != predicate_undefined))
288  adg_fprint_psysteme(stderr, predicate_system(new_pred) );
289  debug(9, "my_adg_expressions_to_predicate", "end \n");
290  return(new_pred);
291 }
292 /*=======================================================================*/
293 
294 
295 
296 
297 
298 
299 
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
list adg_get_disjunctions(list exp_l)
======================================================================
list adg_make_disjunctions(list ps_l1, list ps_l2)
======================================================================
predicate adg_get_predicate_of_loops(list loops)
======================================================================
Definition: adg_predicate.c:55
list adg_predicate_list_dup(list ps_l)
======================================================================
Definition: adg_predicate.c:99
int Gcount_re
External variables.
Definition: array_dfg.c:45
predicate my_adg_expressions_to_predicate(list exp_l)
========================================================================
list adg_get_conjonctions(expression ndf_exp)
======================================================================
void adg_fprint_psysteme(FILE *fp, Psysteme ps)
===========================================================================
void adg_fprint_predicate_list(FILE *fp, list sc_l)
===========================================================================
#define VALUE_ONE
#define EXPRESSION_PVECTEUR(e)
static list loops
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define ADD_ELEMENT_TO_LIST(_list, _type, _element)
Definition: icfg-local.h:50
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_internal_error
Definition: misc-local.h:149
int get_debug_level(void)
GET_DEBUG_LEVEL returns the current debugging level.
Definition: debug.c:67
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
string expression_to_string(expression e)
Definition: expression.c:77
#define ENTITY_OR_P(e)
#define ENTITY_AND_P(e)
#define NORMALIZE_EXPRESSION(e)
#define ENTITY_GREATER_OR_EQUAL_P(e)
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
#define LOOP(x)
LOOP.
Definition: ri.h:1606
#define PREDICATE(x)
PREDICATE.
Definition: ri.h:2040
#define normalized_linear_p(x)
Definition: ri.h:1779
#define call_function(x)
Definition: ri.h:709
#define range_upper(x)
Definition: ri.h:2290
#define syntax_call_p(x)
Definition: ri.h:2734
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define predicate_undefined
Definition: ri.h:2046
#define syntax_call(x)
Definition: ri.h:2736
#define range_lower(x)
Definition: ri.h:2288
#define loop_range(x)
Definition: ri.h:1642
#define call_arguments(x)
Definition: ri.h:711
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define predicate_system(x)
Definition: ri.h:2069
#define loop_index(x)
Definition: ri.h:1640
struct Ssysteme * Psysteme
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
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
void sc_add_inegalite(Psysteme p, Pcontrainte i)
void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une inegalite i a un systeme p; la b...
Definition: sc_alloc.c:406
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...
#define RETURN(x)
flex uses isatty
Definition: sc_lex.c:777
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
Pbase base
Definition: sc-local.h:75
int nb_ineq
Definition: sc-local.h:73
int nb_eq
Definition: sc-local.h:72
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
struct Svecteur * Pvecteur
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75