PIPS
optimize.c
Go to the documentation of this file.
1 /*
2 
3  $Id: optimize.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 #include <stdio.h>
29 #include <stdlib.h>
30 
31 #include "linear.h"
32 
33 #include "genC.h"
34 #include "ri.h"
35 #include "effects.h"
36 #include "ri-util.h"
37 #include "prettyprint.h"
38 #include "effects-util.h"
39 
40 #include "misc.h"
41 #include "properties.h"
42 
43 #include "resources.h"
44 #include "pipsdbm.h"
45 #include "control.h"
46 
47 #include "eole_private.h"
48 #include "expressions.h"
49 
50 #define DEBUG_NAME "TRANSFORMATION_OPTIMIZE_EXPRESSIONS_DEBUG_LEVEL"
51 
52 /****************************************************************** STRATEGY */
53 
54 /* this structure defines a strategy for eole.
55  */
56 typedef struct
57 {
58  /* NAME of the strategy */
59  string name;
60 
61  /* HUFFMAN.
62  */
66 
67  /* EOLE. 2 passes.
68  */
69  string eole_strategy;
70 
72  string apply_eole1_flags; /* not used yet */
73 
76 
77  /* SIMPLIFY.
78  */
81 
82  /* GCM CSE
83  */
84  bool apply_gcm;
85 
86  /* CSE
87  */
88  bool apply_cse;
89 
91 
92 /* current strategy.
93  */
95 
96 /************************************************************** EOLE PROCESS */
97 
98 /* file name prefixes to deal with eole.
99  * /tmp should be fast (may be mapped into memory).
100  */
101 #define OUT_FILE_NAME "/tmp/pips_to_eole"
102 #define IN_FILE_NAME "/tmp/eole_to_pips"
103 
104 /* property names.
105  */
106 #define EOLE "EOLE" /* eole binary */
107 #define EOLE_FLAGS "EOLE_FLAGS" /* default options */
108 #define EOLE_OPTIONS "EOLE_OPTIONS" /* additionnal options */
109 
110 /* returns the eole command to be executed in an allocated string.
111  */
112 static string
114  (const char* in, /* input file from eole. */
115  const char* out,/* output file to eole. */
116  const char* flags)
117 {
119  flags, " ",
121  " -S ", strategy->eole_strategy,
122  " -o ", in, " ", out, NULL));
123 }
124 
125 /************************************************ EOLE MANAGEABLE EXPRESSION */
126 
128 {
129  basic b = entity_basic(e);
130 
131  if (type_functional_p(entity_type(e)) &&
133  !basic_undefined_p(b))
134  return basic_string_p(b);
135 
136  return false;
137 }
138 
139 static void eole_okay_call_rwt(call c, bool * okay)
140 {
142  *okay = false;
143 
144  /* IMPLIED-DO ? others ? */
145 }
146 
148 {
149  bool okay = true;
150  gen_context_multi_recurse(e, &okay,
152  NULL);
153  return okay;
154 }
155 
156 /********************************************************* INTERFACE TO EOLE */
157 
158 /* extract expressions with loop level information.
159  */
160 typedef struct
161 {
162  list /* expressionwithlevel */ rhs; /* the list of RHS expressions. */
163  list /* entity */ indices; /* the list of loop indices (not used yet). */
165 
167 {
168  expressionwithlevel ewl =
170  context->rhs = CONS(EXPRESSIONWITHLEVEL, ewl, context->rhs);
171 }
172 
174 {
175  entity index = loop_index(l);
176  context->indices = CONS(ENTITY, index, context->indices);
177  return true; /* keep on. */
178 }
179 
181 {
182  list tmp = context->indices;
183  pips_assert("same index", ENTITY(CAR(context->indices))==loop_index(l));
184  context->indices = CDR(context->indices);
185  CDR(tmp) = NIL;
186  gen_free_list(tmp);
187 }
188 
189 /* rhs expressions of assignments.
190  */
192 {
193  /* put all manageable expressions arguments... */
194  MAP(EXPRESSION, e,
196  call_arguments(c));
197  return false;
198 }
199 
200 /* other expressions may be found in loops and so?
201  */
203 {
206  return false;
207 }
208 
209 static list /* of expressionwithlevel */
211 {
213 
214  context.rhs = NIL;
215  context.indices = NIL;
216 
221  NULL);
222 
223  pips_assert("no indices", context.indices==NIL);
224 
225  return gen_nreverse(context.rhs);
226 }
227 
228 /* export a list of expression of the current module.
229  * done thru a convenient reference.
230  */
231 static void write_list_of_rhs(FILE * out, list /* of expressionwithlevel */ le)
232 {
233  /* reference astuce = make_reference(get_current_module_entity(), le);*/
238 }
239 
240 /* export expressions to eole thru the newgen format.
241  * both entities and rhs expressions are exported.
242  */
243 static void write_to_eole(const char* module, list le, const char* file_name)
244 {
245  FILE * toeole;
246 
247  pips_debug(3, "writing to eole for module %s\n", module);
248 
249  toeole = safe_fopen(file_name, "w");
250  write_tabulated_entity(toeole);
251  write_list_of_rhs(toeole, le);
252 
253  safe_fclose(toeole, file_name);
254 }
255 
256 #define SIZE_OF_BUFFER 100
257 
258 static string
260 {
261  int test;
262  char buffer[SIZE_OF_BUFFER];
263 
264  test = fscanf(file, "%s",buffer);
265  pips_assert("fscanf - read string from file \n",(test==1));
266 
267  return strdup(buffer);
268 }
269 
270 
271 /* import a list of entity that have been created during the eole
272  * transformations and create them
273  */
274 static void
275 read_new_entities_from_eole(FILE * file, const char* module){
276  int num = 0;
277  int i, test;
278  string ent_type;
279  string const_type;
280  int const_size = 0;
281  string const_value;
282 
283  entity e;
284 
285  /* read the number of new entities to create */
286  test = fscanf(file,"%d\n",&num);
287  pips_assert("fscanf - read number of entity",(test==1));
288  pips_debug(3,"reading %d new entity from module %s\n", num, module);
289 
290  for (i=0;i<num;i++)
291  {
292  ent_type = read_and_allocate_string_from_file(file);
293 
294  if (!strcmp(ent_type,"constant")) { /* constant */
295 
296  const_type = read_and_allocate_string_from_file(file);
297 
298  test = fscanf(file," %d\n", &const_size);
299  pips_assert("fscanf - read entity basic type size\n",(test==1));
300 
301  const_value = read_and_allocate_string_from_file(file);
302 
303  if (same_string_p(const_type,"int")) {/* int */
304 
305  /* create integer entity */
306  e = make_constant_entity(const_value, is_basic_int, const_size);
307  pips_assert("make integer constant entity", entity_consistent_p(e));
308  }
309  else if (same_string_p(const_type,"float")) {/* float */
310  /* create float entity */
311  e = make_constant_entity(const_value, is_basic_float, const_size);
312  pips_assert("make float constant entity", entity_consistent_p(e));
313  }
314  else if (same_string_p(const_type, "double")) { /* double */
315  e = make_constant_entity(const_value, is_basic_float, const_size);
316  pips_assert("make float constant entity", entity_consistent_p(e));
317  }
318  else
319  pips_internal_error("can't create this kind of constant entity: %s",
320  const_type);
321  free(const_type);
322  free(const_value);
323  }
324  else
325  pips_internal_error("can't create this kind of entity: %s", ent_type);
326 
327  free(ent_type);
328  }
329 }
330 
331 
332 /* import expressions from eole.
333  */
334 static list /* of expression */
335 read_from_eole(const char* module, const char* file_name)
336 {
337  FILE * fromeole;
338  reference astuce;
339  list result;
340 
341  pips_debug(3, "reading from eole for module %s\n", module);
342 
343  fromeole = safe_fopen(file_name, "r");
344 
345  /* read entities to create...
346  * should use some newgen type to do so (to share buffers...)
347  */
349 
350  astuce = read_reference(fromeole);
351  result = reference_indices(astuce);
352  reference_indices(astuce) = NIL;
353  free_reference(astuce);
354 
355  return result;
356 }
357 
358 /* swap term to term syntax field in expression list, as a side effect...
359  */
360 static void
361 swap_syntax_in_expression( list /* of expressionwithlevel */ lcode,
362  list /* of expression */ lnew)
363 {
364  pips_assert("equal length lists", gen_length(lcode)==gen_length(lnew));
365 
366  for(; lcode; lcode=CDR(lcode), lnew=CDR(lnew))
367  {
368  expression old, new;
369  syntax tmp;
370 
372  new = EXPRESSION(CAR(lnew));
373 
374  tmp = expression_syntax(old);
376  expression_syntax(new) = tmp;
377  }
378 }
379 
380 /* apply eole on all expressions in s.
381  */
382 static void
383 apply_eole_on_statement(const char* module_name, statement s, const char* flags)
384 {
385  list /* of expressionwithlevel/expression */ le, ln;
386 
387  ln = NIL;
388  le = get_list_of_rhs(s);
389 
390  if (gen_length(le)) /* not empty list */
391  {
392  string in, out, cmd;
393 
394  /* create temporary files */
397 
398  /* write informations in out file for EOLE */
400 
401  /* run eole (Evaluation Optimization for Loops and Expressions)
402  * as a separate process.
403  */
404  cmd = get_eole_command(in, out, flags);
405 
406  pips_debug(2, "executing: %s\n", cmd);
407 
408  safe_system(cmd);
409 
410  /* read optimized expressions from eole */
411  ln = read_from_eole(module_name, in);
412 
413  /* replace the syntax values inside le by the syntax values from ln */
415 
416  /* must now free the useless expressions */
417 
418 
419  /* remove temorary files and free allocated memory.
420  */
421  safe_unlink(out);
422  safe_unlink(in);
423 
424  /* free strings */
425  free(out), out = NULL;
426  free(in), in = NULL;
427  free(cmd), cmd = NULL;
428  }
429  else
430  pips_debug(3, "no expression for module %s\n", module_name);
431 
432  pips_debug(3,"EOLE transformations done for module %s\n", module_name);
433 
434  /* free lists */
435  gen_free_list(ln);
436  gen_free_list(le);
437 }
438 
439 
440 /************************************************************* SOME PATTERNS */
441 
442 /* A + (--B) -> A - B
443  * FMA -> FMS
444  */
445 static entity
446  bplus = NULL,
447  uminus = NULL,
448  bminus = NULL,
449  fmaop = NULL,
450  fmsop = NULL;
451 
452 /* returns B if uminus(B), else 0
453  */
455 {
456  syntax s = expression_syntax(e);
457  if (syntax_call_p(s))
458  {
459  call c = syntax_call(s);
460  if (call_function(c)==uminus && gen_length(call_arguments(c))==1)
461  return EXPRESSION(CAR(call_arguments(c)));
462  }
463  return NULL;
464 }
465 
466 static void call_simplify_rwt(call c)
467 {
468  if (call_function(c)==bplus)
469  {
470  list la = call_arguments(c);
471  expression e1, e2, me;
472 
473  pips_assert("2 args to binary plus", gen_length(la)==2);
474 
475  e1 = EXPRESSION(CAR(la));
476  e2 = EXPRESSION(CAR(CDR(la)));
477 
478  me = is_uminus(e2);
479  if (me)
480  {
481  EXPRESSION_(CAR(CDR(la))) = me; /* memory leak */
482  call_function(c) = bminus;
483  return;
484  }
485 
486  me = is_uminus(e1);
487  if (me)
488  {
489  EXPRESSION_(CAR(CDR(la))) = me;
490  EXPRESSION_(CAR(la)) = e2; /* memory leak */
491  call_function(c) = bminus;
492  return;
493  }
494  }
495  else if (call_function(c)==fmaop) /* FMA(A,B,-C) => FMS(A,B,C) */
496  {
497  list la = call_arguments(c);
498  expression e3 = EXPRESSION(CAR(CDR(CDR(la)))), me;
499 
500  me = is_uminus(e3);
501  if (me)
502  {
503  /* avoid memory leak */
506  free_expression(e3);
507 
508  call_function(c) = fmsop;
509  EXPRESSION_(CAR(CDR(CDR(la)))) = me;
510  }
511  }
512 }
513 
515 {
521 
523 
524  bplus = NULL;
525  uminus = NULL;
526  bminus = NULL;
527  fmaop = NULL;
528  fmsop = NULL;
529 }
530 
531 /* look for some expressions in s and simplify some patterns.
532  */
534 {
535  /* not implemented yet. */
536 
537  /* a + (-b) -> a - b */
538  /* (-b) + a -> a - b */
539  /* fma(a,b,-c) => fms(a,b,c) */
540  generate_bminus(s);
541 
542  /* a * (1/ b) -> a / b */
543  /* (1/ b) * a -> a / b */
544  /* a + (-b * c) -> a - (b * c) */
545 }
546 
547 
548 /************************************************************ N-ARY SIMPLIFY */
549 
550 static entity
551  multiply = NULL,
552  inverse = NULL,
553  divide = NULL;
554 
555 static bool is_inverse(expression e)
556 {
557  syntax s = expression_syntax(e);
558  if (!syntax_call_p(s)) return false;
559  return call_function(syntax_call(s)) == inverse;
560 }
561 
562 static void call_nary_rwt(call c)
563 {
564  entity func = call_function(c);
565  list numerator = NIL, denominator = NIL;
566  int nnum, nden;
567  expression enu, eden;
568 
569  if (func != multiply) return;
570  /* it is a multiply */
571 
572  MAP(EXPRESSION, e,
573  {
574  if (is_inverse(e))
575  denominator =
576  CONS(EXPRESSION,
578  denominator);
579  else
580  numerator = CONS(EXPRESSION, e, numerator);
581  },
582  call_arguments(c));
583 
584  nden = gen_length(denominator);
585  nnum = gen_length(numerator);
586 
587  switch (nden)
588  {
589  case 0: /* nothing to change */
590  gen_free_list(denominator);
591  gen_free_list(numerator);
592  return;
593  case 1:
594  eden = EXPRESSION(CAR(denominator));
595  gen_free_list(denominator);
596  break;
597  default:
598  eden = call_to_expression(make_call(multiply, denominator));
599  break;
600  }
601 
602  switch (nnum)
603  {
604  case 0:
605  enu = int_to_expression(1);
606  break;
607  case 1:
608  enu = EXPRESSION(CAR(numerator));
609  gen_free_list(numerator);
610  break;
611  default:
612  enu = call_to_expression(make_call(multiply, numerator));
613  break;
614  }
615 
616  call_function(c) = divide;
618  call_arguments(c) = CONS(EXPRESSION, enu, CONS(EXPRESSION, eden, NIL));
619 }
620 
622 {
623  /* N-ARY * and 1/ -> N-ARY* / N-ARY*
624  */
627  divide = entity_intrinsic("/");
628 
630 
631  multiply = NULL;
632  inverse = NULL;
633  divide = NULL;
634 }
635 
636 
637 /* forward substitute if only there once. not implemented.
638  */
639 
640 /*********************************************************** EXPRESSION COST */
641 
642 #if 0
643 /* computes the expression weight.
644  */
645 static double expression_weight(expression e)
646 {
647  double cost = 0.0E0;
648  syntax s = expression_syntax(e);
649  if (syntax_call_p(s))
650  {
651  list args = call_arguments(syntax_call(s));
652  cost = gen_length(args) - 1.0E0;
653  MAP(EXPRESSION, e, cost += expression_weight(e), args);
654  }
655  return cost;
656 }
657 
658 /* computes the expression depth.
659  */
660 static double expression_depth(expression e)
661 {
662  double cost = 0.0E0;
663  syntax s = expression_syntax(e);
664  if (syntax_call_p(s))
665  {
666  MAP(EXPRESSION, e,
667  { double w = expression_depth(e); cost = cost>w? cost: w; },
669  cost += 1.0E0;
670  /* too simple... may depend on the function called. complexity tables? */
671  }
672  return cost;
673 }
674 #endif
675 
676 /* WG */
677 static double expression_gravity_rc(expression e, double depth)
678 {
679  double cost = 0.0E0;
680  syntax s = expression_syntax(e);
681  if (syntax_call_p(s))
682  {
683  MAP(EXPRESSION, e,
684  cost += expression_gravity_rc(e, depth+1.0E0), /* ? */
686  cost += 1.0E0; /* too simple? */
687  }
688  return cost;
689 }
690 
692 {
693  return expression_gravity_rc(e, 0.0E0);
694 }
695 
697 {
698  return -expression_gravity(e);
699 }
700 
701 /************************************************************* NARY-FICATION */
702 /* switch binary to nary expressions where possible.
703  this is normally done in eole anyway.
704 */
705 
706 typedef enum
707 {
708  not_asocom, /* 0 */
712 }
714 
715 typedef struct
716 {
717  char * binary;
718  char * nary;
719 }
721 
722 #define MAX_NAME "MAX"
723 #define MIN_NAME "MIN"
724 
726 {
727  { "+", EOLE_SUM_OPERATOR_NAME },
728  { "*", EOLE_PROD_OPERATOR_NAME },
729 
730  { "MAX", MAX_NAME },
731  { "MIN", MIN_NAME },
732 
733  { "MAX0", MAX_NAME },
734  { "DMAX1", MAX_NAME },
735  { "AMAX1", MAX_NAME },
736  { "AMAX0", MAX_NAME },
737 
738  { "MIN0", MIN_NAME },
739  { "DMIN1", MIN_NAME },
740  { "AMIN1", MIN_NAME },
741  { "AMIN0", MIN_NAME },
742 
743  /* ??? .AND. .OR.
744  */
745  { NULL, NULL }
746 };
747 
749 {
750  const char* lname = entity_local_name(e);
751  binary_to_nary_t * pbn;
752 
753  for (pbn = bton; pbn->binary; pbn++)
754  if (same_string_p(pbn->binary, lname))
755  return entity_intrinsic(pbn->nary);
756 
757  return e;
758 }
759 
760 static bool nary_operator_p(entity e)
761 {
762  binary_to_nary_t * pbn;
763  const char* lname = entity_local_name(e);
764 
765  for (pbn = bton; pbn->nary; pbn++)
766  if (same_string_p(pbn->nary, lname))
767  return true;
768 
769  return false;
770 }
771 
772 /* top-down: switch calls to nary form.
773  */
774 static bool nary_call_flt(call c)
775 {
777  return true;
778 }
779 
780 /* bottom-up: + + -> +
781  */
782 static void nary_call_rwt(call c)
783 {
784  entity called = call_function(c);
785  list newl = NIL, oldl = call_arguments(c);
786 
787  if (nary_operator_p(called))
788  {
789  MAP(EXPRESSION, e,
790  {
791  syntax s = expression_syntax(e);
792  if (syntax_call_p(s) && call_function(syntax_call(s))==called)
793  {
794  newl = gen_nconc(newl, call_arguments(syntax_call(s)));
796  free_expression(e);
797  }
798  else
799  {
800  newl = gen_nconc(newl, CONS(EXPRESSION, e, NIL));
801  }
802  },
803  oldl);
804  }
805 
806  call_arguments(c) = newl;
807  gen_free_list(oldl);
808 }
809 
811 {
813 }
814 
815 /*
816  top down...
817 
818  - -> + --
819  / -> * 1/ [not on integers]
820  -- + -> + -- --
821  1/ * -> * 1/ 1/
822 */
823 
824 typedef struct
825 {
826  string asym;
827  string syme;
828  string inv;
829  bool not_ints;
831 
833 { { "-", "+", "--", false },
834  { "/", "*", INVERSE_OPERATOR_NAME, true },
835  { NULL, NULL, NULL, false }
836 };
837 
838 static symetric_opertor_t * what_operator(entity e, int which_one)
839 {
840  const char* lname = entity_local_name(e);
841  symetric_opertor_t * sot;
842  for (sot = symop; sot->asym; sot++)
843  {
844  if ((which_one==1 && same_string_p(lname, sot->asym)) ||
845  (which_one==0 && same_string_p(lname, sot->inv)) ||
846  (which_one==2 && same_string_p(lname, sot->syme)))
847  return sot;
848  }
849  return NULL;
850 }
851 
853 {
854  symetric_opertor_t * sot = what_operator(e, 2);
855  if (sot) return entity_intrinsic(sot->inv);
856  else return NULL;
857 }
858 
859 static bool inv_call_flt(call c)
860 {
861  entity op = call_function(c);
862  symetric_opertor_t * so;
863 
864  /* switch asymetric operation if needed */
865  so = what_operator(op, true);
866  if (so)
867  {
868  bool doit = true;
869 
870  if (so->not_ints)
871  {
872  /* should use the type_checker results...
873  * maybe it could be implemented also as an analyses
874  * and not only a transformation? Well, I don't know
875  * how to store expression to type data, as expressions
876  * cannot be shared and are not "named" as statements are. FC.
877  */
879  basic b = basic_of_expression(tmp);
880  if (basic_int_p(b)) doit = false;
882  free_expression(tmp);
883  }
884 
885  if (doit) /* we have to substitute. */
886  {
887  list largs = call_arguments(c);
888  expression second;
889  pips_assert("binary call", gen_length(largs)==2);
890  second = EXPRESSION(CAR(CDR(largs)));
891 
893  expression_syntax(second) =
896  CONS(EXPRESSION,
899  NIL)));
900  }
901  }
902 
903  /* push down inverse operators if needed. */
904  so = what_operator(op, false);
905  if (so)
906  {
907  list largs = call_arguments(c);
908  syntax s;
909  pips_assert("one arg to inverse op", gen_length(largs)==1);
910  s = expression_syntax(EXPRESSION(CAR(largs)));
911  if (syntax_call_p(s))
912  {
913  call called = syntax_call(s);
914  if (same_string_p(so->syme,
916  {
917  /* memory leak... */
918  entity invop = call_function(c);
919  call_function(c) = call_function(called);
920  call_arguments(c) = call_arguments(called);
921  /* now insert invop */
922  MAP(EXPRESSION, e,
923  {
924  expression_syntax(e) =
926  make_call(invop,
927  CONS(EXPRESSION,
930  NIL)));
931  },
932  call_arguments(called));
933  }
934  }
935  }
936 
937  return true;
938 }
939 
941 {
943 }
944 
945 /**************************************** HUFFMAN ALGORITHM ON AN EXPRESSION */
946 
947 /* switch nary to binary with huffman algorithm.
948  */
951 static double (*huffman_cost)(expression) = NULL;
952 /* true: Huffman.
953  false: rateau.
954 */
955 static bool huffman_mode = true;
956 
957 typedef struct
958 {
960  double cost;
962 
963 /* comparison function for qsort. descending order.
964  */
965 static int cost_expression_cmp(const void * v1, const void * v2)
966 {
967  cost_expression * c1 = (cost_expression *) v1;
968  cost_expression * c2 = (cost_expression *) v2;
969  if (c1->cost==c2->cost)
970  /* when they are equals another criterion may be used, so as
971  to favor double loads (with neighbor references).
972  */
973  return 0;
974  return 2*(c1->cost<c2->cost) - 1;
975 }
976 
977 /* debug function */
978 /* print informations from an cost_expressions array */
979 static void
981  cost_expression * tce,
982  int size)
983 {
984  int i;
985  pips_debug(9,"%s \n", s);
986  pips_debug(9," %d elements in cost_expression array \n", size);
987 
988  for (i=0; i<size; i++) {
989  pips_debug(9," - %d - expression : ", i);
990  print_expression(tce[i].expr);
991  pips_debug(9,"\n - %d - cost : %f \n", i, tce[i].cost);
992  }
993 }
994 
995 /* build an cost_expression array from an expression list.
996  */
997 static cost_expression *
999  list /* of expression */ le,
1000  double (*cost)(expression))
1001 {
1002  int len = gen_length(le), i=0;
1003  cost_expression * tce = malloc(len * sizeof(cost_expression));
1004  pips_assert("enough memory", tce!=NULL);
1005 
1006  MAP(EXPRESSION, e,
1007  {
1008  tce[i].expr = e;
1009  tce[i].cost = cost(e);
1010  i++;
1011  },
1012  le);
1013 
1014  qsort(tce, len, sizeof(cost_expression), cost_expression_cmp);
1015 
1016  ifdebug(3) debug_cost_expression_array("qsort output", tce, len);
1017 
1018  return tce;
1019 }
1020 
1021 /* insert ce in tce[0..n-1] by decreassing order.
1022  */
1023 static void
1025 {
1026  int i=0;
1027  while (i<n && ce.cost<tce[i].cost) i++; /* find where to insert. */
1028  while (n>=i) tce[n]=tce[n-1], n--; /* shift tail. */
1029  tce[i] = ce; /* insert. */
1030 }
1031 
1032 /* simply insert.
1033  */
1034 static void
1036 {
1037  tce[n] = ce;
1038 }
1039 
1040 /* apply huffman balancing algorithm if it is a call to
1041  * huffman_nary_operator.
1042  *
1043  * the prettyprint may only reflect this if the
1044  * PRETTYPRINT_ALL_PARENTHESES property is set to true.
1045  */
1046 static void call_rwt(call c)
1047 {
1049  {
1050  /* let us switch to a binary tree. */
1051  list args = call_arguments(c);
1052  int nargs = gen_length(args);
1053  cost_expression * tce;
1054 
1055  pips_debug(4, "dealing with operator %s\n",
1057 
1058  //pips_assert("several arguments to nary operator", nargs>=2);
1059  if (nargs < 2)
1060  {
1061  fprintf(stderr,"\n[call_rwt] --- (nargs=%d) < 2; Call = %s \n",
1062  nargs, entity_name(call_function(c)));
1064  return;
1065  }
1066 
1067  if (nargs==2) /* the call is already binary. */
1068  {
1070  return;
1071  }
1072  /* else */
1073 
1075  /* drop initial list: */
1076  gen_free_list(args), args = NIL, call_arguments(c) = NIL;
1077 
1078  while (nargs>2)
1079  {
1080  cost_expression ce;
1082  tce[nargs-1].expr, tce[nargs-2].expr);
1083  ce.cost = huffman_cost(ce.expr);
1084 
1085  if (huffman_mode) insert_sorted_into_array(tce, nargs-2, ce);
1086  else insert_last_into_array(tce, nargs-2, ce);
1087 
1088  ifdebug(3) debug_cost_expression_array("insert done", tce, nargs-1);
1089 
1090  nargs--;
1091  }
1092 
1093  /* last one is done in place. */
1095  call_arguments(c) = CONS(EXPRESSION, tce[0].expr,
1096  CONS(EXPRESSION, tce[1].expr, NIL));
1097  free(tce), tce = NULL;
1098  }
1099  else
1100  pips_debug(3,"non huffman operator : %s\n ",
1102 }
1103 
1104 /* apply the huffman balancing on every call to nary_operator
1105  * and build calls to binary_operator instead, with cost to chose.
1106  */
1107 static void
1109  statement s,
1110  entity nary_operator,
1111  entity binary_operator,
1112  double (*cost)(expression),
1113  bool mode)
1114 {
1115  huffman_nary_operator = nary_operator;
1116  huffman_binary_operator = binary_operator;
1117  huffman_cost = cost;
1118  huffman_mode = mode;
1119 
1120  ifdebug(8) print_statement(s);
1121 
1124  NULL);
1125 
1126  huffman_nary_operator = NULL;
1127  huffman_binary_operator = NULL;
1128  huffman_cost = NULL;
1129  huffman_mode = true;
1130 }
1131 
1132 /* switch nary operators to binary ones.
1133  * n+ -> +, n* -> *
1134  * missing: & | and so on.
1135  */
1136 static void
1138 {
1139  entity
1144 
1145  /* options: another expression cost function could be used.
1146  * for instance, defining -expression_gravity would build
1147  * the most unbalanced possible expression tree wrt WG.
1148  */
1150  (s, nplus, plus, strategy->huffman_cost, strategy->huffman_mode);
1152  (s, nmult, mult, strategy->huffman_cost, strategy->huffman_mode);
1153 }
1154 
1155 /***************************************************** PREDEFINED STRATEGIES */
1156 
1157 /* predefined optimization strategies.
1158  */
1159 static optimization_strategy
1161 {
1162  {
1163  /* name */ "P2SC",
1164  /* huff */ true, expression_gravity, true,
1165  /* eole */ "0", true, "", true, "-m",
1166  /* simp */ true, true,
1167  /* gcm */ true,
1168  /* cse */ false
1169  },
1170  {
1171  /* name */ "IA-64",
1172  /* huff */ true, expression_gravity, true,
1173  /* eole */ "0", true, "", true, "-m",
1174  /* simp */ true, true,
1175  /* gcm */ true,
1176  /* cse */ false
1177  },
1178  {
1179  /* name */ "R10K",
1180  /* huff */ true, expression_gravity_inv, false,
1181  /* eole */ "1", true, "", true, "-m",
1182  /* simp */ true, true,
1183  /* gcm */ true,
1184  /* cse */ false
1185  },
1186  { /* EOLE and Huffman and Simplify with gravity - most balanced tree*/
1187  /* WITHOUT FMA EXTRACTION */
1188  /* name */ "ultraIIi",
1189  /* huff */ true, expression_gravity, true,
1190  /* eole */ "0", true, "", false, "",
1191  /* simp */ true, true,
1192  /* gcm */ false,
1193  /* cse */ false
1194  },
1195  { /* whatever you want */
1196  /* name */ "test",
1197  /* huff */ true, expression_gravity, true,
1198  /* eole */ "0", true, "", true, "-m",
1199  /* simp */ true, true,
1200  /* gcm */ false,
1201  /* cse */ true
1202  },
1203  { /* whatever you want */
1204  /* name */ "test_icm",
1205  /* huff */ true, expression_gravity, true,
1206  /* eole */ "0", true, "", true, "-m",
1207  /* simp */ true, true,
1208  /* gcm */ true,
1209  /* cse */ false
1210  },
1211  { /* whatever you want */
1212  /* name */ "test_cse",
1213  /* huff */ true, expression_gravity, true,
1214  /* eole */ "0", true, "", true, "-m",
1215  /* simp */ true, true,
1216  /* gcm */ false,
1217  /* cse */ true
1218  },
1219  { /* EOLE with gravity criterion only - most balanced tree ! */
1220  /* name */ "EOLE",
1221  /* huff */ false, NULL, false,
1222  /* eole */ "0", true, "", true, "-m",
1223  /* simp */ false, false,
1224  /* gcm */ false,
1225  /* cse */ false
1226  },
1227  { /* EOLE and Huffman and Simplify with gravity - most balanced tree */
1228  /* name */ "GRAVITY",
1229  /* huff */ true, expression_gravity, true,
1230  /* eole */ "0", true, "", true, "-m",
1231  /* simp */ true, true,
1232  /* gcm */ false,
1233  /* cse */ false
1234  },
1235  { /* EOLE and Huffman and Simplify - most UNbalanced tree */
1236  /* name */ "UNBALANCED",
1237  /* huff */ true, expression_gravity_inv, false,
1238  /* eole */ "1", true, "", true, "-m",
1239  /* simp */ true, true,
1240  /* gcm */ false,
1241  /* cse */ false
1242  },
1243  { /* ICM only */
1244  /* name */ "ICM",
1245  /* huff */ false, NULL, false,
1246  /* eole */ "0", false, "", false, "",
1247  /* simp */ false, false,
1248  /* gcm */ true,
1249  /* cse */ false
1250  },
1251  { /* CSE only*/
1252  /* name */ "CSE",
1253  /* huff */ false, NULL, false,
1254  /* eole */ "0", false, "", false, "",
1255  /* simp */ false, false,
1256  /* gcm */ false,
1257  /* cse */ true
1258  },
1259  { /* both ICM and CSE */
1260  /* name */ "ICMCSE",
1261  /* huff */ false, NULL, false,
1262  /* eole */ "0", false, "", false, "",
1263  /* simp */ false, false,
1264  /* gcm */ true,
1265  /* cse */ true
1266  },
1267  { /* Everything must be done */
1268  /* name */ "FULL",
1269  /* huff */ true, expression_gravity, true,
1270  /* eole */ "0", true, "", true, "-m",
1271  /* simp */ true, true,
1272  /* gcm */ true,
1273  /* cse */ true
1274  },
1275  /* this one MUST be the last one! */
1276  {
1277  /* name */ NULL, /* default similar to P2SC. */
1278  /* huff */ true, expression_gravity, true,
1279  /* eole */ "0", true, "", true, "-m",
1280  /* simp */ true, true,
1281  /* gcm */ true,
1282  /* cse */ true
1283  }
1284 };
1285 
1287 {
1288  const char* name = get_string_property("EOLE_OPTIMIZATION_STRATEGY");
1289  for (strategy = strategies; strategy->name!=NULL; strategy++)
1290  {
1291  if (same_string_p(name, strategy->name))
1292  return;
1293  }
1294  pips_user_warning("'%s' strategy not found, default assumed.\n", name);
1295 }
1296 
1298 {
1299  strategy = NULL;
1300 }
1301 
1302 
1303 /************************************************** DAVINCI DUMP EXPRESSIONS
1304 
1305 This seems to be largely redundant with some functions in
1306 ri-utils/expression.c such as davinci_dump_expression()
1307 */
1308 
1309 #define GRAPH_PREFIX "optimize_expressions_"
1310 #define GRAPH_SUFFIX ".daVinci"
1311 
1312 /* dump all expressions in s as davinci graphs.
1313  */
1315  const char* module_name, string phase, statement s)
1316 {
1317  string dir, filename;
1318  FILE * out;
1319 
1320  /* filename: $current.database/$module/$prefix_$phase.$suffix
1321  */
1323  filename = strdup(concatenate
1324  (dir, "/", module_name, "/", GRAPH_PREFIX, phase, GRAPH_SUFFIX, NULL));
1325  free(dir), dir = NULL;
1326 
1327  out = safe_fopen(filename, "w"); /* directory MUST exist */
1329  safe_fclose(out, filename);
1330 
1331  free(filename), filename = NULL;
1332 }
1333 
1334 
1335 static
1337  entity op = call_function(c);
1338  if(ENTITY_PLUS_P(op))
1340  if(ENTITY_MINUS_P(op))
1342 }
1343 void convert_to_c_operators(void * v) {
1345 }
1346 
1347 static
1349  entity op = call_function(c);
1350  if(ENTITY_PLUS_C_P(op) || ENTITY_MINUS_C_P(op) ) {
1353  if(!basic_pointer_p(b0) && !basic_pointer_p(b1)) {
1354  if(ENTITY_PLUS_C_P(op))
1356  if(ENTITY_MINUS_C_P(op))
1358  }
1359  free_basic(b0);
1360  free_basic(b1);
1361  }
1362 }
1363 
1366 }
1367 
1368 
1369 
1370 /* pipsmake interface to apply expression optimization according to
1371  various strategy.
1372 
1373  The strategy to use is specified with the EOLE_OPTIMIZATION_STRATEGY
1374  property. The strategies themselves are defined into the strategies[]
1375  array.
1376 
1377  In general, strategies involve an external optimization tool that is
1378  not provided with PIPS, so they cannot be used...
1379 
1380  At least the CSE, ICM and ICMCSE work without this tool and can be
1381  safely used. See the common_subexpression_elimination and icm phase to
1382  have a direct access to these 2 common working case. Well, it is not
1383  clear that ICMCSE would work since it would need to refresh the
1384  effects, which is not done. So the safe way is to use separately these
1385  2 phases.
1386 
1387  @param[in] module_name
1388 
1389  @return true since it is supposed to always work
1390 */
1392 {
1393  statement s;
1394 
1396 
1397  /* get needed stuff.
1398  */
1401  db_get_memory_resource(DBR_CODE, module_name, true));
1403 
1404 
1407 
1408  /* check consistency before optimizations */
1409  pips_assert("consistency checking before optimizations",
1411 
1412  ifdebug(1) davinci_dump_expressions(module_name, "initial", s);
1413 
1414  /* do something here.
1415  */
1416 
1417  /* Could perform more optimizations here...
1418  */
1419 
1420  /* EOLE Stuff
1421  */
1422 
1423  if (strategy->apply_eole1)
1425 
1426  /* Could perform more optimizations here...
1427  */
1428  /* CSE/ICM + atom
1429  */
1430 
1431  if (strategy->apply_gcm)
1433 
1434  if (strategy->apply_cse)
1436 
1437  /* EOLE Stuff, second pass for FMA.
1438  */
1439  if (strategy->apply_eole2)
1441 
1444 
1447 
1448  if (strategy->apply_simplify)
1450 
1451  /* others?
1452  */
1453 
1454  /* check consistency after optimizations */
1456  clean_up_sequences(s);
1459  pips_assert("consistency checking after optimizations",
1461 
1463 
1464  module_reorder(s);
1465 
1466  /* return result to pipsdbm
1467  */
1468  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module_name, s);
1469 
1473 
1474  debug_off();
1475 
1476  return true; /* okay ! */
1477 }
expressionwithlevel make_expressionwithlevel(list a1, expression a2)
Definition: eole_private.c:94
void free_lexpressionwithlevel(lexpressionwithlevel p)
Definition: eole_private.c:145
lexpressionwithlevel make_lexpressionwithlevel(list a)
Definition: eole_private.c:178
void write_lexpressionwithlevel(FILE *f, lexpressionwithlevel p)
Definition: eole_private.c:172
call make_call(entity a1, list a2)
Definition: ri.c:269
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
void free_reference(reference p)
Definition: ri.c:2050
bool statement_consistent_p(statement p)
Definition: ri.c:2195
reference read_reference(FILE *f)
Definition: ri.c:2080
void free_expression(expression p)
Definition: ri.c:853
void write_tabulated_entity(FILE *f)
Definition: ri.c:2554
syntax make_syntax(enum syntax_utype tag, void *val)
Definition: ri.c:2491
void free_basic(basic p)
Definition: ri.c:107
bool entity_consistent_p(entity p)
Definition: ri.c:2530
static FILE * out
Definition: alias_check.c:128
struct _newgen_struct_expression_ * expression
Definition: alias_private.h:21
static int num
Definition: bourdoncle.c:137
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
entity make_constant_entity(string name, tag bt, size_t size)
For historical reason, call the Fortran version.
Definition: constant.c:301
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#define EXPRESSIONWITHLEVEL(x)
EXPRESSIONWITHLEVEL.
Definition: eole_private.h:105
#define expressionwithlevel_expression(x)
Definition: eole_private.h:137
#define lexpressionwithlevel_list(x)
Definition: eole_private.h:205
void perform_icm_association(const char *, statement)
sequence_gcm_cse.c
void perform_ac_cse(const char *, statement)
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
char * get_string_property(const char *)
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
char * safe_new_tmp_file(char *prefix)
SunOS forgets to declare this one.
Definition: file.c:935
void safe_unlink(const char *file_name)
Delete the given file.
Definition: file.c:852
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void * malloc(YYSIZE_T)
void free(void *)
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
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
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
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#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
#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 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
#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 pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
void safe_system(string)
system.c
Definition: system.c:38
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
static void eole_okay_call_rwt(call c, bool *okay)
Definition: optimize.c:139
static void optimize_simplify_nary_patterns(statement s)
Definition: optimize.c:621
static void write_list_of_rhs(FILE *out, list le)
export a list of expression of the current module.
Definition: optimize.c:231
static void loop_rwt(loop l, extract_expr_p context)
Definition: optimize.c:180
static entity divide
Definition: optimize.c:553
static entity binary_to_nary(entity e)
Definition: optimize.c:748
static void build_binary_operators_with_huffman(statement s, entity nary_operator, entity binary_operator, double(*cost)(expression), bool mode)
apply the huffman balancing on every call to nary_operator and build calls to binary_operator instead...
Definition: optimize.c:1108
static entity inverse
Definition: optimize.c:552
static void call_simplify_rwt(call c)
Definition: optimize.c:466
#define GRAPH_SUFFIX
Definition: optimize.c:1310
static void nary_call_rwt(call c)
bottom-up: + + -> +
Definition: optimize.c:782
static bool nary_call_flt(call c)
top-down: switch calls to nary form.
Definition: optimize.c:774
struct optimization_strategy * poptimization_strategy
#define SIZE_OF_BUFFER
Definition: optimize.c:256
static entity huffman_binary_operator
Definition: optimize.c:950
static string read_and_allocate_string_from_file(FILE *file)
Definition: optimize.c:259
static void optimize_simplify_patterns(statement s)
look for some expressions in s and simplify some patterns.
Definition: optimize.c:533
bool optimize_expressions(const char *module_name)
pipsmake interface to apply expression optimization according to various strategy.
Definition: optimize.c:1391
static void switch_nary_to_binary(statement s)
switch nary operators to binary ones.
Definition: optimize.c:1137
static void insert_last_into_array(cost_expression *tce, int n, cost_expression ce)
simply insert.
Definition: optimize.c:1035
#define EOLE_OPTIONS
Definition: optimize.c:108
static void write_to_eole(const char *module, list le, const char *file_name)
export expressions to eole thru the newgen format.
Definition: optimize.c:243
static bool expr_filter(expression e, extract_expr_p context)
other expressions may be found in loops and so?
Definition: optimize.c:202
static entity uminus
Definition: optimize.c:447
static void do_convert_to_standard_operators(call c)
Definition: optimize.c:1348
static double expression_gravity_rc(expression e, double depth)
forward substitute if only there once.
Definition: optimize.c:677
void convert_to_standard_operators(void *v)
Definition: optimize.c:1364
static void call_nary_rwt(call c)
Definition: optimize.c:562
static symetric_opertor_t * what_operator(entity e, int which_one)
Definition: optimize.c:838
static void reset_current_optimization_strategy(void)
Definition: optimize.c:1297
static bool call_filter(call c, extract_expr_p context)
rhs expressions of assignments.
Definition: optimize.c:191
static symetric_opertor_t symop[]
Definition: optimize.c:832
static entity huffman_nary_operator
switch nary to binary with huffman algorithm.
Definition: optimize.c:949
static double(* huffman_cost)(expression)
Definition: optimize.c:951
#define OUT_FILE_NAME
file name prefixes to deal with eole.
Definition: optimize.c:101
static list read_from_eole(const char *module, const char *file_name)
import expressions from eole.
Definition: optimize.c:335
static poptimization_strategy strategy
current strategy.
Definition: optimize.c:94
#define IN_FILE_NAME
Definition: optimize.c:102
#define MIN_NAME
Definition: optimize.c:723
static list get_list_of_rhs(statement s)
of expressionwithlevel
Definition: optimize.c:210
static entity fmaop
Definition: optimize.c:449
static entity fmsop
Definition: optimize.c:450
void naryfication_of_expressions(statement s)
optimize.c
Definition: optimize.c:810
static int cost_expression_cmp(const void *v1, const void *v2)
comparison function for qsort.
Definition: optimize.c:965
static optimization_strategy strategies[]
predefined optimization strategies.
Definition: optimize.c:1160
static void insert_sorted_into_array(cost_expression *tce, int n, cost_expression ce)
insert ce in tce[0..n-1] by decreassing order.
Definition: optimize.c:1024
#define EOLE_FLAGS
Definition: optimize.c:107
static bool loop_flt(loop l, extract_expr_p context)
Definition: optimize.c:173
static void debug_cost_expression_array(string s, cost_expression *tce, int size)
debug function
Definition: optimize.c:980
#define EOLE
property names.
Definition: optimize.c:106
static double expression_gravity_inv(expression e)
Definition: optimize.c:696
static void generate_bminus(statement s)
Definition: optimize.c:514
static string get_eole_command(const char *in, const char *out, const char *flags)
returns the eole command to be executed in an allocated string.
Definition: optimize.c:114
#define GRAPH_PREFIX
Definition: optimize.c:1309
static void read_new_entities_from_eole(FILE *file, const char *module)
import a list of entity that have been created during the eole transformations and create them
Definition: optimize.c:275
static void apply_eole_on_statement(const char *module_name, statement s, const char *flags)
apply eole on all expressions in s.
Definition: optimize.c:383
static expression is_uminus(expression e)
returns B if uminus(B), else 0
Definition: optimize.c:454
static void call_rwt(call c)
apply huffman balancing algorithm if it is a call to huffman_nary_operator.
Definition: optimize.c:1046
void convert_to_c_operators(void *v)
Definition: optimize.c:1343
static bool nary_operator_p(entity e)
Definition: optimize.c:760
static binary_to_nary_t bton[]
Definition: optimize.c:725
asocom_operator_t
switch binary to nary expressions where possible.
Definition: optimize.c:707
@ is_mult
Definition: optimize.c:709
@ is_plus
0
Definition: optimize.c:709
@ is_max
Definition: optimize.c:710
@ is_min
Definition: optimize.c:710
@ is_and
Definition: optimize.c:711
@ not_asocom
Definition: optimize.c:708
@ is_or
Definition: optimize.c:711
entity inverse_operator_of(entity e)
Definition: optimize.c:852
#define DEBUG_NAME
Definition: optimize.c:50
#define MAX_NAME
Definition: optimize.c:722
static void do_convert_to_c_operator(call c)
Definition: optimize.c:1336
static void swap_syntax_in_expression(list lcode, list lnew)
swap term to term syntax field in expression list, as a side effect...
Definition: optimize.c:361
static double expression_gravity(expression e)
Definition: optimize.c:691
static void davinci_dump_expressions(const char *module_name, string phase, statement s)
dump all expressions in s as davinci graphs.
Definition: optimize.c:1314
struct extract_expr_t * extract_expr_p
static cost_expression * list_of_expressions_to_array(list le, double(*cost)(expression))
build an cost_expression array from an expression list.
Definition: optimize.c:998
static entity multiply
Definition: optimize.c:551
static entity bplus
A + (–B) -> A - B FMA -> FMS.
Definition: optimize.c:446
static bool is_inverse(expression e)
Definition: optimize.c:555
static void set_current_optimization_strategy(void)
Definition: optimize.c:1286
static entity bminus
Definition: optimize.c:448
static void add_one_more_expression(expression e, extract_expr_p context)
Definition: optimize.c:166
static bool huffman_mode
true: Huffman.
Definition: optimize.c:955
static bool inv_call_flt(call c)
Definition: optimize.c:859
static bool is_string_constant(entity e)
Definition: optimize.c:127
static bool eole_manageable_expression(expression e)
Definition: optimize.c:147
void inverse_normalization_of_expressions(statement s)
Definition: optimize.c:940
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
static char * module
Definition: pips.c:74
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
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 print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define binary_call_rhs(c)
#define EOLE_FMA_OPERATOR_NAME
These operators are used within the optimize transformation in order to manipulate operators such as ...
#define MINUS_OPERATOR_NAME
#define ENTITY_MINUS_P(e)
#define PLUS_OPERATOR_NAME
#define ENTITY_PLUS_P(e)
#define INVERSE_OPERATOR_NAME
#define ENTITY_PLUS_C_P(e)
#define EOLE_FMS_OPERATOR_NAME
#define ENTITY_MINUS_C_P(e)
#define UNARY_MINUS_OPERATOR_NAME
#define binary_call_lhs(c)
#define EOLE_PROD_OPERATOR_NAME
#define EOLE_SUM_OPERATOR_NAME
#define MINUS_C_OPERATOR_NAME
#define MULTIPLY_OPERATOR_NAME
#define PLUS_C_OPERATOR_NAME
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
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
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
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
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
void simplify_expressions(void *obj)
Definition: expression.c:3801
void davinci_dump_all_expressions(FILE *out, statement s)
dump all expressions in s to out.
Definition: expression.c:2728
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
#define type_functional_p(x)
Definition: ri.h:2950
struct _newgen_struct_test_ * test
Definition: ri.h:423
@ is_basic_float
Definition: ri.h:572
@ is_basic_int
Definition: ri.h:571
#define normalized_undefined
Definition: ri.h:1745
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define basic_int_p(x)
Definition: ri.h:614
#define call_function(x)
Definition: ri.h:709
#define EXPRESSION_(x)
Definition: ri.h:1220
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
#define basic_pointer_p(x)
Definition: ri.h:635
@ is_syntax_call
Definition: ri.h:2693
#define value_constant_p(x)
Definition: ri.h:3071
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define basic_undefined_p(x)
Definition: ri.h:557
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_name(x)
Definition: ri.h:2790
struct _newgen_struct_mode_ * mode
Definition: ri.h:231
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_call(x)
Definition: ri.h:2736
#define call_arguments(x)
Definition: ri.h:711
#define basic_string_p(x)
Definition: ri.h:629
#define entity_type(x)
Definition: ri.h:2792
#define call_undefined
Definition: ri.h:685
#define expression_syntax(x)
Definition: ri.h:1247
#define loop_index(x)
Definition: ri.h:1640
#define entity_initial(x)
Definition: ri.h:2796
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
static int lname(char *s, int look_for_entry)
check for keywords for subprograms return 0 if comment card, 1 if found name and put in arg string.
Definition: split_file.c:283
static string buffer
Definition: string.c:113
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: delay.c:253
expression expr
Definition: optimize.c:959
extract expressions with loop level information.
Definition: optimize.c:161
list rhs
expressionwithlevel
Definition: optimize.c:162
list indices
the list of RHS expressions.
Definition: optimize.c:163
this structure defines a strategy for eole.
Definition: optimize.c:57
double(* huffman_cost)(expression)
Definition: optimize.c:64
string eole_strategy
EOLE.
Definition: optimize.c:69
bool apply_nary_simplify
SIMPLIFY.
Definition: optimize.c:79
string apply_eole2_flags
Definition: optimize.c:75
bool apply_gcm
GCM CSE.
Definition: optimize.c:84
bool apply_eole2
not used yet
Definition: optimize.c:74
bool apply_balancing
HUFFMAN.
Definition: optimize.c:63
string apply_eole1_flags
Definition: optimize.c:72
string name
NAME of the strategy.
Definition: optimize.c:59
bool apply_cse
CSE.
Definition: optimize.c:88
static int depth
la sequence de nids
static string file_name