PIPS
stats.c
Go to the documentation of this file.
1 /*
2 
3  $Id: stats.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 #include <stdio.h>
28 #include "genC.h"
29 #include "linear.h"
30 #include "ri.h"
31 #include "database.h"
32 #include "resources.h"
33 #include "misc.h"
34 #include "ri-util.h"
35 #include "pipsdbm.h"
36 /* #include "statistics.h" */
37 
42 static bool first_turn ;
43 
44 
48 typedef struct {
49  hash_table contenu;
51  stack statement_stack;
53 
54 static bool loop_flt(loop l, context_p context )
55 {
56  pips_assert("true", l==l && context==context);
57  cpt++;
58  if( ! first_turn ) first_turn = true;
59  return true;
60 }
61 static void loop_rwt(loop l, context_p context )
62 {
63  contenu_t contenu;
65  if (first_turn) {
66  depth =1;
67  hash_put(context->depth,stack_head(context->statement_stack),
68  ( void *) depth);
69  contenu =is_a_perf_nes_loop;
70  hash_put(context->contenu,stack_head(context->statement_stack),
71  (void *) contenu );
72  first_turn= false;
73  }
74  else {
75  statement s = loop_body(l);
76  contenu = (contenu_t) hash_get(context->contenu, s);
77  if (contenu==is_a_no_perf_nes_loop_t)
78  contenu=is_a_no_perf_nes_loop;
79  depth= (intptr_t) hash_get(context->depth, s);
80  depth++;
81  hash_put(context->depth,stack_head(context->statement_stack),
82  ( void *) depth);
83  hash_put(context->contenu,stack_head(context->statement_stack),
84  (void *) contenu );
85  };
86  nbr_loop++;
87  cpt--;
88  if ( cpt ==0) {
89  statement s= loop_body(l);
90  contenu = (contenu_t) hash_get(context->contenu, s);
91  if ( contenu == is_a_no_perf_nes_loop_t){
93  };
94  };
95 
96 }
98 {
99 
100  stack_push(s, context->statement_stack);
101  return true;
102 }
103 
104 
106 {
107  pips_assert("true", s==s);
108  /* pips_assert("information associated to statement",
109  hash_defined_p(context->contenu, s) );
110 
111  pips_assert("information associated to statement",
112  hash_defined_p(context->depth, s) ); */
113  stack_pop(context->statement_stack);
114 
115 }
116 static bool seq_flt( sequence sq, context_p context )
117 {
118  pips_assert("true", sq==sq && context==context);
119  return true;
120 }
122 {
123 
124  contenu_t contenu= is_unknown, contenu_loop=is_unknown ;
125  intptr_t depth=0;
126  intptr_t max=0;
127  intptr_t nbr=0;
128  bool found=false;
129  list l= sequence_statements(sq);
130  MAP(STATEMENT, s,
131  {
132  contenu = (contenu_t) hash_get(context->contenu, s);
133  if ( (nbr !=0)&&((contenu== is_a_perf_nes_loop)||
134  ( contenu== is_a_no_perf_nes_loop)||
135  ( contenu== is_a_no_perf_nes_loop_t) ) )
136  found=true;
137  if ((contenu != is_a_perf_nes_loop)&&
138  ( contenu != is_a_no_perf_nes_loop)&&
139  ( contenu!= is_a_no_perf_nes_loop_t) &&
140  ( contenu != is_a_continue) )
141  found=true;
142  switch ( contenu ){
143  case is_a_perf_nes_loop : {nbr++; contenu_loop=contenu;
144  depth = (intptr_t ) hash_get(context->depth, s);
146  if( depth > max ) max =depth;
148  nbr_nested_loop++;
150  break;
151  }
152 
153  case is_a_no_perf_nes_loop: {nbr++; contenu_loop=contenu;
154  depth = (intptr_t ) hash_get(context->depth, s);
157  nbr_nested_loop++;
158  if( depth > max ) max =depth;
160  break ;
161  }
162  case is_a_no_perf_nes_loop_t: { nbr++; contenu_loop=contenu;
163  depth = (intptr_t ) hash_get(context->depth, s);
164  if( depth > max ) max =depth; break ;}
165  default:
166  break;
167 
168  };
169 
170  };, l);
171  if (max > 0) {
172  if (found){
173  contenu =is_a_no_perf_nes_loop_t;
174  hash_put(context->contenu,
175  stack_head(context->statement_stack),
176  (void *)contenu);
177  hash_put(context->depth,
178  stack_head(context->statement_stack),
179  (void * ) max );
180  }
181  else{
182  hash_put(context->contenu,
183  stack_head(context->statement_stack),
184  (void *) contenu_loop);
185  hash_put(context->depth,
186  stack_head(context->statement_stack),
187  (void * ) max);
188  switch ( contenu_loop ){
191  break;
192  }
193  case is_a_no_perf_nes_loop :{
196  break;
197  }
198  default:break;
199  };
200  }
201 
202  }
203  else {
204  contenu =is_unknown;
205  hash_put(context->contenu,
206  stack_head(context->statement_stack),
207  (void *) contenu);
208  depth=0;
209  hash_put(context->depth,
210  stack_head(context->statement_stack),
211  (void *) depth);
212  };
213 
214 }
216 {
217  pips_assert("true", u==u && context==context);
218  return true;
219 }
221 {
222  list blocks = NIL;
223  statement s;
224  contenu_t contenu;
226  intptr_t max =0;
227  intptr_t depth;
228  CONTROL_MAP(c,
229  {
230  s=control_statement(c);
231  contenu = (contenu_t) hash_get(context->contenu, s);
232  switch ( contenu ){
233  case is_a_perf_nes_loop : {
234  depth = (intptr_t ) hash_get(context->depth, s);
236  if( depth > max ) max =depth;
238  nbr_nested_loop++;
240  break;
241  }
242  case is_a_no_perf_nes_loop: {
243  depth = (intptr_t ) hash_get(context->depth, s);
246  nbr_nested_loop++;
247  if( depth > max ) max =depth;
249  break ;
250  }
251  case is_a_no_perf_nes_loop_t: {
252  depth = (intptr_t ) hash_get(context->depth, s);
253  if( depth > max ) max =depth; break ;}
254  default:
255  break;
256  };
257  },
258  c_in, blocks);
260  if (max > 0) {
261  contenu =is_a_no_perf_nes_loop_t;
262  hash_put(context->contenu,
263  stack_head(context->statement_stack),
264  (void *)contenu);
265  hash_put(context->depth,
266  stack_head(context->statement_stack),
267  (void * ) max );
268  }
269  else
270  { contenu =is_unknown; ;
271  hash_put(context->contenu,
272  stack_head(context->statement_stack),
273  (void *)contenu);
274  }
275 }
277 {
278  pips_assert("true", t==t && context==context);
279  return true;
280 }
282 {
284  statement s2=test_false(t);
285  intptr_t max=0;
286  intptr_t depth;
287  contenu_t contenu1=is_unknown, contenu2=is_unknown,contenu =is_unknown;
288  contenu1 = (contenu_t) hash_get(context->contenu, s1);
289  switch ( contenu1 ){
290  case is_a_perf_nes_loop: {
291  depth= (intptr_t) hash_get(context->depth, s1);
294  nbr_nested_loop++;
295  max=depth;
296  contenu= is_a_no_perf_nes_loop_t;
297  hash_put(context->contenu,
298  stack_head(context->statement_stack),
299  (void *) contenu );
301  break;
302  };
303  case is_a_no_perf_nes_loop :{
304  depth= (intptr_t) hash_get(context->depth, s1);
307  nbr_nested_loop++;
308  max=depth;
309  contenu= is_a_no_perf_nes_loop_t;
310  hash_put(context->contenu,
311  stack_head(context->statement_stack),
312  (void *) contenu );
314  break;
315  };
317  depth= (intptr_t) hash_get(context->depth, s1);
318  max=depth;
319  contenu= is_a_no_perf_nes_loop_t;
320  hash_put(context->contenu,
321  stack_head(context->statement_stack),
322  (void *) contenu );
323  break;
324  };
325  default:break;
326  };
327  contenu2 = (contenu_t) hash_get(context->contenu, s2);
328  switch ( contenu2 ){
329  case is_a_perf_nes_loop : {
330  depth= (intptr_t) hash_get(context->depth, s2);
333  nbr_nested_loop++;
334  if (depth > max ) max =depth;
335  contenu= is_a_no_perf_nes_loop_t;
336  hash_put(context->contenu,
337  stack_head(context->statement_stack),
338  (void *) contenu);
340  break;
341  };
342 
343  case is_a_no_perf_nes_loop: {
344  depth= (intptr_t) hash_get(context->depth, s2);
347  nbr_nested_loop++;
348  if (depth > max ) max =depth;
349  contenu= is_a_no_perf_nes_loop_t;
350  hash_put(context->contenu,
351  stack_head(context->statement_stack),
352  (void *) contenu );
354  break;
355  };
357  depth= (intptr_t) hash_get(context->depth, s2);
358  if ( depth > max) max =depth;
359  contenu= is_a_no_perf_nes_loop_t;
360  hash_put(context->contenu,
361  stack_head(context->statement_stack),
362  (void *) contenu );
363  break;
364  };
365  default: break;
366  };
367  hash_put(context->depth,
368  stack_head(context->statement_stack),
369  (void *) max );
370  if (max==0) {
371  contenu=is_a_test;
372  hash_put(context->contenu,
373  stack_head(context->statement_stack),
374  (void *) contenu );
375  };
376 }
377 static bool call_flt( call ca, context_p context)
378 {
379  pips_assert("true", ca==ca && context==context);
380 
381 return true ;
382 }
383 static void call_rwt(call ca, context_p context)
384 {
385  contenu_t contenu;
386  if ( strcmp( entity_name( call_function(ca)),"TOP-LEVEL:CONTINUE" )==0){
387  contenu=is_a_continue;
388  hash_put(context->contenu,
389  stack_head(context->statement_stack),
390  (void *) contenu);
391  }
392  else{
393  contenu=is_a_call;
394  hash_put(context->contenu,
395  stack_head(context->statement_stack),
396  (void *)contenu );
397  };
398 }
400 {
401  pips_assert("true", w==w && context==context);
402  contenu_t contenu=is_a_while;
403  hash_put(context->contenu,
404  stack_head(context->statement_stack),
405  (void *) contenu );
406 }
407 static void initialize ()
408 {
409  int i;
410  nbr_no_perf_nest_loop_of_depth =(int *) malloc(100 * sizeof (int ));
411  nbr_perf_nest_loop_of_depth =(int *) malloc(100* sizeof (int )) ;
412  for (i=0; i<=99;i++)
414  for (i=0; i<=99;i++)
416  cpt=0;
421  first_turn = true;
422 }
423 static void put_result(string filename)
424 {
425  int i;
426  FILE * file = safe_fopen(filename, "w");
427  fprintf(file,
428  "loops: %d\n"
429  "nested loops: %d\n"
430  "perfectly nested loops: %d\n"
431  "non perfectly nested loops: %d\n"
432  "non perfectly nested loops which we can treat : %d\n",
435 
436 
437  for (i=1; i<= max_depth_perfect; i++)
438  if (*(nbr_perf_nest_loop_of_depth+i) !=0)
439  fprintf(file,"perfectly nested loops of depth %d: %d \n", i,
441  for (i=1; i<= max_depth_no_perfect; i++)
442  if (*(nbr_no_perf_nest_loop_of_depth+i) !=0)
443  fprintf(file,"non perfectly nested loops of depth %d: %d \n", i,
445 
446  safe_fclose(file, filename);
447 }
448 
449 
450 bool loop_statistics(const string name)
451 {
452  statement stat;
453  string filename, localfilename;
455 
456  debug_on("STATISTICS_DEBUG_LEVEL");
457  pips_debug(1, "considering module %s\n", name);
459 
460  initialize() ;
461 
462  stat = (statement) db_get_memory_resource(DBR_CODE, name, true);
463 
464  context.contenu = hash_table_make(hash_pointer, 0);
466  context.statement_stack = stack_make(statement_domain, 0, 0);
467 
468 
470  (stat, & context,
479  NULL);
480 
481 
482  hash_table_free(context.contenu);
483 
484 
485  hash_table_free(context.depth);
486  stack_free(&context.statement_stack);
487 
488  localfilename = db_build_file_resource_name(DBR_STATS_FILE,
489  name, ".loop_stats");
490 
492  "/", localfilename, NULL));
493 
494  put_result(filename);
497  free(filename);
498  DB_PUT_FILE_RESOURCE(DBR_STATS_FILE, name, localfilename);
500 
501 pips_debug(1, "done.\n");
502  debug_off();
503 
504  return true;
505 }
506 
507 
508 
509 
510 
511 
512 
513 
514 
515 
516 
517 
518 
519 
520 
521 
522 
523 
524 
525 
526 
527 
FILE * c_in
Definition: c_syntax.h:291
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
static list blocks
lisp of loops
#define max(a, b)
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
void * malloc(YYSIZE_T)
void free(void *)
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
bool gen_false(__attribute__((unused)) gen_chunk *unused)
Return false and ignore the argument.
Definition: genClib.c:2796
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_FILE_RESOURCE
Put a file resource into the current workspace database.
Definition: pipsdbm-local.h:85
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
string db_build_file_resource_name(const char *rname, const char *oname, const char *suffix)
returns an allocated file name for a file resource.
Definition: lowlevel.c:169
#define debug_on(env)
Definition: misc-local.h:157
#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_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
@ hash_pointer
Definition: newgen_hash.h:32
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
void stack_push(void *, stack)
stack use
Definition: stack.c:373
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399
#define true
Definition: newgen_types.h:81
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
#define loop_body(x)
Definition: ri.h:1644
#define test_domain
newgen_entity_domain_defined
Definition: ri.h:418
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define call_function(x)
Definition: ri.h:709
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define test_false(x)
Definition: ri.h:2837
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define entity_name(x)
Definition: ri.h:2790
#define test_true(x)
Definition: ri.h:2835
#define sequence_statements(x)
Definition: ri.h:2360
#define whileloop_domain
newgen_variable_domain_defined
Definition: ri.h:466
#define control_statement(x)
Definition: ri.h:941
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
s1
Definition: set.c:247
static bool stmt_flt(statement s, context_p context)
Definition: stats.c:97
static int * nbr_perf_nest_loop_of_depth
Definition: stats.c:38
struct context_p context_t
static void uns_rwt(unstructured u, context_p context)
Definition: stats.c:220
static int nbr_no_perfectly_nested_loop
Definition: stats.c:40
static int max_depth_perfect
Definition: stats.c:41
static int nbr_nested_loop
Definition: stats.c:40
contenu_t
Definition: stats.c:45
@ is_unknown
Definition: stats.c:45
@ is_a_no_perf_nes_loop_t
Definition: stats.c:46
@ is_a_test
Definition: stats.c:47
@ is_a_continue
Definition: stats.c:46
@ is_a_perf_nes_loop
Definition: stats.c:45
@ is_a_while
Definition: stats.c:47
@ is_a_call
Definition: stats.c:46
@ is_a_no_perf_nes_loop
Definition: stats.c:45
static int * nbr_no_perf_nest_loop_of_depth
include "statistics.h"
Definition: stats.c:38
static bool uns_flt(unstructured u, context_p context)
Definition: stats.c:215
static void stmt_rwt(statement s, context_p context)
Definition: stats.c:105
static void call_rwt(call ca, context_p context)
Definition: stats.c:383
static int max_depth_no_perfect
Definition: stats.c:41
static bool test_flt(test t, context_p context)
Definition: stats.c:276
bool loop_statistics(const string name)
cproto-generated files
Definition: stats.c:450
static void loop_rwt(loop l, context_p context)
Definition: stats.c:61
static void put_result(string filename)
Definition: stats.c:423
static void seq_rwt(sequence sq, context_p context)
Definition: stats.c:121
static bool loop_flt(loop l, context_p context)
Definition: stats.c:54
static bool call_flt(call ca, context_p context)
Definition: stats.c:377
static void wl_rwt(whileloop w, context_p context)
Definition: stats.c:399
static bool first_turn
Definition: stats.c:42
static int cpt
Definition: stats.c:41
static void initialize()
Definition: stats.c:407
static bool seq_flt(sequence sq, context_p context)
Definition: stats.c:116
static int nbr_perfectly_nested_loop
Definition: stats.c:39
static void test_rwt(test t, context_p context)
Definition: stats.c:281
static int nbr_loop
Definition: stats.c:39
static int nbr_interested_loop
Definition: stats.c:39
#define intptr_t
Definition: stdint.in.h:294
the stack head
Definition: stack.c:62
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
cette structure contient une pile.
Definition: delay.c:253
static int depth
la sequence de nids