PIPS
array_to_pointer.c
Go to the documentation of this file.
1 /*
2  Copyright 1989-2016 MINES ParisTech
3 
4  This file is part of PIPS.
5 
6  PIPS is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  any later version.
10 
11  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
12  WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE.
14 
15  See the GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
19 
20 */
21 
22 /**
23  * @file linearize_array.c
24  * transform arrays to low-level pointers or 1D arrays
25  * @author Serge Guelton <serge.guelton@enst-bretagne.fr>
26  * @date 2009-07-01
27  */
28 #ifdef HAVE_CONFIG_H
29 #include "pips_config.h"
30 #endif
31 #include <ctype.h>
32 
33 #include "genC.h"
34 #include "ri-util.h"
35 #include "effects.h"
36 #include "pipsdbm.h"
37 #include "workspace-util.h"
38 #include "pipsmake.h" // ??? compilation_unit_of_module
39 #include "properties.h"
40 #include "callgraph.h"
41 #include "misc.h"
42 #include "control.h" // module_reorder
43 #include "expressions.h" // cleanup_subscripts
44 #include "preprocessor.h" // AddEntityToModuleCompilationUnit
45 
46 #include "accel-util.h"
47 
48 typedef struct {
49  /**
50  * This bool is controlled by the "LINEARIZE_ARRAY_CAST_AT_CALL_SITE"
51  * property Turning it on break further effects analysis, but without
52  * the cast it might
53  * break compilation or at least generate warnings for type mismatch
54  */
56  /**
57  * This bool is controlled by the "LINEARIZE_ARRAY_USE_POINTERS" property
58  */
60  /**
61  * This bool is controlled by the "LINEARIZE_ARRAY_MODIFY_CALL_SITE"
62  * property
63  */
65 } param_t;
66 
67 
69  if(get_bool_property("LINEARIZE_ARRAY_USE_POINTERS")) {
70  if(get_bool_property("LINEARIZE_ARRAY_SKIP_STATIC_LENGTH_ARRAYS") && !entity_variable_length_array_p(e))
71  return false;
72  value v =entity_initial(e);
74  return true;
75  if( get_bool_property("LINEARIZE_ARRAY_SKIP_LOCAL_ARRAYS") && !entity_formal_p(e) )
76  return false;
77  return true;
78  }
79  return false;
80 }
81 
82 
83 /* @return the number of dimensions in @param t,
84  * counting pointers as a dimension
85  *
86  * BEWARE: does not take structs and unions into account
87  *
88  * */
90  t = ultimate_type(t);
91  if(type_variable_p(t)) {
92  ifdebug(8) {
93  pips_debug(8,"Type is : ");
94  print_type(t);
95  }
96  variable v = type_variable(t);
97  basic b = variable_basic(v);
100  }
101  return 0;
102 }
103 
104 
105 
106 
109  if(entity_variable_p(e)) {
111  list to_be_free = indices;
112  bool fortran_p = fortran_module_p(get_current_module_entity());
113  if (fortran_p) {
115  }
116  if(!ENDP(indices)) {
117  type et = ultimate_type(entity_type(e));
118  list new_indices = NIL;
119  while(!ENDP(indices)) {
120  expression new_index = expression_undefined;
121  variable v = type_variable(et);
122  /* must first check the dimensions , then the pointer type */
123  list vdims = variable_dimensions(v);
124  /* one dimension variable, nothing to do */
125  if(ENDP(vdims)||ENDP(CDR(vdims))) {
126  }
127  else {
128  /* merge all */
129  new_index=int_to_expression(0);/* better start with this than nothing */
130  while(!ENDP(vdims) && !ENDP(indices) ) {
132  if (fortran_p) {
133  // in fortran we have to take care of the lower bound that can
134  // be set to any value
135  // First compute the lower bound
137  if (ENDP(CDR(indices))) {
138  // for the last dimension (the most contiguous in the memory)
139  // substract the lower bound minus 1 since the first index is
140  // one
141  lower = add_integer_to_expression (lower, -1);
142  curr_exp = make_op_exp (MINUS_OPERATOR_NAME, curr_exp, lower);
143  }
144  else {
145  // substract the lower bound to the index to compute the
146  // dimension stride in the linearized array
147  curr_exp = make_op_exp (MINUS_OPERATOR_NAME, curr_exp, lower);
148  }
149  }
152  curr_exp,
153  SizeOfDimensions(CDR(vdims))
154  ),
155  new_index
156  );
157  POP(vdims);
158  POP(indices);
159  }
160  }
161  /* it's a pointer: pop type */
163  et = basic_pointer(variable_basic(v));
164  }
165  if(expression_undefined_p(new_index)) {
166  new_index =copy_expression(EXPRESSION(CAR(indices)));
167  POP(indices);
168  }
169  new_indices=CONS(EXPRESSION,new_index,new_indices);
170  }
171  reference_indices(r)=gen_nreverse(new_indices);
172  gen_full_free_list (to_be_free);
173  }
174  }
175 }
176 
178  pips_user_warning("subscript linearization not handled yet\n");
179 }
180 
182  if(type_void_p(t)) return true;
183  else if(type_variable_p(t)) {
185  return basic_pointer_p(b) &&
187  }
188  return false;
189 }
190 
191 static bool do_linearize_type(type *t, bool *rr) {
192  bool linearized =false;
194  pips_user_warning("cannot linearize void type\n");
195  }
196  else {
197  pips_assert ("variable expected", type_variable_p (*t));
198  pips_debug (5, "try to linearize type: %s\n", type_to_string (*t));
199  if(rr)*rr=false;
200  variable v = type_variable(*t);
201  type ut = ultimate_type(*t);
202  variable uv = type_variable(ut);
203  size_t uvl = gen_length(variable_dimensions(uv));
204  size_t vl = gen_length(variable_dimensions(v));
205  if(uvl > 1 ) {
210  NIL);
211  }
212  else {
216  int_to_expression(1)),
217  NIL);
218  }
219 
220  type nt = type_undefined;
221  bool free_it = false;
222  // copy only if needed, otherwise modify in place
223  if (ut == *t) {
224  nt = *t;
225  free_it = false;
226  }
227  else {
228  nt = copy_type(uvl>vl?ut:*t);
229  free_it = true;
230  }
231  variable nv = type_variable(nt);
234  if (free_it) {
235  // it might be dangerous to free the type that can be reused somewhere
236  // else in the RI
237  free_type(*t);
238  *t=nt;
239  }
240  linearized=true;
241  if(rr)*rr=true;
242  pips_debug (5, "type has been linearized\n");
243  }
244 
246  return do_linearize_type(&basic_pointer(variable_basic(type_variable(*t))),rr) || linearized;
247  }
248  return linearized;
249 }
250 
252  variable v = type_variable(*t);
255  list dimensions = variable_dimensions(v);
257  FOREACH(DIMENSION,d,dimensions) {
260  make_basic_pointer(*t),
261  NIL,NIL
262  )
263  );
264  }
265 }
266 
267  /* returns true if a dereferencment has been supressed */
269  bool remove = false;
270  if(!type_void_or_void_pointer_p(*t)) {
271  if(pointer_type_p(*t)){
272  variable vt = type_variable(*t);
273  basic bt = variable_basic(vt);
274  type t2 = basic_pointer(bt);
275  if(array_type_p(t2)) {
277  free_type(*t);
278  *t=t2;
279  remove=true;
280  }
281  }
283  }
284  return remove;
285 }
286 
287 
288 static void do_linearize_array_manage_callers(entity m,set linearized_param, param_t *param) {
289  list callers = callees_callees((callees)db_get_memory_resource(DBR_CALLERS,module_local_name(m), true));
290  list callers_statement = callers_to_statements(callers);
291  list call_sites = callers_to_call_sites(callers_statement,m);
292 
293  /* we may have to change the call sites, prepare iterators over call sites arguments here */
294  FOREACH(CALL,c,call_sites) {
295  list args = call_arguments(c);
297  if(set_belong_p(linearized_param,p)) {
298  expression * arg = (expression*)REFCAR(args);
299  type type_at_call_site = expression_to_type(*arg);
300  type type_in_func_prototype = parameter_type(p);
301  if(!pointer_type_p(type_at_call_site)) {
302  /*
303  type t = make_type_variable(
304  make_variable(
305  make_basic_pointer(
306  copy_type(parameter_type(p))
307  ),
308  NIL,NIL)
309  );
310  */
311  if(array_type_p(type_at_call_site)) {
312  if(param->cast_at_call_site_p && !fixed_length_array_type_p(type_in_func_prototype)) {
313  *arg =
316  make_cast(
317  copy_type(type_in_func_prototype),
318  *arg
319  )
320  ),
322  );
323  if(!param->use_pointers_p) {
324  *arg=MakeUnaryCall(
326  *arg);
327  }
328  }
329  }
330  else {
331  if(!fixed_length_array_type_p(type_in_func_prototype))
332  *arg =
335  make_cast(
336  copy_type(type_in_func_prototype),
339  *arg
340  )
341  )
342  ),
344  );
345  if(!param->use_pointers_p) {
346  *arg=MakeUnaryCall(
348  *arg);
349  }
350  }
351  }
352  else if(!param->use_pointers_p && !type_equal_p(type_at_call_site,type_in_func_prototype)) {
353  *arg =
356  }
357 
358 #if 0 // ***SG: optional, and I don't want to valdiate it
359  /* handle call sites in the form *pointer_to_array */
360  if( param->cast_at_call_site_p && expression_call_p(*arg) && ENTITY_DEREFERENCING_P(call_function(expression_call(*arg)))) {
361  expression *dereferenced = (expression*)REFCAR(call_arguments(expression_call(*arg)));
362  type dereferenced_type = expression_to_type(*dereferenced);
363  if ( pointer_type_p(dereferenced_type)) {
364  type dereferenced_pointed_type = basic_pointer(variable_basic(type_variable(dereferenced_type)));
365  if(array_type_p(dereferenced_pointed_type)) {
366  *dereferenced =
369  make_cast(
372  make_basic_pointer(copy_type(type_in_func_prototype)),
373  NIL,
374  NIL
375  )
376  ),
377  *dereferenced
378  )
379  ),
381  );
382 
383  }
384  }
385 
386  }
387 #endif
388  free_type(type_at_call_site);
389  }
390  POP(args);
391  }
392  }
393  for(list citer=callers,siter=callers_statement;!ENDP(citer);POP(citer),POP(siter))
394  DB_PUT_MEMORY_RESOURCE(DBR_CODE, STRING(CAR(citer)),STATEMENT(CAR(siter)));
395 
396 }
398  do_linearize_type(&cast_type(c),NULL);
399 }
400 static void do_linearize_array_walker(void* obj) {
401  gen_multi_recurse(obj,
405  NULL);
406 }
407 
410  hash_put(ht,exp,(void*)(intptr_t)basic_pointer_p(b));
411  free_basic(b);
412 }
413 
415  intptr_t t = (intptr_t)hash_get(ht,exp);
416  if(t != (intptr_t)HASH_UNDEFINED_VALUE ) {
418  /*SG: let us hope that by fixing only references, it will be enough */
419  if(t && !basic_pointer_p(b) && expression_reference_p(exp)){
424  make_call(
428  NIL)
429  )
430  )
431  );
432  }
433  free_basic(b);
434  }
435 }
436 
441  if(entity_variable_p(e))
443  }
444  return ht;
445 }
446 
447 static void do_linearize_patch_expressions(void* obj, hash_table ht) {
450  if(entity_variable_p(e))
452  }
453 }
454 
456  if(value_expression_p(v)) {
458  if(expression_call_p(exp)) {
459  call c = expression_call(exp);
460  entity op = call_function(c);
461  if(ENTITY_BRACE_INTRINSIC_P(op)) {
462  list inits = NIL;
463  for(list iter = call_arguments(c); !ENDP(iter) ; POP(iter)) {
464  expression *eiter = (expression*)REFCAR(iter);
465  if(expression_call_p(*eiter)) {
466  call c2 = expression_call(*eiter);
468  iter=gen_append(iter,call_arguments(c2));
469  call_arguments(c2)=NIL;
470  continue;
471  }
472  }
473  inits=CONS(EXPRESSION,copy_expression(*eiter),inits);
474  }
475  inits=gen_nreverse(inits);
477  call_arguments(c)=inits;
478  }
479  }
480  }
481 }
482 
484  if(expression_call_p(exp)) {
485  call c = expression_call(exp);
488  if(expression_reference_p(arg)) {
491  syntax syn = expression_syntax(arg);
494  }
495  }
496  else if(expression_call_p(arg)) {
497  call c2 = expression_call(arg);
498  if(ENTITY_PLUS_C_P(call_function(c2))) {
499  bool remove =false;
500  FOREACH(EXPRESSION,exp2,call_arguments(c2)) {
501  if(expression_reference_p(exp2))
503  }
504  if(remove) {
505  syntax syn = expression_syntax(arg);
508  }
509  }
510 
511  }
512  }
513  }
514 }
518  if(entity_variable_p(e))
521 }
522 
524  if(pointer_type_p(t)) {
526  type t3 = ultimate_type(t2);
527  if(array_type_p(t2)) {
528  variable v = type_variable(t2);
534  type_variable(t)=v;
535  }
536  else if(array_type_p(t3)) {
542  type_variable(t)=v;
543  }
544  }
545 }
546 
547 /* subscripts of the form (*a)[n] are transformed into a[n]
548  * it is coherent with other transformations scattered here and there in this file :p
549  */
552  if(expression_call_p(exp)) {
554  entity op = call_function(c);
555  if(ENTITY_DEREFERENCING_P(op)) {
557  if(expression_reference_p(arg)) {
559  entity var = reference_variable(r);
560  if(entity_pointer_p(var)) {
565  }
566  }
567  }
568  }
569  }
570 }
571 
572 /* transform some subscripts for generic handling later */
577  if(entity_variable_p(e)) {
580  }
581 
582 
583 }
584 
587  if(entity_variable_p(e)) {
588  if(local_entity_of_module_p(e,m) &&
589  entity_pointer_p(e) &&
593  }
595  }
597  dummy d = parameter_dummy(p);
598  if(dummy_identifier_p(d))
599  {
600  entity di = dummy_identifier(d);
602  }
604  pips_assert("everything went well",parameter_consistent_p(p));
605  }
606 }
607 
609  /* step 0: remind all expressions types */
611 
612  /* step 0.25: hack some subscripts typically found in pips inputs */
614 
615  /* step 0.5: transform int (*a) [3] into int a[*][3] */
617 
618  /* step1: the statements */
621  if(entity_variable_p(e))
623 
624  /* step2: the declarations */
626  if(entity_variable_p(e)) {
627  bool rr;
628  pips_debug (5, "linearizing entity %s\n", entity_name (e));
632  }
633  }
634 
635  /* pips bonus step: the consistency */
636  set linearized_param = set_make(set_pointer);
638  dummy d = parameter_dummy(p);
639  pips_debug (5, "linearizing parameters\n");
640  if(dummy_identifier_p(d))
641  {
642  entity di = dummy_identifier(d);
643  do_linearize_type(&entity_type(di),NULL);
644  pips_debug (5, "linearizing dummy parameter %s\n", entity_name (di));
645  }
646 
647  if(do_linearize_type(&parameter_type(p),NULL))
648  set_add_element(linearized_param,linearized_param,p);
649 
650  // Convert to pointer if requested
651  if(param->use_pointers_p) {
652  if(dummy_identifier_p(d)) {
653  entity di = dummy_identifier(d);
657  }
658  }
659  }
660  pips_assert("everything went well",parameter_consistent_p(p));
661  }
662 
663  /* step3: change the caller to reflect the new types accordingly */
664  if (param->modify_call_site_p) {
665  do_linearize_array_manage_callers(m,linearized_param,param);
666  }
667  set_free(linearized_param);
668 
669  /* final step: fix expressions if we have disturbed typing in the process */
671  hash_table_free(e2t);
673  pips_assert("everything went well",parameter_consistent_p(p));
674  }
675 }
676 
683  if(!ENDP(indices)) {
684  expression new_expression = expression_undefined;
687  FOREACH(EXPRESSION,index,indices) {
688  new_expression=MakeUnaryCall(
692  expression_undefined_p(new_expression)?
694  new_expression,
695  index
696  )
697  );
698  }
699  syntax syn = expression_syntax(new_expression);
700  expression_syntax(new_expression)=syntax_undefined;
702  }
703  }
704  }
706  pips_user_warning("subscript are not well handled (yet)!\n");
707  }
708 }
709 
710 /* fix some strange constructs introduced by previous processing */
712  if(expression_call_p(exp)) {
713  call c = expression_call(exp);
714  entity op = call_function(c);
715  if(ENTITY_ADDRESS_OF_P(op)) {
717  if(expression_call_p(arg)) {
718  call c2 = expression_call(arg);
723  }
724  else if( ENTITY_ADDRESS_OF_P(call_function(c2))) {
726  }
727  }
728  }
729  }
730  return true;
731 }
732 
734 {
736 }
737 
738 /* special ad-hoc handler for pointer to arrays */
740  entity op = call_function(c);
741  if(ENTITY_DEREFERENCING_P(op)) {
745  entity e = reference_variable(r);
746  /* pointer to an array ... */
747  if(entity_pointer_p(e)) {
752  make_call(
755  )
756  )
757  );
758  }
759  }
760  }
761  }
762 }
763 
766 }
767 
768 /* converts arrays to pointer */
769 static void do_array_to_pointer_walker(void *obj) {
770  gen_multi_recurse(obj,
774  NULL);
776 
777 }
778 
779 /* create a list of statements from entity declarations */
780 static
782  list stats = NIL;
783  if(entity_array_p(e)) {
784  value v = entity_initial(e);
785  if(value_expression_p(v)) {
787  if(expression_call_p(exp)) {
788  call c = expression_call(exp);
789  entity op = call_function(c);
790  /* we assume that we only have one level of braces, linearize_array should have done the previous job
791  * incomplete type are not handled ...
792  * */
793  if(ENTITY_BRACE_INTRINSIC_P(op)) {
796  stats=CONS(STATEMENT,
800  e,
801  CONS(EXPRESSION,i,NIL)
802  )
803  ),
807  )
808  ),
809  stats);
812  copy_expression(i),
814  );
815  }
816  }
817  }
818  }
819  if(!formal_parameter_p(e)) {
820  value v = entity_initial(e);
821  expression ev;
824  }
825  else {
826  /* use alloca when converting array to pointers, to make sure everything is initialized correctly */
829  if(array_type_p(ct)) {
830  POP(variable_dimensions(type_variable(ct))); //leak spotted !
831  ct = make_type_variable(
834  )
835  );
836  }
837 
841  make_cast(ct,
848  )
849  ),
851  )
852  )
853  )
854  )
855  )
856  );
859  }
860  }
861  }
862  return gen_nreverse(stats);
863 }
864 
865 /* initialization statements are added right after declarations */
867  if(!ENDP(stats)) {
868  if(ENDP(statement_declarations(st))) {
869  insert_statement(st,make_block_statement(stats),true);
870  }
871  else {
872  for(list iter=statement_block(st),prev=NIL;!ENDP(iter);POP(iter)) {
874  prev=iter;
875  } else if(prev == NIL) {
876  /* No declarations */
877  insert_statement(st, make_block_statement(stats), true);
878  } else {
879  CDR(prev) = stats;
880  while(!ENDP(CDR(stats)))
881  POP(stats);
882  CDR(stats) = iter;
883  break;
884  }
885  }
886  }
887 
888  }
889 }
890 
891 /* transform each array type in module @p m with statement @p s */
893  /* step1: the statements */
898  }
899  }
900 
901  /* step2: the declarations */
902  list inits = NIL;
905  // must do this before the type conversion
909  }
910  /* step3: insert the initialization statement just after declarations */
912 
913  /* pips bonus step: the consistency */
915  dummy d = parameter_dummy(p);
916  if(dummy_identifier_p(d))
917  {
918  entity di = dummy_identifier(d);
922  }
923  }
924  pips_assert("everything went well",parameter_consistent_p(p));
925  }
926 
927 }
928 
929 /* linearize accesses to an array, and use pointers if asked to */
931 {
932 
933  debug_on("LINEARIZE_ARRAY_DEBUG_LEVEL");
934  /* prelude */
936 
937  param_t param = { .use_pointers_p = false , .modify_call_site_p = false, .cast_at_call_site_p = false };
938  /* Do we have to cast the array at call site ? */
940  param.use_pointers_p = get_bool_property("LINEARIZE_ARRAY_USE_POINTERS");
941  param.cast_at_call_site_p = get_bool_property("LINEARIZE_ARRAY_CAST_AT_CALL_SITE");
942  }
943  param.modify_call_site_p = get_bool_property("LINEARIZE_ARRAY_MODIFY_CALL_SITE");
944 
945  /* it is too dangerous to perform this task on compilation unit, system variables may be changed */
947 
949 
950  /* just linearize accesses and change signature from n-D arrays to 1-D arrays */
952 
953  /* additionally perform array-to-pointer conversion for c modules only */
954  if(param.use_pointers_p) {
959  if(entity_variable_p(e)) {
961  }
962  }
963  }
964  else pips_user_warning("no pointers in fortran !,LINEARIZE_ARRAY_USE_POINTERS ignored\n");
965  }
966 
967  /* validate */
972  // remove decls_text or the prettyprinter will use that field
974  } else {
975  //compilation unti doesn't exit in fortran
977  }
978  /*postlude*/
980  }
982  debug_off();
983  return true;
984 }
985 
986 /* linearize accesses to an array, and use pointers if asked to */
987 bool linearize_array(const char* module_name)
988 {
990 }
991 
993 {
995 }
cast make_cast(type a1, expression a2)
Definition: ri.c:311
call make_call(entity a1, list a2)
Definition: ri.c:269
bool parameter_consistent_p(parameter p)
Definition: ri.c:1468
value make_value_expression(expression _field_)
Definition: ri.c:2850
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
type make_type_variable(variable _field_)
Definition: ri.c:2715
syntax make_syntax_sizeofexpression(sizeofexpression _field_)
Definition: ri.c:2506
type copy_type(type p)
TYPE.
Definition: ri.c:2655
basic make_basic_pointer(type _field_)
Definition: ri.c:179
variable copy_variable(variable p)
VARIABLE.
Definition: ri.c:2859
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
bool statement_consistent_p(statement p)
Definition: ri.c:2195
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
sizeofexpression make_sizeofexpression_type(type _field_)
Definition: ri.c:2177
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
syntax copy_syntax(syntax p)
SYNTAX.
Definition: ri.c:2442
syntax make_syntax_cast(cast _field_)
Definition: ri.c:2503
void free_type(type p)
Definition: ri.c:2658
void free_basic(basic p)
Definition: ri.c:107
void free_variable(variable p)
Definition: ri.c:2862
void free_value(value p)
Definition: ri.c:2787
bool db_touch_resource(const char *rname, const char *oname)
touch logical time for resource[owner], possibly behind the back of pipsdbm.
Definition: database.c:538
static void do_array_to_pointer_type_aux(type *t)
static void do_linearize_patch_expressions(void *obj, hash_table ht)
static void do_linearize_array_reference(reference r)
bool do_convert_this_array_to_pointer_p(entity e)
array_to_pointer.c
static void do_linearize_array(entity m, statement s, param_t *param)
static void do_linearize_prepatch_subscript(subscript s)
subscripts of the form (*a)[n] are transformed into a[n] it is coherent with other transformations sc...
static void insert_statements_after_declarations(statement st, list stats)
initialization statements are added right after declarations
static bool do_linearize_type(type *t, bool *rr)
static void do_linearize_remove_dereferencment_walker(expression exp, entity e)
size_t type_dereferencement_depth(type t)
static list initialization_list_to_statements(entity e)
create a list of statements from entity declarations
static void do_array_to_pointer_patch_call_expr_rwt(expression e)
static void do_linearize_array_cast(cast c)
bool linearize_array_fortran(const char *module_name)
bool linearize_array(const char *module_name)
linearize accesses to an array, and use pointers if asked to
static void do_array_to_pointer(entity m, statement s, _UNUSED_ param_t *p)
transform each array type in module m with statement s
static void do_array_to_pointer_walker(void *obj)
converts arrays to pointer
static hash_table init_expression_is_pointer(void *obj)
static void do_array_to_pointer_walk_expression(expression exp)
static void do_linearize_pointer_is_expression(expression exp, hash_table ht)
static bool do_array_to_pointer_patch_call_expression(expression exp)
fix some strange constructs introduced by previous processing
static bool type_void_or_void_pointer_p(type t)
static void do_array_to_pointer_walk_cast(cast ct)
static void do_array_to_pointer_walk_call_and_patch(call c)
special ad-hoc handler for pointer to arrays
static void do_linearize_array_subscript(_UNUSED_ subscript s)
static void do_linearize_array_walker(void *obj)
static void do_linearize_array_init(value v)
static void do_linearize_expression_is_pointer(expression exp, hash_table ht)
static void do_linearize_prepatch_type(type t)
static void do_linearize_remove_dereferencment(statement s, entity e)
static bool do_array_to_pointer_type(type *t)
returns true if a dereferencment has been supressed
static void do_linearize_array_manage_callers(entity m, set linearized_param, param_t *param)
static void do_linearize_prepatch(entity m, _UNUSED_ statement s)
static void do_linearize_prepatch_subscripts(entity m, statement s)
transform some subscripts for generic handling later
bool linearize_array_generic(const char *module_name)
linearize accesses to an array, and use pointers if asked to
list callers_to_call_sites(list callers_statement, entity called_module)
given a list callers_statement of module statements returns a list of calls to module called_module
Definition: callgraph.c:149
list callers_to_statements(list callers)
given a list callers of module name calling module called module return a list of their body
Definition: callgraph.c:163
string compilation_unit_of_module(const char *)
The output is undefined if the module is referenced but not defined in the workspace,...
Definition: module.c:350
int dummy
A dummy file, to prevent empty libraries from breaking builds.
Definition: dummy.c:41
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void cleanup_subscripts(void *)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
#define STRING(x)
Definition: genC.h:87
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void gen_full_free_list(list l)
Definition: genClib.c:1023
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
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
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
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
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define REFCAR(pc)
Get the adress of the first element of a list.
Definition: newgen_list.h:119
#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
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#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
list gen_append(list l1, const list l2)
Definition: list.c:471
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
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
statement make_assign_statement(expression, expression)
Definition: statement.c:583
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
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
static list indices
Definition: icm.c:204
#define debug_on(env)
Definition: misc-local.h:157
#define _UNUSED_
Definition: misc-local.h:232
#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
@ hash_int
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define HASH_DEFAULT_SIZE
Definition: newgen_hash.h:26
void set_free(set)
Definition: set.c:332
bool set_belong_p(const set, const void *)
Definition: set.c:194
@ set_pointer
Definition: newgen_set.h:44
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152
#define false
Definition: newgen_types.h:80
void print_type(type)
For debugging.
Definition: type.c:111
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define ALLOCA_FUNCTION_NAME
#define MINUS_OPERATOR_NAME
#define ENTITY_DEREFERENCING_P(e)
#define PLUS_OPERATOR_NAME
#define DEREFERENCING_OPERATOR_NAME
Definition: ri-util-local.h:93
#define ENTITY_BRACE_INTRINSIC_P(e)
C initialization expression.
#define entity_declarations(e)
MISC: newgen shorthands.
#define ENTITY_PLUS_C_P(e)
#define ADDRESS_OF_OPERATOR_NAME
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
#define ENTITY_ADDRESS_OF_P(e)
#define module_functional_parameters(func)
#define MULTIPLY_OPERATOR_NAME
#define PLUS_C_OPERATOR_NAME
bool entity_formal_p(entity p)
is p a formal parameter?
Definition: entity.c:1935
bool entity_array_p(entity e)
Is e a variable with an array type?
Definition: entity.c:754
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool local_entity_of_module_p(entity e, entity module)
This test shows that "e" has been declared in "module".
Definition: entity.c:1069
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
bool entity_variable_length_array_p(entity e)
Definition: entity.c:798
bool entity_pointer_p(entity e)
Definition: entity.c:745
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression add_integer_to_expression(expression exp, int val)
Definition: expression.c:2132
expression reference_to_expression(reference r)
Definition: expression.c:196
bool expression_call_p(expression e)
Definition: expression.c:415
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
bool expression_brace_p(expression e)
predicates and short cut accessors on expressions
Definition: expression.c:407
call expression_call(expression e)
Definition: expression.c:445
void update_expression_syntax(expression e, syntax s)
frees expression syntax of e and replace it by the new syntax s
Definition: expression.c:3564
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 make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
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
expression syntax_to_expression(syntax s)
generates an expression from a syntax
Definition: expression.c:3581
bool compilation_unit_entity_p(entity e)
Check if the given module entity is a compilation unit.
Definition: module.c:87
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
type ultimate_type(type)
Definition: type.c:3466
bool array_type_p(type)
Definition: type.c:2942
bool fixed_length_array_type_p(type)
Definition: type.c:2987
expression SizeOfDimensions(list)
computes the product of all dimensions in dims
Definition: size.c:522
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
bool type_equal_p(type, type)
Definition: type.c:547
void discard_module_declaration_text(entity)
Discard the decls_text string of the module code to make the prettyprinter ignoring the textual decla...
Definition: variable.c:1696
type pointed_type(type)
returns the type pointed by the input type if it is a pointer or an array of pointers
Definition: type.c:3035
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
bool formal_parameter_p(entity)
Definition: variable.c:1489
string type_to_string(const type)
type.c
Definition: type.c:51
#define value_undefined_p(x)
Definition: ri.h:3017
#define dummy_identifier(x)
Definition: ri.h:1033
#define basic_pointer(x)
Definition: ri.h:637
#define normalized_undefined
Definition: ri.h:1745
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define parameter_dummy(x)
Definition: ri.h:1823
#define parameter_type(x)
Definition: ri.h:1819
#define cast_domain
newgen_call_domain_defined
Definition: ri.h:66
#define call_function(x)
Definition: ri.h:709
#define callees_callees(x)
Definition: ri.h:675
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define value_unknown_p(x)
Definition: ri.h:3077
#define dimension_lower(x)
Definition: ri.h:980
#define subscript_domain
newgen_storage_domain_defined
Definition: ri.h:378
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#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 type_void_p(x)
Definition: ri.h:2959
#define entity_name(x)
Definition: ri.h:2790
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define reference_indices(x)
Definition: ri.h:2328
#define dimension_undefined
Definition: ri.h:955
#define cast_type(x)
Definition: ri.h:745
#define expression_undefined_p(x)
Definition: ri.h:1224
#define subscript_array(x)
Definition: ri.h:2561
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_declarations(x)
Definition: ri.h:2460
#define syntax_undefined
Definition: ri.h:2676
#define type_undefined
Definition: ri.h:2883
#define CALL(x)
CALL.
Definition: ri.h:679
#define call_arguments(x)
Definition: ri.h:711
#define entity_type(x)
Definition: ri.h:2792
#define value_expression_p(x)
Definition: ri.h:3080
#define expression_syntax(x)
Definition: ri.h:1247
#define dummy_identifier_p(x)
Definition: ri.h:1031
#define type_variable_p(x)
Definition: ri.h:2947
#define value_expression(x)
Definition: ri.h:3082
#define variable_basic(x)
Definition: ri.h:3120
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
#define syntax_subscript_p(x)
Definition: ri.h:2743
#define ifdebug(n)
Definition: sg.c:47
#define intptr_t
Definition: stdint.in.h:294
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
bool use_pointers_p
This bool is controlled by the "LINEARIZE_ARRAY_USE_POINTERS" property.
bool modify_call_site_p
This bool is controlled by the "LINEARIZE_ARRAY_MODIFY_CALL_SITE" property.
bool cast_at_call_site_p
This bool is controlled by the "LINEARIZE_ARRAY_CAST_AT_CALL_SITE" property Turning it on break furth...
Definition: replace.c:135
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
void AddEntityToModuleCompilationUnit(entity e, entity module)
Definition: module.c:301