PIPS
interactive_loop_transformation.c
Go to the documentation of this file.
1 /*
2 
3  $Id: interactive_loop_transformation.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 #ifdef HAVE_CONFIG_H
26  #include "pips_config.h"
27 #endif
28 /* Interface with pipsmake for interactive loop transformations: loop
29  * interchange, hyperplane method,...
30  */
31 
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include "genC.h"
36 #include "linear.h"
37 
38 #include "misc.h"
39 #include "pipsdbm.h"
40 #include "properties.h"
41 
42 #include "ri.h"
43 #include "ri-util.h"
44 #include "text-util.h"
45 
46 #include "control.h" // module_reorder
47 #include "conversion.h" // look_for_nested_loop_statements
48 #include "pipsmake.h" // safe_make hack?
49 
50 #include "prettyprint.h" // extension_to_string
51 
52 #include "transformations.h" // find_loop_from_label in "util.c"
53 
54 // forward declaration
55 /*
56 static char* loop_pragma(const char*, const char*);
57 static char* module_loops(const char*, const char*);
58 */
59 
60 // hmmm...
62 
64 {
65  /* SG+EC 2010:
66  The loop_label(statement_loop(s)) is kept for compatibility reasons
67  but is invalid and should eventually be removed */
68  return statement_loop_p(s) &&
71 }
72 
74 (const char* module_name,
75  statement (*loop_transformation)(list, bool (*)(statement))
76 )
77 {
78  const char *lp_label=NULL;
81  bool return_status = false;
82 
83  pips_assert("interactive_loop_transformation", entity_module_p(module));
84 
85  /* DBR_CODE will be changed: argument "pure" should take false but
86  this would be useless since there is only *one* version of code;
87  a new version will be put back in the data base after transforming
88  the loops */
89  s = (statement) db_get_memory_resource(DBR_CODE, module_name, true);
92 
93  /* Get the loop label from the user */
94  lp_label = get_string_property_or_ask("LOOP_LABEL","Which loop do you want to transform?\n"
95  "(give its label): ");
96  if( string_undefined_p( lp_label ) )
97  {
98  pips_user_error("please set %s property to a valid label\n","LOOP_LABEL");
99  }
100 
101  if(lp_label)
102  {
105  pips_user_error("loop label `%s' does not exist\n", lp_label);
106  }
107 
108  debug_on("INTERACTIVE_LOOP_TRANSFORMATION_DEBUG_LEVEL");
109 
110  look_for_nested_loop_statements(s, loop_transformation, selected_loop_p);
111 
112  debug_off();
113 
114  /* Reorder the module, because new statements have been generated. */
115  module_reorder(s);
116 
117  DB_PUT_MEMORY_RESOURCE(DBR_CODE,
119  (char*) s);
120  return_status = true;
121  }
124 
125  return return_status;
126 }
127 
128 typedef struct {
132 
133 static void flag_loop(statement st, flag_loop_param_t *flp)
134 {
137  {
139  flp->new_label_created=true;
140  }
141  if( !get_bool_property("FLAG_LOOPS_DO_LOOPS_ONLY")
142  && instruction_forloop_p(i))
143  {
146  flp->new_label_created=true;
147  }
149  }
150 }
151 
152 bool print_loops(const string module_name)
153 {
154  /* prelude */
158 
159  /* do the job */
160  {
161  string local = db_build_file_resource_name(DBR_LOOPS_FILE, module_name, ".loops");
162  string dir = db_get_current_workspace_directory();
163  string full = strdup(concatenate(dir,"/",local, NULL));
164  free(dir);
165  FILE * fp = safe_fopen(full,"w");
166  text r = make_text(NIL);
168  {
170  }
171  print_text(fp,r);
172  free_text(r);
173  safe_fclose(fp,full);
174  free(full);
175  DB_PUT_FILE_RESOURCE(DBR_LOOPS_FILE, module_name, local);
176  }
177 
178  /*postlude*/
181  return true;
182 }
183 
184 /**
185  * put a label on each doloop without label
186  *
187  * @param module_name
188  *
189  * @return
190  */
191 bool flag_loops(const string module_name)
192 {
193  /* prelude */
196  ((statement) db_get_memory_resource(DBR_CODE, module_name, true) );
197  flag_loop_param_t flp = { .loops = NIL, .new_label_created = false };
198 
199  /* run loop labeler */
202 
203  /* validate */
206 
207  /*postlude*/
210  return true;
211 }
212 
214 {
215  if(statement_loop_p(s))
216  {
217  string tmp;
218  asprintf(&tmp,"%s ",label_local_name(statement_label(s)));
219  *l=CONS(STRING,tmp,*l);
220  return false;
221  }
222  return true;
223 }
224 
225 char* loop_pragma(const char* module_name, const char* parent_loop)
226 {
227  // ensure pipsmake is ok with what we ask for
228  safe_make(DBR_LOOPS,module_name);
229 
230  // prelude
233  ((statement) db_get_memory_resource(DBR_CODE, module_name, true) );
234 
235  entity label = find_label_entity(module_name,parent_loop);
236  if(entity_undefined_p(label))
237  pips_user_error("label '%s' does not exist\n",parent_loop);
240  pips_user_error("label '%s' is not on a loop\n",parent_loop);
242  if(string_undefined_p(s)) s = strdup("");
245  return s;
246 }
247 
248 /**
249  * gather the list of enclosing loops
250  * expect flag_loops has been called before
251  *
252  * @param module_name module we want the loops of
253  * @param parent_loop null if we wat to gather outer loops, a loop_label if we want to gather enclosed loops
254  *
255  * @return list of strings, one string per loop label
256  *
257  * this function is needed by pyps?
258  */
259 char* module_loops(const char* module_name, const char* parent_loop)
260 {
261  // ensure pipsmake is ok with what we ask for
262  safe_make(DBR_LOOPS,module_name);
263 
264  // prelude
267  ((statement) db_get_memory_resource(DBR_CODE, module_name, true) );
268  list loops = NIL;
269 
271  if(empty_string_p(parent_loop))
273  else {
274  entity label = find_label_entity(module_name,parent_loop);
275  if(entity_undefined_p(label))
276  pips_user_error("label '%s' does not exist\n",parent_loop);
279  pips_user_error("label '%s' is not on a loop\n",parent_loop);
281  }
282 
283  // run loop gatherer
284  gen_context_recurse(seed, &loops,
287 
288  // postlude
291  string out = list_to_string(loops);
293  if(out) out[strlen(out)-1]=0;
294  return out;
295 }
callees make_callees(list a)
Definition: ri.c:227
text make_text(list a)
Definition: text.c:107
void free_text(text p)
Definition: text.c:74
static FILE * out
Definition: alias_check.c:128
string list_to_string(list l)
Return the malloc()ed version of the concatenation of all the strings in the list.
Definition: args.c:74
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
static list loops
void look_for_nested_loop_statements(statement, statement(*)(list, bool(*)(statement)), bool(*)(statement))
look_for_nested_loops.c
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
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
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
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
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
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
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
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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
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 DB_PUT_FILE_RESOURCE
Put a file resource into the current workspace database.
Definition: pipsdbm-local.h:85
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
bool statement_loop_p(statement)
Definition: statement.c:349
bool interactive_loop_transformation(const char *module_name, statement(*loop_transformation)(list, bool(*)(statement)))
entity selected_label
Interface with pipsmake for interactive loop transformations: loop interchange, hyperplane method,...
char * loop_pragma(const char *module_name, const char *parent_loop)
static void flag_loop(statement st, flag_loop_param_t *flp)
bool selected_loop_p(statement s)
bool print_loops(const string module_name)
char * module_loops(const char *module_name, const char *parent_loop)
gather the list of enclosing loops expect flag_loops has been called before
static bool module_loops_walker(statement s, list *l)
bool flag_loops(const string module_name)
put a label on each doloop without label
string db_build_file_resource_name(const char *rname, const char *oname, const char *suffix)
returns an allocated file name for a file resource.
Definition: lowlevel.c:169
#define debug_on(env)
Definition: misc-local.h:157
#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 debug_off()
Definition: misc-local.h:160
#define pips_user_error
Definition: misc-local.h:147
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define string_undefined_p(s)
Definition: newgen_types.h:41
static char * module
Definition: pips.c:74
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
bool safe_make(const char *res_n, const char *module_n)
Definition: pipsmake.c:1717
string extensions_to_string(extensions es, bool nl)
return a new allocated string with the string representation of the extensions.
Definition: extension.c:111
const char * get_string_property_or_ask(const char *, const char[])
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool entity_empty_label_p(entity e)
Definition: entity.c:666
bool entity_module_p(entity e)
Definition: entity.c:683
entity make_new_label(entity module)
This function returns a new label.
Definition: entity.c:357
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
entity find_label_entity(const char *, const char *)
util.c
Definition: util.c:43
#define loop_body(x)
Definition: ri.h:1644
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define instruction_loop_p(x)
Definition: ri.h:1518
#define callees_callees(x)
Definition: ri.h:675
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define instruction_forloop_p(x)
Definition: ri.h:1536
#define statement_label(x)
Definition: ri.h:2450
#define entity_undefined_p(x)
Definition: ri.h:2762
#define statement_extensions(x)
Definition: ri.h:2464
#define loop_label(x)
Definition: ri.h:1646
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_undefined_p(x)
Definition: ri.h:2420
#define statement_undefined
Definition: ri.h:2419
char * strdup()
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:54
#define MAKE_ONE_WORD_SENTENCE(m, s)
#define ADD_SENTENCE_TO_TEXT(t, p)
void print_text(FILE *fd, text t)
Definition: print.c:195
statement find_loop_from_label(statement, entity)
Definition: util.c:218
@ full
Definition: union-local.h:65