PIPS
utils.c
Go to the documentation of this file.
1 /*
2 
3  $Id: utils.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  * utilities for reductions.
29  *
30  * FC, June 1996.
31  */
32 
33 #include "local-header.h"
34 #include "prettyprint.h" // for same_ref_name_p()
35 #include "semantics.h"
36 /******************************************************************** MISC */
37 /* ??? some arrangements with words_range to print a star in this case:-)
38  */
40 {
45 }
52  return true;
53  }
54  return false;
55 }
56 
57 /***************************************************** REFERENCED ENTITIES */
58 /* returns the list of referenced variables
59  */
60 static list /* of entity */ referenced;
61 static void ref_rwt(reference r)
63 
64 static list /* of entity */
66 {
67  referenced = NIL;
69  return referenced;
70 }
71 
72 /************************************** REMOVE A VARIABLE FROM A REDUCTION */
73 /* must be able to remove a modified variable from a reduction:
74  * . A(I) / I -> A(*)
75  * . A(B(C(I))) / C -> A(B(*))
76  * . A(I+J) / I -> A(*)
77  * . A(B(I)+C(I)) / I -> A(*) or A(B(*)+C(*)) ? former looks better
78  */
79 
80 /* the variable that must be removed is stored here
81  */
83 /* list of expressions to be deleted (at rwt)
84  */
85 static list /* of expression */ dead_expressions;
86 /* the first expression encountered which is a function call, so as
87  * to avoid "*+J" results
88  */
90 /* stack of reference expressions (if there is no call)
91  */
93 
94 static bool expr_flt(expression e)
95 {
96  if (expression_reference_p(e)) /* REFERENCE */
97  ref_exprs_push(e);
98  else if (!first_encountered_call && expression_call_p(e)) /* CALL */
100  return true;
101 }
102 
103 static void expr_rwt(expression e)
104 {
105  if (expression_reference_p(e))
106  ref_exprs_pop();
107  else if (first_encountered_call==e)
108  first_encountered_call = NULL;
109 
111  {
114  }
115 }
116 
117 static bool ref_flt(reference r)
118 {
120  {
123  ref_exprs_head(), dead_expressions);
124  return false;
125  }
126  return true;
127 }
128 
129 void
131  reduction red,
132  entity var)
133 {
134  variable_to_remove = var;
136  first_encountered_call = NULL;
137  make_ref_exprs_stack();
138 
139  pips_debug(8, "removing %s from %s[%s]\n",
140  entity_name(var),
144 
148  NULL);
149 
151  free_ref_exprs_stack();
152 }
153 
154 bool
156  reduction red,
157  effect eff)
158 {
159  entity var = effect_variable(eff);
160  bool updated = false;
161 
162  pips_debug(7, "reduction %s[%s] under effect %s on %s\n",
166  effect_write_p(eff)? "W": "R",
168 
169  if(!store_effect_p(eff)) {
170  return true;
171  }
172 
173 
174  /* REDUCTION is dead if the reduction variable is affected
175  */
177  {
180  return false;
181  }
182  /* else */
183 
184  if (effect_read_p(eff)) return true;
185 
186  /* now var is written */
188  if (entities_may_conflict_p(var, e)) {
189  updated = true;
191  }
192  }
193 
194  if (updated)
195  {
197  reduction_dependences(red) =
199  }
200 
201  return true;
202 }
203 
204 /* looks for a reduction about var in reds, and returns it.
205  * tells whether it worths keeping on. It does not if there may be some
206  * conflicts with other reduced variables...
207  */
208 static bool
210  entity var,
211  reductions reds,
212  reduction *pr)
213 {
214  FOREACH (REDUCTION, r, reductions_list(reds)) {
215  entity red_var = reduction_variable(r);
216  if (red_var==var) {
217  *pr = copy_reduction(r);
218  return true;
219  }
220  else if (entities_may_conflict_p(red_var, var))
221  return false; /* I will not combine them... */
222  }
223  return true;
224 }
225 
226 /* merge two reductions into first so as to be compatible with both.
227  * deletes the second. tells whether they where compatibles
228  * quite basic at the time
229  */
230 static bool
232 {
233  pips_assert("same variable",
234  reduction_variable(first)==reduction_variable(second));
235 
238  {
239  free_reduction(second);
240  return false;
241  }
242 
244  reduction_reference(second)))
245  {
246  /* actually merges, very simple at the time
247  */
249  reduction_reference(first) =
251  }
252 
253  free_reduction(second);
254  return true;
255 }
256 
257 /* update *pr according to r for variable var
258  * r is not touched.
259  */
261  if(reduction_variable(r) != var)
263 
264  /* else same var and no conflict */
265  if(reduction_none_p(*pr)) {
266  free_reduction(*pr);
267  *pr = copy_reduction(r);
268  return true;
269  }
270  /* else are they compatible?
271  */
272  if(reduction_tag(*pr) != reduction_tag(r))
273  return false;
274  /* ok, let us merge them
275  */
276  return merge_two_reductions(*pr, copy_reduction(r));
277 }
278 
279 /* what to do with reduction *pr for variable var
280  * under effects le and reductions reds.
281  * returns whether worth to go on.
282  * conditions:
283  */
284 bool
286  reduction *pr,
287  entity var,
288  list /* of effect */ le,
289  reductions reds)
290 {
291  reduction found = NULL;
292 
293  if (!find_reduction_of_var(var, reds, &found))
294  return false;
295 
296  if (found)
297  {
298  if (!reduction_none_p(*pr)) /* some reduction already available */
299  return merge_two_reductions(*pr, found);
300  else { /* must update the reduction with the encountered effects */
303  }
304  free_reduction(*pr); *pr = found;
305  return true;
306  }
307  }
308  /* else
309  * now no new reduction waas found, must check *pr against effects
310  */
311  if (!reduction_none_p(*pr)) /* some reduction */
312  {
313  FOREACH (EFFECT, e, le) {
314  if(!store_effect_p(e)) continue;
315  if (!update_reduction_under_effect(*pr, e)) {
316  DEBUG_REDUCTION(8, "kill of ", *pr);
317  pips_debug(8, "under effect to %s\n",
319  return false;
320  }
321  }
322  }
323  else
324  {
325  FOREACH (EFFECT, e, le) {
326  if(!store_effect_p(e)) continue;
328  return false;
329  else if (effect_write_p(e)) /* stores for latter cleaning */
331  reduction_dependences(*pr));
332  }
333  }
334  return true;
335 }
336 
337 /*************************************************** CALL PROPER REDUCTION */
338 /* extract the proper reduction of a call (instruction) if any.
339  */
340 
341 /* I trust intrinsics (operations?) and summary effects...
342  */
344 {
345  value v = entity_initial(f);
346 
348  return true;
349  /* else */
350 
351  if (entity_module_p(f))
352  {
354  if(!store_effect_p(e)) continue;
355  if (effect_write_p(e)) /* a side effect!? */
356  return false;
357  if (io_effect_entity_p(effect_variable(e))) /* LUNS */
358  return false;
359  }
360  }
361 
362  return true;
363 }
364 
365 /* tells whether r is a functional reference...
366  * actually I would need to recompute somehow the proper effects of obj?
367  */
368 static bool is_functional;
369 static bool call_flt(call c)
370 {
372  return true;
373  /* else */
374  is_functional = false;
375  gen_recurse_stop(NULL);
376  return false;
377 }
378 static bool
380 {
381  is_functional = true;
383  return is_functional;
384 }
385 
386 /****************************************************** REDUCTION OPERATOR */
387 
388 #define OKAY(op,com) do { *op_tag=op; *commutative=com; return true;} while(false)
389 #define OKAY_WO_COMM(op) do { *op_tag=op; return true;} while(false)
390 /* tells whether entity f is a reduction operator function
391  * also returns the corresponding tag, and if commutative
392  * @return true if the entity f is a reduction operator function
393  * @param f, the entity to look at
394  * @param op_tag, use to return the reduction operator (+, * ...)
395  * @param commutative, use to return the operator commutativity
396  */
397 static bool
399  entity f,
400  tag *op_tag,
401  bool *commutative)
402 {
403  if (ENTITY_PLUS_P(f))
405  else if (ENTITY_MINUS_P(f))
407  else if (ENTITY_MULTIPLY_P(f))
409  else if (ENTITY_DIVIDE_P(f))
411  else if (ENTITY_MIN_P(f) || ENTITY_MIN0_P(f))
413  else if (ENTITY_MAX_P(f) || ENTITY_MAX0_P(f))
415  else if (ENTITY_AND_P(f))
417  else if (ENTITY_OR_P(f))
419  else if (ENTITY_BITWISE_AND_P(f))
421  else if (ENTITY_BITWISE_OR_P(f))
423  else if (ENTITY_BITWISE_XOR_P(f))
425  else if (ENTITY_EQUIV_P(f))
427  else if (ENTITY_NON_EQUIV_P(f))
429  else
430  return false;
431 }
432 
433 /* returns the possible operator of expression e if it is a reduction,
434  * and the operation commutative. (- and / are not)
435  */
436 static bool
438  expression e,
439  tag *op_tag,
440  bool *commutative)
441 {
442  syntax s = expression_syntax(e);
443  call c;
444  entity f;
445 
446  if (!syntax_call_p(s)) return false;
447  c = syntax_call(s);
448  f = call_function(c);
449  return function_reduction_operator_p(f, op_tag, commutative);
450 }
451 
452 /* Test if the operator is an update operator compatible with reduction
453  * This also returns the corresponding tag, and if commutative
454  * @return true if the operator is an update operator compatible with reduction
455  * @param operator, the operator (as an entity) to look at
456  * @param op_tag, used to return the reduction operator (+, * ...)
457  * @param commutative, used to return the operator commutativity
458  */
460  tag* op_tag,
461  bool* commutative)
462 {
463  if (ENTITY_PLUS_UPDATE_P (operator))
465  else if (ENTITY_MINUS_UPDATE_P (operator))
467  else if (ENTITY_MULTIPLY_UPDATE_P (operator))
469  else if (ENTITY_DIVIDE_UPDATE_P (operator))
471  else if (ENTITY_BITWISE_OR_UPDATE_P (operator))
473  else if (ENTITY_BITWISE_AND_UPDATE_P (operator))
475  else if (ENTITY_BITWISE_XOR_UPDATE_P (operator))
477 
478  return false;
479 }
480 
481 /* Test if the operator is an unary update operator compatible with reduction
482  * This also returns the corresponding tag
483  * @return true if the operator is an update operator compatible with reduction
484  * @param operator, the operator (as an entity) to look at
485  * @param op_tag, used to return the reduction operator (+, ...)
486  */
488  tag* op_tag)
489 {
490  if (ENTITY_POST_INCREMENT_P(operator) ||
491  ENTITY_POST_DECREMENT_P(operator) ||
492  ENTITY_PRE_INCREMENT_P(operator) ||
493  ENTITY_PRE_DECREMENT_P(operator))
495 
496  return false;
497 }
498 
499 /* @return true if f is compatible with tag op.
500  * @param f the entity to check.
501  * @param op the tag to check against.
502  * @param pcomm the commutative return value.
503  */
504 static bool
506  entity f,
507  tag op,
508  bool *pcomm)
509 {
510  tag nop;
511  if (!function_reduction_operator_p(f, &nop, pcomm))
512  return false;
513  return nop==op;
514 }
515 
516 /***************************************************** FIND SAME REFERENCE */
517 
518 /* looks for an equal reference in e, for reduction rop.
519  * the reference found is also returned.
520  * caution:
521  * - for integers, / is *not* a valid reduction operator:-(
522  * this case is detected here...
523  * static variables:
524  * - refererence looked for fsr_ref,
525  * - reduction operator tag fsr_op,
526  * - returned reference fsr_found,
527  */
530 static tag fsr_op;
531 
533 {
534  pips_debug(7,"r: %s, fsr_ref: %s\n",
537  if (reference_equal_p(r, fsr_ref))
538  {
539  fsr_found = r;
540  /* stop the recursion if does not need to check int div
541  */
544  gen_recurse_stop(NULL);
545  }
546 
547  return false; /* no candidate refs within a ref! */
548 }
549 
550 /* @return true if the all operators are compatible with the detected reduction operator
551  * @param c, the call to search for operators
552  */
553 static bool fsr_call_flt(call c)
554 {
555  bool comm;
557  return false;
558  /* else */
559  if (!comm)
560  {
561  list /* of expression */ le = call_arguments(c);
562  pips_assert("length is two", gen_length(le)==2);
564  }
565 
566  return true;
567 }
568 
569 static bool
571  reference r, /* looked for */
572  expression e, /* visited object */
573  tag rop, /* assumed reduction */
574  bool red_up_op,
575  reference *pfound) /* returned */
576 {
577  fsr_ref = r;
578  fsr_op = rop;
579  fsr_found = NULL;
580 
584  NULL);
585 
586  *pfound = fsr_found;
587  return (red_up_op || (fsr_found != NULL));
588 }
589 
590 /******************************************************** NO OTHER EFFECTS */
591 
592 /* checks that the references are the only touched within this statement.
593  * I trust the proper effects to store all references...
594  */
595 bool
597  statement s,
598  list /* of reference on the same variable */ lr)
599 {
600  list /* of effect */ le;
601  entity var;
602  if (ENDP(lr)) return true;
603 
605  var = reference_variable(REFERENCE(CAR(lr)));
606 
607  pips_debug(7,"entity name: %s\n", entity_name(var));
608 
609  FOREACH (EFFECT, e, le) {
610  if(!store_effect_p(e)) continue;
612  if (!gen_in_list_p(r, lr) && store_effect_p(e) &&
614  pips_debug(7,"Effect may touch variable : ");print_effect(e);
615  return false;
616  }
617  pips_debug(7,"refrence r: %p of entity: %s\n", r, entity_name (reference_variable(r)));
618  }
619 
620  return true;
621 }
622 
623 /************************************************ EXTRACT PROPER REDUCTION */
624 /* This function look for a reduction and return it if found
625  * mallocs are avoided if nothing is found...
626  * looks for v = v OP y or v OP= y, where y is independent of v.
627  * @return true if the call in s a reduction
628  * @param s,
629  * @param c, the call to test for reduction
630  * @param red, the reduction to return
631  */
632 bool
634  statement s, /* needed to query about proper effects */
635  call c, /* the call of interest */
636  reduction *red) /* the returned reduction (if any) */
637 {
638  tag op; // The operator tag (sum, mul ...)
639  list le = NIL; // list of expression
640  list lr = NIL; // list of reference
641  list lp = NIL; // list of Preference
642  bool comm = false; // The commutatity operator flag
643  bool assign_op = false; // The assign operator flag
644  bool update_op = false; // The reduction update operator flag;
645  bool unary_op = false; // The reduction unary update operator flag;
646  entity fct = call_function(c); // the call function to test for reduction
651 
652  pips_debug(7, "call to %s (%p)\n", entity_name(call_function(c)), s);
653 
654  // First init the operation flags
655  // only check the operator type if the previous test failed
656  if ((assign_op = ENTITY_ASSIGN_P (fct)) == false)
657  if ((update_op=extract_reduction_update_operator(fct, &op, &comm))==false)
658  unary_op = extract_reduction_unary_update_operator (fct, &op);
659 
660  // if no suitable operator has been found : return false
661  if ((unary_op == false) && (update_op == false) && (assign_op == false)) {
662  pips_debug(5,"No unary, nor update, no assign !\n");
663  return false;
664  }
665 
666  // get the left and right operands
667  le = call_arguments(c);
668  elhs = EXPRESSION(CAR(le));
669  //no right operand for unary operator
670  if (unary_op == false) erhs = EXPRESSION(CAR(CDR(le)));
671  if (syntax_reference_p(expression_syntax(elhs)) == false) {
672  pips_user_warning ("The left hand side of assignment is not a reference, "
673  "this is not handled and no reduction will be detected\n");
674  return false;
675  }
676  lhs = syntax_reference(expression_syntax(elhs));
677 
678  // the lhs and rhs (if exits) must be functionnal
679  // (same location on different evaluations)
680  if (!functional_object_p((gen_chunk *) lhs) ||
681  ((unary_op == false) && !functional_object_p((gen_chunk *) erhs))) {
682  pips_debug(5,"Lhs or Rhs not functional !\n");
683  return false;
684  }
685  pips_debug(8, "lhs and rhs are functional\n");
686 
687  // Check that the operation performed is valid for a reduction,
688  // The check is useless for reduction update and unary operator because
689  // already done previously by "extract_reduction_update_operator" and
690  // "extract_reduction_unary_update_operator"
691  if ((unary_op == false) && (update_op == false) &&
692  (extract_reduction_operator(erhs, &op, &comm) == false)) {
693  pips_debug(5,"extract_reduction_operator returned false !!\n");
694  return false;
695  }
696  pips_debug(8, "reduction operator %s\n", reduction_operator_tag_name(op));
697 
698  // there should be another direct reference to lhs if not unary
699  // !!! syntax is a call if extract_reduction_operator returned TRUE
700  if (unary_op == false) {
701  if (!equal_reference_in_expression_p(lhs, erhs, op, update_op, &other)) {
702  pips_debug(5,"!equal_reference_in_expression_p !!\n");
703  return false;
704  }
705  pips_debug(8, "matching reference found (%p)\n", other);
706  }
707 
708  // build the list of found reference to the reduced variable
709  if ((update_op == true) || (unary_op == true))
710  lr = CONS(REFERENCE, lhs, NIL);
711  else
712  lr = CONS(REFERENCE, lhs, CONS(REFERENCE, other, NIL));
713  pips_debug(7,"list lr is: %p and %p\n", other, lhs);
714  // there should be no extra effects on the reduced variable
715  if (!no_other_effects_on_references (s, lr)) {
716  pips_debug(5,"Other effects on references !!\n");
717  gen_free_list(lr);
718  return false;
719  }
720  pips_debug(8, "no other effects\n");
721 
722  FOREACH (REFERENCE, r, lr) {
723  lp = CONS(PREFERENCE, make_preference(r), lp);
724  }
725  gen_free_list(lr), lr = NIL;
726 
727  // well, it is ok for a reduction now!
728  *red = make_reduction(copy_reference(lhs),
731  lp);
732 
733  DEBUG_REDUCTION(7, "returning\n", *red);
734  return true;
735 }
736 
737 
738 /**
739  * Return the "other part" of the reduction. If the statement is :
740  * sum = sum + a[i];
741  * then we'll return a[i]
742  */
744  expression complement = expression_undefined;
745  // We handle only trivial cases
746  if(statement_call_p(s)) {
747  call c = statement_call(s);
748  entity fct = call_function(c);
749  list le = call_arguments(c);
750  tag op;
751  bool comm = false; // Commutativity
752  // Differentiate unary && update && binary operators
753  if (ENTITY_ASSIGN_P (fct)){
754  // Normal case, binary expected
755  expression rhs = EXPRESSION(CAR(CDR(le)));
756  if(expression_call_p(rhs)) {
757  list args = call_arguments(expression_call(rhs));
758  pips_assert("Have a binary operator\n", gen_length(args)==2);
759  /* try to find out which of the two expression corresponds to the
760  * reduced reference. We'll return the other...
761  */
762  expression e1 = EXPRESSION(CAR(args));
763  expression e2 = EXPRESSION(CAR(CDR(args)));
764  if(expression_reference_p(e1) &&
765  same_ref_name_p(reduced,expression_reference(e1))) {
766  complement = e2;
767  } else if(expression_reference_p(e2) &&
768  same_ref_name_p(reduced,expression_reference(e2))) {
769  complement = e2;
770  } else {
771  pips_user_warning("Atomic operation replacement seems less general"
772  " than reduction detection. This merits a bug report !\n");
773  }
774  } else {
775  pips_user_warning("Atomic operation replacement seems less general than"
776  " reduction detection. This merits a bug report !\n");
777  }
778  } else if(extract_reduction_unary_update_operator(fct, &op)) {
779  // ++ or -- : we return 1
780  pips_debug(3,"We have an unary operator\n");
781  complement = int_to_expression(1);
782  } else if(extract_reduction_update_operator(fct, &op, &comm)) {
783  // += or similar, return directly rhs
784  pips_debug(3,"We have an update operator\n");
785  complement = EXPRESSION(CAR(CDR(le)));
786  } else {
787  pips_internal_error("We have a reduction, but the statement is neither an"
788  " unary nor a binary ? It's a bug, sorry no choice but abort !\n");
789  }
790  }
791  return complement;
792 }
793 
reduction copy_reduction(reduction p)
REDUCTION.
void free_reduction(reduction p)
reduction_operator make_reduction_operator(enum reduction_operator_utype tag, void *val)
reduction make_reduction(reference a1, reduction_operator a2, list a3, list a4)
void free_reference(reference p)
Definition: ri.c:2050
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
void free_syntax(syntax p)
Definition: ri.c:2445
syntax make_syntax(enum syntax_utype tag, void *val)
Definition: ri.c:2491
preference make_preference(reference a1)
Definition: ri.c:1862
range make_range(expression a1, expression a2, expression a3)
Definition: ri.c:2041
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
list load_summary_effects(entity e)
FI->FI, FI->BC: these two functions should be moved into effects-util or effects-simple.
effects load_proper_references(statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
bool store_effect_p(effect)
Definition: effects.c:1062
bool io_effect_entity_p(entity)
Definition: effects.c:496
#define effects_effects(x)
Definition: effects.h:710
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void update_op(int op, char *error_msg)
UPDATE_OP checks whether the just read OPerator is compatible with the current one.
Definition: genspec_yacc.c:120
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
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
#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 FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool statement_call_p(statement)
Definition: statement.c:364
#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 pips_internal_error
Definition: misc-local.h:149
#define DEFINE_LOCAL_STACK(name, type)
int tag
TAG.
Definition: newgen_types.h:92
#define UU
Definition: newgen_types.h:98
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define print_effect(e)
Definition: print.c:336
bool same_ref_name_p(reference, reference)
Definition: same_names.c:75
#define reduction_variable(r)
shorthands for REDUCTION:
#define DEBUG_REDUCTION(level, msg, red)
quick debug macros
#define reduction_tag(r)
#define reduction_none_p(r)
string reduction_operator_tag_name(tag t)
returns a (static) string describing the tag t reduction
Definition: prettyprint.c:78
static void ref_rwt(reference r)
Definition: utils.c:61
static list referenced
returns the list of referenced variables
Definition: utils.c:60
static reference fsr_ref
looks for an equal reference in e, for reduction rop.
Definition: utils.c:528
bool no_other_effects_on_references(statement s, list lr)
checks that the references are the only touched within this statement.
Definition: utils.c:596
static bool functional_object_p(gen_chunk *obj)
Definition: utils.c:379
expression get_complement_expression(statement s, reference reduced)
Return the "other part" of the reduction.
Definition: utils.c:743
static bool is_functional
tells whether r is a functional reference...
Definition: utils.c:368
static bool call_flt(call c)
Definition: utils.c:369
static void expr_rwt(expression e)
Definition: utils.c:103
static list dead_expressions
list of expressions to be deleted (at rwt)
Definition: utils.c:85
static bool find_reduction_of_var(entity var, reductions reds, reduction *pr)
looks for a reduction about var in reds, and returns it.
Definition: utils.c:209
static tag fsr_op
Definition: utils.c:530
static expression first_encountered_call
the first expression encountered which is a function call, so as to avoid "*+J" results
Definition: utils.c:89
static bool fsr_reference_flt(reference r)
Definition: utils.c:532
bool update_reduction_under_effect(reduction red, effect eff)
Definition: utils.c:155
bool update_compatible_reduction_with(reduction *pr, entity var, reduction r)
update *pr according to r for variable var r is not touched.
Definition: utils.c:260
bool reduction_star_p(reduction r)
utils.c
Definition: utils.c:46
bool call_proper_reduction_p(statement s, call c, reduction *red)
This function look for a reduction and return it if found mallocs are avoided if nothing is found....
Definition: utils.c:633
static bool function_reduction_operator_p(entity f, tag *op_tag, bool *commutative)
tells whether entity f is a reduction operator function also returns the corresponding tag,...
Definition: utils.c:398
static bool extract_reduction_update_operator(entity operator, tag *op_tag, bool *commutative)
Test if the operator is an update operator compatible with reduction This also returns the correspond...
Definition: utils.c:459
static list referenced_variables(reference r)
of entity
Definition: utils.c:65
bool pure_function_p(entity f)
extract the proper reduction of a call (instruction) if any.
Definition: utils.c:343
static entity variable_to_remove
must be able to remove a modified variable from a reduction:
Definition: utils.c:82
static bool reduction_function_compatible_p(entity f, tag op, bool *pcomm)
Definition: utils.c:505
static bool extract_reduction_operator(expression e, tag *op_tag, bool *commutative)
returns the possible operator of expression e if it is a reduction, and the operation commutative.
Definition: utils.c:437
void remove_variable_from_reduction(reduction red, entity var)
Definition: utils.c:130
static bool equal_reference_in_expression_p(reference r, expression e, tag rop, bool red_up_op, reference *pfound)
returned
Definition: utils.c:570
#define OKAY(op, com)
Definition: utils.c:388
static bool ref_flt(reference r)
Definition: utils.c:117
static bool expr_flt(expression e)
stack of reference expressions (if there is no call)
Definition: utils.c:94
static reference fsr_found
Definition: utils.c:529
bool update_compatible_reduction(reduction *pr, entity var, list le, reductions reds)
what to do with reduction *pr for variable var under effects le and reductions reds.
Definition: utils.c:285
#define OKAY_WO_COMM(op)
Definition: utils.c:389
static syntax make_star_syntax()
??? some arrangements with words_range to print a star in this case:-)
Definition: utils.c:39
static bool merge_two_reductions(reduction first, reduction second)
merge two reductions into first so as to be compatible with both.
Definition: utils.c:231
static bool fsr_call_flt(call c)
Definition: utils.c:553
static bool extract_reduction_unary_update_operator(entity operator, tag *op_tag)
Test if the operator is an unary update operator compatible with reduction This also returns the corr...
Definition: utils.c:487
@ is_reduction_operator_bitwise_xor
@ is_reduction_operator_none
@ is_reduction_operator_min
@ is_reduction_operator_bitwise_and
@ is_reduction_operator_neqv
@ is_reduction_operator_max
@ is_reduction_operator_bitwise_or
@ is_reduction_operator_eqv
@ is_reduction_operator_prod
@ is_reduction_operator_or
@ is_reduction_operator_and
@ is_reduction_operator_sum
#define REDUCTION(x)
REDUCTION.
#define reduction_operator_tag(x)
#define reduction_op(x)
#define reduction_dependences(x)
#define reduction_reference(x)
#define reductions_list(x)
#define ENTITY_OR_P(e)
#define ENTITY_PLUS_UPDATE_P(e)
#define ENTITY_DIVIDE_P(e)
#define ENTITY_AND_P(e)
#define ENTITY_MAX0_P(e)
#define ENTITY_BITWISE_AND_UPDATE_P(e)
#define ENTITY_ASSIGN_P(e)
#define ENTITY_MINUS_P(e)
#define ENTITY_PLUS_P(e)
#define ENTITY_MULTIPLY_P(e)
#define ENTITY_PRE_DECREMENT_P(e)
#define ENTITY_POST_DECREMENT_P(e)
#define ENTITY_POST_INCREMENT_P(e)
#define ENTITY_PRE_INCREMENT_P(e)
#define ENTITY_BITWISE_OR_UPDATE_P(e)
#define ENTITY_MAX_P(e)
#define ENTITY_NON_EQUIV_P(e)
#define ENTITY_MULTIPLY_UPDATE_P(e)
#define ENTITY_BITWISE_OR_P(e)
#define ENTITY_BITWISE_XOR_P(e)
#define ENTITY_MIN0_P(e)
#define ENTITY_DIVIDE_UPDATE_P(e)
#define ENTITY_MIN_P(e)
#define ENTITY_BITWISE_XOR_UPDATE_P(e)
#define ENTITY_MINUS_UPDATE_P(e)
#define ENTITY_BITWISE_AND_P(e)
#define ENTITY_EQUIV_P(e)
basic entity_basic(entity e)
return the basic associated to entity e if it's a function/variable/constant basic_undefined otherwis...
Definition: entity.c:1380
bool entity_module_p(entity e)
Definition: entity.c:683
bool expression_call_p(expression e)
Definition: expression.c:415
call expression_call(expression e)
Definition: expression.c:445
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
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
#define PREFERENCE(x)
PREFERENCE.
Definition: ri.h:2073
#define syntax_reference_p(x)
Definition: ri.h:2728
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
#define basic_int_p(x)
Definition: ri.h:614
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_undefined
Definition: ri.h:2302
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define range_upper(x)
Definition: ri.h:2290
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
#define syntax_range(x)
Definition: ri.h:2733
@ is_syntax_range
Definition: ri.h:2692
#define value_constant_p(x)
Definition: ri.h:3071
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define expression_undefined
Definition: ri.h:1223
#define value_symbolic_p(x)
Definition: ri.h:3068
#define entity_name(x)
Definition: ri.h:2790
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_call(x)
Definition: ri.h:2736
#define expression_undefined_p(x)
Definition: ri.h:1224
#define call_arguments(x)
Definition: ri.h:711
#define syntax_range_p(x)
Definition: ri.h:2731
#define expression_syntax(x)
Definition: ri.h:1247
#define entity_initial(x)
Definition: ri.h:2796
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
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