PIPS
points_to_prettyprint.c
Go to the documentation of this file.
1 /*
2 
3  $Id: points_to_prettyprint.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  * (prettyg)print of POINTS TO.
26  *
27  * AM, August 2009.
28  */
29 #ifdef HAVE_CONFIG_H
30  #include "pips_config.h"
31 #endif
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 
36 #include "genC.h"
37 #include "linear.h"
38 
39 #include "text.h"
40 #include "text-util.h"
41 
42 #include "ri.h"
43 #include "effects.h"
44 #include "ri-util.h"
45 #include "effects-util.h"
46 
47 #include "pipsdbm.h"
48 #include "properties.h"
49 #include "misc.h"
50 
51 #include "prettyprint.h"
52 #include "semantics.h" // ??? bound_printed_points_to_list_p
53 
54 #include "points-to.h"
55 
56 #define PT_TO_SUFFIX ".points_to"
57 #define PT_TO_DECO "points to = "
58 #define SUMMARY_PT_TO_SUFFIX ".summary_points_to"
59 #define SUMMARY_PT_TO_DECO "summary points to = "
60 
61 /****************************************************** STATIC INFORMATION */
62 GENERIC_GLOBAL_FUNCTION(printed_points_to_list, statement_points_to)
63 
64 /************************************************************* BASIC WORDS */
65 
66 text text_points_to(entity module __attribute__ ((__unused__)),int margin __attribute__ ((__unused__)), statement s)
67 {
68 
69  text t;
78 
79 
80  return t;
81 }
82 
83 
85 {
86  text t;
87  debug_on("PRETTYPRINT_DEBUG_LEVEL");
91  debug_off();
92  return t;
93 }
94 
95 /* bool print_code_points_to(const char* module_name, */
96 /* string resource_name __attribute__ ((__unused__)), */
97 /* string file_suffix) */
98 /* { */
99 /* list wl = list_undefined; */
100 /* text t, st = text_undefined; */
101 /* bool res; */
102 /* debug_on("POINTS_TO_DEBUG_LEVEL"); */
103 /* set_current_module_entity(local_name_to_top_level_entity(module_name)); */
104 /* points_to_list summary_pts_to = (points_to_list) */
105 /* db_get_memory_resource(DBR_SUMMARY_POINTS_TO_LIST, module_name, true); */
106 /* wl = words_points_to_list(PT_TO_DECO, summary_pts_to); */
107 /* pips_debug(1, "considering module %s \n", */
108 /* module_name); */
109 
110 /* /\* FI: just for debugging *\/ */
111 /* // check_abstract_locations(); */
112 /* set_printed_points_to_list((statement_points_to) */
113 /* db_get_memory_resource(DBR_POINTS_TO_LIST, module_name, true)); */
114 /* statement_points_to_consistent_p(get_printed_points_to_list()); */
115 /* set_current_module_statement((statement) */
116 /* db_get_memory_resource(DBR_CODE, */
117 /* module_name, */
118 /* true)); */
119 /* // FI: should be language neutral... */
120 
121 /* st = words_predicate_to_commentary(wl, get_comment_sentinel()); */
122 /* t = text_code_points_to(get_current_module_statement()); */
123 /* MERGE_TEXTS(st, t); */
124 /* res= make_text_resource_and_free(module_name,DBR_PRINTED_FILE,file_suffix, st); */
125 /* reset_current_module_entity(); */
126 /* reset_current_module_statement(); */
127 /* reset_printed_points_to_list(); */
128 /* debug_off(); */
129 /* return true; */
130 /* } */
132  string resource_name __attribute__ ((__unused__)),
133  string file_suffix)
134 {
135  //list wl = list_undefined;
136  bool res;
137  debug_on("POINTS_TO_DEBUG_LEVEL");
139 
140 
141  /* Load IN pts-to */
142  points_to_list pts_to_in = (points_to_list)
143  db_get_memory_resource(DBR_POINTS_TO_IN, module_name, true);
144  //list l_pt_to_in = points_to_list_list(pts_to_in);
145 
146  /* Load OUT pts-to */
147  points_to_list pts_to_out = (points_to_list)
148  db_get_memory_resource(DBR_POINTS_TO_OUT, module_name, true);
149  //list l_pt_to_out = points_to_list_list(pts_to_out);
150 
151  pips_debug(1, "considering module %s \n",
152  module_name);
153 
154  /* FI: just for debugging */
155  // check_abstract_locations();
157  db_get_memory_resource(DBR_POINTS_TO, module_name, true));
158  /* statement_points_to_consistent_p(get_printed_points_to_list()); */
160  db_get_memory_resource(DBR_CODE,
161  module_name,
162  true));
163 
165  /* text sum_tex = text_points_to_relations(l_sum_pt_to, "Points To:"); */
166  text in_tex = text_points_to_relations(pts_to_in, "Points To IN:");
167  text out_tex = text_points_to_relations(pts_to_out, "Points To OUT:");
168  text t = make_text(NIL);
169  /* MERGE_TEXTS( t, sum_tex ); */
170  MERGE_TEXTS( t, in_tex );
171  MERGE_TEXTS( t, out_tex );
174  res = make_text_resource_and_free(module_name,DBR_PRINTED_FILE,file_suffix, t);
179  debug_off();
180  return res;
181 }
182 
184 {
185  text t = text_points_to_relations(ptl, "");
186  print_text(stderr, t);
187  free_text(t);
188 }
189 
191 {
192  bool ok = !points_to_graph_bottom(ptg);
193  if(!ok)
194  fprintf(stderr, "Points-to graph does not exist, dead code\n");
195  else {
196  set s = points_to_graph_set(ptg);
197  print_points_to_set("", s);
198  }
199 }
200 
201 //Handlers for PIPSMAKE
203 {
205  DBR_POINTS_TO,
206  PT_TO_SUFFIX);
207 }
208 
209 
211 {
212  cell source = points_to_source(pt);
213  cell sink = points_to_sink(pt);
214 
215  pips_assert("there should not be preference cells in points to (source) \n",
216  !cell_preference_p(source));
217  pips_assert("there should not be preference cells in points to (sink) \n",
218  !cell_preference_p(sink));
219 
220  pips_assert("gaps not handled yet (source)", !cell_gap_p(source));
221  pips_assert("gaps not handled yet (sink)", !cell_gap_p(sink));
222 
223 
224  list w = NIL;
225 
226  reference source_ref = cell_reference(source);
227  reference sink_ref = cell_reference(sink);
229  pips_assert("approximation is not must\n", !approximation_exact_p(ap));
230 
231  w = gen_nconc(w, effect_words_reference(source_ref));
232  w = CHAIN_SWORD(w," -> ");
233  if(!nowhere_cell_p(sink)) {
234  w = gen_nconc(w, effect_words_reference(sink_ref));
235  }
236  else {
237  string undef = "undefined" ;
238  w = gen_nconc(w, CONS(STRING,undef,NIL));
239  }
240 
241  w = CHAIN_SWORD(w, approximation_may_p(ap) ? " (may)" : " (exact)" );
242  return (w);
243 }
244 
245 #define append(s) add_to_current_line(line_buffer, s, str_prefix, tpt_to)
246 
247 /* text text_region(effect reg)
248  * input : a region
249  * output : a text consisting of several lines of commentaries,
250  * representing the region
251  * modifies : nothing
252  */
254 {
255  text tpt_to = text_undefined;
256 
257  bool foresys = false;
258  string str_prefix = get_comment_continuation();
260  Psysteme sc;
261  list /* of string */ ls;
262 
263  if (points_to_undefined_p(pt_to))
264  {
265  ifdebug(1)
266  {
267  return make_text(CONS(SENTENCE,
269  strdup(concatenate(str_prefix,
270  "undefined points to relation\n",
271  NULL))),
272  NIL));
273  }
274  else
275  pips_user_warning("unexpected points-to relation undefined\n");
276  }
277  else
278  tpt_to = make_text(NIL);
279 
280  cell source = points_to_source(pt_to);
281  cell sink = points_to_sink(pt_to);
282 
283  pips_assert("there should not be preference cells in points to relation (source) \n",
284  !cell_preference_p(source));
285  pips_assert("there should not be preference cells in points to relation (sink) \n",
286  !cell_preference_p(sink));
287 
288  pips_assert("gaps not handled yet (source)", !cell_gap_p(source));
289  pips_assert("gaps not handled yet (sink)", !cell_gap_p(sink));
290 
291 
292  reference source_r = cell_reference(source);
293  reference sink_r = cell_reference(sink);
295  descriptor d = points_to_descriptor(pt_to);
296 
297  /* PREFIX
298  */
300  append(" ");
301 
302  /* REFERENCES */
303  ls = effect_words_reference(source_r);
304 
305  FOREACH(STRING, s, ls) {append(s);}
306  gen_free_string_list(ls); ls = NIL;
307 
308  append(" -> ");
309 
310  /* Change nowhere cells into undefined to comply with the C standard */
311  entity e = reference_variable(sink_r);
313  ls = effect_words_reference(sink_r);
314  }
315  else {
316  string undef = "undefined" ;
317  ls = CONS(STRING,strdup(undef),NIL);
318  }
319  // ls = effect_words_reference(sink_r);
320  /* if (points_to_second_address_of_p(pt_to)) */
321  /* append("&"); */
322 
323  FOREACH(STRING, s, ls) {append(s);}
324  gen_free_string_list(ls); ls = NIL;
325 
326  /* DESCRIPTOR */
327  /* sorts in such a way that constraints with phi variables come first.
328  */
329  if(!descriptor_none_p(d))
330  {
331  sc = sc_copy(descriptor_convex(d));
333  system_sorted_text_format(line_buffer, str_prefix, tpt_to, sc,
335  vect_contains_phi_p, foresys);
336  sc_rm(sc);
337  }
338 
339  /* APPROXIMATION */
340  append(approximation_may_p(ap) ? " , MAY" : " , EXACT");
341 
342  /* CLOSE */
343  close_current_line(line_buffer, tpt_to, str_prefix);
344 
345  return tpt_to;
346 }
347 
348 text
350 {
351  list l_pt_to = points_to_list_list(ptl);
352  bool bottom_p = points_to_list_bottom(ptl);
353 
354  text tpt_to = make_text(NIL);
355  /* in case of loose_prettyprint, at least one region to print? */
356  bool loose_p = get_bool_property("PRETTYPRINT_LOOSE");
357 
358  /* GO: No redundant test anymore, see text_statement_array_regions */
359  if (l_pt_to != (list) HASH_UNDEFINED_VALUE && l_pt_to != list_undefined)
360  {
361  /* header first */
363  string str_prefix = get_comment_continuation();
364  if (loose_p)
365  {
366  strcpy(line_buffer,"\n");
368  }
369  else
370  {
372  }
373  append(" ");
374  append(header);
375  if(bottom_p)
376  append(" unreachable\n");
377  else if(ENDP(l_pt_to))
378  append(" none\n");
379  else
380  append("\n");
381  ADD_SENTENCE_TO_TEXT(tpt_to,
383  strdup(line_buffer)));
384  l_pt_to = points_to_list_sort(l_pt_to);
385  FOREACH(points_to, pt_to, l_pt_to)
386  {
387  MERGE_TEXTS(tpt_to, text_points_to_relation(pt_to));
388  }
389 
390  if (loose_p)
391  ADD_SENTENCE_TO_TEXT(tpt_to,
393  strdup("\n")));
394  }
395  return tpt_to;
396 }
397 
398 /* print a points-to arc, print_points_to() or print_points_to_arc() */
400 {
401  text t = text_points_to_relation(pt_to);
402  print_text(stderr, t);
403  free_text(t);
404 }
405 
406 /* print a list of points-to arcs */
408 {
409  fprintf(stderr,"\n");
410  if (ENDP(l_pt_to))
411  fprintf(stderr,"<none>");
412  else
413  {
414  FOREACH(POINTS_TO, pt, l_pt_to)
415  {
417  }
418  }
419  fprintf(stderr,"\n");
420 }
421 
423 {
425  text t = text_points_to_relations(ptl, "Points To:");
426  return t;
427 }
428 
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
sentence make_sentence(enum sentence_utype tag, void *val)
Definition: text.c:59
text make_text(list a)
Definition: text.c:107
void free_text(text p)
Definition: text.c:74
bool entity_typed_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
int is_inferior_cell_descriptor_pvarval(Pvecteur *pvarval1, Pvecteur *pvarval2)
weight function for Pvecteur passed as argument to sc_lexicographic_sort in prettyprint functions inv...
Definition: compare.c:305
void system_sorted_text_format(string line, string prefix, text txt, Psysteme ps, string(*variable_name)(Variable), bool(*put_first)(Pvecteur), bool a_la_fortran)
lower level hook for regions.
#define resource_name(x)
Definition: database.h:108
list effect_words_reference(reference)
prettyprint.c
Definition: prettyprint.c:68
const char * pips_region_user_name(entity)
char * pips_region_user_name(entity ent) output : the name of entity.
Definition: prettyprint.c:169
list points_to_list_sort(list)
Allocate a copy of ptl and sort it.
Definition: prettyprint.c:389
bool nowhere_cell_p(cell)
Target of an undefined pointer.
Definition: effects.c:455
list words_points_to_list(string, points_to_list)
bool vect_contains_phi_p(Pvecteur)
bool vect_contains_phi_p(Pvecteur v) input : a vector output : true if v contains a PHI variable,...
Definition: effects.c:1427
#define cell_reference(x)
Definition: effects.h:469
#define approximation_exact_p(x)
Definition: effects.h:369
#define approximation_may_p(x)
Definition: effects.h:363
#define cell_gap_p(x)
Definition: effects.h:473
#define descriptor_convex(x)
Definition: effects.h:601
#define cell_preference_p(x)
Definition: effects.h:470
#define descriptor_none_p(x)
Definition: effects.h:602
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define STRING(x)
Definition: genC.h:87
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
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_free_string_list(list ls)
Definition: list.c:564
#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 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 list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
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 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 pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define GENERIC_GLOBAL_FUNCTION(name, type)
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
static char * module
Definition: pips.c:74
bool bound_printed_points_to_list_p(statement)
void set_printed_points_to_list(statement_points_to)
void print_points_to_set(string, set)
void reset_printed_points_to_list(void)
points_to_list load_printed_points_to_list(statement)
void print_points_to_relation(points_to pt_to)
print a points-to arc, print_points_to() or print_points_to_arc()
bool print_code_points_to(const char *module_name, string resource_name __attribute__((__unused__)), string file_suffix)
bool print_code_points_to(const char* module_name,
void print_points_to_relations(list l_pt_to)
print a list of points-to arcs
text text_code_points_to(statement s)
bool print_code_points_to_list(const char *module_name)
text text_points_to_relation(points_to pt_to)
text text_region(effect reg) input : a region output : a text consisting of several lines of commenta...
void print_points_to_list(points_to_list ptl)
text text_points_to_relations(points_to_list ptl, string header)
text text_pt_to(entity __attribute__((unused)) module_name, int __attribute__((unused)) margin, statement s)
#define PT_TO_SUFFIX
void print_points_to_graph(points_to_graph ptg)
#define append(s)
list words_points_to(points_to pt)
text text_points_to(entity module __attribute__((__unused__)), int margin __attribute__((__unused__)), statement s)
#define PT_TO_DECO
#define points_to_approximation(x)
#define points_to_undefined_p(x)
#define points_to_sink(x)
#define points_to_list_list(x)
#define points_to_graph_bottom(x)
#define POINTS_TO(x)
POINTS_TO.
#define points_to_list_bottom(x)
struct _newgen_struct_points_to_list_ * points_to_list
#define points_to_graph_set(x)
#define points_to_descriptor(x)
#define points_to_source(x)
string get_comment_sentinel()
Start a single line comment.
Definition: misc.c:154
string get_comment_continuation()
Start a single line comment with continuation (blank spaces)
Definition: misc.c:167
void close_prettyprint()
because some prettyprint functions may be used for debug, so the last hook set by somebody may have s...
Definition: misc.c:242
void init_prettyprint(text(*hook)(entity, int, statement))
checks that the prettyprint hook was actually reset...
Definition: misc.c:231
text text_module(entity, statement)
bool make_text_resource_and_free(const char *, const char *, const char *, text)
Definition: print.c:82
static int * line_buffer
le buffer contenant la ligne que l'on doit lire en avance pour se rendre compte qu'on a finit de lire...
Definition: reader.c:251
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
#define reference_variable(x)
Definition: ri.h:2326
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Psysteme sc_copy(Psysteme ps)
Psysteme sc_copy(Psysteme ps): duplication d'un systeme (allocation et copie complete des champs sans...
Definition: sc_alloc.c:230
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
void sc_lexicographic_sort(Psysteme sc, int(*compare)(Pvecteur *, Pvecteur *))
Minimize first the lexico-graphic weight of each constraint according to the comparison function "com...
Definition: sc_unaires.c:206
text words_predicate_to_commentary(list w_pred, string comment_prefix)
text words_predicate_to_commentary(list w_pred, string comment_prefix) input : a list of strings,...
Definition: prettyprint.c:653
#define ifdebug(n)
Definition: sg.c:47
static bool ok
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
#define CHAIN_SWORD(l, s)
#define MERGE_TEXTS(r, t)
#define ADD_SENTENCE_TO_TEXT(t, p)
#define MAX_LINE_LENGTH
maximum length of a line when prettyprinting...
void print_text(FILE *fd, text t)
Definition: print.c:195
void close_current_line(string, text, string)
Definition: util.c:235
#define SENTENCE(x)
newgen_unformatted_domain_defined
Definition: text.h:36
#define text_undefined
Definition: text.h:91
@ is_sentence_formatted
Definition: text.h:57
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62