PIPS
inlining.c
Go to the documentation of this file.
1 /*
2 
3  $Id: inlining.c 23495 2018-10-24 09:19:47Z 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 /**
25  * @file inlining.c
26  * @brief add inlining support to pips, with two flavors
27  * - inlining(char* module) to inline all calls to a module
28  * - unfolding(char* module) to inline all call in a module
29  *
30  * @author Serge Guelton <serge.guelton@enst-bretagne.fr>
31  * I am not proud of this code, it is a real mess !
32  * @date 2009-01-07
33  */
34 #ifdef HAVE_CONFIG_H
35  #include "pips_config.h"
36 #endif
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include "genC.h"
42 #include "linear.h"
43 #include "ri.h"
44 #include "effects.h"
45 #include "ri-util.h"
46 #include "prettyprint.h"
47 #include "effects-util.h"
48 #include "text.h"
49 #include "pipsdbm.h"
50 #include "workspace-util.h"
51 #include "resources.h"
52 #include "properties.h"
53 #include "misc.h"
54 #include "callgraph.h"
55 #include "effects-generic.h"
56 #include "effects-convex.h"
57 #include "preprocessor.h"
58 #include "text-util.h"
59 #include "parser_private.h"
60 #include "pipsmake.h"
61 #include "accel-util.h"
62 
63 
64 /**
65  * @name inlining
66  * @{ */
67 
68 /**
69  * structure containing all the parameters needed by inlining.
70  * It avoids using globals
71  * newgen like macros are defined
72  */
73 typedef struct {
84 #define IPARAM_INIT { \
85  ._inlined_module_=entity_undefined,\
86  ._inlined_module_statement_=statement_undefined,\
87  ._new_statements_=statement_undefined,\
88  ._has_static_declaration_=false,\
89  ._has_inlinable_calls_=false,\
90  ._laststmt_=statement_undefined,\
91  ._tail_ins_=instruction_undefined,\
92  ._returned_entity_=entity_undefined,\
93  ._use_effects_=true\
94 }
95 #define inlined_module(p) (p)->_inlined_module_
96 #define inlined_module_statement(p) (p)->_inlined_module_statement_
97 #define new_statements(p) (p)->_new_statements_
98 #define has_static_declaration(p) (p)->_has_static_declaration_
99 #define has_inlinable_calls(p) (p)->_has_inlinable_calls_
100 #define laststmt(p) (p)->_laststmt_
101 #define tail_ins(p) (p)->_tail_ins_
102 #define returned_entity(p) (p)->_returned_entity_
103 #define use_effects(p) (p)->_use_effects_
104 
105 
106 /* replace return instruction by a goto
107  */
108 static
110 {
111  if( return_statement_p( s ) )
113 }
114 
115 /* replace return instruction by an assignment and a goto
116  */
117 static
119 {
120  if( return_statement_p( s ) )
121  {
122  // create the goto
123  list l= (statement_instruction(s) == tail_ins(p)) ?
124  NIL :
126  // create the assign and push it if needed
127  call ic = statement_call(s);
128  if( !ENDP(call_arguments(ic)) )
129  {
130  pips_assert("return is called with one argument",ENDP(CDR(call_arguments(ic))));
134  l = CONS( STATEMENT, assign , l );
135  }
137  }
138 }
139 
140 /* helper function to check if a call is a call to the inlined function
141  */
142 static
144 {
146 }
147 
148 static bool has_similar_entity(entity e,set se)
149 {
150  SET_FOREACH(entity,ee,se)
152  return true;
153  return false;
154 }
155 
156 
158 
159 /* look for entity locally named has `new' in statements `s'
160  * when found, find a new name and perform substitution
161  */
162 static void
164 {
165  if(!implicit_c_variable_p(new)) {
168  for(;!ENDP(l);POP(l))
169  {
170  entity decl_ent = ENTITY(CAR(l));
171  if( same_string_p(entity_user_name(decl_ent), entity_user_name(new)))
172  {
173  entity solve_clash = copy_entity(decl_ent);
174  string ename = strdup(entity_name(solve_clash));
175  do {
176  string tmp;
177  asprintf(&tmp,"%s_",ename);
178  free(ename);
179  ename=tmp;
180  entity_name(solve_clash)=ename;
181  } while( has_similar_entity(solve_clash,re));
182  CAR(l).p = (void*)solve_clash;
183  replace_entity(expanded,decl_ent,solve_clash);
184  gen_recurse_stop(0);
185  }
186  }
187  set_free(re);
188  }
189 }
190 
191 /* return true if an entity declared in `iter' is static to `module'
192  */
193 static
195 {
196  FOREACH(ENTITY, e ,iter)
197  {
198  if ( variable_static_p(e))
199  return true;
200  }
201  return false;
202 }
203 
204 /* return true if an entity declared in the statement `s' from
205  `p->inlined_module'
206  */
207 static
209 {
211 }
212 
213 /* create a scalar similar to `efrom' initialized with expression `from'
214  */
215 static
217 {
218  pips_assert("expression is valid",expression_consistent_p(from)&&!expression_undefined_p(from));
219  /* create the scalar */
222  some_basic_of_any_expression(from,false,false)
223  );
224  /* set intial */
225  if(!expression_undefined_p(from))
226  {
228  }
229  return new;
230 }
231 
232 /* regenerate the label of each statement with a label.
233  * it avoid duplications due to copy_statement
234  */
235 static
237 {
238  entity lbl = statement_label(s);
239  if(!entity_empty_label_p(lbl))
240  {
242  {
243  statement_label(s)=lbl=make_new_label(new_module);
244  }
245  else
247  if( statement_loop_p(s) )
248  loop_label(statement_loop(s))=lbl;
249  }
250  else if( statement_loop_p(s) ) {
252  loop_label(statement_loop(s))=make_new_label(new_module);
253  }
254 }
255 
257  FOREACH(ENTITY,ent,l)
258  if(same_entity_name_p(e,ent)) return true;
259  return false;
260 }
261 
263  static const unsigned int magic_block_number = (unsigned int)-1;
264  /* forge a new name with a magical block number */
265  if(declaration_statement_p(s)) {
266  for(list iter=statement_declarations(s);!ENDP(iter);POP(iter)) {
267  entity *e=(entity*)REFCAR(iter);
268  if(!formal_parameter_p(*e)) {
269  entity ebis = copy_entity(*e);
270  char* ename = entity_name(ebis);
271  const char* euname = entity_user_name(ebis);
272  const char* eprefix = strndup(ename,euname-ename);
273  asprintf(&entity_name(ebis),"%s%u"BLOCK_SEP_STRING"%s",eprefix,magic_block_number,euname);
274  free(ename);
275  hash_put(old_new,*e,ebis);
276  *e=ebis;
277  }
278  }
279  }
280  /* beacause of bottom up transversal,
281  * we are sure old_new has already been fed
282  */
283  else if(statement_block_p(s)) {
284  for(list iter=statement_declarations(s);!ENDP(iter);POP(iter)) {
285  entity *e=(entity*)REFCAR(iter);
286  entity new = (entity)hash_get(old_new,*e);
287  if(new != HASH_UNDEFINED_VALUE)
288  *e=new;
289  }
290  }
291 }
292 
293 /* sg: this is another inlining mostruosity
294  * it ensures all entities in s have new pointer
295  * and different name (is it usefull ?)
296  * it takes care of dependant types
297  */
301  HASH_FOREACH(entity,old,entity,new,old_new)
302  replace_entities(new,old_new);
303  replace_entities(s,old_new);
304 
305  hash_table_free(old_new);
306 }
307 
308 
309 
310 /* this should inline the call callee
311  * calling module inlined_module
312  */
313 static
315 {
316  /* only inline the right call */
317  pips_assert("inline the right call",inline_should_inline(inlined_module(p),callee));
318 
319  value inlined_value = entity_initial(inlined_module(p));
320  pips_assert("is a code", value_code_p(inlined_value));
321  code inlined_code = value_code(inlined_value);
322 
323  /* stop if the function has static declaration */
324  {
325  has_static_declaration(p)=false;
326  if( c_module_p(inlined_module(p)) )
328  else
330 
331  if( has_static_declaration(p))
332  {
333  pips_user_warning("cannot inline function with static declarations\n");
334  return statement_undefined;
335  }
336  }
337 
338  /* create the new instruction sequence
339  * no need to change all entities in the new statements, because we build a new text resource later
340  * sg: not so true, because of dependant types
341  */
343 
344  statement declaration_holder = make_empty_block_statement();
345 
346  /* add external declarations for all extern referenced entities it
347  * is needed because inlined module and current module may not
348  * share the same compilation unit.
349  * Not relevant for Fortran
350  *
351  * FI: However, it would be nice to check first if the entity is not
352  * already in the scope for the function or in the scope of its
353  * compilation unit (OK, the later is difficult because the order
354  * of declarations has to be taken into account).
355  */
357  {
359  set inlined_referenced_entities = get_referenced_entities(expanded);
360  list lire = set_to_sorted_list(inlined_referenced_entities,(gen_cmp_func_t)compare_entities);
361  set_free(inlined_referenced_entities);
362 
363 
364  FOREACH(ENTITY,ref_ent,lire)
365  {
366  if( entity_field_p(ref_ent) ) /* special hook for struct member : consider their structure instead of the field */
367  {
369  }
370 
371  if(!entity_enum_member_p(ref_ent) && /* enum member cannot be added to declarations */
372  !entity_formal_p(ref_ent) ) /* formal parameters are not considered */
373  {
374  const char* emn = entity_module_name(ref_ent);
377  {
380  }
381  else if(variable_static_p(ref_ent) &&
383  {
384  pips_user_warning("replacing static variable \"%s\" by a global one, this may lead to incorrect code\n", entity_user_name(ref_ent));
385  entity add = make_global_entity_from_local(ref_ent);
386  replace_entity(expanded,ref_ent,add);
390  }
391  else if(!variable_entity_p(ref_ent) && !same_string_p(emn,cu_name) &&
393  {
395  }
396  }
397  }
398  gen_free_list(lire);
400  }
401  else {
402  bool did_something = false;
404  {
405  if(!entity_area_p(e) && !implicit_c_variable_p(e))
406  {
407  entity new;
408  if(entity_variable_p(e)) {
409  if(entity_scalar_p(e)||entity_pointer_p(e)) {
411  }
412  else {
415  }
416  }
417  else
418  {
419  /*sg: unsafe
420  *sg: I am unsure this is still needed */
423  if(regenerate)
424  {
425  pips_user_warning("regenerating entity, should this happen ?\n");
429  }
430  }
433  replace_entity(expanded,e,new);
434  did_something=true;
435  }
436  }
437  if(did_something)
438  {
440  if(decls && !empty_string_p(decls)){
441  free(decls);
443  }
444  }
445  }
446 
447 
448  /* ensure block status */
449  if( ! statement_block_p( expanded ) )
450  {
453  }
454 
455 
456  /* avoid duplicated label due to copy_statement */
459 
460  /* add label at the end of the statement */
463 
464  /* fix `return' calls
465  * in case a goto is immediately followed by its targeted label
466  * the goto is not needed (SG: seems difficult to do in the previous gen_recurse)
467  */
468  {
470  {
471 
473  if( type_void_p(treturn) ) /* only replace return statement by gotos */
474  {
476  }
477  else /* replace by affectation + goto */
478  {
479  /* create new variable to receive computation result */
480  pips_assert("returned value is a variable", type_variable_p(treturn));
482  "_return",
485  );
487 
488  /* do the replacement */
489  if(!ENDP(tail) && !ENDP(CDR(tail))) {
492  }
493 
494  /* change the caller from an expression call to a call to a constant */
496  {
497  expression_syntax(modified_expression) = make_syntax_call(make_call(returned_entity(p),NIL));
498  }
499  /* ... or to a reference */
500  else
501  {
503  expression_syntax(modified_expression) = make_syntax_reference(r);
504  }
505  }
506  }
507  }
508 
509  /* fix declarations */
510  {
511  /* retrieve formal parameters*/
512  list formal_parameters = module_formal_parameters(inlined_module(p));
513  list new_old_pairs = NIL ; /* store association between new and old declarations */
514  { /* some basic checks */
515  size_t n1 = gen_length(formal_parameters), n2 = gen_length(call_arguments(callee));
516  pips_assert("function call has enough arguments",n1 >= n2);
517  }
518  /* iterate over the parameters and perform substitution between formal and actual parameters */
519  for(list iter = formal_parameters,c_iter = call_arguments(callee) ; !ENDP(c_iter); POP(iter),POP(c_iter) )
520  {
521  entity e = ENTITY(CAR(iter));
522  expression from = EXPRESSION(CAR(c_iter));
523 
524  /* check if there is a write effect on this parameter */
526 
527  /* generate a copy for this parameter */
528  entity new = entity_undefined;
529  if(need_copy)
530  {
531  if(entity_scalar_p(e)||entity_pointer_p(e)) {
533  }
534  else {
535  if(formal_parameter_p(e)) {
539  free_expression(etmp);
540  }
541  else
544  }
545 
546  /* fix value */
547  if(get_bool_property("INLINING_USE_INITIALIZATION_LIST"))
549  else
550  insert_statement(declaration_holder,make_assign_statement(entity_to_expression(new),copy_expression(from)),false);
551 
552 
553  /* add the entity to our list */
554  //statement_declarations(declaration_holder)=CONS(ENTITY,new,statement_declarations(declaration_holder));
557  replace_entity(expanded,e,new);
558  pips_debug(2,"replace %s by %s",entity_user_name(e),entity_user_name(new));
559  }
560  /* substitute variables */
561  else
562  {
563  /* get new reference */
564 
565  bool add_dereferencment = false;
566  reget:
567  switch(syntax_tag(expression_syntax(from)))
568  {
569  case is_syntax_reference:
570  {
572  size_t nb_indices = gen_length(reference_indices(r));
573  if( nb_indices == 0 )
574  {
575  new = reference_variable(r);
576  }
577  else /* need a temporary variable */
578  {
580  {
582  new = make_temporary_scalar_entity(from,&st);
583  if(!statement_undefined_p(st))
584  insert_statement(declaration_holder,st,false);
585  }
586  else
587  {
589  add_dereferencment=true;
590  }
592 
593  }
594  } break;
595  /* this one is more complicated than I thought,
596  * what of the side effect of the call ?
597  * we must create a new variable holding the call result before
598  */
599  case is_syntax_call:
600  {
602  size_t nb_param = gen_length(call_arguments(c));
603  if( nb_param == 0 && expression_constant_p(from))
604  new = call_function(c);
605  else
606  {
608  {
610  new = make_temporary_scalar_entity(from,&st);
611  if(!statement_undefined_p(st))
612  insert_statement(declaration_holder,st,false);
613  }
614  else
615  {
617  new = make_temporary_scalar_entity(from,&st);
618  if(!statement_undefined_p(st))
619  insert_statement(declaration_holder,st,false);
620  }
622  }
623  } break;
624  case is_syntax_subscript:
625  /* need a temporary variable */
626  {
628  {
630  new = make_temporary_scalar_entity(from,&st);
631  if(!statement_undefined_p(st))
632  insert_statement(declaration_holder,st,false);
633  }
634  else
635  {
637  add_dereferencment=true;
638  }
640 
641  } break;
644  new = make_temporary_scalar_entity(from,&st);
645  if(!statement_undefined_p(st))
646  insert_statement(declaration_holder,st,false);
648  } break;
649 
650  case is_syntax_cast:
651  pips_user_warning("ignoring cast\n");
653  goto reget;
654 
655  default:
656  pips_internal_error("unhandled tag %d", syntax_tag(expression_syntax(from)) );
657  };
658 
659  /* check wether the substitution will cause naming clashes
660  * then perform the substitution
661  */
664  else replace_entity(expanded ,e,new);
665  pips_debug(3,"replace %s by %s\n",entity_user_name(e),entity_user_name(new));
666 
667 
668  }
669  new_old_pairs=CONS(ENTITY,new,CONS(ENTITY,e,new_old_pairs));
670 
671  }
672  gen_free_list(formal_parameters);
673  /* SG: C dependant types are a pain in the a**,
674  we fix them here, that is perform substitution if needed
675  */
676  for(list iter = new_old_pairs;!ENDP(iter);POP(iter)) {
677  entity new = ENTITY(CAR(iter));
678  POP(iter);
679  entity old = ENTITY(CAR(iter));
680  replace_entity(declaration_holder,old,new);
681  }
682  gen_free_list(new_old_pairs);
683  }
684 
685 
686  /* add declaration at the beginning of the statement */
687  insert_statement(declaration_holder,expanded,false);
688 
689  /* final cleanings
690  */
693  ifdebug(1) statement_consistent_p(declaration_holder);
694  ifdebug(2) {
695  pips_debug(2,"inlined statement after substitution\n");
696  print_statement(declaration_holder);
697  }
698  return declaration_holder;
699 }
700 
701 
702 /* recursievly inline an expression if needed
703  */
704 static
706 {
707  if( expression_call_p(expr) )
708  {
711  {
712  statement s = inline_expression_call(p, expr, callee );
713  if( !statement_undefined_p(s) )
714  {
715  insert_statement(new_statements(p),s,true);
716  }
718  ifdebug(2) {
719  pips_debug(2,"inserted inline statement\n");
721  }
722  }
723  }
724 }
725 
726 /* check if a call has inlinable calls
727  */
728 static
730 {
732  gen_recurse_stop(0);
733 }
734 
735 static
737 {
738  iparam p = { ._inlined_module_=inlined_module,._has_inlinable_calls_=false};
739  gen_context_recurse(elem, &p,
741  return has_inlinable_calls(&p);
742 }
743 
744 
745 /* this is in charge of replacing instruction by new ones
746  * only apply if this instruction does not contain other instructions
747  */
748 static
750 {
754  {
755  /* the gen_recurse can only handle expressions, so we turn this call into an expression */
758  }
759 
762 
763  if( !ENDP(statement_block(new_statements(p))) ) /* something happens on the way to heaven */
764  {
765  if(get_bool_property("INLINING_COMMENT_ORIGIN")) {
766  char *the_comment;
767  asprintf(&the_comment,"inlined by pips from ``%s''\n", entity_user_name(inlined_module(p)));
769  free(the_comment);
770  }
771 
773  if( ! type_void_p(t) )
774  {
775  //pips_assert("inlining instruction modification is ok", instruction_consistent_p(sti));
777  }
779  {
780  list iter=statement_block(stmt);
781  for(stmt=STATEMENT(CAR(iter));continue_statement_p(stmt);POP(iter))
782  stmt=STATEMENT(CAR(iter));
783  }
784 
785  if(cprev!=NULL){
788  make_test(
790  new_statements(p),
792  )
793  );
794  }
796  ifdebug(2) {
797  pips_debug(2,"updated statement instruction\n");
799  }
800  //pips_assert("inlining statement generation is ok",statement_consistent_p(stmt));
801  }
803 }
804 
805 /* split the declarations from s from their initialization if they contain a call to inlined_module
806  */
807 static
809 {
810 
811  if(statement_block_p(s))
812  {
813  list prelude = NIL;
814  set selected_entities = set_make(set_pointer);
816  {
817  value v = entity_initial(e);
819  {
820  /* the first condition is a bit tricky :
821  * check int a = foo(); int b=bar();
822  * once we decide to inline foo(), we must split b=bar()
823  * because foo may touch a global variable used in bar()
824  */
825  if( !ENDP(prelude) ||
827  {
828  set_add_element(selected_entities,selected_entities,e);
832  }
833  }
834  }
835  set_free(selected_entities);
836  FOREACH(STATEMENT,st,prelude)
837  insert_statement(s,st,true);
838  gen_free_list(prelude);
839  }
841  pips_user_warning("only blocks and declaration statements should have declarations\n");
842 }
843 
844 /* this should replace all call to `inlined' in `module'
845  * by the expansion of `inlined'
846  */
847 static void
849 {
850  entity modified_module = module_name_to_entity(module);
851  /* get target module's ressources */
852  statement modified_module_statement =
853  (statement) db_get_memory_resource(DBR_CODE, module, true);
854  pips_assert("statements found", !statement_undefined_p(modified_module_statement) );
855  pips_debug(2,"inlining %s in %s\n",entity_user_name(inlined_module(p)),module);
856 
857  set_current_module_entity( modified_module );
858  set_current_module_statement( modified_module_statement );
859 
860  /* first pass : convert some declaration with assignment to declarations + statements, if needed */
862  /* inline all calls to inlined_module */
864  ifdebug(1) statement_consistent_p(modified_module_statement);
865  ifdebug(2) {
866  pips_debug(2,"in inline_calls for %s\n",module);
867  print_statement(modified_module_statement);
868  }
869 
870  DB_PUT_MEMORY_RESOURCE(DBR_CODE, module, modified_module_statement);
871  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, module, compute_callees(modified_module_statement));
874 }
875 
876 /**
877  * this should inline all calls to module `module_name'
878  * in calling modules, if possible ...
879  *
880  * @param module_name name of the module to inline
881  *
882  * @return true if we did something
883  */
884 static
886 {
887  if(get_bool_property("INLINING_IGNORE_STUBS") && db_resource_p(DBR_STUBS, "")) {
888  // Look for stubs and prevent inlining them
889  callees stubs=(callees)db_get_memory_resource(DBR_STUBS,"",true);
890  FOREACH(string,stub,callees_callees(stubs)) {
891  if(same_string_p(module_name,stub)) {
892  return true;
893  }
894  }
895  }
896 
897  /* Get the module ressource */
900 
902 
903  /* check them */
906  debug_on("INLINING_DEBUG_LEVEL");
907 
908 
909  /* parse filter property */
910  string inlining_callers_name = strdup(get_string_property("INLINING_CALLERS"));
911  list callers_l = NIL;
912 
913  string c_name= NULL;
914  for(c_name = strtok(inlining_callers_name," ") ; c_name ; c_name=strtok(NULL," ") )
915  {
916  callers_l = CONS(STRING, c_name, callers_l);
917  }
918  /* or get module's callers */
919  callees callers = (callees)db_get_memory_resource(DBR_CALLERS, module_name, true);
920  if(ENDP(callers_l))
921  {
922  callers_l = callees_callees(callers);
923  }
924 
925  /* inline call in each caller */
926  FOREACH(STRING, caller_name,callers_l)
927  {
930  }
931  FOREACH(STRING,c0,callers_l) {
932  FOREACH(STRING,c1,callees_callees(callers)) {
933  if(same_string_p(c0,c1)) {
934  gen_remove_once(&callees_callees(callers),c1);
935  break;
936  }
937  }
938  }
939 
940  DB_PUT_MEMORY_RESOURCE(DBR_CALLERS,module_name,callers);
941 
943 
944  pips_debug(2, "inlining done for %s\n", module_name);
945  debug_off();
946  /* Should have worked: */
947  return true;
948 }
949 
950 /**
951  * perform inlining using effects
952  *
953  * @param module_name name of the module to inline
954  *
955  * @return
956  */
957 bool inlining(const char* module_name)
958 {
959  iparam p =IPARAM_INIT;
960  use_effects(&p)=true;
961  return do_inlining(&p,module_name);
962 }
963 
964 /**
965  * perform inlining without using effects
966  *
967  * @param module_name name of the module to inline
968  *
969  * @return
970  */
971 bool inlining_simple(const char* module_name)
972 {
973  iparam p =IPARAM_INIT;
974  use_effects(&p)=false;
975  return do_inlining(&p,module_name);
976 }
977 
978 /** @} */
979 
980 /**
981  * @name unfolding
982  * @{ */
983 
984 /**
985  * get ressources for the call to inline and call
986  * apropriate inlining function
987  *
988  * @param caller_name calling module name
989  * @param module_name called module name
990  */
991 static bool
993 {
994  /* Get the module ressource */
997  (statement) db_get_memory_resource(DBR_CODE, module_name, true);
998 
1001  {
1002  pips_user_warning("not inlining empty function %s, "
1003  "this should be a generated skeleton ...\n",
1004  module_name);
1005  return false;
1006  }
1007  else {
1009 
1010  /* check them */
1012  pips_assert("statements found", !statement_undefined_p(inlined_module_statement(p)) );
1013 
1014  /* inline call */
1015  inline_calls( p, caller_name );
1017  return true;
1018  }
1019 }
1020 
1021 
1022 /**
1023  * this should inline all call in module `module_name'
1024  * it does not works recursievly, so multiple pass may be needed
1025  * returns true if at least one function has been inlined
1026  *
1027  * @param module_name name of the module to unfold
1028  *
1029  * @return true if we did something
1030  */
1031 static
1033 {
1034  debug_on("UNFOLDING_DEBUG_LEVEL");
1035 
1036  /* parse filter property */
1037  string unfolding_filter_names = strdup(get_string_property("UNFOLDING_FILTER"));
1038  set unfolding_filters = set_make(set_string);
1039 
1040  list filtersname = strsplit(unfolding_filter_names," ");
1041  FOREACH(STRING,filter_name,filtersname)
1042  {
1043  set_add_element(unfolding_filters, unfolding_filters, filter_name);
1045  }
1046  gen_map(free,filtersname);gen_free_list(filtersname);
1047 
1048  /* parse callee property */
1049  string unfolding_callees_names = strdup(get_string_property("UNFOLDING_CALLEES"));
1050  set unfolding_callees = set_make(set_string);
1051 
1052  string callee_name= NULL;
1053  for(callee_name = strtok(unfolding_callees_names," ") ; callee_name ; callee_name=strtok(NULL," ") )
1054  {
1055  set_add_element(unfolding_callees, unfolding_callees, callee_name);
1056  }
1057 
1058  /* gather all referenced calls as long as there are some */
1059  bool statement_has_callee = false;
1060  do {
1061  statement_has_callee = false;
1062  statement unfolded_module_statement =
1063  (statement) db_get_memory_resource(DBR_CODE, module_name, true);
1064  /* gather all referenced calls */
1065  callees cc =compute_callees(unfolded_module_statement);
1066  set calls_name = set_make(set_string);
1067  set_assign_list(calls_name,callees_callees(cc));
1068 
1069 
1070  /* maybe the user put a restriction on the calls to inline ?*/
1071  if(!set_empty_p(unfolding_callees))
1072  calls_name=set_intersection(calls_name,calls_name,unfolding_callees);
1073 
1074  /* maybe the user used a filter ?*/
1075  calls_name=set_difference(calls_name,calls_name,unfolding_filters);
1076 
1077 
1078 
1079  /* there is something to inline */
1080  if( (statement_has_callee=!set_empty_p(calls_name)) )
1081  {
1083  FOREACH(STRING,call_name,sorted) {
1084  if(!run_inlining(module_name,call_name,p))
1085  set_add_element(unfolding_filters,unfolding_filters,call_name);
1086  }
1087  free(sorted);
1089 #if 0
1090  /* we can try to remove some labels now*/
1091  if( get_bool_property("INLINING_PURGE_LABELS"))
1093  pips_user_warning("failed to remove useless labels after restructure_control in inlining");
1094 #endif
1095  }
1096  set_free(calls_name);
1097  free_callees(cc);
1098  } while(statement_has_callee);
1099 
1100  set_free(unfolding_filters);
1101  free(unfolding_filter_names);
1102 
1103 
1104  pips_debug(2, "unfolding done for %s\n", module_name);
1105 
1106  debug_off();
1107  return true;
1108 }
1109 
1110 
1111 /**
1112  * perform unfolding using effect
1113  *
1114  * @param module_name name of the module to unfold
1115  *
1116  * @return
1117  */
1119 {
1120  iparam p = IPARAM_INIT;
1121  use_effects(&p)=true;
1122  return do_unfolding(&p,module_name);
1123 }
1124 
1125 
1126 /**
1127  * perform unfolding without using effects
1128  *
1129  * @param module_name name of the module to unfold
1130  *
1131  * @return true upon success
1132  */
1134 {
1135  iparam p = IPARAM_INIT;
1136  use_effects(&p)=false;
1137  return do_unfolding(&p,module_name);
1138 }
1139 /** @} */
instruction copy_instruction(instruction p)
INSTRUCTION.
Definition: ri.c:1115
call make_call(entity a1, list a2)
Definition: ri.c:269
value make_value_unknown(void)
Definition: ri.c:2847
value make_value_expression(expression _field_)
Definition: ri.c:2850
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
type copy_type(type p)
TYPE.
Definition: ri.c:2655
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
instruction make_instruction_expression(expression _field_)
Definition: ri.c:1196
void free_callees(callees p)
Definition: ri.c:194
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
bool statement_consistent_p(statement p)
Definition: ri.c:2195
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
instruction make_instruction_sequence(sequence _field_)
Definition: ri.c:1169
instruction make_instruction_test(test _field_)
Definition: ri.c:1172
value copy_value(value p)
VALUE.
Definition: ri.c:2784
bool expression_consistent_p(expression p)
Definition: ri.c:859
call copy_call(call p)
CALL.
Definition: ri.c:233
void free_expression(expression p)
Definition: ri.c:853
storage copy_storage(storage p)
STORAGE.
Definition: ri.c:2228
entity copy_entity(entity p)
ENTITY.
Definition: ri.c:2521
sequence make_sequence(list a)
Definition: ri.c:2125
instruction make_instruction_goto(statement _field_)
Definition: ri.c:1181
void free_value(value p)
Definition: ri.c:2787
syntax make_syntax_reference(reference _field_)
Definition: ri.c:2494
bool db_resource_p(const char *rname, const char *oname)
true if exists and in loaded or stored state.
Definition: database.c:524
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
static const char * caller_name
Definition: alias_check.c:122
static entity callee
Definition: alias_pairs.c:62
void const char const char const int
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
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
void set_cumulated_rw_effects(statement_effects)
bool find_write_effect_on_entity(statement, entity)
void reset_cumulated_rw_effects(void)
bool empty_string_p(const char *s)
Definition: entity_names.c:239
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
char * get_string_property(const char *)
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 free(void *)
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
statement make_empty_block_statement(void)
Build an empty statement (block/sequence)
Definition: statement.c:625
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
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void replace_entities(void *s, hash_table ht)
Recursively substitute a set of entities in a statement.
Definition: replace.c:91
void replace_entity(void *s, entity old, entity new)
per variable version of replace_entities.
Definition: replace.c:113
void replace_entity_by_expression(void *s, entity ent, expression exp)
replace all reference to entity ent by expression exp in s.
Definition: replace.c:220
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
gen_chunk * gen_get_ancestor(int, const void *)
return the first ancestor object found of the given type.
Definition: genClib.c:3560
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
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
#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
void gen_map(gen_iter_func_t fp, const list l)
Definition: list.c:172
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
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
#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
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool statement_loop_p(statement)
Definition: statement.c:349
statement make_assign_statement(expression, expression)
Definition: statement.c:583
void insert_comments_to_statement(statement, const char *)
Insert a comment string (if non empty) at the beginning of the comments of a statement.
Definition: statement.c:1916
statement update_statement_instruction(statement, instruction)
Replace the instruction in statement s by instruction i.
Definition: statement.c:3039
bool return_statement_p(statement)
Test if a statement is a C or Fortran "return".
Definition: statement.c:172
bool continue_statement_p(statement)
Test if a statement is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: statement.c:203
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
statement make_continue_statement(entity)
Definition: statement.c:953
void fix_statement_attributes_if_sequence(statement)
Apply fix_sequence_statement_attributes() on the statement only if it really a sequence.
Definition: statement.c:2078
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
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
#define inlined_module(p)
Definition: inlining.c:95
static void inline_return_crawler(statement s, inlining_parameters p)
replace return instruction by an assignment and a goto
Definition: inlining.c:118
#define use_effects(p)
Definition: inlining.c:103
static bool inline_has_inlinable_calls(entity inlined_module, void *elem)
Definition: inlining.c:736
#define has_inlinable_calls(p)
Definition: inlining.c:99
static void do_slightly_rename_entities(statement s, hash_table old_new)
Definition: inlining.c:262
static void inline_has_inlinable_calls_crawler(call callee, inlining_parameters p)
check if a call has inlinable calls
Definition: inlining.c:729
static bool inline_should_inline(entity inlined_module, call callee)
helper function to check if a call is a call to the inlined function
Definition: inlining.c:143
static entity make_temporary_scalar_entity(expression from, statement *assign)
create a scalar similar to ‘efrom’ initialized with expression ‘from’
Definition: inlining.c:216
static void inline_split_declarations(statement s, entity inlined_module)
split the declarations from s from their initialization if they contain a call to inlined_module
Definition: inlining.c:808
static void solve_name_clashes(statement s, entity new)
look for entity locally named has ‘new’ in statements ‘s’ when found, find a new name and perform sub...
Definition: inlining.c:163
#define returned_entity(p)
Definition: inlining.c:102
static void statement_with_static_declarations_p(statement s, inlining_parameters p)
return true if an entity declared in the statement ‘s’ from ‘p->inlined_module’
Definition: inlining.c:208
bool unfolding(char *module_name)
perform unfolding using effect
Definition: inlining.c:1118
static bool has_similar_entity(entity e, set se)
Definition: inlining.c:148
static statement expanded
Definition: inlining.c:157
static void inline_calls(inlining_parameters p, char *module)
this should replace all call to ‘inlined’ in ‘module’ by the expansion of ‘inlined’
Definition: inlining.c:848
#define IPARAM_INIT
Definition: inlining.c:84
bool has_entity_with_same_name(entity e, list l)
inlining.c
Definition: inlining.c:256
static bool do_inlining(inlining_parameters p, const char *module_name)
this should inline all calls to module ‘module_name’ in calling modules, if possible ....
Definition: inlining.c:885
#define laststmt(p)
Definition: inlining.c:100
static void inlining_regenerate_labels(statement s, entity new_module)
regenerate the label of each statement with a label.
Definition: inlining.c:236
static statement inline_expression_call(inlining_parameters p, expression modified_expression, call callee)
this should inline the call callee calling module inlined_module
Definition: inlining.c:314
bool inlining_simple(const char *module_name)
perform inlining without using effects
Definition: inlining.c:971
bool unfolding_simple(char *module_name)
perform unfolding without using effects
Definition: inlining.c:1133
static void inline_statement_crawler(statement stmt, inlining_parameters p)
this is in charge of replacing instruction by new ones only apply if this instruction does not contai...
Definition: inlining.c:749
struct iparam * inlining_parameters
static void inline_return_remover(statement s, inlining_parameters p)
replace return instruction by a goto
Definition: inlining.c:109
bool inlining(const char *module_name)
perform inlining using effects
Definition: inlining.c:957
#define inlined_module_statement(p)
Definition: inlining.c:96
static bool inline_has_static_declaration(list iter)
return true if an entity declared in ‘iter’ is static to ‘module’
Definition: inlining.c:194
#define tail_ins(p)
Definition: inlining.c:101
#define has_static_declaration(p)
Definition: inlining.c:98
static bool run_inlining(string caller_name, const char *module_name, inlining_parameters p)
get ressources for the call to inline and call apropriate inlining function
Definition: inlining.c:992
static void slightly_rename_entities(statement s)
sg: this is another inlining mostruosity it ensures all entities in s have new pointer and different ...
Definition: inlining.c:298
static bool do_unfolding(inlining_parameters p, char *module_name)
this should inline all call in module ‘module_name’ it does not works recursievly,...
Definition: inlining.c:1032
static void inline_expression(expression expr, inlining_parameters p)
recursievly inline an expression if needed
Definition: inlining.c:705
#define new_statements(p)
Definition: inlining.c:97
struct _newgen_struct_control_ * control
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define asprintf
Definition: misc-local.h:225
#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
#define BLOCK_SEP_STRING
Scope separator.
Definition: naming-local.h:50
list strsplit(const char *, const char *)
Definition: string.c:318
int gen_qsort_string_cmp(const void *, const void *)
Callback for sorting string with qsort.
Definition: string.c:332
@ hash_pointer
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_FOREACH(key_type, k, value_type, v, ht)
Definition: newgen_hash.h:71
#define HASH_DEFAULT_SIZE
Definition: newgen_hash.h:26
#define same_string_p(s1, s2)
bool set_empty_p(const set)
tell whether set s is empty.
Definition: set.c:367
set set_assign_list(set, const list)
assigns a list contents to a set all duplicated elements are lost
Definition: set.c:474
set set_intersection(set, const set, const set)
Definition: set.c:229
list set_to_sorted_list(const set, gen_cmp_func_t)
Definition: set.c:447
set set_difference(set, const set, const set)
Definition: set.c:256
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
void set_free(set)
Definition: set.c:332
@ set_pointer
Definition: newgen_set.h:44
@ set_string
Definition: newgen_set.h:42
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114
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
bool recompile_module(const string module)
build a textual representation of the modified module and update db
Definition: module.c:87
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
bool same_entity_lname_p(entity, entity)
Definition: same_names.c:64
#define statement_block_p(stat)
#define DEREFERENCING_OPERATOR_NAME
Definition: ri-util-local.h:93
#define entity_declarations(e)
MISC: newgen shorthands.
#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 make_statement_list(stats...)
easy list constructor
#define entity_constant_p(e)
bool entity_area_p(entity e)
Definition: area.c:149
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
bool entity_enum_member_p(entity e)
Definition: entity.c:980
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
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 FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
int compare_entities(const entity *pe1, const entity *pe2)
Comparison function for qsort.
Definition: entity.c:1328
bool entity_formal_p(entity p)
is p a formal parameter?
Definition: entity.c:1935
bool entity_subroutine_p(entity e)
Definition: entity.c:737
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
code entity_code(entity e)
Definition: entity.c:1098
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool extern_entity_p(entity module, entity e)
Definition: entity.c:1977
bool entity_function_p(entity e)
Definition: entity.c:724
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_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool entity_empty_label_p(entity e)
Definition: entity.c:666
bool same_entity_name_p(entity e1, entity e2)
compare entity names
Definition: entity.c:2208
entity make_new_label(entity module)
This function returns a new label.
Definition: entity.c:357
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
bool entity_pointer_p(entity e)
Definition: entity.c:745
entity entity_field_to_entity_struct_or_union(entity f)
Definition: entity.c:925
set get_referenced_entities(void *elem)
retrieves the set of entities used in elem beware that this entities may be formal parameters,...
Definition: entity.c:3063
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
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 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 MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
Definition: module.c:327
void AddLocalEntityToDeclarations(entity, entity, statement)
Add the variable entity e to the list of variables of the function module.
Definition: variable.c:233
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
entity make_new_array_variable_with_prefix(const char *, entity, basic, list)
J'ai ameliore la fonction make_new_scalar_variable_with_prefix
Definition: variable.c:785
entity make_new_scalar_variable(entity, basic)
Definition: variable.c:741
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70
entity make_temporary_pointer_to_array_entity(entity, expression, entity)
Definition: variable.c:819
void AddEntityToDeclarations(entity, entity)
END_EOLE.
Definition: variable.c:108
basic some_basic_of_any_expression(expression, bool, bool)
basic basic_of_any_expression(expression exp, bool apply_p): Makes a basic of the same basic as the e...
Definition: type.c:1258
void AddEntityToCurrentModule(entity)
Add a variable entity to the current module declarations.
Definition: variable.c:260
bool formal_parameter_p(entity)
Definition: variable.c:1489
entity make_new_scalar_variable_with_prefix(const char *, entity, basic)
Create a new scalar variable of type b in the given module.
Definition: variable.c:592
entity find_label_entity(const char *, const char *)
util.c
Definition: util.c:43
bool implicit_c_variable_p(entity)
Definition: variable.c:1877
entity make_global_entity_from_local(entity)
Definition: variable.c:281
bool variable_static_p(entity)
true if v appears in a SAVE statement, or in a DATA statement, or is declared static i C.
Definition: variable.c:1579
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_code_p(x)
Definition: ri.h:3065
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define functional_result(x)
Definition: ri.h:1444
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#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 code_externs(x)
Definition: ri.h:790
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_cast(x)
Definition: ri.h:2739
#define type_functional(x)
Definition: ri.h:2952
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define control_domain
newgen_controlmap_domain_defined
Definition: ri.h:98
#define code_declarations(x)
Definition: ri.h:784
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
#define statement_label(x)
Definition: ri.h:2450
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#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 sequence_statements(x)
Definition: ri.h:2360
#define reference_indices(x)
Definition: ri.h:2328
#define value_code(x)
Definition: ri.h:3067
#define instruction_sequence(x)
Definition: ri.h:1514
#define syntax_call(x)
Definition: ri.h:2736
#define loop_label(x)
Definition: ri.h:1646
#define instruction_call_p(x)
Definition: ri.h:1527
#define expression_undefined_p(x)
Definition: ri.h:1224
#define variable_dimensions(x)
Definition: ri.h:3122
#define code_decls_text(x)
Definition: ri.h:786
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define call_arguments(x)
Definition: ri.h:711
#define statement_undefined_p(x)
Definition: ri.h:2420
#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 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_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
char * strndup(char const *s, size_t n)
A replacement function, for systems that lack strndup.
Definition: strndup.c:26
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
structure containing all the parameters needed by inlining.
Definition: inlining.c:73
entity _returned_entity_
Definition: inlining.c:81
bool _use_effects_
Definition: inlining.c:82
statement _new_statements_
Definition: inlining.c:76
entity _inlined_module_
Definition: inlining.c:74
bool _has_inlinable_calls_
Definition: inlining.c:78
statement _inlined_module_statement_
Definition: inlining.c:75
instruction _tail_ins_
Definition: inlining.c:80
bool _has_static_declaration_
Definition: inlining.c:77
statement _laststmt_
Definition: inlining.c:79
Definition: statement.c:54
bool remove_useless_label(const string)
void AddEntityToModuleCompilationUnit(entity e, entity module)
Definition: module.c:301