PIPS
propagation.c
Go to the documentation of this file.
1 /*
2 
3  $Id: propagation.c 23065 2016-03-02 09:05:50Z 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 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 #include "genC.h"
29 #include "linear.h"
30 #include "ri.h"
31 #include "effects.h"
32 
33 #include "resources.h"
34 
35 #include "misc.h"
36 #include "ri-util.h"
37 #include "effects-util.h"
38 #include "pipsdbm.h"
39 #include "reductions.h"
40 #include "expressions.h"
41 
42 #include "dg.h"
43 
46 
47 #include "graph.h"
48 #include "ricedg.h"
49 
50 
51 #include "control.h"
52 
53 
54 /* sg: this function does a huge pattern matching :)
55  * and is not very smart
56  */
60  {
62  if(!set_belong_p(seen,s)) {
64  /* lazy ... s = f(sigma) */
65  if(assignment_statement_p(s)) {
66  expression assigned_exp = binary_call_lhs(statement_call(s));
67  /* lazier */
68  if(expression_reference_p(assigned_exp)) {
70  if(expression_call_p(rhs)) {
71  reference assigned_ref = expression_reference(assigned_exp);
72  if(reference_scalar_p(assigned_ref)) {
73  call rhs_call = expression_call(rhs);
74  entity rhs_op = call_function(rhs_call);
75 
77  vertex sv = successor_vertex(su);
79  /* even lazier */
80  if(assignment_statement_p(ssv)) {
82  /* we got some simple reductions here, try to propagate them backward */
83  if(gen_length(reductions) == 1 ) {
87  if(effect_read_p(conflict_sink(con)) &&
90  expression rhs_fst_arg =EXPRESSION(CAR(call_arguments(rhs_call)));
91  if(expression_scalar_p(rhs_fst_arg)) {
92  reference rhs_fst_ref = copy_reference(expression_reference(rhs_fst_arg));
94  replace_entity_by_expression(s,reference_variable(rhs_fst_ref),red_exp);
95  replace_reference(ssv,assigned_ref,reference_variable(rhs_fst_ref));
96  replace_entity_by_expression(s,reference_variable(assigned_ref),red_exp);
97  free_reference(rhs_fst_ref);
99  free_expression(red_exp);
100  }
101  else pips_user_warning("replacement of non reference expression not implemented yet \n");
102  }
103  }
104  }
105  }
106  }
107  }
108  }
109  }
110  }
111  }
112  }
113  }
114  set_free(seen);
115 }
116 /* now try to backward propagate the reduction, if it is meaningful.
117  * the pattern checked is
118  * a = b + c;
119  * r = r + a;
120  * which should become
121  * r = r +b ;
122  * r = r +c ;
123  */
124 
125 bool reduction_propagation(const char * mod_name) {
126  /* get the resources */
127  statement mod_stmt = (statement)
128  db_get_memory_resource(DBR_CODE, mod_name, true);
129 
130  set_current_module_statement(mod_stmt);
131  set_proper_reductions((pstatement_reductions) db_get_memory_resource(DBR_PROPER_REDUCTIONS, mod_name, true));
133  set_ordering_to_statement(mod_stmt);
135  (graph) db_get_memory_resource(DBR_DG, mod_name, true);
136 
138 
139  /* do the job */
141 
142  /* validate computation */
143  module_reorder(mod_stmt);
144  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name, mod_stmt);
145 
146  /* update/release resources */
151  return true;
152 }
153 
157  /* this looks like a potential reduction to me */
161  if ( reference_scalar_p(out) ) {
162  pips_debug(1,"potential reduction: %s\n",entity_user_name(reference_variable(out)));
163  *relevant=c;
164  break;
165  }
166  else out = reference_undefined;
167  }
168  }
169  return out;
170 }
171 
172 static bool potential_reduction_substitution_valid_p(list/*of successors*/ sus, conflict legal_conflict,reference ref) {
173  FOREACH(SUCCESSOR,su,sus) {
176  ) {
177  return false;
178  }
179  }
180  }
181  return true;
182 }
183 
184 /* sg: this function does a huge pattern matching :)
185  * and is not very smart
186  */
190  {
192  if(!set_belong_p(seen,s) ) {
194  /* lazy ... s = f(sigma) */
195  if(assignment_statement_p(s)) {
196  expression assigned_exp = binary_call_lhs(statement_call(s));
197  /* lazier , only scalar on lhs */
198  if(expression_scalar_p(assigned_exp)) {
200  /* lazier, only intrinsic call on rhs */
201  if(expression_call_p(rhs)) {
202  reference assigned_ref = expression_reference(assigned_exp);
203  conflict cculprit = conflict_undefined;
204  call rhs_call = expression_call(rhs);
205  entity rhs_op = call_function(rhs_call);
206  if(intrinsic_entity_p(rhs_op)) {
207  reference potential_reduction = reference_undefined;
208  /* look for a potential reduction */
210  vertex sv = successor_vertex(su);
211  statement ssv = vertex_to_statement(sv);
212  /* even lazier */
213  if(assignment_statement_p(ssv)) {
214  expression assigned_exp_sv = binary_call_lhs(statement_call(ssv));
215  if(expression_scalar_p(assigned_exp_sv)) {
216  reference assigned_ref_sv = expression_reference(assigned_exp_sv);
217  potential_reduction = guess_potential_reduction(su,&cculprit);
218  if(!reference_undefined_p(potential_reduction) &&
219  reference_equal_p(potential_reduction,assigned_ref_sv)) {
220  break;
221  }
222  }
223  }
224  }
225  /* verify validity of the substitution */
226  if(!reference_undefined_p(potential_reduction)) {
227  if(potential_reduction_substitution_valid_p(vertex_successors(v),cculprit,potential_reduction)) {
228  pips_debug(1,"replacing %s by %s\n",entity_user_name(reference_variable(assigned_ref)),entity_user_name(reference_variable(potential_reduction)));
230  replace_reference(get_current_module_statement(),assigned_ref,reference_variable(potential_reduction));
231  set_free(seen);
232  return true;
233  }
234  }
235  }
236  }
237  }
238  }
239  }
240  }
241  set_free(seen);
242  return false;
243 }
244 
245 bool reduction_detection(const char * mod_name) {
246  /* get the resources */
247  statement mod_stmt = (statement)
248  db_get_memory_resource(DBR_CODE, mod_name, true);
249 
250  set_current_module_statement(mod_stmt);
252  set_ordering_to_statement(mod_stmt);
254  (graph) db_get_memory_resource(DBR_DG, mod_name, true);
255 
256  /* do the job */
257  debug_on("REDUCTION_DETECTION_DEBUG_LEVEL");
259  debug_off();
260  if(res) {
261  /* validate computation */
262  module_reorder(mod_stmt);
263  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name, mod_stmt);
264  }
265 
266  /* update/release resources */
270  return res;
271 }
static hash_table seen
static function to store whether a module has been seen during the recursive generation of the daVinc...
Definition: graph.c:85
void free_reference(reference p)
Definition: ri.c:2050
void free_expression(expression p)
Definition: ri.c:853
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
static graph dependence_graph
Definition: delay.c:93
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static FILE * out
Definition: alias_check.c:128
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
Definition: chains.c:124
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
#define conflict_sink(x)
Definition: dg.h:167
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define conflict_source(x)
Definition: dg.h:165
#define conflict_undefined
Definition: dg.h:140
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
void simplify_c_operator(statement)
replace PLUS_C_OPERATOR_NAME by PLUS_OPERATOR_NAME when relevant
Definition: simplify.c:621
#define successor_vertex(x)
Definition: graph.h:118
#define successor_arc_label(x)
Definition: graph.h:116
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define graph_vertices(x)
Definition: graph.h:82
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
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_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
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
size_t gen_length(const list l)
Definition: list.c: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
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool assignment_statement_p(statement)
Test if a statement is an assignment.
Definition: statement.c:135
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define debug_off()
Definition: misc-local.h:160
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
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
entity reduction_operator_entity(reduction_operator op)
match a reduction operator against operator entity
Definition: reductions.c:577
bool reduction_propagation(const char *mod_name)
now try to backward propagate the reduction, if it is meaningful.
Definition: propagation.c:125
static bool potential_reduction_substitution_valid_p(list sus, conflict legal_conflict, reference ref)
Definition: propagation.c:172
static bool do_reduction_detection(graph dg)
sg: this function does a huge pattern matching :) and is not very smart
Definition: propagation.c:187
bool reduction_detection(const char *mod_name)
Definition: propagation.c:245
dg_vertex_label vertex_label
Definition: propagation.c:45
static void do_reduction_propagation(graph dg)
sg: this function does a huge pattern matching :) and is not very smart
Definition: propagation.c:57
dg_arc_label arc_label
Definition: propagation.c:44
static reference guess_potential_reduction(successor su, conflict *relevant)
Definition: propagation.c:154
reductions load_proper_reductions(statement)
void reset_proper_reductions(void)
void set_proper_reductions(pstatement_reductions)
#define REDUCTION(x)
REDUCTION.
#define reduction_op(x)
#define reduction_reference(x)
#define reductions_list(x)
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define binary_call_rhs(c)
#define expression_scalar_p(e)
#define binary_call_lhs(c)
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 intrinsic_entity_p(entity e)
Definition: entity.c:1272
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
expression reference_to_expression(reference r)
Definition: expression.c:196
bool expression_call_p(expression e)
Definition: expression.c:415
call expression_call(expression e)
Definition: expression.c:445
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
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
bool reference_scalar_p(reference r)
This function returns true if Reference r is scalar.
Definition: expression.c:3530
void RemoveLocalEntityFromDeclarations(entity, entity, statement)
Definition: variable.c:120
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_undefined
Definition: ri.h:2302
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define reference_undefined_p(x)
Definition: ri.h:2303
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
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