PIPS
replace.c
Go to the documentation of this file.
1 #ifdef HAVE_CONFIG_H
2  #include "pips_config.h"
3 #endif
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include "linear.h"
9 #include "genC.h"
10 #include "misc.h"
11 #include "ri.h"
12 
13 #include "ri-util.h"
14 
15 /** @defgroup entity replacement in statements
16  * it is not unusual to generate a new entity,
17  * this helper functions will take care of substituing all referenced to
18  * an old entity by reference in new entities
19  * @{
20  */
21 
22 static void
24 {
25  // FI: this does not seem to replace the declaration itself
26  // I need a side-effect on the statement_declarations list when
27  // decl_ent == thecouple->old
29  replace_entities(decl_ent,ht);
30 }
31 
32 static void
34  entity new = hash_get(ht, call_function(c));
35  if( new != HASH_UNDEFINED_VALUE) {
36  call_function(c)=new;
37  }
38 }
39 
40 static void
42 {
43  if(expression_reference_p(parent)) {
44  reference r = expression_reference(parent);
45  entity new = hash_get(ht,reference_variable(r));
46  if(new!= HASH_UNDEFINED_VALUE) {
47  if(entity_constant_p(new)) {
50  );
51  }
52  else
53  reference_variable(r)=new;
54  expression next=parent,root=parent;
55  /* we need to unormalize the uppermost parent of this expression
56  * otherwise its normalized field gets incorrect */
57  while((next=(expression) gen_get_ancestor(expression_domain,next)))
58  root=next;
59  unnormalize_expression(root); /* otherwise field normalized get wrong */
60  }
61  }
62 }
63 
65  entity new = hash_get(ht,loop_index(l));
66  if(new!= HASH_UNDEFINED_VALUE) {
67  // We replace the loop index
68  loop_index(l) = new;
69  }
70 
71  // Handle loop locals, in-place replacement
72  for(list ll = loop_locals(l); !ENDP(ll); POP(ll)) {
73  entity local = ENTITY(CAR(ll));
74  entity new = hash_get(ht,local);
75  if(new!= HASH_UNDEFINED_VALUE) {
76  CAR(ll).p = (gen_chunkp)new;
77  }
78  }
79 }
80 
81 /**
82  * @brief Recursively substitute a set of entities in a statement
83  *
84  * @param s newgen type where the substitution must be done
85  * @param ht table of old->new pairs
86  *
87  * Warning: if the intersection between the input and output sets is not empty, the
88  * behavior is undefined
89  */
90 void
92 {
93  if( INSTANCE_OF(entity,(gen_chunkp)s) ) {
95  value v = entity_initial((entity)s);
96  if( !value_undefined_p(v) && value_expression_p( v ) )
97  replace_entities(v,ht);
98  }
99  else {
105  NULL);
106  }
107 }
108 
109 /* per variable version of replace_entities.
110  * Much slower if you have an hash table of old/new pairs than the replace_entities version
111  */
112 void
113 replace_entity(void* s, entity old, entity new) {
115  hash_put(ht,old,new);
116  replace_entities(s,ht);
117  hash_table_free(ht);
118 }
119 
120 
121 /** Replace an old reference by a reference to a new entity in a statement
122  */
123 void
124 replace_reference(void* s, reference old, entity new) {
125  /* If the reference is a scalar, it's similar to replace_entity,
126  otherwise, it's replace_entity_by_expression */
127  if (ENDP(reference_indices(old)))
128  replace_entity(s, reference_variable(old), new);
129  else {
130  pips_internal_error("not implemented yet");
131  }
132 }
133 
134 
136 static
138 {
139  if( expression_reference_p(e) )
140  {
143  {
145  if(!ENDP(reference_indices(r))) {
147  /* if both are references , concatenante indices */
149  {
151  syn = make_syntax_reference(
153  reference_variable(pr),
155  )
156  );
157  }
158  /* else generate a subscript */
159  else {
161  }
162  }
164  }
165  }
166  else if(expression_call_p(e))
167  {
168  call c = expression_call(e);
171 
172  }
173 }
174 
175 static
177 {
178  if( ! set_belong_p(p->visited_entities,e)) {
180  value v = entity_initial(e);
181  if( value_expression_p(v) )
186  }
187 }
188 
189 
190 static
192 {
195 
196 }
197 
198 static
200 {
202 }
203 void
205 {
206  struct param p = { ent, exp, set_make(set_pointer)};
211  NULL);
213 }
214 
215 /**
216  * replace all reference to entity @a ent by expression @e exp
217  * in @a s. @s can be any newgen type !
218  */
219 void
221 {
223 }
224 void
226 {
228 }
229 /** @} */
call make_call(entity a1, list a2)
Definition: ri.c:269
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
subscript make_subscript(expression a1, list a2)
Definition: ri.c:2327
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
syntax copy_syntax(syntax p)
SYNTAX.
Definition: ri.c:2442
syntax make_syntax_subscript(subscript _field_)
Definition: ri.c:2509
syntax make_syntax_reference(reference _field_)
Definition: ri.c:2494
#define call_constant_p(C)
Definition: flint_check.c:51
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
union gen_chunk * gen_chunkp
static void replace_entity_by_expression_loop_walker(loop l, struct param *p)
Definition: replace.c:199
static void replace_entity_by_expression_declarations_walker(statement s, struct param *p)
Definition: replace.c:191
void replace_entity_by_expression_with_filter(void *s, entity ent, expression exp, bool(*filter)(expression))
Definition: replace.c:204
static void replace_entities_loop_walker(loop l, hash_table ht)
Definition: replace.c:64
static void replace_entities_expression_walker(expression parent, hash_table ht)
Definition: replace.c:41
static void replace_entity_by_expression_expression_walker(expression e, struct param *p)
Definition: replace.c:137
void replace_entities(void *s, hash_table ht)
Recursively substitute a set of entities in a statement.
Definition: replace.c:91
static void replace_entity_by_expression_entity_walker(entity e, struct param *p)
Definition: replace.c:176
void replace_reference(void *s, reference old, entity new)
Replace an old reference by a reference to a new entity in a statement.
Definition: replace.c:124
static void replace_entities_declaration_walker(statement s, hash_table ht)
Definition: replace.c:23
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
static void replace_entities_call_walker(call c, hash_table ht)
Definition: replace.c:33
void replace_entities_by_expression(void *s, hash_table ht)
Definition: replace.c:225
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
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
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#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
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
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 pips_internal_error
Definition: misc-local.h:149
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
@ 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
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
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
#define INSTANCE_OF(type, value)
polymorhism thanks to newgen !
#define entity_constant_p(e)
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool expression_call_p(expression e)
Definition: expression.c:415
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
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
#define value_undefined_p(x)
Definition: ri.h:3017
#define normalized_undefined
Definition: ri.h:1745
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define reference_indices(x)
Definition: ri.h:2328
#define loop_locals(x)
Definition: ri.h:1650
#define statement_declarations(x)
Definition: ri.h:2460
#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 value_expression(x)
Definition: ri.h:3082
#define loop_index(x)
Definition: ri.h:1640
#define entity_initial(x)
Definition: ri.h:2796
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
Definition: replace.c:135
expression exp
Definition: replace.c:135
entity ent
Definition: replace.c:135
set visited_entities
Definition: replace.c:135
A gen_chunk is used to store every object.
Definition: genC.h:58
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207