PIPS
adg_summary.c
Go to the documentation of this file.
1 /*
2 
3  $Id: adg_summary.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_summary.c
28  * Package : array_dfg
29  * Author : Arnauld LESERVOT
30  * Date : 94/02/10
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 /* Local defines */
42 #define NEXT(cp) (((cp) == NIL) ? NIL : (cp)->cdr)
43 
44 /* Global variables */
46 extern int Gcount_re;
49 
50 extern int my_pip_count;
51 
52 /*=======================================================================*/
53 /* Pentity_vertices pev_new() AL 15/02/94
54  * Allocates a Pentity_vertices.
55  */
57 {
58  Pentity_vertices ret_pev = NULL;
59 
60  ret_pev = (Pentity_vertices) malloc( sizeof( Sentity_vertices ) );
61  if (ret_pev == NULL) {
62  (void) fprintf(stderr,"pev_new: Out of memory space\n");
63  exit(-1);
64  }
65  ret_pev->ent = (void *) NULL;
66  ret_pev->lis = (void *) NULL;
67  return ret_pev;
68 }
69 
70 /*=======================================================================*/
71 /* list adg_get_read_entity_vertices( (graph) in_dg ) AL 94/02/10
72  *
73  * Returns a list of Pentity_vertices, that represents all
74  * variables read in the input graph and vertices that read each
75  * of these variables. We do not keep entities that are in in_l,
76  * which represent structural parameters.
77  * PRIVATE use.
78  */
80 graph in_dg;
81 list in_l;
82 {
83  list vl = NULL, ret_list = NIL;
84 
85  /* Initialization */
86  debug(9, "adg_get_read_entity_vertices", "begin \n");
87 
88  /* Run over all vertices to take their read variables */
89  for( vl = graph_vertices( in_dg ); !ENDP(vl); POP(vl) ) {
90  vertex ver = NULL; /* Current vertex */
91  statement sta = NULL; /* Statement of vertex */
92  list effs = NULL; /* effects linked to ver */
93  list ent_l = NIL; /* variable read by ver */
94 
95  /* Take current vertex and effects links to it */
96  ver = VERTEX(CAR( vl ));
97  sta = adg_vertex_to_statement( ver );
98  effs = load_proper_rw_effects_list( sta );
99 
100 
101  /* Put in ent_l variables readen by ver */
102  for(; !ENDP(effs); POP(effs)) {
103  effect eff = NULL; /* Current effect */
104  entity ent = NULL; /* variable readden by effect eff */
105 
106  eff = EFFECT(CAR( effs ));
108  if (!action_read_p(effect_action( eff ))) continue;
109  if (is_entity_in_list_p( ent, ent_l )) continue;
110  if (is_entity_in_list_p( ent, in_l )) continue;
111  ADD_ELEMENT_TO_LIST( ent_l, ENTITY, ent );
112  }
113 
114  /* Update our list */
115  /* We scan over the readen variables in ent_l... */
116  for(; !ENDP(ent_l); POP(ent_l)) {
117  entity ent = NULL;
118  list prov_l = NULL;
119  Pentity_vertices pev = NULL;
120  boolean found = false;
121 
122  ent = ENTITY(CAR( ent_l ));
123 
124  /* ... to see if it is already in our ret_list */
125  for(prov_l = ret_list; !ENDP(prov_l); POP(prov_l)) {
126  Pentity_vertices pev2 = NULL;
127 
128  pev2 = (Pentity_vertices) CHUNK(CAR( prov_l ));
129  if (pev2->ent != ent) continue;
130 
131  /* We find it : we update pev2 */
132  ADD_ELEMENT_TO_LIST(pev2->lis, VERTEX, ver);
133  found = true;
134  break;
135  }
136  if (found) continue;
137 
138  /* entity ent is not in our ret_list : we add it */
139  pev = pev_new();
140  pev->ent = ENTITY(CAR( ent_l ));
141  ADD_ELEMENT_TO_LIST(pev->lis, VERTEX, ver);
142  ADD_ELEMENT_TO_LIST(ret_list, CHUNK, (chunk *) pev);
143  }
144  }
145 
146  debug(9, "adg_get_read_entity_vertices", "end \n");
147  return ret_list;
148 }
149 
150 
151 /*=======================================================================*/
152 /* list adg_get_write_entity_vertices( (graph) in_dg ) AL 94/02/10
153  *
154  * Returns a list of Pentity_vertices, that represents all
155  * variables written in the input graph and vertices that write each
156  * of these variables.
157  * PRIVATE use.
158  */
160 graph in_dg;
161 {
162  list vl = NULL, ret_list = NIL;
163 
164  /* Initialization */
165  debug(9, "adg_get_write_entity_vertices", "begin \n");
166 
167  /* Run over all vertices to take their write variable */
168  for( vl = graph_vertices( in_dg ); !ENDP(vl); POP(vl) ) {
169  vertex ver = NULL; /* Current vertex */
170  statement sta = NULL; /* statement of ver */
171  list effs = NULL; /* effects linked of sta */
172  entity w_ent = NULL; /* variable written by sta */
173  list prov_l = NULL;
174  boolean found = false;
175  Pentity_vertices pev = NULL;
176 
177  /* Take current vertex and effects links to it */
178  ver = VERTEX(CAR( vl ));
179  sta = adg_vertex_to_statement( ver );
180  if (!assignment_statement_p( sta )) continue;
181  effs = load_proper_rw_effects_list( sta );
182 
183  /* Put in ent_l variables readen by ver */
184  for(; !ENDP(effs); POP(effs)) {
185  effect eff = NULL; /* Current effect */
186  entity ent = NULL; /* variable readden by effect eff */
187 
188  eff = EFFECT(CAR( effs ));
190  if (!action_write_p(effect_action( eff ))) continue;
191  w_ent = ent;
192  break;
193  }
194 
195  /* Update our list */
196  /* Is w_ent already in our ret_list ?*/
197  for(prov_l = ret_list; !ENDP(prov_l); POP(prov_l)) {
198  Pentity_vertices pev2 = NULL;
199 
200  pev2 = (Pentity_vertices) CHUNK(CAR( prov_l ));
201  if (pev2->ent != w_ent) continue;
202 
203  /* We find it : we update pev2 */
204  ADD_ELEMENT_TO_LIST(pev2->lis, VERTEX, ver);
205  found = true;
206  break;
207  }
208  if (found) continue;
209 
210  /* entity w_ent is not in our ret_list : we add it */
211  pev = pev_new();
212  pev->ent = w_ent;
213  ADD_ELEMENT_TO_LIST(pev->lis, VERTEX, ver);
214  ADD_ELEMENT_TO_LIST(ret_list, CHUNK, (chunk *) pev);
215  }
216 
217  debug(9, "adg_get_write_entity_vertices", "end \n");
218  return ret_list;
219 }
220 
221 
222 
223 /*=======================================================================*/
224 /* graph adg_dataflowgraph_with_extremities(
225  * (statement) module_statement,
226  * (statement_mapping) static_control_map,
227  * (graph) reversed_dg )
228  * AL 94/02/10
229  */
231  mod_stat, stco_map, dup_dg )
233 statement_mapping stco_map;
234 graph dup_dg;
235 {
236  graph ret_graph = graph_undefined;
237  list ret_verl = NIL;
238  vertex ret_dest_ver = NULL;
239  list dest_psl = NULL;
240  predicate prov_pr = NULL;
241  list write_list = NULL, read_list = NULL;
242  quast entry_q = NULL, exit_q = NULL;
243  vertex entry_v = NULL, exit_v = NULL;
244 
245 
246  debug(1, "adg_dataflowgraph_with_extremities", "begin \n");
247 
248  /* We first put entry node in the return list */
251  ADD_ELEMENT_TO_LIST( ret_verl, VERTEX, entry_v );
254  NIL );
256 
257 
258  /* Make exit_v : the exit node */
261  ADD_ELEMENT_TO_LIST( ret_verl, VERTEX, exit_v );
264  NIL );
266 
267 
268 
269 
270  /*******************************************************************
271  * WRITE EFFECTS
272  */
273  if (get_debug_level() > 3) { /* For debug purpose */
274  fprintf(stderr, "\n========================================\n");
275  fprintf(stderr, "Destination Statement: EXIT NODE \n");
276  }
277 
278 
279  /* Compute source quast for the exit node */
280  ret_dest_ver = exit_v;
281  write_list = adg_get_write_entity_vertices( dup_dg );
282  for(; !ENDP( write_list ); POP( write_list )) {
283  Pentity_vertices pev = NULL;
284  list sou_l = NULL;
285  entity dest_ent = NULL;
286  Psysteme dest_context = SC_RN;
287  list dims = NIL; /* Dim des tableaux */
288  list dest_indic = NIL; /* Indices of Exit */
289  reference dest_ref = NULL;
290  int ie = (int) NULL, dims_length = (int) NULL;
291  quast source = quast_undefined;
292 
293 
294  /* Get write entity and vertices that write it */
295  pev = (Pentity_vertices) CHUNK(CAR( write_list ));
296  dest_ent = pev->ent;
297  sou_l = pev->lis;
298 
299  /* Build reference associated to destination entity */
300  dims = variable_dimensions(type_variable(entity_type(dest_ent)));
301  dims_length = gen_length( dims );
302  for(ie = 1; ie <= dims_length; ie++) {
303  entity ind = NULL;
304  ind = adg_get_integer_entity( ie );
306  }
307  dest_ref = make_reference( dest_ent, dest_indic );
308 
309 
310  /* No sources : ENTRY writes it */
311  if (sou_l == NIL) {
312  /* No sources : Comes from Entry point */
313  adg_fill_with_quast( &source, entry_q );
314 
315  /* Debugging */
316  debug(9,"adg_dataflowgraph",
317  "No candidates => Entry Flow\n");
318  if (get_debug_level() > 2) {
319  fprintf(stderr,
320  "\n ------ Final Source ------\n");
321  imprime_special_quast( stderr, source );
322  }
323 
324  adg_update_dfg( source,
325  dest_ref,
326  ret_dest_ver,
327  pa_full(),
328  dest_context,
329  SC_RN,
330  dup_dg,
331  &ret_verl );
332 
333  continue;
334  }
335  sou_l = adg_decreasing_stat_order_sort( sou_l );
336 
337 
338  /* Get context of destination entity */
339  for( ie = 1; !ENDP(dims); POP(dims), ie++) {
340  Pvecteur pv = NULL;
341  dimension dim = DIMENSION(CAR( dims ));
342  entity ind = NULL;
343  Psysteme pss = NULL;
344 
345  ind = adg_get_integer_entity( ie );
347  vect_new((Variable) ind , VALUE_ONE) );
349  dest_context = sc_append(dest_context, sc_dup(pss));
350  pv = vect_substract( vect_new((Variable) ind , VALUE_ONE),
353  dest_context = sc_append(dest_context, sc_dup(pss));
354  }
355 
356 
357  /* We run over all possible candidates
358  * and compute to see how it could contribute to the source
359  */
360  for(; !ENDP( sou_l ); POP(sou_l) ) {
361  vertex sou_v = NULL;
362  int sou_order = (int) NULL, sou_d = (int) NULL;
363  leaf_label sou_lel = NULL;
364  predicate sou_pred = NULL;
365  list sou_lcl = NULL, sou_args = NIL;
366  statement sou_s = NULL;
367  static_control sou_stco = NULL;
368  list sou_psl = NULL;
369  list sou_loops = NULL;
370  Psysteme sou_ps = SC_RN;
371  Psysteme prov_ps = SC_RN;
372  Psysteme loc_context = SC_RN;
373  quast sou_q = NULL;
374  Pposs_source poss = NULL;
375  quast *local_source = NULL;
376  Ppath local_path = NULL;
377  int max_depth = (int) NULL;
378  int enclosing_nb = (int) NULL;
379 
380 
381 
382  /* Get possible source vertex and informations
383  * linked to it
384  */
385  sou_v = VERTEX(CAR( sou_l ));
386  sou_d = 0;
389 
390  sou_s = adg_vertex_to_statement( sou_v );
391  sou_order = statement_ordering( sou_s );
392  sou_stco = (static_control) GET_STATEMENT_MAPPING( stco_map,sou_s );
393  sou_psl = static_control_params( sou_stco );
394  sou_loops = static_control_loops(sou_stco);
395  max_depth = 0;
396  sou_lcl = adg_get_loop_indices( sou_loops );
397  enclosing_nb = gen_length( sou_lcl );
398 
399 
400  /* If this candidate is not possible, see the next.
401  * if candidate is not valid with the present source.
402  */
403  poss = adg_path_possible_source(&source, sou_v, sou_d, pa_full(), TAKE_LAST);
404  local_path = (Ppath) poss->pat;
405  /* Not a possible source => get the next candidate */
406  if (is_pa_empty_p( local_path )) continue;
407 
408  if (local_path == PA_UNDEFINED) prov_ps = SC_UNDEFINED;
409  else prov_ps = local_path->psys;
410  local_source = (quast*) (poss->qua);
411 
412  loc_context = sc_append(sc_dup(prov_ps), dest_context);
413  prov_ps = SC_RN;
414 
415  /* For debug purpose */
416  if (get_debug_level() > 2) {
417  fprintf(stderr, "\nPossible Source Statement (ordering %d) ",sou_order);
418  fprintf(stderr, "at depth %d :\n", sou_d);
419  print_statement( sou_s );
420  }
421 
422 
423  /* Get the f(u) = g(b) psystem
424  * We first duplicate arguments expressions,
425  * then we rename entities that are at
426  * a deeper depth than sou_d and forward
427  * subsitute those new entities in the
428  * expressions
429  */
434  statement_instruction(sou_s) )))
435  ))));
436 
437 
438 
439  /* Make corresponding indices equal in source and dest
440  * F(u) = g(b) and put it in sou_ps.
441  */
442  for(ie = 1; !ENDP(sou_args); POP(sou_args), ie++){
443  expression sou_e = NULL;
444  Pvecteur pvec = NULL, exit_pv = NULL;
445  Psysteme pss = NULL;
446 
448  sou_e = copy_expression(EXPRESSION(CAR(sou_args)));
449  pvec = vect_substract( exit_pv, EXPRESSION_PVECTEUR( sou_e ));
450  if (pvec != NULL) {
452  sou_ps = sc_append(sou_ps, sc_dup(pss));
453  }
454  }
455 
456 
457  /* Build source Psysteme (IF and DO contraints).
458  * Build the context and rename variables .
459  */
460  /* Get predicate that comes from an IF statement */
462  if (sou_pred != predicate_undefined)
463  prov_ps = adg_sc_dup(predicate_system(sou_pred));
464 
465  /* Get predicate that comes from enclosing DO */
466  prov_pr = adg_get_predicate_of_loops( sou_loops );
467  if (prov_pr != predicate_undefined)
468  prov_ps = sc_append( prov_ps, predicate_system( prov_pr ) );
469 
470 
471  /* Append sous_ps (F(u) = g(b) and seq. predicate)
472  * with prov_ps (IF and DO constraints).
473  */
474  sou_ps = adg_suppress_2nd_in_1st_ps( sc_append(sou_ps, prov_ps), loc_context);
475  if ((sou_ps != NULL) && !my_sc_faisabilite( sou_ps )) continue;
476 
477 
478 
479 
480  /* Compute the new candidate source.
481  * We try to call PIP only if necesary.
482  */
483  if (get_debug_level() > 4) {
484  fprintf(stderr, "\nSource Psysteme :\n");
485  fprint_psysteme(stderr, sou_ps);
486  if (sou_ps != SC_UNDEFINED)
487  pu_vect_fprint(stderr, sou_ps->base);
488 
489  fprintf(stderr, "\nContext Psysteme :\n");
490  fprint_psysteme(stderr, loc_context);
491  if (loc_context != SC_RN) pu_vect_fprint(stderr,loc_context->base);
492  }
493  /* If there is no condition on source...*/
494  if (sou_ps == SC_UNDEFINED) {
497  }
498  else if (enclosing_nb == 0) {
499  quast prov_q = NULL;
500 
501  prov_ps = sc_append(sc_dup(sou_ps),loc_context);
502  if( (prov_ps == NULL) || my_sc_faisabilite(prov_ps)) {
503  prov_q = make_quast( make_quast_value(
506  sou_q = make_quast( make_quast_value(
509  prov_q, quast_undefined) ),
510  NIL );
511  }
512  else sou_q = quast_undefined;
513  }
514  else {
515  /* Order the psysteme according to ent_l */
516  Pvecteur prov_pv = NULL;
517 
518  prov_pv = adg_list_to_vect(sou_lcl, false);
519  sou_q = pip_integer_max( sou_ps , loc_context , prov_pv);
520  my_pip_count++;
521 
522  if (get_debug_level() > 4) imprime_special_quast( stderr, sou_q );
523  sou_q = adg_compact_quast( sou_q );
524  }
525  adg_enrichir( sou_q, sou_lel );
526  if (get_debug_level() > 4) {
527  fprintf(stderr, "\nPresent source quast :\n");
528  imprime_special_quast( stderr, sou_q );
529  }
530 
531 
532  /* Find the new source and simplify it */
533  adg_path_max_source( local_source, &sou_q, local_path, dest_psl, TAKE_LAST );
534 
535  if (get_debug_level() > 4) {
536  fprintf(stderr, "\n Updated Source :\n");
537  imprime_special_quast( stderr, source );
538  }
539  }
540 
541  /* Fill "quast_undefined" part of the source
542  * with ENTRY node.
543  */
544  adg_fill_with_quast( &source, entry_q );
545 
546 
547  /* Build the new Data Flow Graph with the new source*/
548  if (get_debug_level() > 2) {
549  fprintf(stderr, "\n ------ Final Source ------\n");
550  imprime_special_quast( stderr, source );
551  }
552 
553  adg_update_dfg( source,
554  dest_ref,
555  ret_dest_ver,
556  pa_full(),
557  dest_context,
558  SC_RN,
559  dup_dg,
560  &ret_verl );
561  }
562 
563  if (get_debug_level() > 0) fprint_dfg(stderr, make_graph(ret_verl));
564 
565 
566  /*******************************************************************
567  * READ EFFECTS
568  *
569  * Here, the order is reversed: we compute for each reference the
570  * first operation that reads it. Destination is always the entry point,
571  * and the source an operation of the program.
572  */
573  if (get_debug_level() > 3) { /* For debug purpose */
574  fprintf(stderr, "\n========================================\n");
575  fprintf(stderr, "Destination Statement: ENTRY NODE \n");
576  }
577 
578 
579  /* Compute source quast for the entry node */
580  ret_dest_ver = entry_v;
582  for(; !ENDP( read_list ); POP( read_list )) {
583  Pentity_vertices pev = NULL;
584  list sou_l = NULL;
585  entity dest_ent = NULL;
586  Psysteme dest_context = SC_RN;
587  list dims = NIL; /* Dim des tableaux */
588  list dest_indic = NIL; /* Indices of Exit */
589  reference dest_ref = NULL;
590  int ie = (int) NULL, dims_length = (int) NULL;
591  quast source = quast_undefined;
592 
593 
594  /* Get read entity and vertices that read it */
595  pev = (Pentity_vertices) CHUNK(CAR( read_list ));
596  dest_ent = pev->ent;
597  sou_l = pev->lis;
598 
599  /* Build reference associated to destination entity */
600  dims = variable_dimensions(type_variable(entity_type(dest_ent)));
601  dims_length = gen_length( dims );
602  for(ie = 1; ie <= dims_length; ie++) {
603  entity ind = NULL;
604  ind = adg_get_integer_entity( ie );
606  }
607  dest_ref = make_reference( dest_ent, dest_indic );
608 
609 
610  /* No sources : EXIT reads it */
611  if (sou_l == NIL) {
612  /* No sources : Comes from exit point */
613  adg_fill_with_quast( &source, exit_q );
614 
615  /* Debugging */
616  debug(9,"adg_dataflowgraph", "No candidates => Exit Flow\n");
617  if (get_debug_level() > 2) {
618  fprintf(stderr,"\n ------ Final Source ------\n");
619  imprime_special_quast( stderr, source );
620  }
621 
622  adg_update_dfg( source,
623  dest_ref,
624  ret_dest_ver,
625  pa_full(),
626  dest_context,
627  SC_RN,
628  dup_dg,
629  &ret_verl );
630 
631  continue;
632  }
633  sou_l = adg_increasing_stat_order_sort( sou_l );
634 
635 
636  /* Get context of destination entity */
637  for( ie = 1; !ENDP(dims); POP(dims), ie++) {
638  Pvecteur pv = NULL;
639  dimension dim = DIMENSION(CAR( dims ));
640  entity ind = NULL;
641  Psysteme pss = NULL;
642 
643  ind = adg_get_integer_entity( ie );
645  vect_new((Variable) ind , VALUE_ONE) );
647  dest_context = sc_append(dest_context, sc_dup(pss));
648  pv = vect_substract( vect_new((Variable) ind , VALUE_ONE),
651  dest_context = sc_append(dest_context, sc_dup(pss));
652  }
653 
654 
655  /* We run over all possible candidates
656  * and compute to see how it could contribute to the source
657  */
658  for(; !ENDP( sou_l ); POP(sou_l) ) {
659  vertex sou_v = NULL;
660  int sou_order = (int) NULL, sou_d = (int) NULL;
661  leaf_label sou_lel = NULL;
662  predicate sou_pred = NULL;
663  list sou_lcl = NULL;
664  statement sou_s = NULL;
665  static_control sou_stco = NULL;
666  list sou_psl = NULL, sou_loops = NULL;
667  list sou_read = NIL, sou_effs = NIL;
668  Psysteme sou_ps = SC_RN, sou_context = SC_RN;
669  Psysteme prov_ps = SC_RN;
670  Psysteme loc_context = SC_RN;
671  quast sou_q = NULL;
672  Pposs_source poss = NULL;
673  quast *local_source = NULL;
674  Ppath local_path = NULL;
675  int max_depth = (int) NULL;
676  int enclosing_nb = (int) NULL;
677 
678 
679 
680  /* Get possible source vertex and informations
681  * linked to it
682  */
683  sou_v = VERTEX(CAR( sou_l ));
684  sou_d = 0;
687 
688  sou_s = adg_vertex_to_statement( sou_v );
689  sou_order = statement_ordering( sou_s );
690  sou_stco = (static_control) GET_STATEMENT_MAPPING( stco_map, sou_s );
691  sou_psl = static_control_params( sou_stco );
692  sou_loops = static_control_loops(sou_stco);
693  max_depth = 0;
694  sou_lcl = adg_get_loop_indices( sou_loops );
695  enclosing_nb = gen_length( sou_lcl );
696 
697 
698  /* If this candidate is not possible, see the next.
699  * if candidate is not valid with the present source.
700  */
701  poss = adg_path_possible_source(&source, sou_v, sou_d, pa_full(), TAKE_FIRST);
702  local_path = (Ppath) poss->pat;
703  /* Not a possible source => get the next candidate */
704  if (is_pa_empty_p( local_path )) continue;
705 
706  local_source = (quast*) &source;
707  loc_context = sc_dup( dest_context );
708 
709 
710  /* Build source Psysteme (IF and DO contraints).
711  */
712  /* Get predicate that comes from an IF statement */
714  if (sou_pred != predicate_undefined) {
715  sou_context = adg_sc_dup(predicate_system(sou_pred));
716  }
717 
718  /* Get predicate that comes from enclosing DO */
719  prov_pr = adg_get_predicate_of_loops( sou_loops );
720  if (prov_pr != predicate_undefined)
721  sou_context = sc_append( prov_ps,predicate_system( prov_pr ) );
722 
723 
724 
725 
726  /* Get all different effects that reads dest_ent */
727  sou_effs = load_proper_rw_effects_list( sou_s );
728 
729  /* Put in ent_l variables readen by ver */
730  for(; !ENDP(sou_effs); POP(sou_effs)) {
731  effect eff = NULL; /* Current effect */
732  entity ent = NULL; /* variable readden by effect eff */
733 
734  eff = EFFECT(CAR( sou_effs ));
735  if (!action_read_p(effect_action( eff ))) continue;
737  if ( ent != dest_ent) continue;
738  if (is_entity_in_list_p( ent, sou_lcl )) continue;
739  ADD_ELEMENT_TO_LIST( sou_read, EFFECT, eff );
740  }
741 
742 
743  for(; !ENDP(sou_read); POP(sou_read)) {
744  effect sou_eff = NULL;
745  list sou_args = NULL;
746 
747 
748  sou_eff = EFFECT(CAR( sou_read ));
749  /* For debug purpose */
750  if (get_debug_level() > 2) {
751  fprintf(stderr, "\nPossible Source Statement (ordering %d) ",sou_order);
752  fprintf(stderr, "at depth %d :\n", sou_d);
753  print_statement( sou_s );
754  fprintf(stderr,"for effect :\n");
755  print_words(stderr, words_effect(sou_eff));
756  }
757 
758  /* Get the f(u) = g(b) psystem
759  * We first duplicate arguments expressions,
760  * then we rename entities that are at
761  * a deeper depth than sou_d and forward
762  * subsitute those new entities in the
763  * expressions
764  */
765  sou_args = reference_indices(effect_any_reference(sou_eff));
766 
767  /* Make corresponding indices equal in source and dest
768  * F(u) = g(b) and put it in sou_ps.
769  */
770  for(ie = 1; !ENDP(sou_args); POP(sou_args), ie++){
771  expression sou_e = NULL;
772  Pvecteur pvec = NULL, exit_v = NULL;
773  Psysteme pss = NULL;
774 
776  sou_e = copy_expression(EXPRESSION(CAR(sou_args)));
777  pvec = vect_substract( exit_v,EXPRESSION_PVECTEUR( sou_e ));
778  if (pvec != NULL) {
780  sou_ps = sc_append(sou_ps, sc_dup(pss));
781  }
782  }
783 
784 
785 
786 
787 
788  /* Append sous_ps (F(u) = g(b) and seq. predicate)
789  * with prov_ps (IF and DO constraints).
790  */
791  sou_ps = adg_suppress_2nd_in_1st_ps( sc_append(sou_ps, sou_context), loc_context);
792  if ((sou_ps != NULL) && !my_sc_faisabilite( sou_ps )) continue;
793 
794 
795 
796 
797  /* Compute the new candidate source.
798  * We try to call PIP only if necesary.
799  */
800  if (get_debug_level() > 4) {
801  fprintf(stderr, "\nSource Psysteme :\n");
802  fprint_psysteme(stderr, sou_ps);
803  if (sou_ps != SC_UNDEFINED) pu_vect_fprint(stderr, sou_ps->base);
804 
805  fprintf(stderr, "\nContext Psysteme :\n");
806  fprint_psysteme(stderr, loc_context);
807  if (loc_context != SC_RN) pu_vect_fprint(stderr,loc_context->base);
808  }
809  /* If there is no condition on source...*/
810  if (sou_ps == SC_UNDEFINED) {
813  }
814  else if (enclosing_nb == 0) {
815  quast prov_q = NULL;
816 
817  prov_ps = sc_append(sc_dup(sou_ps),loc_context);
818  if( (prov_ps == NULL) || my_sc_faisabilite(prov_ps)) {
823  make_predicate(sou_ps),
824  prov_q, quast_undefined)
825  ), NIL );
826  }
827  else sou_q = quast_undefined;
828  }
829  else {
830  /* Order the psysteme according to ent_l */
831  Pvecteur prov_pv = NULL;
832 
833  prov_pv = adg_list_to_vect(sou_lcl, false);
834  sou_q = pip_integer_max( sou_ps , loc_context , prov_pv);
835  my_pip_count++;
836 
837  if (get_debug_level() > 4) imprime_special_quast( stderr, sou_q );
838  sou_q = adg_compact_quast( sou_q );
839  }
840  adg_enrichir( sou_q, sou_lel );
841  if (get_debug_level() > 4) {
842  fprintf(stderr, "\nPresent source quast :\n");
843  imprime_special_quast( stderr, sou_q );
844  }
845 
846 
847  /* Find the new source and simplify it */
848  adg_path_max_source(local_source, &sou_q, local_path, dest_psl, TAKE_FIRST );
849 
850  if (get_debug_level() > 4) {
851  fprintf(stderr, "\n Updated Source :\n");
852  imprime_special_quast( stderr, source );
853  }
854  }
855  }
856 
857  /* Fill "quast_undefined" part of the source
858  * with EXIT node.
859  */
860  adg_fill_with_quast( &source, exit_q );
861 
862 
863  /* Build the new Data Flow Graph with the new source*/
864  if (get_debug_level() > 2) {
865  fprintf(stderr, "\n ------ Final Source ------\n");
866  imprime_special_quast( stderr, source );
867  }
868 
869  adg_update_dfg( source,
870  dest_ref,
871  ret_dest_ver,
872  pa_full(),
873  dest_context,
874  SC_RN,
875  dup_dg,
876  &ret_verl );
877  }
878 
879 
880  if (get_debug_level() > 0) fprint_dfg(stderr, make_graph(ret_verl));
881 
882 
883  ret_graph = make_graph( ret_verl );
884  debug(1, "adg_dataflowgraph", "end \n");
885  return( ret_graph );
886 
887 }
888 /*=======================================================================*/
graph make_graph(list a)
Definition: graph.c:56
vertex make_vertex(vertex_label a1, list a2)
Definition: graph.c:140
leaf_label make_leaf_label(intptr_t a1, intptr_t a2)
Definition: paf_ri.c:306
quast_value make_quast_value(enum quast_value_utype tag, void *val)
Definition: paf_ri.c:565
quast make_quast(quast_value a1, list a2)
Definition: paf_ri.c:516
conditional make_conditional(predicate a1, quast a2, quast a3)
Definition: paf_ri.c:138
quast_leaf make_quast_leaf(list a1, leaf_label a2)
Definition: paf_ri.c:474
dfg_vertex_label make_dfg_vertex_label(intptr_t a1, predicate a2, sccflags a3)
Definition: paf_ri.c:264
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
statement adg_vertex_to_statement(vertex in_ver)
======================================================================
Definition: adg_graph.c:266
void adg_update_dfg(quast in_sou, reference in_ref, vertex in_dest, Ppath in_pa, Psysteme in_context, Psysteme in_test, graph in_gr, list *in_lp)
======================================================================
Definition: adg_graph.c:386
predicate adg_get_predicate_of_loops(list loops)
======================================================================
Definition: adg_predicate.c:55
void fprint_dfg(FILE *fp, graph obj)
===========================================================================
void imprime_special_quast(FILE *fp, quast qu)
===========================================================================
Pentity_vertices pev_new()
======================================================================
Definition: adg_summary.c:56
int Gcount_re
External variables.
Definition: array_dfg.c:45
hash_table Gvertex_number_to_statement
Global variables.
Definition: adg_graph.c:42
list Gstructural_parameters
Definition: array_dfg.c:48
statement_mapping Gstco_map
Definition: array_dfg.c:47
list adg_get_read_entity_vertices(graph in_dg, list in_l)
======================================================================
Definition: adg_summary.c:79
graph adg_dataflowgraph_with_extremities(statement mod_stat, statement_mapping stco_map, graph dup_dg)
======================================================================
Definition: adg_summary.c:230
int my_pip_count
Definition: array_dfg.c:50
list adg_get_write_entity_vertices(graph in_dg)
======================================================================
Definition: adg_summary.c:159
quast adg_path_max_source(quast *tsou, quast *tsou2, Ppath in_pa, list psl, boolean take_last)
======================================================================
Definition: adg_utils.c:726
quast adg_compact_quast(quast in_q)
======================================================================
Definition: adg_utils.c:129
Pvecteur adg_list_to_vect(list in_list, bool with_tcst)
======================================================================
Definition: adg_utils.c:865
void adg_fill_with_quast(quast *in_pq, quast in_q)
======================================================================
Definition: adg_utils.c:52
list adg_decreasing_stat_order_sort(list in_list)
======================================================================
Definition: adg_utils.c:1028
list adg_increasing_stat_order_sort(list in_list)
======================================================================
Definition: adg_utils.c:1013
Psysteme adg_sc_dup(Psysteme in_ps)
======================================================================
Definition: adg_utils.c:331
Pposs_source adg_path_possible_source(quast *in_tsou, vertex in_ver, int in_dep, Ppath in_pa, bool take_last)
======================================================================
Definition: adg_utils.c:929
list adg_get_loop_indices(list ll)
======================================================================
Definition: adg_utils.c:1186
void adg_enrichir(quast in_qu, leaf_label in_ll)
======================================================================
Definition: adg_utils.c:474
Psysteme adg_suppress_2nd_in_1st_ps(Psysteme in_ps1, Psysteme in_ps2)
======================================================================
Definition: adg_utils.c:403
entity adg_get_integer_entity(int in_i)
======================================================================
Definition: adg_utils.c:83
void const char const char const int
#define VALUE_ONE
#define EXIT_ORDER
#define TAKE_FIRST
#define EXPRESSION_PVECTEUR(e)
#define ENTRY_ORDER
#define TAKE_LAST
struct Sentity_vertices * Pentity_vertices
bool my_sc_faisabilite(Psysteme in_ps)
Definition: array_dfg.c:55
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
#define sccflags_undefined
Definition: dg.h:247
list load_proper_rw_effects_list(statement)
list words_effect(effect)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314
#define action_read_p(x)
Definition: effects.h:311
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define CHUNK(x)
Definition: genC.h:90
if(!(yy_init))
Definition: genread_lex.c:1029
void * malloc(YYSIZE_T)
#define vertex_vertex_label(x)
Definition: graph.h:152
#define graph_vertices(x)
Definition: graph.h:82
#define graph_undefined
Definition: graph.h:60
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
#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
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
bool assignment_statement_p(statement)
Test if a statement is an assignment.
Definition: statement.c:135
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
#define ADD_ELEMENT_TO_LIST(_list, _type, _element)
Definition: icfg-local.h:50
static statement mod_stat
We want to keep track of the current statement inside the recurse.
Definition: impact_check.c:41
#define exit(code)
Definition: misc-local.h:54
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
#define GET_STATEMENT_MAPPING(map, stat)
Definition: newgen-local.h:49
bool is_entity_in_list_p(entity, list)
===========================================================================
Definition: utils.c:1281
void pu_vect_fprint(FILE *, Pvecteur)
===========================================================================
Definition: print.c:446
void fprint_psysteme(FILE *, Psysteme)
===========================================================================
Definition: print.c:302
#define static_control_loops(x)
Definition: paf_ri.h:757
#define quast_undefined
Definition: paf_ri.h:603
struct _newgen_struct_static_control_ * static_control
Definition: paf_ri.h:184
@ is_quast_value_quast_leaf
Definition: paf_ri.h:654
@ is_quast_value_conditional
Definition: paf_ri.h:655
#define static_control_params(x)
Definition: paf_ri.h:755
#define dfg_vertex_label_statement(x)
Definition: paf_ri.h:413
#define quast_leaf_undefined
Definition: paf_ri.h:567
#define dfg_vertex_label_exec_domain(x)
Definition: paf_ri.h:415
Ppath pa_full()
Ppath pa_full() AL 18/11/93 Returns full space path : pa_full = pa_new()
Definition: path.c:117
quast pip_integer_max(Psysteme ps_dep, Psysteme ps_context, Pvecteur pv_unknowns)
==================================================================
Definition: pip.c:637
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_ordering(x)
Definition: ri.h:2454
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define predicate_undefined
Definition: ri.h:2046
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define call_arguments(x)
Definition: ri.h:711
#define entity_type(x)
Definition: ri.h:2792
#define expression_syntax(x)
Definition: ri.h:1247
#define predicate_system(x)
Definition: ri.h:2069
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_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...
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
Structure to list wich node read or write an effect.
Psysteme psys
Definition: union-local.h:19
Structure for return of a possible source.
Pbase base
Definition: sc-local.h:75
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
void print_words(FILE *fd, cons *lw)
Definition: print.c:263
#define PA_UNDEFINED
Definition: union-local.h:23
#define is_pa_empty_p(pa)
Definition: union-local.h:75
struct Spath * Ppath
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