PIPS
impact_check.c
Go to the documentation of this file.
1 /*
2 
3  $Id: impact_check.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 "local.h"
28 #include "prettyprint.h"
29 
30 #define DEP_FLOW 0
31 #define DEP_ANTI 1
32 #define DEP_OUTP 2
33 
34 #define MUST_APPROXIMATION 0
35 #define MAY_APPROXIMATION 1
36 #define NOT_APPROXIMATION 2
37 
38 /* We want to keep track of the current statement inside the recurse */
39 /*DEFINE_LOCAL_STACK(current_stmt, statement)*/
40 
43 static graph dg = NULL; /* data dependence graph */
46 static list stat_reads1 = NIL; /* list of statement_approximation_p */
47 static list stat_writes1 = NIL; /* list of statement_approximation_p */
48 static list stat_reads2 = NIL; /* list of statement_approximation_p */
49 static list stat_writes2 = NIL; /* list of statement_approximation_p */
50 
52 /* This list tells us if two variables have been checked dynamically or not */
56 static const char* caller_name;
59 static int number_of_impact_alias = 0;
60 
62 {
63  user_log("\n Number of processed modules: %d", number_of_processed_modules);
64  user_log("\n Number of impact alias: %d\n", number_of_impact_alias);
65 }
66 
67 // DUPLICATED FUNCTIONS also instrumentation/alias_check.c
68 // some alias-utils is missing?
69 
70 static bool same_call_site_p(call_site cs1, call_site cs2)
71 {
72  entity f1 = call_site_function(cs1);
74  int o1 = call_site_ordering(cs1);
75  int o2 = call_site_ordering(cs2);
76  return (same_entity_p(f1,f2) && (o1==o2));
77 }
78 
79 // function also in instrumentation/alias_check.c
80 static bool included_call_chain_p(list l1, list l2)
81 {
82  while (!ENDP(l1) && !ENDP(l2))
83  {
84  call_site cs1 = CALL_SITE(CAR(l1));
85  call_site cs2 = CALL_SITE(CAR(l2));
86  if (!same_call_site_p(cs1,cs2)) return false;
87  l1 = CDR(l1);
88  l2 = CDR(l2);
89  }
90  return true;
91 }
92 
93 /****************************************************************************
94 
95  This function returns true if l1 = conc(cs,l2)
96 
97 *****************************************************************************/
98 
99 static bool tail_call_path_p(call_site cs, list l1, list l2)
100 {
101  if (gen_length(l1) == gen_length(l2)+1)
102  {
103  call_site cs1 = CALL_SITE(CAR(l1));
104  return (same_call_site_p(cs,cs1) && included_call_chain_p(l2,CDR(l1)));
105  }
106  return false;
107 }
108 
109 /*****************************************************************************
110 
111  This function computes the offset of a storage ram variable :
112  offset = initial_offset + subscript_value_stride
113 
114 *****************************************************************************/
115 
117 {
118  ram r = storage_ram(s);
119  int initial_off = ram_offset(r);
120  expression exp = int_to_expression(initial_off);
121  if (!expression_equal_integer_p(subval,0))
122  {
123  if (initial_off == 0)
124  exp = copy_expression(subval);
125  else
127  int_to_expression(initial_off),
128  copy_expression(subval));
129  }
130  return exp;
131 }
132 
133 /****************************************************************************
134 
135  This function computes the offset of a formal storage variable :
136  offset = initial_offset + subscript_value_stride
137 
138  initial_offset is from alias_association with path' = path - {cs}
139 
140 *****************************************************************************/
141 
143  expression subval,list path)
144 {
145  list l_caller_aliases = alias_associations_list((alias_associations)
146  db_get_memory_resource(DBR_ALIAS_ASSOCIATIONS,caller_name,true));
149  {
150  entity caller_var = alias_association_variable(aa);
151  list caller_path = alias_association_call_chain(aa);
152  if (same_entity_p(caller_var,actual_var) && tail_call_path_p(cs,caller_path,path))
153  {
154  expression initial_off = alias_association_offset(aa);
155  if (!expression_undefined_p(initial_off))
156  {
157  if (expression_equal_integer_p(subval,0))
158  exp = copy_expression(initial_off);
159  else
161  copy_expression(initial_off),
162  copy_expression(subval));
163  }
164  return exp;
165  }
166  },
167  l_caller_aliases);
168  return exp;
169 }
170 
171 
172 /*****************************************************************************
173 
174  If e is a formal parameter, find its rank in the formal parameter list of
175  current module in order to find out the corresponding actual argument and
176  then its offset
177 
178  If e is a common variable in the current module, offset of e is constant
179 
180 *****************************************************************************/
181 
183 {
184  ram ra ;
185  if (formal_parameter_p(e))
186  {
188  int rank = formal_offset(f);
189  list l_args = call_arguments(current_call);
190  expression actual_arg = find_ith_argument(l_args,rank);
191  reference actual_ref = expression_reference(actual_arg);
192  entity actual_var = reference_variable(actual_ref);
193  list l_actual_inds = reference_indices(actual_ref);
194  /* compute the subscript value, return expression_undefined if
195  if the actual argument is a scalar variable or array name*/
196  expression subval = subscript_value_stride(actual_var,l_actual_inds);
197  storage s = entity_storage(actual_var);
198  ifdebug(3)
199  fprintf(stderr, " \n Current actual argument %s",entity_name(actual_var));
200  if (storage_ram_p(s))
201  /* The actual argument has a ram storage */
202  return storage_ram_offset(s,subval);
203  if (storage_formal_p(s))
204  /* The actual argument is a formal parameter of the current caller,
205  we must take the alias_associations of the caller */
206  return storage_formal_offset(cs,actual_var,subval,path);
207  }
208  // common variable
209  ra = storage_ram(entity_storage(e));
210  return int_to_expression(ram_offset(ra));
211 }
212 
214 {
217  return false;
218  }
219  return true;
220 }
221 
223 {
224  return (statement_number(s1) == statement_number(s2));
225 }
226 
228 {
229  MAP(VERTEX, v, {
231  if (statement_equal_p(s, sv))
232  return v;
233  }, graph_vertices(g));
234  return vertex_undefined;
235 }
236 
237 /* Check to see if new dependence is covered by arcs in dependence graph at reference level */
238 bool find_covering_reference_path(set arcs_processed_set,
239  statement s_src,
240  action act_src,
241  entity ent_src,
242  statement s_dest,
243  action act_dest,
244  entity ent_dest)
245 {
246  if (statement_equal_p(s_src, s_dest))
247  {
248  if (entities_may_conflict_p(ent_src, ent_dest))
249  return (action_write_p(act_dest) || action_read_p(act_src));
250  else
251  return (action_write_p(act_dest) && action_read_p(act_src));
252  }
253  else
254  {
255  vertex ver_src = statement_to_vertex(s_src, dg);
256  MAP(SUCCESSOR, su, {
259  MAP(CONFLICT, c, {
260  effect e_tmp_src = conflict_source(c);
261  effect e_tmp_dest = conflict_sink(c);
262  entity ent_tmp_src = reference_variable(effect_any_reference(e_tmp_src));
263  entity ent_tmp_dest = reference_variable(effect_any_reference(e_tmp_dest));
264  action act_tmp_src = effect_action(e_tmp_src);
265  action act_tmp_dest = effect_action(e_tmp_dest);
266  set arcs_processed_tmp_set = set_make(set_pointer);
267  if (set_belong_p(arcs_processed_set, (char *)c)) continue;
268  arcs_processed_tmp_set = set_add_element(arcs_processed_tmp_set, arcs_processed_set, (char *)c);
269  if (entities_may_conflict_p(ent_src, ent_tmp_src))
270  {
271  if (action_write_p(act_tmp_src) || action_read_p(act_src))
272  if (find_covering_reference_path(arcs_processed_tmp_set,
273  s_tmp, act_tmp_dest, ent_tmp_dest,
274  s_dest, act_dest, ent_dest)) return true;
275  }
276  else
277  {
278  if (action_write_p(act_tmp_src) && action_read_p(act_src))
279  if (find_covering_reference_path(arcs_processed_tmp_set,
280  s_tmp, act_tmp_dest, ent_tmp_dest,
281  s_dest, act_dest, ent_dest)) return true;
282  }
283  }, dg_arc_label_conflicts(dal));
284  }, vertex_successors(ver_src));
285  }
286  return false;
287 }
288 
289 /* Check to see if there is a directed way between 2 statements in the graph specified */
291 {
292  vertex v1 = statement_to_vertex(s1, g);
293  list vertex_processed_list = NIL;
294  list vertex_rest_list = NIL;
295  ADD_ELEMENT_TO_LIST(vertex_rest_list, VERTEX, v1);
296 
297  while(!ENDP(vertex_rest_list)) {
298  vertex v = VERTEX(CAR(vertex_rest_list));
299  POP(vertex_rest_list);
300  if (!gen_in_list_p(v, vertex_processed_list)) {
302  if (statement_equal_p(sv, s2))
303  return true;
304  else {
305  ADD_ELEMENT_TO_LIST(vertex_processed_list, VERTEX, v);
306  MAP(SUCCESSOR, su, {
307  vertex v2 = successor_vertex(su);
308  if (!gen_in_list_p(v2, vertex_processed_list) && !gen_in_list_p(v2, vertex_rest_list))
309  ADD_ELEMENT_TO_LIST(vertex_rest_list, VERTEX, v2);
310  }, vertex_successors(v));
311  }
312  }
313  }
314  return false;
315 }
316 
317 /* This function prints the call path , including names of caller functions
318  and orderings of call sites in their corresponding functions */
319 static string print_call_path(list path)
320 {
321  list pc = NIL;
322  MAP(CALL_SITE,casi,
323  {
324  entity casifunc = call_site_function(casi);
325  int casiord = call_site_ordering(casi);
326  pc = CHAIN_SWORD(pc,"(");
327  pc = CHAIN_SWORD(pc,module_local_name(casifunc));
328  pc = CHAIN_SWORD(pc,":(");
329  pc = CHAIN_SWORD(pc,int2a(ORDERING_NUMBER(casiord)));
330  pc = CHAIN_SWORD(pc,",");
331  pc = CHAIN_SWORD(pc,int2a(ORDERING_STATEMENT(casiord)));
332  pc = CHAIN_SWORD(pc,")) ");
333  },path);
334  return words_to_string(pc);
335 }
336 
337 
338 static void insert_impact_description_as_comment(statement s1, statement s2, bool impact_must_p, int dep_type)
339 {
341  switch(dep_type) {
342  case DEP_FLOW:
343  insert_comments_to_statement(s2, "C\tNew flow-dependence with statement\n");
344  break;
345  case DEP_ANTI:
346  insert_comments_to_statement(s2, "C\tNew anti-dependence with statement\n");
347  break;
348  case DEP_OUTP:
349  insert_comments_to_statement(s2, "C\tNew output-dependence with statement\n");
350  break;
351  }
352  insert_comments_to_statement(s2, strdup(concatenate("C\tAttention: impact alias ",
353  impact_must_p ? "MUST":"MAY",
354  " at ",
356  " between ",
358  " and ",
360  "\n",
361  NULL)));
362  return;
363 }
364 
365 /*
366 list union_list(list l1, list l2) {
367  MAP(STATEMENT, s, {
368  if (!gen_in_list_p(s, l1))
369  ADD_ELEMENT_TO_LIST(l1, STATEMENT, s);
370  }, l2);
371  return l1;
372 }
373 */
374 
375 /* Union is not typed... */
377  list cl = list_undefined;
378 
379  for(cl=l2; !ENDP(cl); POP(cl)) {
380  gen_chunk * gcp = CHUNK(CAR(cl));
381  if(!gen_in_list_p(gcp , l1))
382  l1 = gen_nconc(l1, gen_cons(gcp, NIL));
383  }
384 
385  return l1;
386 }
387 
389 {
390  MAP(EFFECT, eff, {
393  return eff;
394  }, statement_to_effects(s));
395  return NULL;
396 }
397 
399 {
400  MAP(EFFECT, eff, {
403  return eff;
404  }, statement_to_effects(s));
405  return NULL;
406 }
407 
408 static int __attribute__ ((unused)) expression_approximation(statement s, expression ex)
409 {
412  Psysteme precondition_ps = predicate_system(transformer_relation(pre));
413  if (normalized_linear_p(n))
414  {
416  Pcontrainte volatile pc = contrainte_make(pv);
417  /* Automatic variables read in a CATCH block need to be declared volatile as
418  * specified by the documentation*/
419  Psysteme volatile ps = sc_dup(precondition_ps);
420  sc_add_ineg(ps, pc);
422  sc_rm(ps);
423  return MAY_APPROXIMATION;
424  }
425  TRY {
426  bool n_positif, n_negatif;
427  n_negatif = sc_rational_feasibility_ofl_ctrl(ps,FWD_OFL_CTRL,true);
428  (void) vect_chg_sgn(pv);
429  n_positif = sc_rational_feasibility_ofl_ctrl(ps,FWD_OFL_CTRL,true);
430  fprintf(stderr, "n_negatif : %s\n", n_negatif ? "TRUE" : "FALSE");
431  fprintf(stderr, "n_positif : %s\n", n_positif ? "TRUE" : "FALSE");
433  }
434  sc_rm(ps);
435  }
436  return MAY_APPROXIMATION;
437 }
438 
440 {
442  normalized
443  n_m1 = NORMALIZE_EXPRESSION(range_lower(rg)),
444  n_m2 = NORMALIZE_EXPRESSION(range_upper(rg)),
446 
448  Psysteme precondition_ps = predicate_system(transformer_relation(pre));
449 
450  if (normalized_linear_p(n_m1) && normalized_linear_p(n_m2) && normalized_linear_p(n_m3))
451  {
452  bool m3_negatif, m3_positif;
453  /* Tester le signe de l'incrï¿œment en fonction des prï¿œconditions : */
454  Pvecteur pv3 = vect_dup(normalized_linear(n_m3));
455  Pcontrainte pc3 = contrainte_make(pv3);
456  /* Automatic variables read in a CATCH block need to be declared volatile as
457  * specified by the documentation*/
458  Psysteme volatile ps = sc_dup(precondition_ps);
459  sc_add_ineg(ps, pc3);
461  sc_rm(ps);
462  return MAY_APPROXIMATION;
463  }
464  TRY {
465  m3_negatif = sc_rational_feasibility_ofl_ctrl(ps,FWD_OFL_CTRL,true);
466  (void) vect_chg_sgn(pv3);
467  m3_positif = sc_rational_feasibility_ofl_ctrl(ps,FWD_OFL_CTRL,true);
469  }
470  pips_debug(2, "loop_increment_value positif = %d, negatif = %d\n",
471  m3_positif, m3_negatif);
472 
473  /* Vire aussi pv3 & pc3 : */
474  sc_rm(ps);
475 
476  /* le signe est dï¿œterminï¿œ et diffï¿œrent de 0 */
477  if (m3_positif ^ m3_negatif)
478  {
479  Pvecteur pv1, pv2, pv, pv_inverse;
480  Pcontrainte c, c_inverse;
481 
482  pv1 = normalized_linear(n_m1);
483  pv2 = normalized_linear(n_m2);
484 
485  /* pv = m1 - m2 */
486  pv = vect_substract(pv1, pv2);
487  pv_inverse = vect_dup(pv);
488  /* pv_inverse = m2 - m1 */
489  (void)vect_chg_sgn(pv_inverse);
490 
491  c = contrainte_make(pv);
492  c_inverse = contrainte_make(pv_inverse);
493 
494  /* ??? on overflows, go next ... */
495  if(ineq_redund_with_sc_p(precondition_ps, c)) {
496  contrainte_free(c);
497  return (m3_positif ? MUST_APPROXIMATION : NOT_APPROXIMATION);
498  }
499  contrainte_free(c);
500 
501  /* ??? on overflows, should assume MAY_BE_EXECUTED... */
502  if(ineq_redund_with_sc_p(precondition_ps, c_inverse)) {
503  contrainte_free(c_inverse);
504  return (m3_positif ? NOT_APPROXIMATION : MUST_APPROXIMATION);
505  }
506  contrainte_free(c_inverse);
507  return MAY_APPROXIMATION;
508  }
509  }
510  return MAY_APPROXIMATION;
511 }
512 
514  hash_table control_to_set_of_dominators)
515 {
516  if (!hash_defined_p(control_to_set_of_dominators, (char *)c))
517  {
518  set dominator = set_make(set_pointer);
519  hash_put(control_to_set_of_dominators, (char *)c, (char *)dominator);
520  return dominator;
521  }
522  else
523  return (set) hash_get(control_to_set_of_dominators, (char *)c);
524 }
525 
526 static void __attribute__ ((unused)) computing_dominators(hash_table control_to_set_of_dominators, control n0)
527 {
528  bool change = true;
529  list blocs = NIL;
530  int count = 0;
531  control c_count = NULL;
532  set set_N;
533  set dominator_dn = create_or_get_a_set_from_control(n0, control_to_set_of_dominators);
534  set_add_element(dominator_dn, dominator_dn, (char *)n0);
535 
536  /* compute the set N of nodes in flowgraph */
537  set_N = set_make(set_pointer);
538  CONTROL_MAP(n, set_add_element(set_N, set_N, (char *)n), n0, blocs);
539  gen_free_list(blocs);
540  blocs = NIL;
541 
542  /* Initialization D(n) = N */
543  CONTROL_MAP(n, {
544  if (n == n0) continue;
545  dominator_dn = create_or_get_a_set_from_control(n, control_to_set_of_dominators);
546  set_assign(dominator_dn, set_N);
547  }, n0, blocs);
548  gen_free_list(blocs);
549  blocs = NIL;
550  set_free(set_N);
551 
552  while (change)
553  {
554  list sub_blocs = NIL;
555  change = false;
556  CONTROL_MAP(n, {
557  set dominator_dp = NULL;
558  if (n == n0) continue;
559  count++;
560  dominator_dn = set_make(set_pointer);
561  set_add_element(dominator_dn, dominator_dn, (char *)n);
562 
563  BACKWARD_CONTROL_MAP(pred, {
564  if (dominator_dp == NULL)
565  {
566  dominator_dp = set_make(set_pointer);
567  set_assign(dominator_dp,
568  create_or_get_a_set_from_control(pred, control_to_set_of_dominators));
569  } else
570  set_intersection(dominator_dp, dominator_dp,
571  create_or_get_a_set_from_control(pred, control_to_set_of_dominators));
572  }, n, sub_blocs);
573  gen_free_list(sub_blocs);
574  sub_blocs = NIL;
575 
576  set_union(dominator_dn, dominator_dn, dominator_dp);
577 
578  if (!set_equal_p(dominator_dn,
579  create_or_get_a_set_from_control(n, control_to_set_of_dominators)))
580  {
581  change = true;
582  hash_update(control_to_set_of_dominators, (char *)n, dominator_dn);
583  }
584  if (count == 11)
585  c_count = n;
586 
587  }, n0, blocs);
588  gen_free_list(blocs);
589  blocs = NIL;
590  }
591  dominator_dn = create_or_get_a_set_from_control(c_count, control_to_set_of_dominators);
592  fprintf(stderr, "dominators of statement\n");
594  count = 0;
595  SET_MAP(dom, {
596  control c = (control) dom;
597  fprintf(stderr, "#%d : ", ++count);
599  }, dominator_dn);
600 }
601 
602 static int __attribute__ ((unused)) control_approximation_between_statement_p(statement s1, statement s2)
603 {
604  /* control_graph does not work until load_ctrl_graph is called
605  * control
606  * c1 = unstructured_control(control_graph(s1)),
607  * c2 = unstructured_control(control_graph(s2));
608  *
609  * load_ctrl_graph work only if full_control_graph is called before
610  * and clean_ctrl_graph is called after
611  */
612  control
613  c1 = load_ctrl_graph(s1),
614  c2 = load_ctrl_graph(s2);
615  list blocs = NIL;
616  statement s;
617  int
618  statement_exec_appro = MUST_APPROXIMATION,
619  statement_exec_appro1 = MUST_APPROXIMATION,
620  statement_exec_appro2 = MUST_APPROXIMATION;
621 
622  BACKWARD_CONTROL_MAP(pred, {
623  s = control_statement(pred);
624  if (gen_length(control_successors(pred)) <= 1) continue;
626  case is_instruction_test:
627  /*fprintf(stderr, "TEST......\n");*/
628  return false;
629  break;
630  case is_instruction_loop:
631  statement_exec_appro = loop_executed_approximation(s);
632  break;
634  /*fprintf(stderr, "START.....\n");
635  safe_print_statement(s1);
636  safe_print_statement(s);
637  statement_exec_appro = expression_approximation(s, whileloop_condition(instruction_whileloop(statement_instruction(s))));*/
638  break;
639  case is_instruction_call:
640  /* consideration of parameters here */
641  break;
644  case is_instruction_goto:
645  default:
646  break;
647  }
648 
649  switch (statement_exec_appro) {
650  case MUST_APPROXIMATION:
651  break;
652  case MAY_APPROXIMATION:
653  statement_exec_appro1 = statement_exec_appro;
654  break;
655  case NOT_APPROXIMATION:
656  return NOT_APPROXIMATION;
657  }
658 
659  }, c1, blocs);
660  gen_free_list(blocs);
661 
662  blocs = NIL;
663  BACKWARD_CONTROL_MAP(pred, {
664  s = control_statement(pred);
665  if (gen_length(control_successors(pred)) <= 1) continue;
667  case is_instruction_test:
668  /*fprintf(stderr, "TEST......\n");*/
669  return false;
670  break;
671  case is_instruction_loop:
672  statement_exec_appro = loop_executed_approximation(s);
673  break;
675  /*fprintf(stderr, "START.....\n");
676  safe_print_statement(s2);
677  safe_print_statement(s);
678  statement_exec_appro = expression_approximation(s, whileloop_condition(instruction_whileloop(statement_instruction(s))));*/
679  break;
680  case is_instruction_call:
681  /* consideration of parameters here */
682  break;
685  case is_instruction_goto:
686  default:
687  break;
688  }
689 
690  switch (statement_exec_appro) {
691  case MUST_APPROXIMATION:
692  break;
693  case MAY_APPROXIMATION:
694  statement_exec_appro2 = statement_exec_appro;
695  break;
696  case NOT_APPROXIMATION:
697  return NOT_APPROXIMATION;
698  }
699 
700  }, c2, blocs);
701  gen_free_list(blocs);
702 
703  return ((statement_exec_appro1 == MUST_APPROXIMATION) && (statement_exec_appro2 == MUST_APPROXIMATION))
705 }
706 
708 {
709  set arcs_processed_set = set_make(set_pointer);
710  list stat_reads1_old = gen_copy_seq(stat_reads1);
711  list stat_writes1_old = gen_copy_seq(stat_writes1);
712  list stat_reads2_old = gen_copy_seq(stat_reads2);
713  list stat_writes2_old = gen_copy_seq(stat_writes2);
714 
715  MAP(EFFECT, eff, {
717  action act_dest = effect_action(eff);
718  bool impact_must_p = false; /* default value of dependence : MAY */
719  effect eff_tmp;
720 
721  if (entities_may_conflict_p(ent_dest, alias_ent1)) {
722  if (action_read_p(act_dest)) {
724  /* used for remember to rebuild the list of read statements for alias_ent1 */
725  stat_reads1 = CONS(STATEMENT, s, NIL);
726  MAP(STATEMENT, sw2, {
727  if (!statement_undefined_p(sw2)) { /* new flow-dependence created */
728  set_clear(arcs_processed_set);
729  if (!find_covering_reference_path(arcs_processed_set,
731  s, act_dest, alias_ent1))
732  {
734  /*switch (control_approximation_between_statement_p(sw2, s)) {*/
735  switch(MUST_APPROXIMATION) {
736  case MUST_APPROXIMATION:
738  if (!effect_undefined_p(eff_tmp))
739  impact_must_p = approximation_exact_p(effect_approximation(eff_tmp));
740  impact_must_p = impact_must_p &&
742  insert_impact_description_as_comment(sw2, s, impact_must_p, DEP_FLOW);
743  break;
744  case MAY_APPROXIMATION:
746  break;
747  case NOT_APPROXIMATION:
748  /* dependence does not exist so no impact alias*/
749  break;
750  }
751  }
752  }
753  }, stat_writes2_old);
754  } else {
756  /* used for remember to rebuild the list of write statements for alias_ent1 */
758  MAP(STATEMENT, sr2, {
759  if (!statement_undefined_p(sr2)) { /* new anti-dependence created */
760  set_clear(arcs_processed_set);
761  if (!find_covering_reference_path(arcs_processed_set,
763  s, act_dest, alias_ent1))
764  {
766  /*switch (control_approximation_between_statement_p(sr2, s)) {*/
767  switch(MUST_APPROXIMATION) {
768  case MUST_APPROXIMATION:
770  if (!effect_undefined_p(eff_tmp))
771  impact_must_p = approximation_exact_p(effect_approximation(eff_tmp));
772  impact_must_p = impact_must_p &&
774  insert_impact_description_as_comment(sr2, s, impact_must_p, DEP_ANTI);
775  break;
776  case MAY_APPROXIMATION:
778  break;
779  case NOT_APPROXIMATION:
780  /* dependence does not exist so don't the impact alias*/
781  break;
782  }
783  }
784  }
785  }, stat_reads2_old);
786  MAP(STATEMENT, sw2, {
787  if (!statement_undefined_p(sw2)) { /* new output-dependence created */
788  set_clear(arcs_processed_set);
789  if (!find_covering_reference_path(arcs_processed_set,
791  s, act_dest, alias_ent1))
792  {
794  /*switch (control_approximation_between_statement_p(sw2, s)) {*/
795  switch(MUST_APPROXIMATION) {
796  case MUST_APPROXIMATION:
798  if (!effect_undefined_p(eff_tmp))
799  impact_must_p = approximation_exact_p(effect_approximation(eff_tmp));
800  impact_must_p = impact_must_p &&
802  insert_impact_description_as_comment(sw2, s, impact_must_p, DEP_OUTP);
803  break;
804  case MAY_APPROXIMATION:
806  break;
807  case NOT_APPROXIMATION:
808  /* dependence does not exist so don't the impact alias*/
809  break;
810  }
811  }
812  }
813  }, stat_writes2_old);
814  }
815  }
816  if (entities_may_conflict_p(ent_dest, alias_ent2)) {
817  if (action_read_p(act_dest)) {
819  /* rebuild the list of read statements for alias_ent2 */
820  stat_reads2 = CONS(STATEMENT, s, NIL);
821  MAP(STATEMENT, sw1, {
822  if (!statement_undefined_p(sw1)) { /* new flow-dependence created */
823  set_clear(arcs_processed_set);
824  if (!find_covering_reference_path(arcs_processed_set,
826  s, act_dest, alias_ent2))
827  {
829  /*switch (control_approximation_between_statement_p(sw1, s)) {*/
830  switch(MUST_APPROXIMATION) {
831  case MUST_APPROXIMATION:
833  if (!effect_undefined_p(eff_tmp))
834  impact_must_p = approximation_exact_p(effect_approximation(eff_tmp));
835  impact_must_p = impact_must_p &&
837  insert_impact_description_as_comment(sw1, s, impact_must_p, DEP_FLOW);
838  break;
839  case MAY_APPROXIMATION:
841  break;
842  case NOT_APPROXIMATION:
843  /* dependence does not exist so don't the impact alias*/
844  break;
845  }
846  }
847  }
848  }, stat_writes1_old);
849  } else {
851  /* rebuild the list of write statements for alias_ent2 */
853  MAP(STATEMENT, sr1, {
854  if (!statement_undefined_p(sr1)) { /* new anti-dependence created */
855  set_clear(arcs_processed_set);
856  if (!find_covering_reference_path(arcs_processed_set,
858  s, act_dest, alias_ent2))
859  {
861  /*switch(control_approximation_between_statement_p(sr1, s)) {*/
862  switch(MUST_APPROXIMATION) {
863  case MUST_APPROXIMATION:
865  if (!effect_undefined_p(eff_tmp))
866  impact_must_p = approximation_exact_p(effect_approximation(eff_tmp));
867  impact_must_p = impact_must_p &&
869  insert_impact_description_as_comment(sr1, s, impact_must_p, DEP_ANTI);
870  break;
871  case MAY_APPROXIMATION:
873  break;
874  case NOT_APPROXIMATION:
875  /* dependence does not exist so don't the impact alias*/
876  break;
877  }
878  }
879  }
880  }, stat_reads1_old);
881  MAP(STATEMENT, sw1, {
882  if (!statement_undefined_p(sw1)) { /* new output-dependence created */
883  set_clear(arcs_processed_set);
884  if (!find_covering_reference_path(arcs_processed_set,
886  s, act_dest, alias_ent2))
887  {
889  /*switch (control_approximation_between_statement_p(sw1, s)) {*/
890  switch(MUST_APPROXIMATION) {
891  case MUST_APPROXIMATION:
893  if (!effect_undefined_p(eff_tmp))
894  impact_must_p = approximation_exact_p(effect_approximation(eff_tmp));
895  impact_must_p = impact_must_p &&
897  insert_impact_description_as_comment(sw1, s, impact_must_p, DEP_OUTP);
898  break;
899  case MAY_APPROXIMATION:
901  break;
902  case NOT_APPROXIMATION:
903  /* dependence does not exist so don't the impact alias*/
904  break;
905  }
906  }
907  }
908  }, stat_writes1_old);
909  }
910  }
911  }, le);
912  set_free(arcs_processed_set);
913  gen_free_list(stat_reads1_old);
914  gen_free_list(stat_writes1_old);
915  gen_free_list(stat_reads2_old);
916  gen_free_list(stat_writes2_old);
917  return;
918 }
919 
921 {
922  instruction istat;
923  list /* of effects */ le = NIL;
924  list /* of effects */ l = NIL;
925  list blocs = NIL;
926 
927  if ((statement_undefined_p(s)) || (s == NULL)) return;
928 
929  /* precondition is used to determine if the statement is executed */
930  /*if (!statement_feasible_p(s)) return;*/
931 
932  istat = statement_instruction(s);
933 
934  switch(instruction_tag(istat)) {
936  MAP(STATEMENT, s,
938  instruction_block(istat));
939  break;
940  case is_instruction_test:
941  {
942  list stat_reads1_true = NIL;
943  list stat_reads2_true = NIL;
944  list stat_writes1_true = NIL;
945  list stat_writes2_true = NIL;
946 
947  list stat_reads1_old = NIL;
948  list stat_reads2_old = NIL;
949  list stat_writes1_old = NIL;
950  list stat_writes2_old = NIL;
951 
954 
955  /* save the old read, write statements */
956  stat_reads1_old = gen_copy_seq(stat_reads1);
957  stat_reads2_old = gen_copy_seq(stat_reads2);
958  stat_writes1_old = gen_copy_seq(stat_writes1);
959  stat_writes2_old = gen_copy_seq(stat_writes2);
960 
961  /* read, write statements may be modified after the line below */
963 
964  /* store the new version */
965  stat_reads1_true = stat_reads1;
966  stat_reads2_true = stat_reads2;
967  stat_writes1_true = stat_writes1;
968  stat_writes2_true = stat_writes2;
969 
970  /* restore the old version */
971  stat_reads1 = stat_reads1_old;
972  stat_reads2 = stat_reads2_old;
973  stat_writes1 = stat_writes1_old;
974  stat_writes2 = stat_writes2_old;
975 
976  stat_reads1_old = NIL;
977  stat_reads2_old = NIL;
978  stat_writes1_old = NIL;
979  stat_writes2_old = NIL;
980 
981  /* read, write statements may be modified after the line below */
983 
984  stat_reads1 = union_list(stat_reads1, stat_reads1_true);
985  stat_reads2 = union_list(stat_reads2, stat_reads2_true);
986  stat_writes1 = union_list(stat_writes1, stat_writes1_true);
987  stat_writes2 = union_list(stat_writes2, stat_writes2_true);
988 
989  gen_free_list(stat_reads1_true);
990  gen_free_list(stat_reads2_true);
991  gen_free_list(stat_writes1_true);
992  gen_free_list(stat_writes2_true);
993 
994  break;
995  }
996  case is_instruction_loop:
997  /*safe_print_statement(s);
998  switch (loop_executed_approximation(s)) {
999  case MUST_BE_EXECUTED:
1000  fprintf(stderr, "MUST_BE_EXECUTED\n");
1001  break;
1002  case MAY_BE_EXECUTED:
1003  fprintf(stderr, "MAY_BE_EXECUTED\n");
1004  break;
1005  case MUST_NOT_BE_EXECUTED:
1006  fprintf(stderr, "MUST_NOT_BE_EXECUTED\n");
1007  break;
1008  }*/
1011  le = union_list(le, l);
1013  le = union_list(le, l);
1016  break;
1021  break;
1022  case is_instruction_goto:
1024  break;
1026  CONTROL_MAP(c, {
1027  fprintf(stderr, "i am here UNSTRUCTURED ");
1031  gen_free_list(blocs);
1032  break;
1033  case is_instruction_call:
1034  /* consideration of parameters here */
1036  break;
1037  default:
1038  pips_internal_error("case default reached");
1039  break;
1040  }
1041 }
1042 
1044 {
1045  expression diff = eq_expression(off1, off2);
1046  clean_all_normalized(diff);
1047  ifdebug(3) {
1048  fprintf(stderr, "entity1 local name: %s\n", entity_local_name(e1));
1049  fprintf(stderr, "entity2 local name: %s\n", entity_local_name(e2));
1050  print_expression(off1);
1051  print_expression(off2);
1052  fprintf(stderr, "call path: %s\n", print_call_path(path));
1053  }
1054  if (trivial_expression_p(diff) == -1)
1055  /* off1 != off2 => Okay, no alias between these 2 variables */
1056  return;
1057  else {
1058  /* alias */
1059 
1060  alias_ent1 = e1;
1061  alias_ent2 = e2;
1062  current_path = path;
1063 
1065  /*gen_recurse(mod_stat, statement_domain, check_new_arc_for_structured_statement, gen_null);*/
1066 
1071  stat_reads1 = NIL;
1072  stat_reads2 = NIL;
1073  stat_writes1 = NIL;
1074  stat_writes2 = NIL;
1075 
1078  current_path = NIL;
1079  }
1080  return;
1081 }
1082 
1084 {
1086  impact_check_two_scalar_variables_in_path(e1, e2, off1, off2, path);
1088  {
1089  fprintf(stderr, "alias entre variable scalaire e1 et variable tableau e2\n");
1090  impact_check_two_scalar_variables_in_path(e1, e2, off1, off2, path);
1091  }
1093  {
1094  fprintf(stderr, "alias entre variable tableau e1 et variable scalaire e2\n");
1095  impact_check_two_scalar_variables_in_path(e1, e2, off1, off2, path);
1096  }
1098  {
1099  fprintf(stderr, "alias entre 2 variables tableau\n");
1100  impact_check_two_scalar_variables_in_path(e1, e2, off1, off2, path);
1101  }
1102 }
1103 
1104 static bool written = false;
1106 
1107 /* This function returns true if the variable is written directly in the current module,
1108  or by its callees */
1110 {
1111  if (statement_call_p(s)) {
1112  list l_rw = statement_to_effects(s);
1113  MAP(EFFECT, eff, {
1114  action a = effect_action(eff);
1115  if (action_write_p(a)) {
1117  entity e = reference_variable(r);
1118  if (same_entity_p(e,current_entity)) {
1119  ifdebug(3) {
1120  fprintf(stderr,"\n Write on entity %s :\n",entity_name(e));
1121  fprintf(stderr,"\n Current entity %s :\n",entity_name(current_entity));
1122  }
1123  written = true;
1124  /* gen_recurse_stop(NULL); */
1125  return false;
1126  }
1127  }
1128  }, l_rw);
1129  return false;
1130  }
1131  return true;
1132 }
1133 
1135 {
1136  written = false;
1137  current_entity = ent;
1141  return written;
1142 }
1143 
1144 static void set_dynamic_checked(entity e1, entity e2)
1145 {
1146  MAP(DYNAMIC_CHECK,dc,
1147  {
1148  if ((dynamic_check_first(dc)==e1) && (dynamic_check_second(dc)==e2))
1149  dynamic_check_checked(dc) = true;
1150  }, l_dynamic_check);
1151 }
1152 
1153 static bool dynamic_checked_p(entity e1, entity e2)
1154 {
1155  MAP(DYNAMIC_CHECK, dc, {
1156  if ((dynamic_check_first(dc)==e1)&&(dynamic_check_second(dc)==e2))
1157  return dynamic_check_checked(dc);
1158  }, l_dynamic_check);
1159  return false;
1160 }
1161 
1163 {
1165  list l_formals = NIL;
1166  list l_commons = NIL;
1167 
1168  /* search for formal parameters in the declaration list */
1169  MAP(ENTITY, e, {
1170  if (formal_parameter_p(e))
1171  l_formals = gen_nconc(l_formals,CONS(ENTITY,e,NIL));
1172  }, l_decls);
1173 
1174  MAP(ENTITY, e, {
1175  if (variable_in_common_p(e))
1177  }, l_decls);
1178 
1179  MAP(ENTITY,e1, {
1180  MAP(ENTITY,e2, {
1181  dynamic_check dc = make_dynamic_check(e1,e2,false);
1183  }, l_formals);
1184 
1185  MAP(ENTITY,e2, {
1186  dynamic_check dc = make_dynamic_check(e1,e2,false);
1188  }, l_commons);
1189  }, l_formals);
1190 }
1191 
1193 {
1195  if (!expression_undefined_p(off1) && !expression_undefined_p(off2)) {
1196  /* good offset --> check */
1197  impact_check_in_path(e1, e2, off1, off2, path);
1198  } else {
1199  /* As we do not have exact offsets of variables, we have to go to the
1200  caller's frame to check for alias impact. The direct caller is
1201  CAR(call_path) because of the following concatenation in alias_propagation:
1202  path = CONS(CALL_SITE,cs,gen_full_copy_list(alias_association_call_chain(aa)));
1203 
1204  To find a call site from its ordering, we have to do a gen_recurse
1205  in the caller module. */
1206  call_site cs = CALL_SITE(CAR(path));
1207  statement caller_statement;
1210  caller_statement = (statement)db_get_memory_resource(DBR_CODE,caller_name,true);
1211 
1214  gen_recurse(caller_statement,statement_domain,
1216 
1219  expression new_off1, new_off2;
1221  new_off1 = offset_in_caller(e1, cs, path);
1222  new_off2 = offset_in_caller(e2, cs, path);
1223  if (!expression_undefined_p(new_off1) && !expression_undefined_p(new_off2)) {
1224  /* good offset --> check */
1225  impact_check_in_path(e1, e2, new_off1, new_off2, path);
1226  } else {
1227  /* Try with special cases : CALL FOO(R(TR(K)),R(TR(K))) ???????
1228  Does this case exist when we create special section + offset
1229  for same actual arguments ??? */
1230  /* use dynamic alias check*/
1231  set_dynamic_checked(e1, e2);
1232  }
1234  } else
1235  pips_user_warning("Problem with statement ordering *\n");
1238  }
1239  }
1240 }
1241 
1243 {
1245  /*hash_table control_to_set_of_dominators = hash_table_make(hash_pointer, 0);*/
1246 
1249 
1250  debug_on("RICEDG_DEBUG_LEVEL");
1251 
1252 
1254  db_get_memory_resource(DBR_ALIAS_ASSOCIATIONS,
1255  module_name, true));
1256 
1257  if (l_module_aliases != NIL) {
1258  dg = (graph) db_get_memory_resource(DBR_DG, module_name, true);
1259  /*full_control_graph(module_name);*/
1262 
1265 
1266  /*computing_dominators(control_to_set_of_dominators, load_ctrl_graph(mod_stat));
1267 
1268  set_precondition_map((statement_mapping)
1269  db_get_memory_resource(DBR_PRECONDITIONS,
1270  module_name,
1271  true));*/
1272  while (!ENDP(l_module_aliases)) {
1275  entity sec1 = alias_association_section(aa1);
1276  list path1 = alias_association_call_chain(aa1);
1278  int l1 = alias_association_lower_offset(aa1);
1279  int u1 = alias_association_upper_offset(aa1);
1281 
1282  /* Looking for another formal variable in the list of alias
1283  associations that has same section and included call path.
1284  If this variable is checked dynamically with e1 => no need
1285  to continue */
1286  MAP(ALIAS_ASSOCIATION, aa2, {
1288  entity sec2 = alias_association_section(aa2);
1289  list path2 = alias_association_call_chain(aa2);
1290  if (!same_entity_p(e1,e2) && same_entity_p(sec1,sec2) &&
1291  !dynamic_checked_p(e1, e2) && included_call_chain_p(path1,path2)) {
1292 
1293  int l2 = alias_association_lower_offset(aa2);
1294  int u2 = alias_association_upper_offset(aa2);
1295 
1296  if (((u1==-1)||(u1>=l2))&&((u2==-1)||(u2>=l1))) {
1298  if (gen_length(path1) < gen_length(path2))
1299  impact_check_two_variables(e1, e2, off1, off2, path2);
1300  else
1301  impact_check_two_variables(e1, e2, off1, off2, path1);
1302  }
1303  }
1304  }, l_module_aliases);
1305 
1306  /* Looking for common variables in module or callee of modules
1307  to check for alias impact ... */
1308  MAP(ENTITY, e2, {
1309  if (variable_in_common_p(e2)) {
1310  ram ra = storage_ram(entity_storage(e2));
1311  entity sec2 = ram_section(ra);
1312  if (!dynamic_checked_p(e1, e2) && same_entity_p(sec1,sec2)) {
1313  /* formal parameter has a same section with other common variable */
1314  int l2 = ram_offset(ra);
1315  int u2 = l2;
1316  if (array_entity_p(e2))
1317  {
1318  int tmp;
1319  if (SizeOfArray(e2, &tmp))
1320  u2 = tmp - SizeOfElements(variable_basic(type_variable(entity_type(e2)))) + l2;
1321  else
1322  user_log("Varying size of common variable");
1323  }
1324  /* If u1 is defined (different to -1) and u1<l2, there is no alias impact
1325  The same for: l1 is defined (different to -1) and u2<l1 */
1326  if (((u1==-1)||(u1>=l2)) && (u2>=l1)) {
1327  expression off2 = int_to_expression(l2);
1328  /* The common variable always have a good offset off2 */
1329  impact_check_two_variables(e1, e2, off1, off2, path1);
1330  }
1331  }
1332  }
1334  }
1335  l_dynamic_check = NIL;
1336 
1338 
1339  /*hash_table_free(control_to_set_of_dominators);*/
1340  /*clean_ctrl_graph();*/
1343  /*reset_precondition_map();*/
1345  }
1349 
1350  debug_off();
1351  return true;
1352 }
void user_log(const char *format,...)
Definition: message.c:234
dynamic_check make_dynamic_check(entity a1, entity a2, bool a3)
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
static int count
Definition: SDG.c:519
static entity current_caller
Definition: alias_check.c:121
static list l_module_aliases
Definition: alias_check.c:124
#define dynamic_check_second(x)
#define alias_associations_list(x)
Definition: alias_private.h:86
#define alias_association_lower_offset(x)
#define CALL_SITE(x)
CALL_SITE.
#define call_site_function(x)
#define alias_association_upper_offset(x)
#define alias_association_section(x)
#define alias_association_variable(x)
#define ALIAS_ASSOCIATION(x)
ALIAS_ASSOCIATION.
Definition: alias_private.h:90
#define dynamic_check_checked(x)
#define alias_association_call_chain(x)
#define dynamic_check_first(x)
#define alias_association_offset(x)
#define DYNAMIC_CHECK(x)
DYNAMIC_CHECK.
#define call_site_ordering(x)
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
static list l_commons
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
Pcontrainte contrainte_free(Pcontrainte c)
Pcontrainte contrainte_free(Pcontrainte c): liberation de l'espace memoire alloue a la contrainte c a...
Definition: alloc.c:184
control load_ctrl_graph(statement)
struct _newgen_struct_dg_arc_label_ * dg_arc_label
Definition: dg.h:60
#define conflict_sink(x)
Definition: dg.h:167
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define conflict_source(x)
Definition: dg.h:165
list proper_effects_of_expression(expression)
list statement_to_effects(statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
action make_action_read_memory(void)
Definition: effects.c:1017
#define effect_undefined_p(x)
Definition: effects.h:615
#define approximation_exact_p(x)
Definition: effects.h:369
#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_approximation(x)
Definition: effects.h:644
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#define CHUNK(x)
Definition: genC.h:90
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
#define successor_vertex(x)
Definition: graph.h:118
#define vertex_undefined
Definition: graph.h:128
#define successor_arc_label(x)
Definition: graph.h:116
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define graph_vertices(x)
Definition: graph.h:82
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
#define BACKWARD_CONTROL_MAP(ctl, code, c, list)
Walk through all the controls backward-reachable from a given control node of an unstructured.
#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_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
#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_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
size_t gen_length(const list l)
Definition: list.c:150
list gen_cons(const void *item, const list next)
Definition: list.c:888
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#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_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool statement_call_p(statement)
Definition: statement.c:364
void insert_comments_to_statement(statement, const char *)
Insert a comment string (if non empty) at the beginning of the comments of a statement.
Definition: statement.c:1916
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_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
Definition: hash.c:491
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
#define ADD_ELEMENT_TO_LIST(_list, _type, _element)
Definition: icfg-local.h:50
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
static void display_impact_alias_statistics()
Definition: impact_check.c:61
static void check_new_arc_for_structured_statement(statement s)
Definition: impact_check.c:920
static statement statement_in_caller
Definition: impact_check.c:55
#define MAY_APPROXIMATION
Definition: impact_check.c:35
static void impact_check_two_variables(entity e1, entity e2, expression off1, expression off2, list path)
static bool statement_equal_p(statement s1, statement s2)
Definition: impact_check.c:222
static list stat_reads2
list of statement_approximation_p
Definition: impact_check.c:48
#define MUST_APPROXIMATION
Definition: impact_check.c:34
static effect get_effect_read_of_statement_on_variable(statement s, entity var)
Definition: impact_check.c:388
static expression offset_in_caller(entity e, call_site cs, list path)
Definition: impact_check.c:182
static bool same_call_site_p(call_site cs1, call_site cs2)
Definition: impact_check.c:70
static int loop_executed_approximation(statement s)
Definition: impact_check.c:439
static string print_call_path(list path)
This function prints the call path , including names of caller functions and orderings of call sites ...
Definition: impact_check.c:319
static bool dynamic_checked_p(entity e1, entity e2)
#define DEP_OUTP
Definition: impact_check.c:32
static int __attribute__((unused))
Definition: impact_check.c:408
static entity alias_ent1
data dependence graph
Definition: impact_check.c:44
static void insert_impact_description_as_comment(statement s1, statement s2, bool impact_must_p, int dep_type)
Definition: impact_check.c:338
static int statement_in_caller_ordering
Definition: impact_check.c:54
bool impact_check(char *module_name)
static statement mod_stat
We want to keep track of the current statement inside the recurse.
Definition: impact_check.c:41
bool find_covering_reference_path(set arcs_processed_set, statement s_src, action act_src, entity ent_src, statement s_dest, action act_dest, entity ent_dest)
Check to see if new dependence is covered by arcs in dependence graph at reference level.
Definition: impact_check.c:238
#define DEP_ANTI
Definition: impact_check.c:31
static bool search_statement_by_ordering_flt(statement s)
Definition: impact_check.c:213
static void init_dynamic_check_list(entity current_mod)
static void impact_check_in_path(entity e1, entity e2, expression off1, expression off2, list path)
static list stat_writes1
list of statement_approximation_p
Definition: impact_check.c:47
static int number_of_impact_alias
Definition: impact_check.c:59
static entity alias_ent2
Definition: impact_check.c:45
static set create_or_get_a_set_from_control(control c, hash_table control_to_set_of_dominators)
Definition: impact_check.c:513
static effect get_effect_write_of_statement_on_variable(statement s, entity var)
Definition: impact_check.c:398
static entity current_entity
static void set_dynamic_checked(entity e1, entity e2)
static bool variable_is_written_p(entity ent)
static bool tail_call_path_p(call_site cs, list l1, list l2)
Definition: impact_check.c:99
static void check_for_effected_statement(statement s, list le)
Definition: impact_check.c:707
#define DEP_FLOW
Definition: impact_check.c:30
static expression storage_formal_offset(call_site cs, entity actual_var, expression subval, list path)
Definition: impact_check.c:142
static int number_of_processed_modules
Definition: impact_check.c:58
static void impact_check_two_scalar_variables_in_path(entity e1, entity e2, expression off1, expression off2, list path)
static list stat_reads1
Definition: impact_check.c:46
static expression storage_ram_offset(storage s, expression subval)
Definition: impact_check.c:116
static bool included_call_chain_p(list l1, list l2)
Definition: impact_check.c:80
#define NOT_APPROXIMATION
Definition: impact_check.c:36
static list current_path
list of statement_approximation_p
Definition: impact_check.c:51
bool check_way_between_two_statements(statement s1, statement s2, graph g)
Check to see if there is a directed way between 2 statements in the graph specified.
Definition: impact_check.c:290
static list stat_writes2
list of statement_approximation_p
Definition: impact_check.c:49
static call current_call
Definition: impact_check.c:57
static vertex statement_to_vertex(statement s, graph g)
Definition: impact_check.c:227
static list l_dynamic_check
This list tells us if two variables have been checked dynamically or not.
Definition: impact_check.c:53
static entity current_mod
Definition: impact_check.c:42
static const char * caller_name
Definition: impact_check.c:56
static bool variable_is_written_by_statement_flt(statement s)
This function returns true if the variable is written directly in the current module,...
static bool written
static graph dg
Definition: impact_check.c:43
list union_list(list l1, list l2)
Union is not typed...
Definition: impact_check.c:376
struct _newgen_struct_control_ * control
#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_user_warning
Definition: misc-local.h:146
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
static entity rank
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
set set_intersection(set, const set, const set)
Definition: set.c:229
#define SET_MAP(element, code, the_set)
Definition: newgen_set.h:54
set set_assign(set, const set)
Assign a set with the content of another set.
Definition: set.c:129
bool set_equal_p(const set, const set)
returns whether s1 == s2
Definition: set.c:316
void set_free(set)
Definition: set.c:332
set set_clear(set)
Assign the empty set to s s := {}.
Definition: set.c:326
bool set_belong_p(const set, const void *)
Definition: set.c:194
set set_union(set, const set, const set)
Definition: set.c:211
@ set_pointer
Definition: newgen_set.h:44
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152
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
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
void safe_print_statement(statement)
Definition: statement.c:140
text statement_to_text(statement)
Definition: statement.c:124
#define PLUS_OPERATOR_NAME
#define ORDERING_NUMBER(o)
#define ORDERING_STATEMENT(o)
#define NORMALIZE_EXPRESSION(e)
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define binary_intrinsic_expression(name, e1, e2)
#define is_instruction_block
soft block->sequence transition
#define eq_expression(e1, e2)
#define instruction_block(i)
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool array_entity_p(entity e)
Definition: entity.c:793
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
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
code entity_code(entity e)
Definition: entity.c:1098
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
void clean_all_normalized(expression e)
Definition: expression.c:4102
int trivial_expression_p(expression e)
This function returns:
Definition: expression.c:679
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression find_ith_argument(list args, int n)
Definition: expression.c:1147
expression subscript_value_stride(entity arr, list l_inds)
Definition: expression.c:4127
bool expression_equal_integer_p(expression exp, int i)
================================================================
Definition: expression.c:1977
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
bool SizeOfArray(entity, int *)
This function computes the total size of a variable in bytes, ie.
Definition: size.c:87
bool variable_in_common_p(entity)
true if v is in a common.
Definition: variable.c:1570
bool formal_parameter_p(entity)
Definition: variable.c:1489
bool entity_atomic_reference_p(entity)
Any reference r such that reference_variable(r)==e accesses all bytes (or bits) allocated to variable...
Definition: variable.c:1163
_int SizeOfElements(basic)
This function returns the length in bytes of the Fortran or C type represented by a basic,...
Definition: size.c:297
#define formal_offset(x)
Definition: ri.h:1408
#define loop_body(x)
Definition: ri.h:1644
#define storage_formal_p(x)
Definition: ri.h:2522
#define normalized_linear_p(x)
Definition: ri.h:1779
#define reference_variable(x)
Definition: ri.h:2326
#define range_upper(x)
Definition: ri.h:2290
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
#define instruction_goto(x)
Definition: ri.h:1526
#define test_false(x)
Definition: ri.h:2837
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define code_declarations(x)
Definition: ri.h:784
#define range_increment(x)
Definition: ri.h:2292
#define storage_ram_p(x)
Definition: ri.h:2519
#define ram_section(x)
Definition: ri.h:2249
#define storage_formal(x)
Definition: ri.h:2524
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define entity_name(x)
Definition: ri.h:2790
#define transformer_relation(x)
Definition: ri.h:2873
#define test_true(x)
Definition: ri.h:2835
#define reference_indices(x)
Definition: ri.h:2328
#define control_successors(x)
Definition: ri.h:945
#define expression_undefined_p(x)
Definition: ri.h:1224
#define test_condition(x)
Definition: ri.h:2833
#define instruction_whileloop(x)
Definition: ri.h:1523
#define range_lower(x)
Definition: ri.h:2288
#define whileloop_body(x)
Definition: ri.h:3162
#define statement_instruction(x)
Definition: ri.h:2458
#define storage_ram(x)
Definition: ri.h:2521
#define loop_range(x)
Definition: ri.h:1642
#define call_arguments(x)
Definition: ri.h:711
#define control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define statement_undefined_p(x)
Definition: ri.h:2420
#define whileloop_condition(x)
Definition: ri.h:3160
#define entity_type(x)
Definition: ri.h:2792
#define call_undefined
Definition: ri.h:685
#define statement_number(x)
Definition: ri.h:2452
#define normalized_linear(x)
Definition: ri.h:1781
#define predicate_system(x)
Definition: ri.h:2069
#define instruction_unstructured(x)
Definition: ri.h:1532
#define variable_basic(x)
Definition: ri.h:3120
#define statement_undefined
Definition: ri.h:2419
#define ram_offset(x)
Definition: ri.h:2251
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
int dep_type(action, action)
int dep_type(action ac1,action ac2) This function test the type of the dependence.
Definition: testdep_util.c:378
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
bool ineq_redund_with_sc_p(Psysteme sc, Pcontrainte ineq)
This function returns true if the inequation ineq is redundant for the system ps and false otherwise.
bool sc_rational_feasibility_ofl_ctrl(Psysteme sc, int ofl_ctrl, bool ofl_res)
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
transformer load_statement_precondition(statement)
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define CHAIN_SWORD(l, s)
string text_to_string(text t)
SG: moved here from ricedg.
Definition: print.c:239
string words_to_string(cons *lw)
Definition: print.c:211
char * int2a(int)
util.c
Definition: util.c:42
A gen_chunk is used to store every object.
Definition: genC.h:58
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
#define FWD_OFL_CTRL
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
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