PIPS
unstructured.c
Go to the documentation of this file.
1 /*
2 
3  $Id: unstructured.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 
25 /*
26  * This file contains functions used to deal with unstructured statements
27  *
28  * The similar functions in Amira's implementation are located in
29  * points_to_analysis_general_algorithm.c.
30  */
31 
32 #include <stdlib.h>
33 #include <stdio.h>
34 
35 #include "genC.h"
36 #include "linear.h"
37 
38 #include "ri.h"
39 #include "effects.h"
40 
41 #include "ri-util.h"
42 #include "effects-util.h"
43 
44 #include "misc.h"
45 #include "properties.h"
46 
47 #include "prettyprint.h" // for debugging
48 
49 #include "points-to.h"
50 
51 // FI: I have not cleaned up these functions yet
52 
53 // FI: I avoid name conflicts by declaring them static
54 
56 {
57  return (statement_ordering(s1) == statement_ordering(s2));
58 }
59 
60 /* test if a control belong to a set */
62 {
63  bool in_p = false;
64  SET_FOREACH(control, n, s) {
66  in_p = true;
67  }
68  return in_p;
69 }
70 
71 bool control_equal_p(const void* vc1, const void* vc2)
72 {
73  control c1 = (control)vc1;
74  control c2 = (control)vc2;
77 
79 
80 }
81 
82 /* create a key which is the statement number */
83 _uint control_rank( const void * vc, size_t size)
84 {
85  control c = (control)vc;
87  // FI: use asprintf?
88  extern char * int2a(int);
89  string key = strdup(int2a(statement_ordering(s)));
90  return hash_string_rank(key,size);
91 }
92 
93 
94 /* A node is ready to be processed if its predecessors are not
95  * reachable or processed.
96  */
97 bool Ready_p(control c, set Processed, set Reachable)
98 {
99  set Pred = set_make(set_pointer);
100  list Pred_l = control_predecessors(c);
101  FOREACH(control, ctr, Pred_l) {
102  Pred = set_add_element(Pred, Pred, (void*)ctr);
103  }
104  /* Pred = set_assign_list(Pred,gen_full_copy_list( Pred_l)); */
105  bool ready_p = false;
106  SET_FOREACH(control, p , Pred) {
107  ready_p = set_belong_p(Processed,(void*) p) || !set_belong_p(Reachable,(void*) p);
108  }
109  return ready_p;
110 }
111 
112 
113 /* A set containing all the successors of n that are ready to be processed */
114 set ready_to_be_processed_set(control n, set Processed, set Reachable)
115 {
116  set Succ = set_make(set_pointer);
117  set rtbp = set_make(set_pointer);
118  list Succ_l = control_successors(n);
119  FOREACH(control, ctr, Succ_l) {
120  Succ = set_add_element(Succ, Succ, (void*)ctr);
121  }
122  /* Succ = set_assign_list(Succ, gen_full_copy_list(Succ_l)); */
123  SET_FOREACH(control, p , Succ){
124  if(Ready_p(p, Processed, Reachable))
125  set_add_element(rtbp, rtbp, (void*)p);
126  }
127  return rtbp;
128 }
129 
130 
131 static pt_map control_to_points_to(control c, pt_map in, __attribute__ ((__unused__))bool store)
132 {
133  pt_map out = new_pt_map();
134 
137  out = statement_to_points_to(s, in); // FI: seems to anihilate
138  // previous assignment to out
139 
141  FOREACH(control, ctr, Succ_l) {
143  }
145 
146  return out;
147 }
148 
149 
150 //
151 // FI: a little bit of clean-up from here down, in fact, renaming
152 // rather than cleaning
153 //
154 
155 
156 /*
157  in: unreachable controls
158  out: points_to computed in a flow-insensitive way
159 */
161  pt_map in,
162  bool store __attribute__ ((unused)))
163 {
164  pt_map out = new_pt_map();
165  set Pred = set_make(set_pointer);
166  set Succ = set_make(set_pointer);
167  /* sequence seq = sequence_undefined; */
168  list /* seq_l = NIL, */ succ = NIL, pred = NIL;
170  SET_FOREACH(control, c, ctrls) {
172  pred = control_predecessors(c);
173  /* Pred = set_assign_list(Pred, gen_full_copy_list(pred)); */
174  }
175  FOREACH(control, ctr, pred) {
176  Pred = set_add_element(Pred, Pred, (void*)ctr);
177  }
178  SET_FOREACH(control, p, Pred) {
180  succ = gen_copy_seq(control_successors(p));
181  }
182 
183 
184  Succ = set_assign_list(Succ, succ);
185  SET_FOREACH(control, s, Succ) {
187  }
188  return out;
189 }
190 
191 
192 /*
193  For unstructured code, we ignore the statements order and we construct a
194  sequence of statments from the entry and the exit control. This sequence
195  will be analyzed in an flow-insensitive way.
196 
197  After the analysis of the unstructured we have to change the exact points-to
198  relations into may points-to.
199 
200  FI: is the may flag enough? Are the comments above still consistent
201 with the code? Is this correct and cover all execution orders? How is a fix point reached?
202 
203  */
205  pt_map pt_in_g,
206  bool __attribute__ ((__unused__))store)
207 {
208  set pt_in = points_to_graph_set(pt_in_g);
213  pt_map out_g = new_pt_map();
214  list Pred_l = NIL, nodes_l = NIL, nodes_l_exit = NIL ;
215  list blocs = NIL ;
217  control_rank);
219  control_rank);
221  control_rank);
223  control_rank);
225  control_rank);
227  control_rank);
229  control_rank);
231  control_rank);
233  control_rank);
234  control entry = unstructured_control(uns) ;
236  Pred_l = control_predecessors(entry);
237  Pred = set_assign_list(Pred, gen_full_copy_list(Pred_l));
238  list trail = unstructured_to_trail(uns);
239 
240  /* Get all the nodes of the unstructured*/
241 #if 0
242  CONTROL_MAP(c, {
243  ;
244  }, entry, nodes_l) ;
245 #endif
246  FOREACH(control, ctrl, trail) {
247  Nodes = set_add_element(Nodes, Nodes, (void*)ctrl);
248  }
249 #if 0
250  CONTROL_MAP(c, {
251  ;
252  }, exit, nodes_l_exit) ;
253 #endif
254  nodes_l = gen_nconc(nodes_l, nodes_l_exit);
255 
256  /* Gel all the reachable nodes of the unstructured */
257 /* #if 0 */
259  Reachable = set_add_element(Reachable, Reachable, (void*)c);
260  }, entry, blocs) ;
261 /* #endif */
262 
263  bool inter_p = set_intersection_p(Reachable, Pred);
264  if(!inter_p)
265  set_add_element(rtbp, rtbp, (void*)entry);
266  else {
267  /* The entry node is part of a cycle, rtbp is empty and the while
268  loop below is soing to be skipped. Relation "out_g" must be
269  properly initialized. */
270  out_g = full_copy_pt_map(pt_in_g);
271  }
272 
273  while(!set_empty_p(rtbp)) {
274  rtbp_tmp = set_assign(rtbp_tmp,rtbp);
275  SET_FOREACH(control, n , rtbp) {
276  // to test the control's equality, I test if their statements are equals
278  pt_in_n = set_assign(pt_in_n, pt_in);
279  out = set_assign(out, pt_in_n);
280  }
281  Pred_l = NIL;
282  Pred_l = control_predecessors(n);
283  FOREACH(control, ctr, Pred_l) {
284  Pred = set_add_element(Pred, Pred, (void*)ctr);
285  }
286  set_clear(Pred);
287  /* Pred = set_assign_list(Pred, gen_full_copy_list(Pred_l)); */
288  inter = set_intersection(inter,Reachable, Pred);
289  out_g = make_points_to_graph(false, out);
290  SET_FOREACH(control, p , inter) {
291  out_g = control_to_points_to(p, out_g, true);
292  }
293  out_g = control_to_points_to(n, out_g, true);
294  if(!control_in_set_p(n, Processed))
295  Processed = set_add_element(Processed,Processed, (void*)n );
296  rtbp_tmp = set_del_element(rtbp_tmp,rtbp_tmp,(void*)n);
297  rtbp_tmp = set_union(rtbp_tmp,rtbp_tmp,
298  ready_to_be_processed_set(n, Processed, Reachable));
299  set_clear(rtbp);
300  rtbp = set_assign(rtbp,rtbp_tmp);
301  }
302  }
303 
304  UnProcessed = set_difference(UnProcessed, Reachable, Processed);
305  out_g = cyclic_graph_to_points_to(UnProcessed, out_g, store);
306  tmp = set_difference(tmp, Nodes, Reachable);
307  SET_FOREACH(control, cc, tmp) {
308  pt_in_n = set_clear(pt_in_n);
309  out_g = statement_to_points_to(control_statement(cc), out_g);
310  }
311 
312  free(blocs);
313  free(nodes_l);
314  statement exit_s = control_statement(exit);
315  out_g = merge_points_to_graphs(out_g, pt_in_g);
316  out_g = statement_to_points_to(exit_s, out_g);
317  return out_g;
318 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
points_to_graph make_points_to_graph(bool a1, set a2)
#define new_pt_map()
static FILE * out
Definition: alias_check.c:128
void free(void *)
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
#define FORWARD_CONTROL_MAP(ctl, code, c, list)
Walk through all the controls forward-reachable from a given control node of an unstructured.
#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
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#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
_uint hash_string_rank(const void *, size_t)
en s'inspirant vaguement de Fast Hashing of Variable-Length Text Strings Peter K.
Definition: hash.c:642
struct _newgen_struct_control_ * control
#define exit(code)
Definition: misc-local.h:54
set set_generic_make(set_type, hash_equals_t, hash_rank_t)
what about this replacement? #define SET_MAP(the_item, the_code, the_set) \ { SET_FOREACH(void *,...
Definition: set.c:83
bool set_empty_p(const set)
tell whether set s is empty.
Definition: set.c:367
set set_assign_list(set, const list)
assigns a list contents to a set all duplicated elements are lost
Definition: set.c:474
bool set_intersection_p(const set, const set)
returns whether s1 n s2 <> 0 complexity of the intersection
Definition: set.c:288
set set_del_element(set, const set, const void *)
Definition: set.c:265
set set_intersection(set, const set, const set)
Definition: set.c:229
set set_assign(set, const set)
Assign a set with the content of another set.
Definition: set.c:129
set set_difference(set, const set, const set)
Definition: set.c:256
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
set set_clear(set)
Assign the empty set to s s := {}.
Definition: set.c:326
bool set_belong_p(const set, const void *)
Definition: set.c:194
set set_union(set, const set, const set)
Definition: set.c:211
@ set_pointer
Definition: newgen_set.h:44
@ set_private
Definition: newgen_set.h:45
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
uintptr_t _uint
Definition: newgen_types.h:54
static bool statement_equal_p(statement s1, statement s2)
Definition: unstructured.c:55
bool control_equal_p(const void *vc1, const void *vc2)
Definition: unstructured.c:71
set ready_to_be_processed_set(control n, set Processed, set Reachable)
A set containing all the successors of n that are ready to be processed.
Definition: unstructured.c:114
static pt_map cyclic_graph_to_points_to(set ctrls, pt_map in, bool store __attribute__((unused)))
Definition: unstructured.c:160
static pt_map control_to_points_to(control c, pt_map in, __attribute__((__unused__)) bool store)
Definition: unstructured.c:131
pt_map new_points_to_unstructured(unstructured uns, pt_map pt_in_g, bool __attribute__((__unused__)) store)
Definition: unstructured.c:204
_uint control_rank(const void *vc, size_t size)
create a key which is the statement number
Definition: unstructured.c:83
bool control_in_set_p(control c, set s)
test if a control belong to a set
Definition: unstructured.c:61
bool Ready_p(control c, set Processed, set Reachable)
A node is ready to be processed if its predecessors are not reachable or processed.
Definition: unstructured.c:97
_uint points_to_rank(const void *, size_t)
create a key which is a concatenation of the source's name, the sink's name and the approximation of ...
pt_map full_copy_pt_map(pt_map)
Definition: statement.c:67
pt_map points_to_graph_assign(pt_map, pt_map)
pt_map statement_to_points_to(statement, pt_map)
See points_to_statement()
Definition: statement.c:154
int points_to_equal_p(const void *, const void *)
returns true if two points-to arcs "vpt1" and "vpt2" are equal.
Definition: points_to_set.c:98
pt_map merge_points_to_graphs(pt_map, pt_map)
#define points_to_graph_set(x)
list unstructured_to_trail(unstructured u)
Definition: unstructured.c:240
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define control_predecessors(x)
Definition: ri.h:943
#define statement_ordering(x)
Definition: ri.h:2454
#define control_successors(x)
Definition: ri.h:945
#define unstructured_exit(x)
Definition: ri.h:3006
#define control_statement(x)
Definition: ri.h:941
char * strdup()
s1
Definition: set.c:247
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
char * int2a(int)
util.c
Definition: util.c:42