PIPS
rename_operator.c
Go to the documentation of this file.
1 #ifdef HAVE_CONFIG_H
2  #include "pips_config.h"
3 #endif
4 
5 #include <stdlib.h>
6 #include <stdio.h>
7 
8 #include "genC.h"
9 #include "newgen_set.h"
10 #include "linear.h"
11 #include "ri.h"
12 #include "ri-util.h"
13 #include "control.h"
14 #include "pipsdbm.h"
15 #include "resources.h"
16 #include "properties.h"
17 
18 #include "callgraph.h"
19 
20 #include "misc.h"
21 
22 static set ops_set = NULL;
23 static set suffixes_set = NULL;
24 static const char* prefix = NULL;
25 
26 //Helper macro for tiedous tasks.
27 #define __KV(key, value) if(strcmp( key ,s) == 0) return value;
28 #define __MKV(key, value) __KV(TOP_LEVEL_MODULE_NAME MODULE_SEP_STRING key , value)
29 
30 //Returns the name of an operation.
31 //NULL if not found.
32 static const char* opname(const char* s)
33 {
34  // /!\ When adding operators to this list,
35  // don’t forget to update the corresponding table in the
36  // Rename Operator section of pipsmake-rc.tex
37 
40 
43 
45  __MKV(PLUS_OPERATOR_NAME, "plus")
48  __MKV(MINUS_OPERATOR_NAME, "minus")
49  __MKV(UNARY_MINUS_OPERATOR_NAME, "un_minus")
50 
54 
55  __MKV(ASSIGN_OPERATOR_NAME, "assign")
61 
68  return NULL;
69 }
70 
71 static bool take_lvalue(const char* s)
72 {
79  return false;
80 }
81 
82 //Returns the short suffix associated with a type.
83 //NULL if not found.
84 static const char* typesuffix(const char* s)
85 {
86  // /!\ When adding types to this list,
87  // don’t forget to update the corresponding table in the
88  // Rename Operator section of pipsmake-rc.tex
89 
90  __KV("char","c")
91  __KV("short","s")
92  __KV("int","i")
93  __KV("long","l")
94  __KV("float","f")
95  __KV("double","d")
96  __KV("_Bool","b")
97  __KV("_Complex","C")
98  __KV("_Imaginary","I")
99  return NULL;
100 }
101 
102 static
104 {
105  //TODO: Unary operators
106 
107  //Retrieve operator name
108  entity f = call_function(c);
109  string fname = entity_name(f);
110 
111  const char* name = opname(fname);
112 
113  if(!name || !set_belong_p(ops_set, name))
114  return; //Not an operator, skip it !
115 
116  //Retrieve arguments type.
117  //All arguments should have the same type
118 
119  list args = call_arguments(c);
120 
121  string tname = NULL; //Arguments type
122 
123  FOREACH(EXPRESSION, arg, args)
124  {
125  type t = expression_to_type(arg); //Get argument type
126 
127  if(type_variable_p(t))
128  {
130  if(tname && !same_string_p(tname,n))
131  {
132  //Arguments have not the same type
133  //Skip it
134  free_type(t); free(n);
135  return;
136  }
137  free(tname);
138  tname = n;
139  }
140  else
141  {
142  //Not a basic type, maybe a compound type
143  //Skip it
144  free_type(t);
145  return;
146  }
147  free_type(t);
148  }
149 
150  if(!tname)
151  //Nullary function, quite strange for an operator
152  return;
153 
154  //Try to find the suffix
155  const char* suffix = typesuffix(tname);
156  if(!suffix || !set_belong_p(suffixes_set, suffix))
157  {
158  free(tname);
159  return; //Unknow suffix, is it really a basic type ?
160  }
161 
162  //Now try to construct a complete function name for the operator
163  //Function name look like TOP-LEVEL:<prefix><op name><type suffix>
164 
165  string fullname = malloc(1 + strlen(prefix) + strlen(name) + strlen(suffix));
166  strcat(strcat(strcpy(fullname, prefix), name), suffix);
167 
168  //Find the associated function in the entity list
169  entity newe = FindEntity(TOP_LEVEL_MODULE_NAME, fullname);
170 
171  if(newe == entity_undefined)
172  {
173  //Missing function ?
174  pips_user_warning("No function %s found, skipping operator %s\n", fullname, fname);
175  free(fullname);
176  free(tname);
177  return;
178  }
179 
180  if(take_lvalue(fname))
181  {
182  //Takes a lvalue as first argument
183  expression farg = EXPRESSION(CAR(args));
184  list l = CONS(EXPRESSION, copy_expression(farg), NIL);
187  }
188 
189  call_function(c) = newe; //Replace the operator by the new function
190 
191  free(fullname);
192  free(tname);
193 }
194 
195 static
197 {
198  if(statement_loop_p(sl))
200 }
201 
202 static
204 {
205  set s = set_make(set_string);
206  list l = strsplit(prop," ");
207  set_append_list(s, l);
208  //list_free(l);
209  return s;
210 }
211 
212 
213 /* A short pass that replace operators by function calls
214  */
215 bool rename_operator(const char* module_name)
216 {
217  /* prelude */
220 
221  /* some properties */
222  const char* ops_string = get_string_property("RENAME_OPERATOR_OPS");
223  ops_set = make_string_set_from_prop(ops_string);
224 
225  const char* suffixes_string = get_string_property("RENAME_OPERATOR_SUFFIXES");
226  suffixes_set = make_string_set_from_prop(suffixes_string);
227 
228  prefix = get_string_property("RENAME_OPERATOR_PREFIX");
229 
230  /* search */
231  if(get_bool_property("RENAME_OPERATOR_REWRITE_DO_LOOP_RANGE"))
234 
235  /* free properties */
236  set_free(ops_set);
237  ops_set = NULL;
238 
240  suffixes_set = NULL;
241 
242  prefix = NULL;
243 
244  /* update ressources */
247 
248  /*postlude*/
251  return true;
252 }
call make_call(entity a1, list a2)
Definition: ri.c:269
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
void free_type(type p)
Definition: ri.c:2658
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
void do_loop_to_for_loop(statement)
converts a doloop to a for loop, in place
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_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void * malloc(YYSIZE_T)
void free(void *)
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#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
#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
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
bool statement_loop_p(statement)
Definition: statement.c:349
#define pips_user_warning
Definition: misc-local.h:146
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
list strsplit(const char *, const char *)
Definition: string.c:318
#define same_string_p(s1, s2)
void set_free(set)
Definition: set.c:332
bool set_belong_p(const set, const void *)
Definition: set.c:194
@ set_string
Definition: newgen_set.h:42
set set_append_list(set, const list)
add list l items to set s, which is returned.
Definition: set.c:460
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
string basic_to_string(basic)
Definition: type.c:87
#define __KV(key, value)
static void rename_op(call c)
static set ops_set
static void rw_loop(statement sl)
static set make_string_set_from_prop(const char *prop)
static const char * prefix
static bool take_lvalue(const char *s)
static const char * typesuffix(const char *s)
static set suffixes_set
bool rename_operator(const char *module_name)
A short pass that replace operators by function calls.
#define __MKV(key, value)
static const char * opname(const char *s)
#define POST_DECREMENT_OPERATOR_NAME
Definition: ri-util-local.h:98
#define C_LESS_OR_EQUAL_OPERATOR_NAME
#define C_GREATER_OR_EQUAL_OPERATOR_NAME
#define C_GREATER_THAN_OPERATOR_NAME
#define MINUS_OPERATOR_NAME
#define DIVIDE_UPDATE_OPERATOR_NAME
#define MODULO_UPDATE_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define C_NON_EQUAL_OPERATOR_NAME
#define MULTIPLY_UPDATE_OPERATOR_NAME
#define MINUS_UPDATE_OPERATOR_NAME
#define ADDRESS_OF_OPERATOR_NAME
#define PRE_DECREMENT_OPERATOR_NAME
#define DIVIDE_OPERATOR_NAME
#define UNARY_MINUS_OPERATOR_NAME
#define UNARY_PLUS_OPERATOR_NAME
#define C_LESS_THAN_OPERATOR_NAME
#define PRE_INCREMENT_OPERATOR_NAME
Definition: ri-util-local.h:99
#define POST_INCREMENT_OPERATOR_NAME
Definition: ri-util-local.h:97
#define PLUS_UPDATE_OPERATOR_NAME
#define MINUS_C_OPERATOR_NAME
#define MULTIPLY_OPERATOR_NAME
#define C_EQUAL_OPERATOR_NAME
#define ASSIGN_OPERATOR_NAME
Definition: ri-util-local.h:95
#define MODULO_OPERATOR_NAME
#define PLUS_C_OPERATOR_NAME
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
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
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
#define call_function(x)
Definition: ri.h:709
#define type_variable(x)
Definition: ri.h:2949
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define call_arguments(x)
Definition: ri.h:711
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
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