PIPS
compare.c
Go to the documentation of this file.
1 /*
2 
3  $Id: compare.c 22777 2015-08-23 20:56:50Z irigoin $
4 
5  Copyright 1989-2009 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 /*
25  effects-util/compare.c: sorting comparison functions for cells, cell references,
26  effects and pointer values
27  */
28 
29 /************* CELLS */
30 
31 #ifdef HAVE_CONFIG_H
32  #include "pips_config.h"
33 #endif
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <string.h>
37 
38 #include "genC.h"
39 
40 #include "text.h"
41 #include "text-util.h"
42 
43 #include "top-level.h"
44 
45 #include "linear.h"
46 #include "ri.h"
47 #include "effects.h"
48 #include "ri-util.h"
49 #include "prettyprint.h"
50 #include "effects-util.h"
51 #include "misc.h"
52 
53 
55 {
56  int c1_pos = 0; /* result */
57  reference r1 = *pr1;
58  reference r2 = *pr2;
59  entity e1 = reference_variable(r1);
60  entity e2 = reference_variable(r2);
61 
62  if(same_entity_p(e1, e2))
63  {
64  /* same entity, sort on indices values */
65  list dims1 = reference_indices(r1);
66  list dims2 = reference_indices(r2);
67 
68  size_t nb_dims1 = gen_length(dims1);
69  size_t nb_dims2 = gen_length(dims2);
70 
71  for(;!ENDP(dims1) && !ENDP(dims2) && c1_pos == 0; POP(dims1), POP(dims2))
72  {
73  expression e1 = EXPRESSION(CAR(dims1));
74  expression e2 = EXPRESSION(CAR(dims2));
75 
78  c1_pos = 0;
79  else
80  c1_pos = 1;
81  else
83  c1_pos = -1;
84  else
85  {
87  syntax s2 = expression_syntax(e2);
89  {
92 
93  if (!same_entity_p(e1, e2))
94  c1_pos = strcmp(entity_name(e1),entity_name(e2));
95  }
96  else
97  {
98  intptr_t i1 = 0;
99  intptr_t i2 = 0;
100  intptr_t diff = 0;
101 
102  int r1 = expression_integer_value(e1, &i1);
103  int r2 = expression_integer_value(e2, &i2);
104 
105  if (r1 && r2)
106  {
107  diff = i1 - i2;
108  c1_pos = diff==0? 0 : (diff>0?1:-1);
109  }
110  else
111  {
112  string ch1 = expression_to_string(e1);
113  string ch2 = expression_to_string(e2);
114  c1_pos = strcmp(ch1, ch2);
115  free(ch1);
116  free(ch2);
117  }
118  }
119  }
120  }
121 
122  if (c1_pos == 0)
123  c1_pos = (nb_dims1 < nb_dims2) ? -1 : ( (nb_dims1 > nb_dims2) ? 1 : 0);
124  }
125  else
126  {
127  /* not same entity, sort on entity name */
128  /* sort on module name */
129  char * mod1 = strdup(entity_module_name(e1));
130  string mod2 = strdup(entity_module_name(e2));
131 
132  c1_pos = strcmp(mod1, mod2);
133  /* if same module name: sort on entity local name */
134  if (c1_pos == 0)
135  {
136  c1_pos = strcmp(entity_user_name(e1), entity_user_name(e2));
137  }
138  /* else: current module and top_level come first, then others in lexicographic order */
139  else
140  {
142  const char* current_mod = module_local_name(module);
143  if (strcmp(current_mod, mod1) == 0)
144  {
145  if (top_level_entity_p(e2))
146  c1_pos = strcmp(entity_user_name(e1), entity_user_name(e2));
147  else
148  c1_pos = -1;
149  }
150  else if (strcmp(current_mod, mod2) == 0)
151  {
152  if (top_level_entity_p(e1))
153  c1_pos = strcmp(entity_user_name(e1), entity_user_name(e2));
154  else
155  c1_pos = 1;
156  }
157  else if (top_level_entity_p(e1))
158  c1_pos = -1;
159  else if (top_level_entity_p(e2))
160  c1_pos = 1;
161  }
162  free(mod1); free(mod2);
163  }
164 
165  return c1_pos;
166 }
167 
168 int cell_compare(cell *c1, cell *c2)
169 {
170  pips_assert("gaps not handled yet (ppv1 first)", !cell_gap_p(*c1));
171  pips_assert("gaps not handled yet (ppv2 first)", !cell_gap_p(*c2));
172 
174 
175 }
176 
177 /************* EFFECTS */
178 
179 /* Compares two effects for sorting. The first criterion is based on names.
180  * Local entities come first; then they are sorted according to the
181  * lexicographic order of the module name, and inside each module name class,
182  * according to the local name lexicographic order. Then for a given
183  * entity name, a read effect comes before a write effect. It is assumed
184  * that there is only one effect of each type per entity. bc.
185  */
186 int
187 effect_compare(effect *peff1, effect *peff2)
188 {
189  int eff1_pos = 0;
190 
191  eff1_pos = cell_compare(&effect_cell(*peff1), &effect_cell(*peff2));
192  if (eff1_pos == 0)
193  {
194  /* same paths, sort on action, reads first */
195  if (effect_read_p(*peff1))
196  eff1_pos = -1;
197  else if (effect_read_p(*peff2))
198  eff1_pos = 1;
199  else eff1_pos = 0;
200  }
201  return(eff1_pos);
202 }
203 
204 /* int compare_effect_reference(e1, e2):
205  *
206  * returns -1 if "e1" is before "e2" in the alphabetic order, else
207  * +1. "e1" and "e2" are pointers to effect, we compare the names of their
208  * reference's entity. */
209 int
211 {
214  return cell_reference_compare(&r1, &r2);
215 }
216 
217 /* int compare_effect_reference_in_common(e1, e2):
218  *
219  * returns -1 if "e1" is before "e2" in the alphabetic order, else
220  * +1. "e1" and "e2" are pointers to effect, we compare the names of their
221  * reference's entity with the common name in first if the entity belongs
222  * to a common */
223 int
225 {
226  entity v1, v2;
227  int n1, n2 ,result;
228  string name1, name2;
231  n1 = (v1==(entity)NULL),
232  n2 = (v2==(entity)NULL);
233  name1= strdup((entity_in_common_p(v1)) ?
234  (string) entity_and_common_name(v1):
235  entity_name(v1));
236  name2= strdup((entity_in_common_p(v2)) ?
237  (string) entity_and_common_name(v2):
238  entity_name(v2));
239 
240  result = (n1 || n2)? (n2-n1): strcmp(name1,name2);
241  free(name1);free(name2);
242  return result;
243 }
244 
245 /************* POINTER VALUES */
246 
247 /* Compares two pointer values for sorting. The first criterion is based on names.
248  * Local entities come first; then they are sorted according to the
249  * lexicographic order of the module name, and inside each module name class,
250  * according to the local name lexicographic order. Then for a given
251  * entity name, a read effect comes before a write effect. It is assumed
252  * that there is only one effect of each type per entity. bc.
253  */
254 int
256 {
257  int ppv1_pos = 0; /* result */
258  /* compare first references of *ppv1 and *ppv2 */
259 
260  cell ppv1_first_c = cell_relation_first_cell(*ppv1);
261  cell ppv2_first_c = cell_relation_first_cell(*ppv2);
262 
263  pips_assert("there should not be preference cells in pointer values (ppv1 first) \n",
264  !cell_preference_p(ppv1_first_c));
265  pips_assert("there should not be preference cells in pointer values (ppv2 first) \n",
266  !cell_preference_p(ppv2_first_c));
267 
268  pips_assert("the first cell must have value_of interpretation (ppv1)\n",
270  pips_assert("the first cell must have value_of interpretation (ppv2)\n",
272 
273  ppv1_pos = cell_compare(&ppv1_first_c, &ppv2_first_c);
274 
275  if (ppv1_pos == 0) /* same first cells */
276  {
277  /* put second cells value_of before address_of */
278  bool ppv1_second_value_of_p = cell_relation_second_value_of_p(*ppv1);
279  bool ppv2_second_value_of_p = cell_relation_second_value_of_p(*ppv2);
280 
281  ppv1_pos = (ppv1_second_value_of_p == ppv2_second_value_of_p) ? 0 :
282  (ppv1_second_value_of_p ? -1 : 1);
283 
284  if (ppv1_pos == 0) /* both are value_of or address_of*/
285  {
286  /* compare second cells */
287  cell ppv1_second_c = cell_relation_second_cell(*ppv1);
288  cell ppv2_second_c = cell_relation_second_cell(*ppv2);
289  ppv1_pos = cell_compare(&ppv1_second_c, &ppv2_second_c);
290 
291  }
292  }
293  return(ppv1_pos);
294 }
295 
296 /************ PVECTEUR */
297 
298 /** @brief weight function for Pvecteur passed as argument to
299  * sc_lexicographic_sort in prettyprint functions involving cell descriptors.
300  *
301  * The strange argument type is required by qsort(), deep down in the calls.
302  * This function is an adaptation of is_inferior_pvarval in semantics
303  */
304 int
306 {
307  /* The constant term is given the highest weight to push constant
308  terms at the end of the constraints and to make those easy
309  to compare. If not, constant 0 will be handled differently from
310  other constants. However, it would be nice to give constant terms
311  the lowest weight to print simple constraints first...
312 
313  Either I define two comparison functions, or I cheat somewhere else.
314  Let's cheat? */
315  int is_equal = 0;
316 
317  if (term_cst(*pvarval1) && !term_cst(*pvarval2))
318  is_equal = 1;
319  else if (term_cst(*pvarval1) && term_cst(*pvarval2))
320  is_equal = 0;
321  else if(term_cst(*pvarval2))
322  is_equal = -1;
323  else if(variable_phi_p((entity) vecteur_var(*pvarval1))
324  && !variable_phi_p((entity) vecteur_var(*pvarval2)))
325  is_equal = -1;
326  else if(variable_phi_p((entity) vecteur_var(*pvarval2))
327  && !variable_phi_p((entity) vecteur_var(*pvarval1)))
328  is_equal = 1;
329  else
330  is_equal =
331  strcmp(entity_name((entity) vecteur_var(*pvarval1)),
332  entity_name((entity) vecteur_var(*pvarval2)));
333 
334  return is_equal;
335 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
static entity current_mod
Definition: alias_check.c:120
int cell_compare(cell *c1, cell *c2)
Definition: compare.c:168
int is_inferior_cell_descriptor_pvarval(Pvecteur *pvarval1, Pvecteur *pvarval2)
weight function for Pvecteur passed as argument to sc_lexicographic_sort in prettyprint functions inv...
Definition: compare.c:305
int compare_effect_reference(effect *e1, effect *e2)
int compare_effect_reference(e1, e2):
Definition: compare.c:210
int effect_compare(effect *peff1, effect *peff2)
Compares two effects for sorting.
Definition: compare.c:187
int compare_effect_reference_in_common(effect *e1, effect *e2)
int compare_effect_reference_in_common(e1, e2):
Definition: compare.c:224
int pointer_value_compare(cell_relation *ppv1, cell_relation *ppv2)
Compares two pointer values for sorting.
Definition: compare.c:255
int cell_reference_compare(reference *pr1, reference *pr2)
compare.c
Definition: compare.c:54
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define cell_relation_second_cell(cr)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
#define cell_relation_second_value_of_p(cr)
#define cell_relation_first_cell(cr)
#define variable_phi_p(e)
true if e is a phi variable PHI entities have a name like: REGIONS:PHI#, where # is a number.
#define cell_relation_first_value_of_p(cr)
#define cell_reference(x)
Definition: effects.h:469
#define cell_gap_p(x)
Definition: effects.h:473
#define cell_preference_p(x)
Definition: effects.h:470
#define effect_cell(x)
Definition: effects.h:640
void free(void *)
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#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
size_t gen_length(const list l)
Definition: list.c:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
static char * module
Definition: pips.c:74
string expression_to_string(expression e)
Definition: expression.c:77
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
const char * entity_and_common_name(entity e)
See next function!
Definition: entity.c:654
bool entity_in_common_p(entity e)
Definition: entity.c:1082
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_name(x)
Definition: ri.h:2790
#define reference_indices(x)
Definition: ri.h:2328
#define expression_syntax(x)
Definition: ri.h:1247
char * strdup()
s1
Definition: set.c:247
#define intptr_t
Definition: stdint.in.h:294
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 vecteur_var(v)
#define term_cst(varval)