PIPS
defs_elim.c
Go to the documentation of this file.
1 /*
2 
3  $Id: defs_elim.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 /* -- defs_elim.c
28  *
29  * package atomizer : Alexis Platonoff, aout 91
30  * --
31  *
32  * Those functions remove the definition instructions with no def-use
33  * dependence.
34  */
35 
36 #include "local.h"
37 #include "prettyprint.h"
38 
39 
40 
41 /*============================================================================*/
42 /* static vertex get_vertex_of_statement(graph dg, statement stmt): returns
43  * the vertex of "dg" corresponding to "stmt".
44  *
45  * We scan all the "dg" until we find the "vertex" with the same "ordering"
46  * as "stmt".
47  */
48 static vertex
50 graph dg;
52 {
54  list dg_vertices = graph_vertices(dg);
55  bool not_found = true;
56 
57  for(; (dg_vertices != NIL) && not_found ; dg_vertices = CDR(dg_vertices))
58  {
59  vertex v = VERTEX(CAR(dg_vertices));
61  {
62  rv = v;
63  not_found = false;
64  }
65  }
66  return(rv);
67 }
68 
69 
70 /*============================================================================*/
71 /* bool true_dependence_with_entity_p(conflict conf, entity e): returns TRUE
72  * if the conflict "conf" is a true dependence upon the entity "e".
73  *
74  * A true dependence is a conflict with a Write at the "source" and a Read
75  * at the "sink".
76  *
77  * called functions :
78  * _ effect_entity() : ri-util/util.c
79  * _ same_entity_p() : ri-util/util.c
80  */
81 bool
83 conflict conf;
84 entity e;
85 {
86  effect source_eff, sink_eff;
87  entity source_ent, sink_ent;
88 
89  source_eff = conflict_source(conf);
90  sink_eff = conflict_sink(conf);
91  source_ent = effect_entity(source_eff);
92  sink_ent = effect_entity(sink_eff);
93 
94  pips_debug(6, " CONFLICT : %s --> %s\n",
95  effect_to_string(source_eff),
96  effect_to_string(sink_eff));
97 
98  if(! same_entity_p(source_ent, sink_ent))
99  pips_internal_error("Source and sink entities must be equal");
100 
101  return( same_entity_p(e, source_ent) &&
102  (action_tag(effect_action(source_eff)) == is_action_write) &&
103  (action_tag(effect_action(sink_eff)) == is_action_read) );
104 }
105 
106 
107 /*============================================================================*/
108 /* static bool entity_dynamic_p(entity e): returns true if "e" is a local
109  * variable, ie an entity with a storage DYNAMIC.
110  *
111  * Called_functions :
112  * _ dynamic_area_p() : ri-util/util.c
113  */
114 static bool entity_dynamic_p(entity e)
115 {
116  ram r;
117  storage s = entity_storage(e);
118 
119  if(storage_tag(s) != is_storage_ram)
120  return(false);
121  r = storage_ram(s);
123  return(true);
124  return(false);
125 }
126 
127 
128 /*============================================================================*/
129 /* bool defs_elim_of_assign_call(statement assign_stmt, graph dg): returns
130  * true if "assign_stmt" is to be eliminated.
131  * It is eliminated if the lhs of this assignment verifies two conditions :
132  * 1. it is a local variable
133  * 2. it is not at the source of a def-use dependence, ie true dependence.
134  */
135 bool
137 statement assign_stmt;
138 graph dg;
139 {
140  call assign_call;
141  expression lhs_exp;
142  entity lhs_ent;
143  vertex stmt_vertex;
144  list succs;
145  bool true_dep_found = false;
146 
148  pips_internal_error("Statement must be a CALL");
149 
150  assign_call = instruction_call(statement_instruction(assign_stmt));
151  if(! ENTITY_ASSIGN_P(call_function(assign_call)))
152  pips_internal_error("Call must be an ASSIGN");
153 
154  pips_debug(5, "begin ASSIGN : %s\n",
155  words_to_string(Words_Call(assign_call, 0, true, true)));
156 
157  lhs_exp = EXPRESSION(CAR(call_arguments(assign_call)));
159  pips_internal_error("Lhs must be a REFERENCE");
160 
162 
163 /* Definitions upon non local (non dynamic) variables are always kept. */
164  if(! entity_dynamic_p(lhs_ent) )
165  return(false);
166 
167 /* Gets the vertex of the dependence graph that gives all the edges of
168  * which the assign statement is the source.
169  */
170  stmt_vertex = get_vertex_of_statement(dg, assign_stmt);
171 
172 /* We scan all the dependences of the assign statement. If at least one
173  * true dependence is found, the statement is not removed.
174  */
175  if(stmt_vertex != vertex_undefined)
176  {
177  list confs;
178  dg_arc_label dal;
179  succs = vertex_successors(stmt_vertex);
180  for(; (succs != NIL) && (! true_dep_found) ; succs = CDR(succs))
181  {
183  confs = dg_arc_label_conflicts(dal);
184  for(; (confs != NIL) && (! true_dep_found) ; confs = CDR(confs))
185  if( true_dependence_with_entity_p(CONFLICT(CAR(confs)), lhs_ent) )
186  true_dep_found = true;
187  }
188  }
189  else
190  user_warning("defs_elim_of_assign_call",
191  "Vertex of assign stmt should not be undefined\n");
192 
193  debug(5, "defs_elim_of_assign_call", "end ASSIGN , true dep : %s\n",
194  bool_to_string(true_dep_found));
195 
196  return(! true_dep_found);
197 }
198 
199 
200 
201 /*============================================================================*/
202 /* bool defs_elim_of_statement(statement s, graph dg): returns true if "s"
203  * is to be eliminated.
204  * As we eliminate assign statements, only statement with call to the
205  * assign function may be eliminated.
206  *
207  * Called_functions :
208  * _ make_empty_statement() : ri-util/statement.c
209  */
210 bool
212 statement s;
213 graph dg;
214 {
215  bool elim = false;
217 
218  debug(4, "defs_elim_of_statement", "begin STATEMENT\n");
219 
220  switch(instruction_tag(inst))
221  {
222  /* We scan all the statements of the block, and we build in the same time
223  * a new block where the statements to delete do not appear.
224  */
225  case is_instruction_block :
226  {
227  list new_block = NIL,
228  block = instruction_block(inst);
229  for(; block != NIL ; block = CDR(block))
230  {
233  new_block = gen_nconc(new_block, CONS(STATEMENT, stmt, NIL));
234  }
235  instruction_block(inst) = new_block;
236  break;
237  }
238  case is_instruction_test :
239  {
240  test t = instruction_test(inst);
245  break;
246  }
247  case is_instruction_loop :
248  {
249  loop l = instruction_loop(inst);
252  break;
253  }
254  case is_instruction_call :
255  {
256  call c = instruction_call(inst);
257 
258  debug(4, "defs_elim_of_statement", "Stmt CALL: %s\n",
260 
262  elim = defs_elim_of_assign_call(s, dg);
263  break;
264  }
265  case is_instruction_goto : break;
267  {
269  break;
270  }
271  default : pips_internal_error("Bad instruction tag");
272  }
273  debug(4, "defs_elim_of_statement", "end STATEMENT\n");
274 
275  return(elim);
276 }
277 
278 
279 /*============================================================================*/
280 /* void defs_elim_of_unstructured(unstructured, graph dg): computes the
281  * elimination of all the definitions with no def-use dependence of an
282  * unstructured instruction.
283  *
284  * If the statement of the control of a node of the control graph has to
285  * be eliminated, it is replaced by an empty block of statement.
286  *
287  * Called_functions :
288  * _ make_empty_statement() : ri-util/statement.c
289  */
290 void
292 unstructured u;
293 graph dg;
294 {
295  list blocs = NIL;
296 
297  debug(3, "defs_elim_of_unstructured", "begin UNSTRUCTURED\n");
298 
300  if(elim) { control_statement(c) = make_empty_statement();};},
301  unstructured_control( u ), blocs);
302 
303  gen_free_list(blocs);
304 
305  debug(3, "defs_elim_of_unstructured", "end UNSTRUCTURED\n");
306 }
307 
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
Definition: chains.c:124
static vertex get_vertex_of_statement(graph dg, statement stmt)
– defs_elim.c
Definition: defs_elim.c:49
bool true_dependence_with_entity_p(conflict conf, entity e)
===========================================================================
Definition: defs_elim.c:82
bool defs_elim_of_statement(statement s, graph dg)
===========================================================================
Definition: defs_elim.c:211
static bool entity_dynamic_p(entity e)
===========================================================================
Definition: defs_elim.c:114
bool defs_elim_of_assign_call(statement assign_stmt, graph dg)
===========================================================================
Definition: defs_elim.c:136
void defs_elim_of_unstructured(unstructured u, graph dg)
===========================================================================
Definition: defs_elim.c:291
struct _newgen_struct_dg_arc_label_ * dg_arc_label
Definition: dg.h:60
#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
string effect_to_string(effect)
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
#define effect_action(x)
Definition: effects.h:642
#define action_tag(x)
Definition: effects.h:310
@ is_action_write
Definition: effects.h:293
@ is_action_read
Definition: effects.h:292
#define vertex_undefined
Definition: graph.h:128
#define successor_arc_label(x)
Definition: graph.h:116
#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
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
#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
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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#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_internal_error
Definition: misc-local.h:149
#define user_warning(fn,...)
Definition: misc-local.h:262
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
string bool_to_string(bool)
Definition: string.c:243
list Words_Call(call obj, int precedence, bool leftmost, bool is_a_subroutine)
Definition: misc.c:2597
#define ENTITY_ASSIGN_P(e)
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define is_instruction_block
soft block->sequence transition
#define instruction_block(i)
#define make_empty_statement
An alias for make_empty_block_statement.
bool dynamic_area_p(entity aire)
Definition: area.c:68
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
#define loop_body(x)
Definition: ri.h:1644
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define storage_tag(x)
Definition: ri.h:2515
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
#define test_false(x)
Definition: ri.h:2837
#define entity_storage(x)
Definition: ri.h:2794
@ is_syntax_reference
Definition: ri.h:2691
#define ram_section(x)
Definition: ri.h:2249
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
@ is_storage_ram
Definition: ri.h:2492
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define test_true(x)
Definition: ri.h:2835
#define statement_instruction(x)
Definition: ri.h:2458
#define storage_ram(x)
Definition: ri.h:2521
#define instruction_call(x)
Definition: ri.h:1529
#define call_arguments(x)
Definition: ri.h:711
#define control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define expression_syntax(x)
Definition: ri.h:1247
#define instruction_unstructured(x)
Definition: ri.h:1532
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
int vertex_ordering(vertex)
Definition: util.c:51
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:54
string words_to_string(cons *lw)
Definition: print.c:211