PIPS
array_bound_check_top_down.c
Go to the documentation of this file.
1 /*
2 
3  $Id: array_bound_check_top_down.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 /* -----------------------------------------------------------------
28  *
29  * TOP-DOWN ARRAY BOUND CHECK VERSION
30  *
31  * -----------------------------------------------------------------
32  *
33  * This phase is based on the array region analyses
34  * Different strategies :
35  * 1. When a bounds violation is detected, we generate a STOP
36  * statement and we don't go down anymore
37  * => difficult for debugging all the program's error
38  * => finish as soon as possible
39  * 2. Generate comments for errors and warnings
40  * => convenient for debugging
41  * => can not detect bounds violation for dynamic tests
42  * with generated code
43  * 3. Test and STOP statement every where
44  * => the {0==1} every where , not very intelligent ?
45  *
46  * The first strategy is implemented for this moment
47  *
48  *
49  * Hypotheses : there is no write effect on the array bound expression.
50  *
51  * There was a test for write effect on bound here but I put it away (in
52  * effect_on_array_bound.c) because it takes time to calculate the effect
53  * but in fact this case is rare */
54 
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #include "genC.h"
59 #include "linear.h"
60 #include "ri.h"
61 #include "effects.h"
62 #include "alias_private.h"
63 #include "ri-util.h"
64 #include "prettyprint.h"
65 #include "effects-util.h"
66 #include "database.h"
67 #include "pipsdbm.h"
68 #include "resources.h"
69 #include "misc.h"
70 #include "control.h"
71 #include "transformer.h"
72 #include "properties.h"
73 #include "pipsmake.h"
74 #include "instrumentation.h"
75 #include "abc_private.h"
76 #include "effects-generic.h"
77 #include "effects-convex.h"
78 #include "effects-simple.h"
79 #include "conversion.h"
80 
81 /* The following data structure is the context of top_down_abc:
82  The read_marked_list marks if one bound of one array's dimension
83  is tested or not, for the READ regions.
84  The write_marked_list marks if one bound of one array's dimension
85  is tested or not, for the WRITE regions.
86  The saved list keeps the status before go down in the tree.
87  The hash table statement_check_list associates each statement
88  with its list of checks for each bound of array's dimension */
89 
90 typedef struct
91 {
97  persistant_statement_to_control map; // to treat unstructured case
101 
102 typedef struct Bound_test
103 {
104  bool bound;
107 
108 static string read_or_write(bool a)
109 {
110  if (a)
111  return ", READING, ";
112  return ", WRITING, ";
113 }
114 
115 string bool_to_bound(bool b)
116 {
117  if (b)
118  return ", lower bound, ";
119  return ", upper bound, ";
120 }
121 
122 /* Statistic variables: */
123 
126 
128 {
131 }
132 
134 {
135  if (number_of_added_tests > 0)
136  user_log("* There %s %d array bound check%s added *\n",
137  number_of_added_tests > 1 ? "are" : "is",
139  number_of_added_tests > 1 ? "s" : "");
140 
142  user_log("* There %s %d bound violation%s *\n",
143  number_of_bound_violations > 1 ? "are" : "is",
145  number_of_bound_violations > 1 ? "s" : "");
146 }
147 
149 {
150  list retour = NIL;
151  // get list of entities in the declaration part
152  list ld =
154  MAP(ENTITY,e,
155  {
156  type t = entity_type(e);
157  if (type_variable_p(t))
158  {
160  int length = gen_length(ldim);
161  if (length > 0)
162  {
164  list dc_list = NIL;
165  int i;
167  for(i=1; i <= length; i++ )
168  {
169  dc = make_dimension_checked(i,false,false);
170  dc_list = gen_nconc(dc_list,
172  }
173  adc = make_array_dimension_checked(e, dc_list);
174  retour = gen_nconc(retour,CONS(ARRAY_DIMENSION_CHECKED,adc,NIL));
175  }
176  }
177  },
178  ld);
179  return make_abc_checked(retour);
180 }
181 
183  bool action, entity array, int dim, bool bound)
184 {
185  if (action)
186  {
187  // read region
189  {
192  {
193  if (dimension_checked_dim(dc) == dim)
194  {
195  if (bound)
196  dimension_checked_lower(dc) = true;
197  else
198  dimension_checked_upper(dc) = true;
199  }
201  }, abc_checked_list(context->read_marked_list));
202  }
203  else
204  {
205  // write region
207  {
210  {
211  if (dimension_checked_dim(dc) == dim)
212  {
213  if (bound)
214  dimension_checked_lower(dc) = true;
215  else
216  dimension_checked_upper(dc) = true;
217  }
219  }, abc_checked_list(context->write_marked_list));
220  }
221 }
222 
223 // FC: copy-pasted from elswhere?
225 {
226  /* Project all PHI and #init variables, ....in the system ps,
227  there are 2 cases :
228  1. The result is not sure , there are over flow
229  Return the SC_UNDEFINED
230  2. The result is sure, three small cases:
231  2.1 The system is always false sc_empty => no bounds violation
232  2.2 The system is always true sc_rn => bounds violation
233  2.3 The system is parametric => test to put*/
234 
235  if (!sc_empty_p(ps)&& !sc_rn_p(ps))
236  {
237  list l_phi = phi_entities_list(1,7);
238  list l_var = l_phi;
239  Pvecteur pv_var = NULL;
240  Pbase b = ps->base;
241  /* converts the phi list into a Pvecteur */
242  MAP(ENTITY, e,
243  {
244  if (base_contains_variable_p(ps->base, (Variable) e) )
245  vect_add_elem(&pv_var, (Variable) e, VALUE_ONE);
246  },l_var);
247 
248  for(; !VECTEUR_NUL_P(b);b = b->succ)
249  {
250  entity e = (entity) vecteur_var(b);
251  if (old_value_entity_p(e))
252  vect_add_elem(&pv_var, (Variable) e, VALUE_ONE);
253  }
254  ps = sc_system_projection_along_variables(ps, pv_var);
255  vect_rm(pv_var);
256  gen_free_list(l_phi);
257  }
258  return ps;
259 }
260 
263 {
264  /* If s is in an unstructured instruction, we must pay attetion
265  when inserting s1 before s. */
267  {
268  /* take the control qui has s as statement */
270  if (stack_size(context->uns)>0)
271  {
272  /* take the unstructured correspond to the control c */
274  control newc;
275  /* for a consistent unstructured, a test must have 2 successors,
276  so if s1 is a test, we transform it into sequence in order
277  to avoid this constraint.
278  Then we create a new control for it, with the predecessors
279  are those of c and the only one successor is c.
280  The new predecessors of c are only the new control*/
281  if (statement_test_p(s1))
282  {
283  list seq = CONS(STATEMENT,s1,NIL);
284  statement s2=
286  make_sequence(seq)));
288  }
289  else
291  // replace c by newc as successor of each predecessor of c
292  MAP(CONTROL, co,
293  {
294  MAPL(lc,
295  {
296  if (CONTROL(CAR(lc))==c) CONTROL_(CAR(lc)) = newc;
297  }, control_successors(co));
298  },control_predecessors(c));
300  /* if c is the entry node of the correspond unstructured u,
301  the newc will become the new entry node of u */
302  if (unstructured_control(u)==c)
303  unstructured_control(u) = newc;
304  gen_recurse_stop(newc); // ????????????
305  }
306  else
307  // there is no unstructured (?)
308  insert_statement(s,s1,true);
309  }
310  else
311  // structured case
312  insert_statement(s,s1,true);
313 }
314 
315 
317  dimension dim_i, int i, bool bound)
318 {
319  list retour = NIL;
320  list args = call_arguments(c);
321  MAP(EXPRESSION,e,
322  {
323  syntax s = expression_syntax(e);
324  tag t = syntax_tag(s);
325  switch (t){
326  case is_syntax_call:
327  {
328  list tmp = top_down_abc_call(syntax_call(s),array,dim_i,i,bound);
329  if (tmp != NIL)
330  // add tmp to retour
331  MAP(EXPRESSION, exp,
332  {
333  if (!same_expression_in_list_p(exp,retour))
334  retour = gen_nconc(retour,CONS(EXPRESSION,exp,NIL));
335  },
336  tmp);
337  break;
338  }
339  case is_syntax_range:
340  /* There is nothing to check here*/
341  break;
342  case is_syntax_reference:
343  {
346  if (same_entity_p(arr,array))
347  {
348  list arrayinds = reference_indices(ref);
349  expression ith = find_ith_argument(arrayinds,i);
351  if (!expression_undefined_p(ith))
352  {
353  ifdebug(2)
354  {
355  fprintf(stderr, "\n The ith expression");
356  print_expression(ith);
357  fprintf(stderr, " \n array: %s ",entity_name(array));
358  }
359  if (bound)
360  {
361  /* Make expression : ith < lower_bound */
364  ifdebug(2)
365  {
366  fprintf(stderr, "\n The lower bound test");
368  }
369  }
370  else
371  // test if the upper bound is unbounded or not
372  if (!unbounded_dimension_p(dim_i))
373  {
374  /* Make expression : upper_bound < ith */
376  copy_expression(ith));
377  ifdebug(2)
378  {
379  fprintf(stderr, "\n The upper bound test");
381  }
382  }
383  }
384 
385  /* Remark : Doesn't like the 1st version of abc,
386  we don't have to put a test for ith in the indirect case.
387  F.e : for A(B(i)) = 0.0, we have 2 regions :
388  < B(PHI1)-R-EXACT-{PHI1==I} >
389  < A(PHI1)-W-MAY-{} >
390  when we check for the inexact case of A, we don't have
391  to check for B.
392 
393  In case if there is another access of array B in the same
394  statement, the region of B may be MAY => we check it for
395  the read region of B.
396 
397  In case of A(A(i)) , we have the different regions for read
398  and write effect ??????? => ?????
399  ATT : example Indirection.f */
400 
401  /* Test if exp is trivial or not
402  + If exp is always TRUE: there is certainly bound violation,
403  return make_true_expression
404  + If exp is always false, we don't have to add it to retour
405  + Otherwise, we add it to retour.*/
407  {
408  int tr = trivial_expression_p(exp);
409  switch(tr){
410  case 1:
412  case 0:
413  {
414  // test if exp is already in retour
415  if (!same_expression_in_list_p(exp,retour))
416  retour = gen_nconc(retour,CONS(EXPRESSION,exp,NIL));
417  break;
418  }
419  case -1:
420  break;
421  }
422  }
423  }
424  break;
425  }
426  }
427  },
428  args);
429  return retour;
430 }
431 
434  entity array, dimension dim_i,int i, bool bound)
435 {
436  Bound_test retour;
437  retour.test = expression_undefined;
438  retour.bound = true;
439 
440  /* Test if s is a call (elementary statement)*/
441  if (statement_call_p(s))
442  {
443  /* generate a lower/upper bound test expression for all
444  array reference of this dimension of array*/
446  list l = top_down_abc_call(c,array,dim_i,i,bound);
447  if (l!= NIL)
451  gen_free_list(l);
452  }
453  else
454  /* s is not a call, no conclusion for this bound,
455  continue to go down */
456  retour.bound = false;
457 
458  return retour;
459 }
460 
463  bool action, entity array, int i, bool bound)
464 {
465  Bound_test retour;
468  retour.bound = true;
469  retour.test = expression_undefined;
470  if (!bound && unbounded_dimension_p(dim_i))
471  /* unbounded dimension, we don't have to check for this bound */
473  else
474  {
475  Psysteme P = sc_dup(region_system(re));
479  expression exp_1 = int_to_expression(1);
480  if (bound)
483  exp_1);
484  else
487  exp_1);
489  // fast check: PHIi<=lower-1 (or upper+1<=PHIi) is trivial redundant wrt P or not
490  // transform exp to Pcontrainte con_exp
491  nexpr = NORMALIZE_EXPRESSION(exp);
492  if (normalized_linear_p(nexpr))
493  {
494  entity phi = make_phi_entity(i);
495  Pvecteur v1 = vect_new((Variable) phi, VALUE_ONE);
496  Pvecteur v2 = normalized_linear(nexpr);
497  Pvecteur vect;
498  if (bound)
499  vect = vect_substract(v1, v2);
500  else
501  vect = vect_substract(v2, v1);
502  vect_rm(v1);
503  con_exp = contrainte_make(vect);
504  switch (sc_check_inequality_redundancy(con_exp, P)) {/* try fast check */
505  case 1: /* ok, redundant => there is certainly bound violation */
506  {
508  retour.test = make_true_expression();
509  break;
510  }
511  case 2: /* ok, not feasible => there is no bound violation*/
512  {
514  break;
515  }
516  case 0: /* no result, try slow version */
517  {
518  /* Add the equation PHIi <= lower-1 (upper+1 <= PHIi)
519  to the predicate of region re */
520  if (sc_add_phi_equation(&P,exp,i,false,bound))
521  {
522  /* Every expression is linear.
523  * Test the feasibility of P by using this function:
524  * sc_rational_feasibility_ofl_ctrl(sc, ofl_ctrl, ofl_res) in which
525  *
526  * ofl_ctrl = OFL_CTRL means that the overflows are treated in the
527  * called procedure (sc_rational_feasibility_ofl_ctrl())
528  *
529  * ofl_res = true means that if the overflows occur, function
530  * sc_rational_feasibility_ofl_ctrl will return the value TRUE
531  * we don't know if the system is feasible or not
532  *
533  * The function sc_rational_feasibility_ofl_ctrl() is less
534  * expensive than the function sc_integer_feasibility_ofl_ctrl()*/
535 
537  /* The system is not feasible (certainly) => no violation */
539  else
540  {
541  /* The system is feasible or we don't know it is feasible or not
542  * Test if the region re is EXACT or MAY */
543  if (region_exact_p(re))
544  {
545  /* EXACT region
546  Remove all PHI variables, useless variables such as
547  PIPS generated variables V#init, common variable
548  from another subroutine ......
549 
550  SUBROUTINE X
551  CALL Y(I)
552  <P(I) {I == FOO:J}
553  END
554 
555  SUBROUTINE Y(K)
556  COMMON J
557  K=J
558  END */
560  if (ps == SC_UNDEFINED)
561  // the projection is not exact
562  retour = top_down_abc_not_exact_case (s,context,action,array,dim_i,i,bound);
563  else
564  {
565  // the projection is exact
567  if (!sc_empty_p(ps) && !sc_rn_p(ps))
568  // there is a test to put
569  // sc_normalized or sc_elim_redon ?????
570  retour.test = Psysteme_to_expression(ps);
571  else
572  if (sc_rn_p(ps))
573  // the system is trivial true, there are bounds violation
574  retour.test = make_true_expression();
575  //else, ps=sc_empty, the system is false, no bounds violation
576  }
577  }
578  else
579  /* MAY region */
580  retour = top_down_abc_not_exact_case(s,context,action,array,dim_i,i,bound);
581  }
582  }
583  else
584  // the exp is not linear, we can't add to P
585  retour.bound = false;
586  }
587  }
588  contrainte_free(con_exp);
589  }
590  sc_rm(P);
591  }
592  return retour;
593 }
594 
596 static int current_max;
597 static int current_min = 0;
598 
600 {
601  list effects_list = load_proper_rw_effects_list(s);
602  MAP(EFFECT, eff,
603  {
604  action a = effect_action(eff);
605  if (action_write_p(a))
606  {
608  entity e = reference_variable(r);
609  ifdebug(4)
610  {
611  fprintf(stderr,"\n MAX Write on entity %s :\n",entity_name(e));
612  fprintf(stderr,"\n MAX Current entity %s :\n",entity_name(current_entity));
613  }
614  if (strcmp(entity_name(e),entity_name(current_entity))==0)
615  {
616  int n = statement_ordering(s);
617  ifdebug(4)
618  {
619  fprintf(stderr,"a variable = current entity !!");
620  fprintf(stderr,"This statement writes on %s with max ordering %d",
622  }
623  if (n>current_max) current_max = n;
624  break;
625  }
626  }
627  },
628  effects_list);
629  return true;
630 }
631 
632 /* search for the maximum ordering of statement (after s) that writes on a*/
634 {
635  current_entity = a;
636  current_max = 0;
638  ifdebug(4)
639  fprintf(stderr, " return current_max = %d of current entity %s ",
642  return current_max;
643 }
644 
646 {
647  list effects_list = load_proper_rw_effects_list(s);
648  MAP(EFFECT, eff,
649  {
650  action a = effect_action(eff);
651  if (action_write_p(a))
652  {
654  entity e = reference_variable(r);
655  ifdebug(4)
656  {
657  fprintf(stderr,"\n MIN Write on entity %s :\n",entity_name(e));
658  fprintf(stderr,"\n MIN Current entity %s :\n",entity_name(current_entity));
659  }
660  if (strcmp(entity_name(e),entity_name(current_entity))==0)
661  {
663  ifdebug(4)
664  {
665  fprintf(stderr,"a variable = current entity !!");
666  fprintf(stderr, " This statement writes on %s with min ordering %d",
668  }
669  return false;
670  }
671  }
672  },
673  effects_list);
674  return true;
675 }
676 
677 /* search for the minimum ordering of statement (after s) that writes on a*/
679 {
680  current_entity = a;
681  current_min = 0;
683  ifdebug(4)
684  fprintf(stderr, " return current_min = %d of current entity %s",
687  return current_min;
688 }
689 
691 {
692  int max = maximum_ordering(a,s);
693  ifdebug(4)
694  fprintf(stderr, " max of %s = %d ", entity_name(a), max);
695  MAP(ENTITY,other,
696  {
697  if (strcmp(entity_name(a),entity_name(other))!=0)
698  {
699  int min = minimum_ordering(other,s);
700  ifdebug(4)
701  fprintf(stderr, " min of other %s = %d ", entity_name(other), min);
702  if (max >= min) return false;
703  }
704  },l);
705  return true;
706 }
707 
708 /*
709  - For each write region, find list of statements (down from s) that write on the array
710  - Find order between these written arrays : A <= B <= (C,D,E,F)
711  (A <= B if and only if maximum{statement orderings A} < minimum{statement orderings B})
712  - Apply algorithm for read and write regions on A and then B at this level (tests inserted
713  before s, tests on A before on B)
714  - Go down to substatement of s for the other unordered arrays (C,D,E,F)*/
715 
717 {
718  list l_tmp = gen_full_copy_list(l);
719  MAP(ENTITY,a,
720  {
721  if (is_first_written_array_p(a,l,s))
722  return a;
723  },l_tmp);
724  return entity_undefined;
725 }
726 
728 static bool godown = false;
729 static list lexp = NIL;
730 
732 {
733  list marked_list = NIL;
734  list dc_list = NIL;
735  bool action = region_read_p(re);
736  if (action)
737  marked_list = abc_checked_list(context->read_marked_list);
738  else
739  marked_list = abc_checked_list(context->write_marked_list);
741  {
743  {
744  dc_list = array_dimension_checked_dims(adc);
745  break;
746  }
747  },
748  marked_list);
749  // traverse each dimension
750  while (!ENDP(dc_list)) {
751  dimension_checked dc = DIMENSION_CHECKED(CAR(dc_list));
752  int i = dimension_checked_dim(dc);
753  Bound_test lower, upper;
754  lower.test = expression_undefined;
755  upper.test = expression_undefined;
756  lower.bound = true;
757  upper.bound = true;
758 
759  /* if we have a region like: <A(PHI)-EXACT-{}>
760  * it means that all *declared* elements are touched, although
761  * this is implicit. this occurs with io effects of "PRINT *, A".
762  * in such a case, the declaration constraints MUST be appended
763  * before the translation, otherwise the result might be false.
764  *
765  * potential bug : if the declaration system cannot be generated,
766  * the region should be turned to MAY for the translation? */
768  if (!dimension_checked_upper(dc))
769  {
770  /* The upper bound of the dimension i is not marked TRUE*/
771  upper = top_down_abc_dimension(s,context,re,action,array,i,false);
772  if (!expression_undefined_p(upper.test))
773  {
774  statement sta;
775  test t;
776  string message =
777  strdup(concatenate("\'Bound violation:",
778  read_or_write(action), " array ",
780  bool_to_bound(false),
781  int_to_dimension(i),"\'",NULL));
782 
783  if (true_expression_p(upper.test))
784  {
785  /* There is bounds violation !
786  Insert a STOP before s (bug in Examples/perma.f if replace s by STOP*/
788  user_log("\n Bound violation !!! \n");
789  if (get_bool_property("PROGRAM_VERIFICATION_WITH_PRINT_MESSAGE"))
791  else
793  // top_down_abc_insert_before_statement(s,sta,context);
796  else
798  //return false; // follow the first strategy
799  }
800  // test if expression upper.test exists already in test_sequence
801  else
802  if (!same_expression_in_list_p(upper.test,lexp))
803  {
804  ifdebug(2)
805  {
806  fprintf(stderr, "\n The upper test");
807  print_expression(upper.test);
808  }
811  if (get_bool_property("PROGRAM_VERIFICATION_WITH_PRINT_MESSAGE"))
812  t = make_test(upper.test,
815  else
816  t = make_test(upper.test,
819  sta = test_to_statement(t);
822  else
824  }
825  }
826  }
827  if (!dimension_checked_lower(dc))
828  {
829  /* The lower bound of the dimension i is not marked TRUE*/
830  lower = top_down_abc_dimension(s,context,re,action,array,i,true);
831  if (!expression_undefined_p(lower.test))
832  {
833  statement sta;
834  test t;
835  string message =
836  strdup(concatenate("\'Bound violation:",
837  read_or_write(action)," array ",
839  bool_to_bound(true),
840  int_to_dimension(i),"\'",NULL));
841 
842  if (true_expression_p(lower.test))
843  {
844  /* There is bounds violation !
845  Insert a STOP before s (bug in Examples/perma.f if replace s by STOP*/
847  user_log("\n Bound violation !!! \n");
848  if (get_bool_property("PROGRAM_VERIFICATION_WITH_PRINT_MESSAGE"))
850  else
852  // top_down_abc_insert_before_statement(s,sta,context);
855  else
856  /* insert the test after the generated tests, the order of tests
857  is important */
859  // return false; // follow the first strategy
860  }
861  else
862  // test if expression lower.test exists already in test_sequence
863  if (!same_expression_in_list_p(lower.test,lexp))
864  {
865  ifdebug(2)
866  {
867  fprintf(stderr, "\n The lower test");
868  print_expression(lower.test);
869  }
872  if (get_bool_property("PROGRAM_VERIFICATION_WITH_PRINT_MESSAGE"))
873  t = make_test(lower.test,
876  else
877  t = make_test(lower.test,
880  sta = test_to_statement(t);
883  else
885  }
886  }
887  }
888  /* If one bound of the dimension is marked false,
889  we have to go down*/
890  if ((!lower.bound) || (!upper.bound)) godown = true;
891  dc_list = CDR(dc_list);
892  }
893 }
894 
895  /* The old algorithm is false in the case of incorrect code, because regions are
896  computed with the assumption that the code is correct. Here is an anti-example:
897 
898  COMMON ITAB(10),J
899  REAL A(10)
900 C <A(PHI1)-W-EXACT-{PHI1==11}>
901 C <ITAB(PHI1)-W-MAY-{1<=PHI1}>
902  READ *, M
903  J = 11
904 C <ITAB(PHI1)-W-EXACT-{1<=PHI1, PHI1<=M, J==11}>
905  DO I = 1, M
906 C <ITAB(PHI1)-W-EXACT-{PHI1==I, J==11, 1<=I, I<=M}>
907  ITAB(I) = 1
908  ENDDO
909 C <A(PHI1)-W-EXACT-{PHI1==J, J==11, 1+M<=I, 1<=I}>
910  A(J) = 0
911 
912  The region for array A can be false if there is a bound violation in
913  ITAB for example with M=12, ITAB(11)=1=J, there will be no violation
914  on A but on ITAB. Based on this false region, the algorithm will
915  tell that there is a violation on A.
916 
917  To keep the algorithm safe, we must take into account the order in
918  which arrays are writen (bound violations on read arrays do not make
919  transformers and array regions false). If bound checks on ITAB are
920  inserted before checks on A, tests are checked earlier, so the
921  region of A is not false any more. The tests must be:
922 
923  COMMON ITAB(10),J
924  REAL A(10)
925  READ *, M
926  IF (M.GT.10) STOP "Bound violation ITAB"
927  STOP "Bound violation A"
928  J = 11
929  DO I = 1, M
930  ITAB(I) = 1
931  ENDDO
932  A(J) = 0
933 
934  Modify the algorithm:
935  At each statement s, take its list of regions:
936  - If no array is written => apply the algorithm normally
937  - Else
938  - Find the writing order
939  - Apply the algorithm for the first written array, and then the second, ...
940  - If the order is not found at s, go to the substatements of s */
941 
943 {
945  list l_copy = gen_full_copy_list(l_regions);
946  list l_written_arrays = NIL;
947  lexp = NIL;
949  godown = false;
950  ifdebug(3)
951  {
952  fprintf(stderr, "\n list of regions ");
953  print_effects(l_regions);
954  fprintf(stderr, "\n for the statement");
955  print_statement(s);
956  }
957  hash_put(context->read_saved_list,s,
958  copy_abc_checked(context->read_marked_list));
959  hash_put(context->write_saved_list,s,
960  copy_abc_checked(context->write_marked_list));
961 
962  /* Compute the list of written arrays */
963  /* while (!ENDP(l_copy))
964  {
965  region re = REGION(CAR(l_copy));
966  reference ref = effect_any_reference(re);
967  entity array = reference_variable(ref);
968  if (array_reference_p(ref)
969  && array_need_bound_check_p(array)
970  && region_write_p(re))
971  l_written_arrays = CONS(ENTITY,array,l_written_arrays);
972  l_copy = CDR(l_copy);
973  }
974  ifdebug(3)
975  {
976  fprintf(stderr, "\n List of written arrays : \n ");
977  print_list_entities(l_written_arrays);
978  }*/
979 
980  /* If no array is written */
981  if (ENDP(l_written_arrays))
982  {
983  /* check all arrays in l_regions*/
984  l_copy = gen_full_copy_list(l_regions);
985  while (!ENDP(l_copy))
986  {
987  region re = REGION(CAR(l_copy));
992  l_copy = CDR(l_copy);
993  }
994  }
995  else
996  {
997  /* Choose the first written array and then generate checks for
998  the read and write regions of this array. We can check the
999  second array only when all dimensions of the written regions
1000  of the first array are checked */
1001  while (!ENDP(l_written_arrays) && !godown)
1002  {
1003  entity first_array = find_first_written_array(l_written_arrays,s);
1004  /* if there is no array that is always written before the others,
1005  we have to go down to substatements of s*/
1007  godown = true;
1008  else
1009  {
1010  ifdebug(3)
1011  {
1012  fprintf(stderr, "\n First array: ");
1013  fprintf(stderr, "%s ", entity_name(first_array));
1014  }
1015  gen_remove_once(&l_written_arrays,first_array);
1016  // check for the first array here
1017  l_copy = gen_full_copy_list(l_regions);
1018  while (!ENDP(l_copy))
1019  {
1020  region re = REGION(CAR(l_copy));
1023  // if (same_entity_p(array,first_array))
1024  if (strcmp(entity_name(array),entity_name(first_array))==0)
1026  l_copy = CDR(l_copy);
1027  }
1028  }
1029  }
1030  }
1032  {
1033  ifdebug(3)
1034  {
1035  fprintf(stderr, "\n The sequence of test");
1037  }
1038  if (!godown)
1039  // godown = false, insert new tests for the statement s here
1041  else
1042  // insert new tests in function rwt
1043  hash_put(context->statement_check_list,s,test_sequence);
1044  }
1045  if (!godown)
1046  {
1047  context->read_marked_list =
1048  (abc_checked) hash_get(context->read_saved_list,s);
1049  context->write_marked_list =
1050  (abc_checked) hash_get(context->write_saved_list,s);
1051  }
1052  gen_free_list(l_regions);
1054  lexp = NIL;
1056  return godown;
1057 }
1058 
1061 {
1063  context->read_marked_list =
1064  (abc_checked) hash_get(context->read_saved_list,s);
1065  context->write_marked_list =
1066  (abc_checked) hash_get(context->write_saved_list,s);
1067  test_sequence = (statement) hash_get(context->statement_check_list,s);
1069  {
1070  ifdebug(3)
1071  {
1072  fprintf(stderr, "\n Rewrite : The sequence of test");
1074  fprintf(stderr, "\n of statement");
1075  print_statement(s);
1076  }
1077  // insert the new sequence of tests before the current statement
1079  }
1080 }
1081 
1083 {
1085  control_statement(c), c);
1086  return true;
1087 }
1088 
1090 {
1091  stack_push((char *) u, context->uns);
1092  return true;
1093 }
1094 
1095 static void pop_uns(unstructured __attribute__ ((unused)) u,
1097 {
1098  stack_pop(context->uns);
1099 }
1100 
1101 
1103 {
1105  context.read_marked_list = initiliaze_marked_list();
1106  context.write_marked_list = copy_abc_checked(context.read_marked_list);
1107  context.read_saved_list = hash_table_make(hash_pointer, 0);
1108  context.write_saved_list = hash_table_make(hash_pointer, 0);
1109 
1110  context.statement_check_list = hash_table_make(hash_pointer, 0);
1113 
1118  NULL);
1119 
1120  free_abc_checked(context.read_marked_list);
1121  free_abc_checked(context.write_marked_list);
1122  hash_table_free(context.read_saved_list);
1123  hash_table_free(context.write_saved_list);
1124  hash_table_free(context.statement_check_list);
1126  stack_free(&context.uns);
1127 }
1128 
1130 {
1134  "MUST_REGIONS"))
1135  pips_user_warning("\n MUST REGIONS not selected - "
1136  "\n Do not expect wonderful results\n");
1137  /* set and get the current properties concerning regions */
1138  set_bool_property("MUST_REGIONS", true);
1139  set_bool_property("EXACT_REGIONS", true);
1141  /* Get the code of the module. */
1143  module_name,
1144  true);
1147  /* Get the READ and WRITE regions of the module */
1149  db_get_memory_resource(DBR_REGIONS, module_name, true));
1151  db_get_memory_resource(DBR_PROPER_EFFECTS,
1152  module_name,true));
1153  debug_on("ARRAY_BOUND_CHECK_TOP_DOWN_DEBUG_LEVEL");
1154  pips_debug(1, " Region based ABC, Begin for %s\n", module_name);
1155  pips_assert("Statement is consistent ...",
1160  /* Reorder the module, because the bound checks have been added */
1162  pips_debug(1, "end\n");
1163  debug_off();
1169  reset_rw_effects();
1170  return true;
1171 }
1172 
1173 /* END OF FILE */
1174 
1175 
1176 
1177 
1178 
1179 
1180 
1181 
1182 
1183 
1184 
1185 
1186 
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
void user_log(const char *format,...)
Definition: message.c:234
abc_checked copy_abc_checked(abc_checked p)
ABC_CHECKED.
Definition: abc_private.c:16
void free_abc_checked(abc_checked p)
Definition: abc_private.c:19
dimension_checked make_dimension_checked(intptr_t a1, bool a2, bool a3)
Definition: abc_private.c:136
array_dimension_checked make_array_dimension_checked(entity a1, list a2)
Definition: abc_private.c:94
abc_checked make_abc_checked(list a)
Definition: abc_private.c:52
persistant_statement_to_control make_persistant_statement_to_control(void)
Definition: ri.c:1594
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
bool statement_consistent_p(statement p)
Definition: ri.c:2195
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
dimension copy_dimension(dimension p)
DIMENSION.
Definition: ri.c:529
control apply_persistant_statement_to_control(persistant_statement_to_control f, statement k)
Definition: ri.c:1597
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
bool bound_persistant_statement_to_control_p(persistant_statement_to_control f, statement k)
Definition: ri.c:1609
sequence make_sequence(list a)
Definition: ri.c:2125
control make_control(statement a1, list a2, list a3)
Definition: ri.c:523
void extend_persistant_statement_to_control(persistant_statement_to_control f, statement k, control v)
Definition: ri.c:1603
void free_persistant_statement_to_control(persistant_statement_to_control p)
Definition: ri.c:1561
#define array_dimension_checked_dims(x)
Definition: abc_private.h:107
#define dimension_checked_undefined
Definition: abc_private.h:117
#define abc_checked_list(x)
Definition: abc_private.h:71
#define dimension_checked_dim(x)
Definition: abc_private.h:142
#define DIMENSION_CHECKED(x)
DIMENSION_CHECKED.
Definition: abc_private.h:111
#define ARRAY_DIMENSION_CHECKED(x)
ARRAY_DIMENSION_CHECKED.
Definition: abc_private.h:75
#define dimension_checked_upper(x)
Definition: abc_private.h:146
#define array_dimension_checked_array(x)
Definition: abc_private.h:105
struct _newgen_struct_abc_checked_ * abc_checked
Definition: abc_private.h:22
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
#define dimension_checked_lower(x)
Definition: abc_private.h:144
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static statement module_statement
Definition: alias_check.c:125
#define VALUE_ONE
bool array_need_bound_check_p(entity e)
This function returns true, if the array needs bound checks false, otherwise.
string int_to_dimension(int i)
Warning! Do not modify this file that is automatically generated!
static bool push_uns(unstructured u, top_down_abc_context_p context)
static void display_top_down_abc_statistics()
static int current_max
static Bound_test top_down_abc_dimension(statement s, top_down_abc_context_p context, region re, bool action, entity array, int i, bool bound)
static bool min_statement_write_flt(statement s)
static bool is_first_written_array_p(entity a, list l, statement s)
static list lexp
static int number_of_added_tests
Statistic variables:
static bool top_down_abc_flt(statement s, top_down_abc_context_p context)
The old algorithm is false in the case of incorrect code, because regions are computed with the assum...
static Psysteme my_system_remove_variables(Psysteme ps)
static statement test_sequence
struct top_down_abc_context_t * top_down_abc_context_p
static int maximum_ordering(entity a, statement s)
search for the maximum ordering of statement (after s) that writes on a
static bool store_mapping(control c, top_down_abc_context_p context)
string bool_to_bound(bool b)
array_bound_check_top_down.c
static int minimum_ordering(entity a, statement s)
search for the minimum ordering of statement (after s) that writes on a
static entity current_entity
static void top_down_abc_statement(statement module_statement)
static void top_down_abc_rwt(statement s, top_down_abc_context_p context)
static bool godown
static int current_min
static void top_down_abc_insert_before_statement(statement s, statement s1, top_down_abc_context_p context)
bool array_bound_check_top_down(const char *module_name)
static int number_of_bound_violations
static void pop_uns(unstructured __attribute__((unused)) u, top_down_abc_context_p context)
static bool max_statement_write_flt(statement s)
static void set_array_dimension_checked(top_down_abc_context_p context, bool action, entity array, int dim, bool bound)
static string read_or_write(bool a)
static void initialize_top_down_abc_statistics()
static entity find_first_written_array(list l, statement s)
static list top_down_abc_call(call c, entity array, dimension dim_i, int i, bool bound)
static void top_down_abc_array(entity array, region re, statement s, top_down_abc_context_p context)
static Bound_test top_down_abc_not_exact_case(statement s, top_down_abc_context_p context, bool action, entity array, dimension dim_i, int i, bool bound)
static abc_checked initiliaze_marked_list()
struct Bound_test Bound_test
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
#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
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
expression Psysteme_to_expression(Psysteme)
system_to_code.c
#define region_system(reg)
#define region_read_p(reg)
useful region macros
#define REGION
#define region
simulation of the type region
#define region_exact_p(reg)
#define min(a, b)
#define max(a, b)
entity make_phi_entity(int)
list phi_entities_list(int, int)
void get_regions_properties(void)
bool sc_add_phi_equation(Psysteme *, expression, int, bool, bool)
void append_declaration_sc_if_exact_without_constraints(effect)
list regions_dup(list)
void set_rw_effects(statement_effects)
list load_proper_rw_effects_list(statement)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
list load_statement_local_regions(statement)
void reset_rw_effects(void)
#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 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
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
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
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
#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 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
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#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
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
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
bool statement_test_p(statement)
Definition: statement.c:343
bool statement_call_p(statement)
Definition: statement.c:364
statement make_print_statement(string)
Make a Fortran print statement.
Definition: statement.c:835
statement make_stop_statement(string)
This function returns a Fortran stop statement with an error message.
Definition: statement.c:908
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
entity first_array
une copie de l'un des nids de la sequence
#define rule_phase(x)
Definition: makefile.h:244
#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_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
@ hash_pointer
Definition: newgen_hash.h:32
#define same_string_p(s1, s2)
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
int stack_size(const stack)
observers
void stack_push(void *, stack)
stack use
Definition: stack.c:373
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399
int tag
TAG.
Definition: newgen_types.h:92
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
rule find_rule_by_resource(const char *rname)
This function returns the active rule to produce resource rname.
Definition: pipsmake.c:694
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define print_effects(e)
Definition: print.c:334
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
void set_bool_property(const char *, bool)
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define NORMALIZE_EXPRESSION(e)
#define test_to_statement(t)
#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 lt_expression(e1, e2)
#define OR_OPERATOR_NAME
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
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
void clean_all_normalized(expression e)
Definition: expression.c:4102
bool same_expression_in_list_p(expression e, list le)
This function returns true, if there exists a same expression in the list false, otherwise.
Definition: expression.c:557
int trivial_expression_p(expression e)
This function returns:
Definition: expression.c:679
bool true_expression_p(expression e)
Definition: expression.c:1113
expression expression_list_to_binary_operator_call(list l, entity op)
Definition: expression.c:1917
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
bool unbounded_dimension_p(dimension dim)
bool unbounded_dimension_p(dim) input : a dimension of an array entity.
Definition: expression.c:1130
bool array_reference_p(reference r)
predicates on references
Definition: expression.c:1861
expression make_true_expression()
Definition: expression.c:1103
dimension find_ith_dimension(list, int)
This function returns the ith dimension of a list of dimensions.
Definition: type.c:5621
#define normalized_undefined
Definition: ri.h:1745
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define CONTROL_(x)
Definition: ri.h:913
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define normalized_linear_p(x)
Definition: ri.h:1779
#define reference_variable(x)
Definition: ri.h:2326
#define control_predecessors(x)
Definition: ri.h:943
struct _newgen_struct_unstructured_ * unstructured
Definition: ri.h:447
#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 statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define control_domain
newgen_controlmap_domain_defined
Definition: ri.h:98
#define code_declarations(x)
Definition: ri.h:784
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
@ is_instruction_sequence
Definition: ri.h:1469
#define entity_name(x)
Definition: ri.h:2790
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define value_code(x)
Definition: ri.h:3067
#define syntax_call(x)
Definition: ri.h:2736
#define control_successors(x)
Definition: ri.h:945
#define expression_undefined_p(x)
Definition: ri.h:1224
#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 control_statement(x)
Definition: ri.h:941
#define statement_undefined_p(x)
Definition: ri.h:2420
#define entity_type(x)
Definition: ri.h:2792
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
bool sc_rn_p(Psysteme sc)
bool sc_rn_p(Psysteme sc): check if the set associated to sc is the whole space, rn
Definition: sc_alloc.c:369
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
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
int sc_check_inequality_redundancy(Pcontrainte ineq, Psysteme ps)
int sc_check_inequality_redundancy(Pcontrainte ineq, Psysteme ps) Check if an inequality ineq,...
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()
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
static entity array
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
struct Svecteur * succ
Definition: vecteur-local.h:92
the stack head
Definition: stack.c:62
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: delay.c:253
The following data structure is the context of top_down_abc: The read_marked_list marks if one bound ...
persistant_statement_to_control map
bool old_value_entity_p(entity)
Definition: value.c:936
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
#define vecteur_var(v)
#define VECTEUR_NUL_P(v)
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
#define OFL_CTRL
I do thing that overflows are managed in a very poor manner.
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
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
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
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72