PIPS
group_constants.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 group_constants.c
24  * provide several layour for program constants grouping
25  * @author Serge Guelton <serge.guelton@enst-bretagne.fr>
26  * @date 2010-05-12
27  */
28 #ifdef HAVE_CONFIG_H
29  #include "pips_config.h"
30 #endif
31 #include <ctype.h>
32 
33 
34 #include "genC.h"
35 #include "ri-util.h"
36 #include "effects.h"
37 #include "effects-util.h"
38 #include "pipsdbm.h"
39 #include "resources.h"
40 #include "properties.h"
41 #include "misc.h"
42 #include "control.h"
43 #include "effects-generic.h"
44 #include "effects-convex.h"
45 #include "accel-util.h"
46 
47 static void do_group_constant_entity(expression exp, set constants)
48 {
50  {
53  if (value_symbolic_p(cv))
54  set_add_element(constants,constants,call_function(c));
55  else if (value_constant_p(cv) && get_bool_property("GROUP_CONSTANTS_LITERAL")) {
56  set_add_element(constants,constants,call_function(c));
57 
58  }
59  }
60 }
61 
62 /* remove entities involved in a range from the set of constants */
63 static bool do_group_statement_constant_filter(range r,set constants) {
65  set_difference(constants,constants,ref);
66  set_free(ref);
67  return false;
68 }
69 
70 static bool not_type_chunk_p(void* obj) {
71  return !INSTANCE_OF(type,(gen_chunkp)obj);
72 }
73 
74 /* remove entities that are never referenced by @p st from @p s */
76 {
78  set_intersection(s,s,ref);
79  set_free(ref);
80 }
81 
82 /* gather all entities that are read and constant in statement @p s in
83  * the set @p of constant entities */
84 static void do_group_statement_constant(statement st, set constants)
85 {
86  list regions = load_rw_effects_list(st);
87  list read_regions = regions_read_regions(regions);
88  list write_regions = regions_write_regions(regions);
89  set written_entities = set_make(set_pointer);
90 
91  /* first gather all written entities */
92  FOREACH(REGION,reg,write_regions)
93  {
96  set_add_element(written_entities,written_entities,var);
97  }
98  gen_free_list(write_regions);
99 
100 
101  /* then search among all read and not written variables
102  * those who have constant phis
103  */
104  FOREACH(REGION,reg,read_regions)
105  {
108  if(!set_belong_p(written_entities,var))
109  {
110  bool found_not_constant_constraint = false;
111  Psysteme sc = sc_dup(region_system(reg));
114  {
115  Variable phi = expression_to_entity(index);
116  bool phi_found_p =false;
117  for(Pcontrainte iter = sc_inegalites(sc);iter;iter=contrainte_succ(iter))
118  {
119  Pvecteur cvect = contrainte_vecteur(iter);
120  Value phi_coeff = vect_coeff(phi,cvect);
121  /* we have found the right vector, now check for other vectors */
122  if(phi_coeff != VALUE_ZERO )
123  {
124  phi_found_p=true;
125  Pvecteur other_vects = vect_del_var(cvect,phi);
126  found_not_constant_constraint|=vect_size(other_vects)!=1 || VARIABLE_DEFINED_P(other_vects->var);
127  vect_rm(other_vects);
128  }
129  }
130  found_not_constant_constraint |=!phi_found_p;
131  }
132  if(!found_not_constant_constraint) {
133  set_add_element(constants,constants,var);
134  }
135  else {
136  /* check the size too : small means mask */
137  Ppolynome pp = region_enumerate(reg);
138  if(!POLYNOME_UNDEFINED_P(pp)) {
140  intptr_t ipp;
141  if(expression_integer_value(epp,&ipp) && ipp < 33)
142  found_not_constant_constraint=false;
143  free_expression(epp);
144  polynome_free(pp);
145  }
146  if(!found_not_constant_constraint)
147  set_add_element(constants,constants,var);
148  }
149  }
150  }
151  /* then prune this set, because it contains the preconditions too */
152  do_group_statement_constant_prune(st,constants);
153 
154  /* eventually filter out some entities involved in range computation */
155  if(get_bool_property("GROUP_CONSTANTS_SKIP_LOOP_RANGE"))
157  gen_free_list(read_regions);
158  set_free(written_entities);
159 }
160 
161 typedef enum {
165 
167 {
168  const char* layout = get_string_property("GROUP_CONSTANTS_LAYOUT");
169  if(same_string_p(layout,"terapix")) return TERAPIX_GROUPING;
170  return GROUPING_UNDEFINED;
171 }
172 
173 static void* do_group_basics_maximum_reduce(void *v,const list l)
174 {
175  return basic_maximum((basic)v,entity_basic(ENTITY(CAR(l))));
176 }
177 
179 {
180  if(ENDP(entities)) return basic_undefined;
182 }
183 
184 static void *do_group_count_elements_reduce(void * v, const list l)
185 {
186  entity e = ENTITY(CAR(l));
189  else
191 }
192 
194 {
196 }
197 
198 static bool group_constant_range_filter(range r, set constants)
199 {
200  pips_assert("true", r==r && constants==constants);
201  return !get_bool_property("GROUP_CONSTANTS_SKIP_LOOP_RANGE");
202 }
203 
206 {
207  if(gen_get_ancestor(range_domain,exp) && get_bool_property("GROUP_CONSTANTS_SKIP_LOOP_RANGE") )
208  return false;
210  {
213  }
214  return true;
215 }
216 
218 {
219  return do_grouping_filter_out_self(e);
220 }
221 
222 typedef struct {
224  entity new;
227 
229 {
231  {
234  {
235  /* compute new index */
236  expression current_index = reference_offset(ref);
237  /* perform substitution */
238  reference_variable(ref)=ctxt->new;
241  }
242  }
243 }
244 
246 {
247  grouping_context ctxt = { old,new,offset };
249 }
250 
251 static void do_group_constants_terapix(statement in,set constants)
252 {
253  list lconstants = set_to_sorted_list(constants,(gen_cmp_func_t)compare_entities);
254  basic max = do_group_basics_maximum(lconstants);
255  if(!basic_undefined_p(max))
256  {
257  expression size = do_group_count_elements(lconstants);
259  get_string_property("GROUP_CONSTANTS_HOLDER"),
262  CONS(DIMENSION,
265  NIL),
266  NIL)
267  );
268 
269  /* it may not be possible to initialize statically the array, so use loop initialization
270  * to be more general
271  */
272  list initializations_holder_seq = NIL;
273  expression index = int_to_expression(0);
274 
275  FOREACH(ENTITY,econstant,lconstants)
276  {
277  if((entity_variable_p(econstant) && entity_scalar_p(econstant)) || entity_constant_p(econstant))
278  {
280  initializations_holder_seq=CONS(STATEMENT,
282  new_constant_exp,
283  entity_to_expression(econstant)
284  ),
285  initializations_holder_seq);
288  }
289  else {
290  list indices = NIL;
291  reference lhs = make_reference(constant_holder,NIL);// the indices will be set later
292  reference rhs = make_reference(econstant,NIL);// the indices will be set later I told you
295  dimensions=gen_nreverse(dimensions);
296  FOREACH(DIMENSION,dim,dimensions)
297  {
303  }
306  initializations_holder_seq=CONS(STATEMENT,body,initializations_holder_seq);
308  index=make_op_exp(PLUS_OPERATOR_NAME,index,SizeOfDimensions(dimensions));
309  gen_free_list(dimensions);
310  }
311  }
312  insert_statement(in,make_block_statement(gen_nreverse(initializations_holder_seq)),true);
314  }
315  gen_free_list(lconstants);
316 }
317 
318 
319 
320 static void do_group_constants(statement in,set constants)
321 {
322  /* as of now, put everything in an array, no matter of the real type, yes it is horrible,
323  * but it matches my needs for terapix, where everything as the same type
324  * later on, you may want to use a structure to pass parameters*/
325  switch(get_grouping_layout()) {
326  case TERAPIX_GROUPING:
327  return do_group_constants_terapix(in,constants);
328  case GROUPING_UNDEFINED:
329  pips_user_error("no valid grouping layout given\n");
330  }
331 }
332 
333 /* Do not touch to the prettyprint control list
334  *
335  * Might be better to avoid it... at least for functions if not
336  * control units.
337  */
338 static bool declaration_filter(call c)
339 {
340  bool go_on_p = true;
341  entity f = call_function(c);
342  if(ENTITY_CONTINUE_P(f))
343  go_on_p = false;
344  return go_on_p;
345 }
346 
347 bool group_constants(const string module_name)
348 {
349  /* prelude */
353 
354  set/*of entities*/ constants=set_make(set_pointer);;
355 
356  /* gather statement constants */
357  statement constant_statement = find_statement_from_label_name(get_current_module_statement(),module_name,get_string_property("GROUP_CONSTANTS_STATEMENT_LABEL"));
358  if(statement_undefined_p(constant_statement)) constant_statement=get_current_module_statement();
359  do_group_statement_constant(constant_statement,constants);
360 
361  /* gather constants */
362  gen_context_multi_recurse(constant_statement,constants,
367 
368  /* pack all constants and perform replacement */
369  do_group_constants(constant_statement,constants);
370 
371  set_free(constants);
372 
373  /* validate */
376 
377  /*postlude*/
381  return true;
382 }
instruction make_instruction_loop(loop _field_)
Definition: ri.c:1175
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
Definition: ri.c:1301
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
basic make_basic_int(intptr_t _field_)
Definition: ri.c:158
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
execution make_execution_sequential(void)
Definition: ri.c:841
void free_expression(expression p)
Definition: ri.c:853
range dimension_to_range(dimension)
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
#define VALUE_ZERO
int Value
#define contrainte_succ(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
#define region_any_reference(reg)
To be avoided.
#define region_system(reg)
#define REGION
#define max(a, b)
static Value offset
Definition: translation.c:283
list regions_write_regions(list)
list regions_read_regions(list)
Ppolynome region_enumerate(effect)
void set_rw_effects(statement_effects)
list load_rw_effects_list(statement)
void reset_rw_effects(void)
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
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
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
static bool group_constant_range_filter(range r, set constants)
static void do_group_constant_entity(expression exp, set constants)
static bool do_grouping_filter_out_self(expression exp)
static void do_grouping_replace_reference_by_expression_walker(expression exp, grouping_context *ctxt)
static basic do_group_basics_maximum(list entities)
static grouping_layout get_grouping_layout()
static void do_group_statement_constant_prune(statement st, set s)
remove entities that are never referenced by st from s
grouping_layout
@ TERAPIX_GROUPING
@ GROUPING_UNDEFINED
static entity constant_holder
static void do_group_constants_terapix(statement in, set constants)
bool group_constants(const string module_name)
Dependences for accel-util.h.
static void do_group_constants(statement in, set constants)
static bool do_group_statement_constant_filter(range r, set constants)
remove entities involved in a range from the set of constants
static expression do_group_count_elements(list entities)
static void * do_group_basics_maximum_reduce(void *v, const list l)
static void * do_group_count_elements_reduce(void *v, const list l)
static void do_group_statement_constant(statement st, set constants)
gather all entities that are read and constant in statement s in the set of constant entities
static bool declaration_filter(call c)
Do not touch to the prettyprint control list.
static bool not_type_chunk_p(void *obj)
static bool do_grouping_filter_out_self2(expression e, _UNUSED_ void *ctx)
static void do_grouping_replace_reference_by_expression(void *in, entity old, entity new, expression offset)
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 replace_entity_by_expression_with_filter(void *s, entity ent, expression exp, bool(*filter)(expression))
Definition: replace.c:204
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
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_false(__attribute__((unused)) gen_chunk *unused)
Return false and ignore the argument.
Definition: genClib.c:2796
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
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 NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
#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
#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
void * gen_reduce(void *r, void *(*fp)(void *, const list), const list l)
Definition: list.c:180
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
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
statement find_statement_from_label_name(statement, const char *, const char *)
Definition: statement.c:3816
static list indices
Definition: icm.c:204
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define _UNUSED_
Definition: misc-local.h:232
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_user_error
Definition: misc-local.h:147
#define same_string_p(s1, s2)
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
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
int(* gen_cmp_func_t)(const void *, const void *)
Definition: newgen_types.h:114
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
Ppolynome polynome_free(Ppolynome pp)
Ppolynome polynome_free(Ppolynome pp) frees space occupied by polynomial pp returns pp == POLYNOME_NU...
Definition: pnome-alloc.c:191
#define POLYNOME_UNDEFINED_P(pp)
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define make_expression_list(stats...)
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define DEFAULT_INTEGER_TYPE_SIZE
#define INSTANCE_OF(type, value)
polymorhism thanks to newgen !
#define ENTITY_CONTINUE_P(e)
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
#define entity_constant_p(e)
bool entity_not_constant_or_intrinsic_p(entity e)
Default entity filter for get_referenced_entities()
Definition: entity.c:3050
int compare_entities(const entity *pe1, const entity *pe2)
Comparison function for qsort.
Definition: entity.c:1328
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
set get_referenced_entities_filtered(void *elem, bool(*chunk_filter)(void *), bool(*entity_filter)(entity))
Same as get_referenced_entities, but will only consider entities that fulfills entity_filter and will...
Definition: entity.c:2982
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_empty_label(void)
Definition: entity.c:1105
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
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
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
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
call expression_call(expression e)
Definition: expression.c:445
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
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 reference_offset(reference ref)
computes the offset of a C reference with its origin
Definition: expression.c:3807
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
expression polynome_to_expression(Ppolynome pp)
converts a polynomial to expression
Definition: expression.c:3622
type ultimate_type(type)
Definition: type.c:3466
expression SizeOfDimensions(list)
computes the product of all dimensions in dims
Definition: size.c:522
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_with_prefix(const char *, entity, basic)
Create a new scalar variable of type b in the given module.
Definition: variable.c:592
basic basic_maximum(basic, basic)
Definition: type.c:1816
#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 ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_variable(x)
Definition: ri.h:2949
#define value_constant_p(x)
Definition: ri.h:3071
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define basic_overloaded_p(x)
Definition: ri.h:623
#define basic_undefined_p(x)
Definition: ri.h:557
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define basic_undefined
Definition: ri.h:556
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define value_symbolic_p(x)
Definition: ri.h:3068
#define reference_indices(x)
Definition: ri.h:2328
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_undefined_p(x)
Definition: ri.h:2420
#define entity_type(x)
Definition: ri.h:2792
#define range_domain
newgen_ram_domain_defined
Definition: ri.h:330
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
void sc_transform_eg_in_ineg(Psysteme sc)
Package sc.
#define intptr_t
Definition: stdint.in.h:294
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Variable var
Definition: vecteur-local.h:90
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
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
#define VARIABLE_DEFINED_P(v)
Definition: vecteur-local.h:66
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_del_var(Pvecteur v_in, Variable var)
Pvecteur vect_del_var(Pvecteur v_in, Variable var): allocation d'un nouveau vecteur egal a la project...
Definition: unaires.c:206
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228