PIPS
comp_unstr.c
Go to the documentation of this file.
1 /*
2 
3  $Id: comp_unstr.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 /* comp_unstr.c */
28 /* evaluate the complexity of unstructured graphs of statements */
29 
30 #include <stdio.h>
31 #include <math.h>
32 
33 #include "linear.h"
34 
35 #include "genC.h"
36 
37 #include "ri.h"
38 #include "effects.h"
39 #include "complexity_ri.h"
40 #include "ri-util.h"
41 #include "effects-util.h"
42 #include "properties.h" /* used by get_bool_property */
43 #include "misc.h"
44 #include "matrice.h"
45 #include "complexity.h"
46 
47 /* Added by AP, March 15th 93: allows the simulation of a two-dimensional array
48  * with a mono-dimensional memory allocation.
49  */
50 #define FA(i,j) fa[(i)*n_controls + (j)]
51 
54 
55 /* 6th element of instruction */
56 /* complexity unstructured_to_complexity(unstructured unstr;
57  * transformer precond;
58  * list effects_list;
59  *
60  * Return the complexity of the unstructured graph unstr
61  * whose nodes are controls.
62  *
63  * First runs through the graph to compute nodes' complexities,
64  * the total number of nodes, and give a number to each node.
65  * This is done in "controls_to_hash_table()".
66  *
67  * Then runs again through it to fill the probability matrix [Pij]
68  * ( Pij = probability to go to node j when you're in node i)
69  * This is done in "build_probability_matrix()"
70  *
71  * Then computes A = I-P, then inv_A = 1/A with the matrix package.
72  *
73  * MAX_CONTROLS_IN_UNSTRUCTURED = 100
74  */
75 complexity unstructured_to_complexity(unstr, precond, effects_list)
76 unstructured unstr;
77 transformer precond;
78 list effects_list;
79 {
81  hash_table hash_control_to_complexity = hash_table_make(hash_pointer,
83  int i, j, n_controls = 0;
85  matrice P, A, B;
86 
87  trace_on("unstructured");
88 
90  &n_controls,
91  control_array,
92  hash_control_to_complexity,
93  precond,
94  effects_list);
95 
96 
97  P = average_probability_matrix(unstr, n_controls, control_array);
98  A = matrice_new(n_controls, n_controls);
99  B = matrice_new(n_controls, n_controls);
100 
101  /* A is identity matrix I */
102  matrice_identite(A, n_controls, 0);
103  /* B = A - P = I - P */
104  matrice_substract(B, A, P, n_controls, n_controls);
105 
106  if (get_debug_level() >= 5) {
107  fprintf(stderr, "I - P =");
108  matrice_fprint(stderr, B, n_controls, n_controls);
109  }
110 
111  /* matrice_general_inversion(B, A, n_controls); */
112  /* A = 1/(B) */
113  /* This region will call C routines. LZ 20/10/92 */
114 
115  /*
116  the "global" complexity is:
117  comp = a11 * C1 + a12 * C2 + ... + a1n * Cn
118  where Ci = complexity of control #i
119  */
120 
121  if ( n_controls < MAX_CONTROLS_IN_UNSTRUCTURED ) {
122 
123  /* Modif by AP, March 15th 93: old version had non constant int in dim decl
124  float fa[n_controls][n_controls];
125  int indx[n_controls];
126  int d;
127  */
128  float *fa = (float *) malloc(n_controls*n_controls*sizeof(float));
129  int *indx = (int *) malloc(sizeof(int) * n_controls);
130  int d;
131 
132  for (i=1; i<=n_controls; i++) {
133  for (j=1; j<=n_controls; j++ ) {
134  Value n = ACCESS(B, n_controls, i, j),
135  de = DENOMINATOR(B);
136  float f1 = VALUE_TO_FLOAT(n),
137  f2 = VALUE_TO_FLOAT(de);
138  FA(i-1,j-1) = f1/f2;
139  }
140  }
141 
142  if ( get_debug_level() >= 5 ) {
143  fprintf(stderr, "Before float matrice inversion\n\n");
144  }
145 
146  if ( get_debug_level() >= 9 ) {
147  fprintf(stderr, "(I - P) =\n");
148  for (i=0;i<n_controls;i++) {
149  for (j=0;j<n_controls;j++)
150  fprintf(stderr, "%4.2f ",FA(i,j) );
151  fprintf(stderr, "\n");
152  }
153  }
154 
155  float_matrice_inversion(fa, n_controls, indx, &d);
156 
157  if ( get_debug_level() >= 5 ) {
158  fprintf(stderr, "After float matrice inversion\n\n");
159  }
160 
161  if ( get_debug_level() >= 9 ) {
162  fprintf(stderr, "(I - P)^(-1) =\n");
163  for (i=0;i<n_controls;i++) {
164  for (j=0;j<n_controls;j++)
165  fprintf(stderr, "%4.2f ",FA(i,j) );
166  fprintf(stderr, "\n");
167  }
168  }
169 
170  for (i=1; i<=n_controls; i++) {
171  control conti = control_array[i];
172  complexity compi = (complexity)
173  hash_get(hash_control_to_complexity, (char *) conti);
174  float f = FA(0,i-1);
175 
176  if ( get_debug_level() >= 5 ) {
177  fprintf(stderr, "control $%p:f=%f, compl.=", conti, f);
178  complexity_fprint(stderr, compi, true, false);
179  }
180 
181  complexity_scalar_mult(&compi, f);
182  complexity_add(&comp, compi);
183  }
184  }
185  else
186  pips_internal_error("Too large to compute");
187 
188  if (get_debug_level() >= 5) {
189  fprintf(stderr, "cumulated complexity=");
190  complexity_fprint(stderr, comp, true, false);
191  }
192 
193  matrice_free(B);
194  matrice_free(A);
195  matrice_free(P);
196 
197  hash_table_free(hash_control_to_complexity);
198 
199  complexity_check_and_warn("unstructured_to_complexity", comp);
200 
201  trace_off();
202  return(comp);
203 }
204 
205 ␌
206 /* Returns the hash table hash_control_to_complexity filled in
207  * with the complexities of the successors of control cont.
208  * each control of the graph is also stored in the array
209  * control_array (beginning at 1).
210  * also returns the total number of controls in the unstructured
211  */
212 void controls_to_hash_table(cont, pn_controls, control_array,
213  hash_control_to_complexity, precond, effects_list)
214 control cont;
215 int *pn_controls;
216 control control_array[];
217 hash_table hash_control_to_complexity;
218 transformer precond;
219 list effects_list;
220 {
221  statement s = control_statement(cont);
222  complexity comp;
223 
224  comp = statement_to_complexity(s, precond, effects_list);
225  hash_put(hash_control_to_complexity, (char *) cont, (char *) comp);
226  control_array[++(*pn_controls)] = cont;
227  complexity_check_and_warn("control_to_complexity", comp);
228 
229  if (get_debug_level() >= 5) {
230  fprintf(stderr, "this control($%p) has:", cont);
231  complexity_fprint(stderr, comp, true, true);
232  MAPL(pc, {
233  fprintf(stderr, "successor: $%p\n", CONTROL(CAR(pc)));
234  }, control_successors(cont));
235  if ( control_successors(cont) == NIL )
236  fprintf(stderr, "NO successor at all!\n");
237  fprintf(stderr, ". . . . . . . . . . . . . . . . . . . . . .\n");
238  }
239 
240  MAPL(pc, {
241  control c = CONTROL(CAR(pc));
242  if ( hash_get(hash_control_to_complexity, (char *) c)
244  controls_to_hash_table(c, pn_controls, control_array,
245  hash_control_to_complexity, precond,
246  effects_list);
247  }, control_successors(cont));
248 }
249 
250 /* return the number i, that is i'th element of the control array
251  * Note that i begins from 1 instead of 0
252  */
253 int control_element_position_in_control_array(cont, control_array, n_controls)
254 control cont;
255 control control_array[];
256 int n_controls;
257 {
258  int i;
259 
260  for (i=1; i<=n_controls; i++)
261  if (cont == control_array[i])
262  return (i);
263  pips_internal_error("this control isn't in control_array[]!");
264 
265  /* In order to satisfy compiler. LZ 3 Feb. 93 */
266  return (i);
267 }
268 
269 
270 matrice average_probability_matrix(unstr, n_controls, control_array)
271 unstructured unstr;
272 int n_controls;
273 control control_array[];
274 {
275  control cont = unstructured_control(unstr);
276  bool already_examined[MAX_CONTROLS_IN_UNSTRUCTURED];
277  int i, j , n_succs, max_n_succs = 0;
278  matrice P = matrice_new(n_controls, n_controls);
279 
280  if ( n_controls > MAX_CONTROLS_IN_UNSTRUCTURED ) {
281  pips_internal_error("control number is larger than %d",
283  }
284 
285  matrice_nulle(P, n_controls, n_controls);
286 
287  /* initilize the already_examined to false */
288  for (i=1; i<=n_controls; i++)
289  already_examined[i] = false;
290 
291  /* make in P the matrix "is_successor_of" */
292  node_successors_to_matrix(cont, P, n_controls,
293  control_array, already_examined);
294 
295  /* we'll attribute equitable probabilities to the n succ. of a node */
296  for (i=1; i<=n_controls; i++) {
297  n_succs = 0;
298  for (j=1; j<=n_controls; j++)
299  {
300  Value a = ACCESS(P, n_controls, i, j);
301  n_succs += VALUE_TO_INT(a);
302  }
303  if (n_succs > max_n_succs)
304  max_n_succs = n_succs;
305  }
306 
307  if (get_bool_property("COMPLEXITY_INTERMEDIATES")) {
308  fprintf(stderr, "n_controls=%d, and max_n_succs=%d\n",
309  n_controls,max_n_succs);
310  }
311 
312  /* computes probabilities (0<=p<1) out of the matrix "is_successor_of" */
313 
314 
315  DENOMINATOR(P) = int_to_value(factorielle(max_n_succs));
316 
317  for (i=1; i<=n_controls; i++) {
318  n_succs = 0;
319  for (j=1; j<=n_controls; j++) {
320  Value a = ACCESS(P, n_controls, i, j);
321  n_succs += VALUE_TO_INT(a);
322  }
323  if (n_succs>0)
324  for (j=1; j<=n_controls; j++)
325  {
326  Value x = value_div(DENOMINATOR(P),int_to_value(n_succs));
327  value_product(ACCESS(P, n_controls, i, j),x) ;
328  }
329  }
330 
331  matrice_normalize(P, n_controls, n_controls);
332 
333  if (get_debug_level() > 0) {
334  fprintf(stderr, "n_controls is %d\n", n_controls);
335  fprintf(stderr, "average_probability_matrix: P =\n");
336  matrice_fprint(stderr, P, n_controls, n_controls);
337  }
338 
339  return (P);
340 }
341 
342 /*
343  * On return, Pij = 1 <=> there's an edge from control #i to #j
344  * It means that every succeccor has the same possibility to be reached.
345  *
346  * Modification:
347  * - put already_examined[i] = true out of MAPL.
348  * If control i has several successors, there is no need to set it several
349  * times in MAPL. LZ 13/04/92
350  */
351 void node_successors_to_matrix(cont, P, n_controls,
352  control_array, already_examined)
353 control cont;
354 matrice P;
355 int n_controls;
356 control control_array[];
357 bool already_examined[];
358 {
359  int i = control_element_position_in_control_array(cont, control_array, n_controls);
360 
361  already_examined[i] = true;
362 
363  if (get_bool_property("COMPLEXITY_INTERMEDIATES")) {
364  fprintf(stderr, "CONTROL ($%p) CONTROL_NUMBER %d\n", cont, i);
365  }
366 
367  MAPL(pc, {
368  control succ = CONTROL(CAR(pc));
369  int j = control_element_position_in_control_array(succ, control_array,
370  n_controls);
371 
372  if ( get_debug_level() >= 5 ) {
373  fprintf(stderr,"Control ($%p) %d --> Control ($%p) %d\n",
374  cont, i, succ, j);
375  }
376 
377  /* Here, we give equal possibility , 1 for each one */
378  ACCESS(P, n_controls, i, j) = VALUE_ONE;
379  if (!already_examined[j])
380  node_successors_to_matrix(succ, P, n_controls,
381  control_array, already_examined);
382  else {
383  if ( get_debug_level() >= 5 ) {
384  fprintf(stderr, "Control Number %d already examined!\n",j);
385  }
386  }
387  }, control_successors(cont));
388 }
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
#define VALUE_TO_INT(val)
int Value
#define VALUE_TO_FLOAT(val)
#define value_product(v, w)
#define VALUE_ONE
#define value_div(v1, v2)
void complexity_add(complexity *pcomp1, complexity comp2)
void complexity_add(complexity *pcomp1, comp2) performs *pcomp1 = *pcomp1 + comp2; !...
Definition: comp_math.c:372
void complexity_scalar_mult(complexity *pcomp, float f)
multiply a complexity by a floating-point number.
Definition: comp_math.c:303
complexity make_zero_complexity()
make a zero complexity "0.0000 * TCST" with null statistics
Definition: comp_math.c:238
#define A(i, j)
comp_matrice.c
Definition: comp_matrice.c:63
void float_matrice_inversion(float *a, int n, int *indx, int *pd)
Definition: comp_matrice.c:198
complexity statement_to_complexity(statement stat, transformer precon __attribute__((__unused__)), list eff_list __attribute__((__unused__)))
starting point of Abstract Syntax Tree
Definition: comp_scan.c:230
hash_table hash_complexity_parameters
Definition: comp_scan.c:58
hash_table hash_callee_to_complexity
comp_expr_to_pnome.c
Definition: comp_scan.c:57
complexity unstructured_to_complexity(unstructured unstr, transformer precond, list effects_list)
6th element of instruction
Definition: comp_unstr.c:75
void node_successors_to_matrix(control cont, matrice P, int n_controls, control_array, already_examined)
On return, Pij = 1 <=> there's an edge from control #i to #j It means that every succeccor has the sa...
Definition: comp_unstr.c:351
#define FA(i, j)
comp_unstr.c
Definition: comp_unstr.c:50
void controls_to_hash_table(control cont, int *pn_controls, control_array, hash_table hash_control_to_complexity, transformer precond, list effects_list)
Returns the hash table hash_control_to_complexity filled in with the complexities of the successors o...
Definition: comp_unstr.c:212
matrice average_probability_matrix(unstructured unstr, int n_controls, control_array)
Definition: comp_unstr.c:270
int control_element_position_in_control_array(control cont, control_array, int n_controls)
return the number i, that is i'th element of the control array Note that i begins from 1 instead of 0
Definition: comp_unstr.c:253
void trace_on(char *fmt,...)
Definition: comp_util.c:684
void complexity_fprint(FILE *fd, complexity comp, bool print_stats_p, bool print_local_names_p)
Definition: comp_util.c:217
void complexity_check_and_warn(char *s, complexity comp) const
Definition: comp_util.c:108
void trace_off()
"trace off"
Definition: comp_util.c:714
#define MAX_CONTROLS_IN_UNSTRUCTURED
struct _newgen_struct_complexity_ * complexity
Definition: complexity_ri.h:30
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void * malloc(YYSIZE_T)
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define B(A)
Definition: iabrev.h:61
#define DENOMINATOR(matrix)
int DENOMINATEUR(matrix): acces au denominateur global d'une matrice matrix La combinaison *(&()) est...
Definition: matrice-local.h:93
#define matrice_free(m)
Definition: matrice-local.h:78
#define ACCESS(matrix, column, i, j)
Macros d'acces aux elements d'une matrice.
Definition: matrice-local.h:86
#define matrice_new(n, m)
Allocation et desallocation d'une matrice.
Definition: matrice-local.h:77
Value * matrice
package matrice
Definition: matrice-local.h:71
void matrice_substract(matrice a, matrice b, matrice c, int n, int m)
void matrice_substract(matrice a, matrice b, matrice c, int n, int m): substract rational matrix c fr...
Definition: matrice.c:468
void matrice_normalize(matrice a, int n, int m)
void matrice_normalize(matrice a, int n, int m)
Definition: matrice.c:125
void matrice_nulle(matrice Z, int n, int m)
void matrice_nulle(matrice Z, int n, int m): Initialisation de la matrice Z a la valeur matrice nulle
Definition: matrice.c:311
void matrice_identite(matrice, int, int)
void matrice_identite(matrice ID, int n, int level) Construction d'une sous-matrice identite dans ID(...
Definition: sous-matrice.c:322
void matrice_fprint(FILE *, matrice, int, int)
matrice_io.c
Definition: matrice_io.c:62
#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
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
int f2(int off1, int off2, int w, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:1
int factorielle(int n)
int factorielle (int n) PRIVATE returns n!
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
#define control_successors(x)
Definition: ri.h:945
#define control_statement(x)
Definition: ri.h:941
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
static char * x
Definition: split_file.c:159
Definition: pip__tab.h:25
The structure used to build lists in NewGen.
Definition: newgen_list.h:41