PIPS
constraints.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 constraintes.c
24  * solve constraints equation for restricted hardware
25  * @author Serge Guelton <serge.guelton@enst-bretagne.fr>
26  * @date 2010-05-01
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 "linear.h"
36 #include "ri.h"
37 #include "effects.h"
38 #include "ri-util.h"
39 #include "workspace-util.h"
40 #include "effects-util.h"
41 #include "text.h"
42 #include "pipsdbm.h"
43 #include "resources.h"
44 #include "properties.h"
45 #include "misc.h"
46 #include "control.h"
47 #include "conversion.h"
48 #include "expressions.h"
49 #include "effects-generic.h"
50 #include "effects-simple.h"
51 #include "effects-convex.h"
52 #include "text-util.h"
53 #include "parser_private.h"
54 #include "semantics.h"
55 #include "transformer.h"
56 #include "accel-util.h"
57 
60 
61  list read_regions = regions_read_regions(regions);
62  list write_regions = regions_write_regions(regions);
64  /* add a new constraint to the system */
65  Pvecteur pv = vect_new(e,-1);
66  vect_add_elem(&pv,TCST,3);
68  contrainte_make(pv));
69 
70  set visited_entities = set_make(set_pointer);
71 
73  FOREACH(REGION,reg,regions)
74  {
77  /* check we have not already dealt with this variable */
78  if(!set_belong_p(visited_entities,e))
79  {
80  set_add_element(visited_entities,visited_entities,e);
81  if(entity_array_p(e)) {
82  /* get the associated read and write regions */
83  region read_region = find_region_on_entity(e,read_regions);
84  region write_region = find_region_on_entity(e,write_regions);
85  /* compute their convex hull */
86  region rw_region =
87  region_undefined_p(read_region)?write_region:
88  region_undefined_p(write_region)?read_region:
89  regions_must_convex_hull(read_region,write_region);
90 
91  region hregion = rw_region;//region_hypercube(rw_region);
94  Pbase phis = list_to_base(ephis);
95  gen_free_list(ephis);
96  Psysteme hsc = sc_rectangular_hull(region_system(hregion),phis);
97  base_rm(phis);
98 
99  Pcontrainte lower,upper;
100  constraints_for_bounds(phi,&sc_inegalites(hsc),&lower,&upper);
101  if(!CONTRAINTE_UNDEFINED_P(lower) && !CONTRAINTE_UNDEFINED_P(upper))
102  {
104  simplify_minmax_expression(elower,tr);
106  simplify_minmax_expression(eupper,tr);
107  expression dist = make_op_exp(MINUS_OPERATOR_NAME,eupper,elower);
109 
110  if(expression_undefined_p(max_dim))
111  max_dim = dist;
112  else {
113  max_dim = MakeBinaryCall(
115  max_dim,
116  dist
117  );
118  simplify_minmax_expression(max_dim,tr);
119  }
120 
121  }
122  else
123  pips_user_error("failed to gather enough information for entity %s\n",entity_user_name(e));
124  }
125  }
126  }
127  int max_volume= get_int_property("SOLVE_HARDWARE_CONSTRAINTS_LIMIT");
128  if(max_volume<=0) pips_user_error("constraint limit must be greater than 0\n");
129  /* solve the equation if it is linear */
130  max_dim=make_op_exp(MINUS_OPERATOR_NAME,max_dim,int_to_expression(max_volume));
131  NORMALIZE_EXPRESSION(max_dim);
132  normalized n = expression_normalized(max_dim);
133  if(normalized_linear_p(n)) {
134  /* create a system with preconditions information and the constraint limit*/
137  /* find numerical constraints over unknown e */
138  Value min,max;
139  if(sc_minmax_of_variable(sc,e,&min,&max)) {
141  /* SG: this is over optimistic,
142  * we should verify all elements of soluce are store-independant
143  */
146  soluce);
147  }
148  else /* welcome in the real life (RK(C) we cannot solve this equation at commile time ... never mind let's do it at runtime ! */
149  pips_user_error("unable to solve the equation at compile time\n");
150  }
151  else pips_user_error("unable to get a linear expression for nbproc\n");
152 
153  set_free(visited_entities);
154  gen_free_list(read_regions);
155  gen_free_list(write_regions);
156  free_transformer(tr);
157  return true;
158 }
159 
162 
163  list read_regions = regions_read_regions(regions);
164  list write_regions = regions_write_regions(regions);
166 
167  set visited_entities = set_make(set_pointer);
168 
169  Ppolynome volume_used = POLYNOME_NUL;
170  FOREACH(REGION,reg,regions)
171  {
173  entity e = reference_variable(r);
174  /* check we have not already dealt with this variable */
175  if(!set_belong_p(visited_entities,e))
176  {
177  set_add_element(visited_entities,visited_entities,e);
178  if(entity_array_p(e)) {
179  /* get the associated read and write regions */
180  region read_region = find_region_on_entity(e,read_regions);
181  region write_region = find_region_on_entity(e,write_regions);
182  /* compute their convex hull */
183  region rw_region =
184  region_undefined_p(read_region)?write_region:
185  region_undefined_p(write_region)?read_region:
186  regions_must_convex_hull(read_region,write_region);
187 
188  region hregion = rw_region;//region_hypercube(rw_region);
189  Ppolynome p = region_enumerate(hregion);
190  if(!POLYNOME_UNDEFINED_P(p)) {
191  polynome_add(&volume_used,p);
192  polynome_rm(&p);
193  }
194  else
195  pips_user_error("unable to compute volume of the region of %s\n",entity_user_name(e));
196  }
197  }
198  }
199  int max_volume= get_int_property("SOLVE_HARDWARE_CONSTRAINTS_LIMIT");
200  if(max_volume<=0) pips_user_error("constraint limit must be greater than 0\n");
201  /* create a string representation of all polynomials gathered */
202  Pmonome m = monome_constant_new(-max_volume);
203  polynome_monome_add(&volume_used,m);
204  monome_rm(&m);
205  /* try to solve the polynomial */
206  Pvecteur roots = polynome_roots(volume_used,unknown);
208  if(VECTEUR_UNDEFINED_P(roots)) { // that is volume_used is independent of unknown
209  expression cst = polynome_to_expression(volume_used);
211  intptr_t val;
212  if(expression_integer_value(cst,&val) && val < 0 )
213  eroot=int_to_expression(42);//any value is ok
214  else
215  // no return
216  pips_user_error("no solution possible for this limit\n");
217  }
218  else {
219  Ppolynome root = (Ppolynome)vecteur_var(roots);//yes take the first without thinking more ...
220  eroot = polynome_to_expression(root);
222  /* this takes the floor of the floating point expression ...*/
223  int ival = (int)expression_to_float(eroot);
224  free_expression(eroot);
225  eroot=int_to_expression(ival);
226  }
227  }
228 
229  /* insert solution ~ this is an approximation !
230  * it only works if root is increasing
231  */
234  true);
235 
236  /* tidy */
237  for(Pvecteur v = roots;!VECTEUR_NUL_P(v);v=vecteur_succ(v))
239  vect_rm(roots);
240  set_free(visited_entities);
241  gen_free_list(read_regions);
242  gen_free_list(write_regions);
243  free_transformer(tr);
244  return true;
245 }
246 
247 /* the equation is given by sum(e) { | REGION_READ(e) U REGION_WRITE(e) | } < VOLUME */
249 {
250 
251  /* retreive the unknown variable { */
252  entity unknown = string_to_entity(get_string_property("SOLVE_HARDWARE_CONSTRAINTS_UNKNOWN"),get_current_module_entity());
253  if(entity_undefined_p(unknown))
254  pips_user_error("must provide the unknown value\n");
255  /* } */
256  const char* constraint_type = get_string_property("SOLVE_HARDWARE_CONSTRAINTS_TYPE");
257  if(same_string_p(constraint_type, "VOLUME"))
258  return do_solve_hardware_constraints_on_volume(unknown,s);
259  else if(same_string_p(constraint_type, "NB_PROC"))
261  else {
262  pips_user_error("constraint type '%s' unknown\n",constraint_type);
263  return false;
264  }
265 }
266 
268 {
269  debug_on("SOLVE_HARDWARE_CONSTRAINTS");
276 
277  const char* stmt_label=get_string_property("SOLVE_HARDWARE_CONSTRAINTS_LABEL");
279 
280  bool result =false;
281  if(!statement_undefined_p(equation_to_solve))
282  {
283  if((result=do_solve_hardware_constraints(equation_to_solve))) {
284  /* validate */
287  }
288  }
289 
296  debug_off();
297  return result;
298 }
int get_int_property(const string)
void free_transformer(transformer p)
Definition: ri.c:2616
value make_value_expression(expression _field_)
Definition: ri.c:2850
void free_expression(expression p)
Definition: ri.c:853
void free_value(value p)
Definition: ri.c:2787
effect find_region_on_entity(entity, list)
void const char const char const int
int Value
static bool do_solve_hardware_constraints_on_volume(entity unknown, statement s)
Definition: constraints.c:160
static bool do_solve_hardware_constraints(statement s)
the equation is given by sum(e) { | REGION_READ(e) U REGION_WRITE(e) | } < VOLUME
Definition: constraints.c:248
bool solve_hardware_constraints(const char *module_name)
constraints.c
Definition: constraints.c:267
static bool do_solve_hardware_constraints_on_nb_proc(entity e, statement s)
Definition: constraints.c:58
#define CONTRAINTE_UNDEFINED_P(c)
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
void constraints_for_bounds(Variable, Pcontrainte *, Pcontrainte *, Pcontrainte *)
void constraints_for_bounds(var, pinit, plower, pupper) Variable var; Pcontrainte *pinit,...
Definition: unaires.c:176
expression constraints_to_loop_bound(Pcontrainte, Variable, bool, entity)
expression constraints_to_loop_bound(c, var, is_lower)
#define region_any_reference(reg)
To be avoided.
#define region_system(reg)
#define region_undefined_p(reg)
#define REGION
#define region
simulation of the type region
effect regions_must_convex_hull(region f1, region f2)
1- Union :
#define min(a, b)
#define max(a, b)
list regions_write_regions(list)
list regions_read_regions(list)
Ppolynome region_enumerate(effect)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
list load_cumulated_rw_effects_list(statement)
effects load_cumulated_rw_effects(statement)
void reset_cumulated_rw_effects(void)
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void partial_eval_expression_and_regenerate(expression *, Psysteme, effects)
Definition: partial_eval.c:284
char * get_string_property(const char *)
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
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
#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
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
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
#define pips_user_error
Definition: misc-local.h:147
Pbase list_to_base(list l)
Pbase list_to_base(list l): returns the Pbase that contains the variables of list "l",...
entity string_to_entity(const char *s, entity module)
very simple conversion from string to expression only handles entities and numeric values at the time...
Definition: naming.c:237
#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_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 monome_rm(Pmonome *ppm)
void monome_rm(Pmonome* ppm) PRIVATE frees space occupied by monomial *ppm returns *ppm pointing to M...
Definition: pnome-alloc.c:154
void polynome_rm(Ppolynome *ppp)
void polynome_rm(Ppolynome* ppp) frees space occupied by polynomial *ppp returns *ppp pointing to POL...
Definition: pnome-alloc.c:170
void polynome_monome_add(Ppolynome *ppp, Pmonome pm)
void polynome_monome_add(Ppolynome* ppp, Pmonome pm) PRIVATE Add monomial pm to polynomial *ppp,...
Definition: pnome-bin.c:50
void polynome_add(Ppolynome *ppp, Ppolynome pp2)
void polynome_add(Ppolynome* ppp, Ppolynome pp2) (*ppp) = (*ppp) + pp2.
Definition: pnome-bin.c:171
Pvecteur polynome_roots(Ppolynome p, Variable var)
computes the possible roots of a polynomial currently only works for degree 0,1,2) returned value is ...
Definition: pnome-root.c:48
Psysteme sc_rectangular_hull(Psysteme, Pbase)
take the rectangular bounding box of the systeme sc, by projecting each constraint of the systeme aga...
Definition: sc_enveloppe.c:456
#define POLYNOME_NUL
#define monome_constant_new(coeff)
#define POLYNOME_UNDEFINED_P(pp)
struct Spolynome * Ppolynome
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define MAX_OPERATOR_NAME
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define NORMALIZE_EXPRESSION(e)
#define DIVIDE_OPERATOR_NAME
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_array_p(entity e)
Is e a variable with an array type?
Definition: entity.c:754
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
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
bool expression_integer_constant_p(expression e)
Definition: expression.c:2417
list expressions_to_entities(list expressions)
map expression_to_entity on expressions
Definition: expression.c:3161
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
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
expression Value_to_expression(Value v)
added interface for linear stuff.
Definition: expression.c:1251
float expression_to_float(expression exp)
Same as above for floating point constants.
Definition: expression.c:2305
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
#define normalized_linear_p(x)
Definition: ri.h:1779
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
#define expression_undefined
Definition: ri.h:1223
#define transformer_relation(x)
Definition: ri.h:2873
#define expression_normalized(x)
Definition: ri.h:1249
#define reference_indices(x)
Definition: ri.h:2328
#define expression_undefined_p(x)
Definition: ri.h:1224
#define statement_undefined_p(x)
Definition: ri.h:2420
#define normalized_linear(x)
Definition: ri.h:1781
#define predicate_system(x)
Definition: ri.h:2069
#define entity_initial(x)
Definition: ri.h:2796
void sc_add_egalite(Psysteme p, Pcontrainte e)
void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une egalite e a un systeme p; la base ...
Definition: sc_alloc.c:389
void sc_add_inegalite(Psysteme p, Pcontrainte i)
void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une inegalite i a un systeme p; la b...
Definition: sc_alloc.c:406
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
bool sc_minmax_of_variable(Psysteme ps, Variable var, Value *pmin, Value *pmax)
void sc_minmax_of_variable(Psysteme ps, Variable var, Value *pmin, *pmax): examine un systeme pour tr...
Definition: sc_eval.c:143
void simplify_minmax_expression(expression e, transformer tr)
tries hard to simplify expression e if it is a min or a max operator, by evaluating it under precondi...
Definition: expression.c:5849
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
transformer load_statement_precondition(statement)
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
#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
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
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define vecteur_succ(v)
#define VECTEUR_NUL_P(v)
#define base_rm(b)
#define VECTEUR_UNDEFINED_P(v)
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72